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