1/*
2 * Copyright 2007-2010, Haiku, Inc. All rights reserved.
3 * Copyright 2003-2004 Kian Duffy, myob@users.sourceforge.net
4 * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai.
5 * All rights reserved. Distributed under the terms of the MIT license.
6 */
7
8#include "FindWindow.h"
9
10
11#include <Box.h>
12#include <Button.h>
13#include <Catalog.h>
14#include <CheckBox.h>
15#include <ControlLook.h>
16#include <GridLayoutBuilder.h>
17#include <GroupLayout.h>
18#include <GroupLayoutBuilder.h>
19#include <Locale.h>
20#include <RadioButton.h>
21#include <String.h>
22#include <TextControl.h>
23
24
25const uint32 MSG_FIND_HIDE = 'Fhid';
26const uint32 TOGGLE_FIND_CONTROL = 'MTFG';
27const BRect kWindowFrame(10, 30, 250, 200);
28
29#undef B_TRANSLATION_CONTEXT
30#define B_TRANSLATION_CONTEXT "Terminal FindWindow"
31
32FindWindow::FindWindow(BMessenger messenger, const BString& str,
33		bool findSelection, bool matchWord, bool matchCase, bool forwardSearch)
34	:
35	BWindow(kWindowFrame, B_TRANSLATE("Find"), B_FLOATING_WINDOW,
36		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE
37		| B_AUTO_UPDATE_SIZE_LIMITS),
38	fFindDlgMessenger(messenger)
39{
40	SetLayout(new BGroupLayout(B_VERTICAL));
41
42	BBox *separator = new BBox("separator");
43	separator->SetExplicitMinSize(BSize(250.0, B_SIZE_UNSET));
44	separator->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1.0));
45
46	BRadioButton* useSelection = NULL;
47	const float spacing = be_control_look->DefaultItemSpacing();
48	AddChild(BGroupLayoutBuilder(B_VERTICAL, 5.0)
49		.SetInsets(spacing, spacing, spacing, spacing)
50		.Add(BGridLayoutBuilder()
51			.Add(fTextRadio = new BRadioButton(B_TRANSLATE("Use text:"),
52				new BMessage(TOGGLE_FIND_CONTROL)), 0, 0)
53			.Add(fFindLabel = new BTextControl(NULL, NULL, NULL), 1, 0)
54			.Add(useSelection = new BRadioButton(B_TRANSLATE("Use selection"),
55				new BMessage(TOGGLE_FIND_CONTROL)), 0, 1))
56		.Add(separator)
57		.Add(fForwardSearchBox = new BCheckBox(B_TRANSLATE("Search forward")))
58		.Add(fMatchCaseBox = new BCheckBox(B_TRANSLATE("Match case")))
59		.Add(fMatchWordBox = new BCheckBox(B_TRANSLATE("Match word")))
60		.Add(fFindButton = new BButton(B_TRANSLATE("Find"),
61				new BMessage(MSG_FIND)))
62		.TopView());
63
64	fFindLabel->SetDivider(0.0);
65
66	if (!findSelection) {
67		fFindLabel->SetText(str.String());
68		fFindLabel->MakeFocus(true);
69	} else {
70		fFindLabel->SetEnabled(false);
71	}
72
73	if (findSelection)
74		useSelection->SetValue(B_CONTROL_ON);
75	else
76		fTextRadio->SetValue(B_CONTROL_ON);
77
78	if (forwardSearch)
79		fForwardSearchBox->SetValue(B_CONTROL_ON);
80
81	if (matchCase)
82		fMatchCaseBox->SetValue(B_CONTROL_ON);
83
84	if (matchWord)
85		fMatchWordBox->SetValue(B_CONTROL_ON);
86
87	fFindButton->MakeDefault(true);
88
89	AddShortcut((uint32)'W', B_COMMAND_KEY, new BMessage(MSG_FIND_HIDE));
90
91	Show();
92}
93
94
95FindWindow::~FindWindow()
96{
97}
98
99
100void
101FindWindow::MessageReceived(BMessage *msg)
102{
103	switch (msg->what) {
104		case B_QUIT_REQUESTED:
105			Quit();
106			break;
107
108		case MSG_FIND:
109			_SendFindMessage();
110			break;
111
112		case MSG_FIND_HIDE:
113			Quit();
114			break;
115
116		case TOGGLE_FIND_CONTROL:
117			fFindLabel->SetEnabled(fTextRadio->Value() == B_CONTROL_ON);
118			break;
119
120		default:
121			BWindow::MessageReceived(msg);
122			break;
123	}
124}
125
126
127void
128FindWindow::Quit()
129{
130	fFindDlgMessenger.SendMessage(MSG_FIND_CLOSED);
131	BWindow::Quit();
132}
133
134
135void
136FindWindow::_SendFindMessage()
137{
138	BMessage message(MSG_FIND);
139
140	if (fTextRadio->Value() == B_CONTROL_ON) {
141		message.AddString("findstring", fFindLabel->Text());
142		message.AddBool("findselection", false);
143	} else
144		message.AddBool("findselection", true);
145
146	//Add the other parameters
147	// TODO: "usetext" is never checked for elsewhere and seems
148	// redundant with "findselection", why is it here?
149	message.AddBool("usetext", fTextRadio->Value() == B_CONTROL_ON);
150	message.AddBool("forwardsearch", fForwardSearchBox->Value() == B_CONTROL_ON);
151	message.AddBool("matchcase", fMatchCaseBox->Value() == B_CONTROL_ON);
152	message.AddBool("matchword", fMatchWordBox->Value() == B_CONTROL_ON);
153
154	fFindDlgMessenger.SendMessage(&message);
155}
156