xref: /haiku/src/apps/terminal/FindWindow.cpp (revision b8ded2f89783a220c7b3019d48266a682cc79158)
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 
29 const uint32 MSG_FIND_HIDE = 'Fhid';
30 const uint32 TOGGLE_FIND_CONTROL = 'MTFG';
31 const BRect kWindowFrame(10, 30, 250, 200);
32 
33 
34 #undef B_TRANSLATION_CONTEXT
35 #define B_TRANSLATION_CONTEXT "Terminal FindWindow"
36 
37 
FindWindow(BMessenger messenger,const BString & str,bool findSelection,bool matchWord,bool matchCase,bool forwardSearch)38 FindWindow::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 
~FindWindow()104 FindWindow::~FindWindow()
105 {
106 }
107 
108 
109 void
MessageReceived(BMessage * msg)110 FindWindow::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 
136 void
Quit()137 FindWindow::Quit()
138 {
139 	fFindDlgMessenger.SendMessage(MSG_FIND_CLOSED);
140 	BWindow::Quit();
141 }
142 
143 
144 void
_SendFindMessage()145 FindWindow::_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