xref: /haiku/src/apps/stylededit/ReplaceWindow.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2002-2009, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Mattias Sundblad
7  *		Andrew Bachmann
8  */
9 
10 
11 #include "Constants.h"
12 #include "ReplaceWindow.h"
13 
14 #include <Button.h>
15 #include <Catalog.h>
16 #include <CheckBox.h>
17 #include <GroupLayoutBuilder.h>
18 #include <GridLayoutBuilder.h>
19 #include <Handler.h>
20 #include <Locale.h>
21 #include <LayoutBuilder.h>
22 #include <Message.h>
23 #include <Messenger.h>
24 #include <String.h>
25 #include <TextControl.h>
26 
27 
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "FindandReplaceWindow"
30 
31 ReplaceWindow::ReplaceWindow(BRect frame, BHandler* _handler,
32 	BString* searchString, 	BString* replaceString,
33 	bool caseState, bool wrapState, bool backState)
34 	: BWindow(frame, B_TRANSLATE("Replace"), B_FLOATING_WINDOW,
35 		B_NOT_RESIZABLE |  B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
36 		| B_AUTO_UPDATE_SIZE_LIMITS, B_CURRENT_WORKSPACE)
37 {
38 	AddShortcut('W', B_COMMAND_KEY, new BMessage(MSG_HIDE_WINDOW));
39 
40 	fSearchString = new BTextControl("", B_TRANSLATE("Find:"), NULL, NULL);
41 	fReplaceString = new BTextControl("", B_TRANSLATE("Replace with:"),
42 		NULL, NULL);
43 	fCaseSensBox = new BCheckBox("", B_TRANSLATE("Case-sensitive"), NULL);
44 	fWrapBox = new BCheckBox("", B_TRANSLATE("Wrap-around search"), NULL);
45 	fBackSearchBox = new BCheckBox("", B_TRANSLATE("Search backwards"), NULL);
46 	fAllWindowsBox = new BCheckBox("", B_TRANSLATE("Replace in all windows"),
47 		new BMessage(CHANGE_WINDOW));
48 	fUIchange = false;
49 
50 	fReplaceAllButton = new BButton("", B_TRANSLATE("Replace all"),
51 		new BMessage(MSG_REPLACE_ALL));
52 	fCancelButton = new BButton("", B_TRANSLATE("Cancel"),
53 		new BMessage(MSG_HIDE_WINDOW));
54 	fReplaceButton = new BButton("", B_TRANSLATE("Replace"),
55 		new BMessage(MSG_REPLACE));
56 
57 	SetLayout(new BGroupLayout(B_HORIZONTAL));
58 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 4)
59 		.Add(BGridLayoutBuilder(6, 2)
60 				.Add(fSearchString->CreateLabelLayoutItem(), 0, 0)
61 				.Add(fSearchString->CreateTextViewLayoutItem(), 1, 0)
62 				.Add(fReplaceString->CreateLabelLayoutItem(), 0, 1)
63 				.Add(fReplaceString->CreateTextViewLayoutItem(), 1, 1)
64 				.Add(fCaseSensBox, 1, 2)
65 				.Add(fWrapBox, 1, 3)
66 				.Add(fBackSearchBox, 1, 4)
67 				.Add(fAllWindowsBox, 1, 5)
68 				)
69 		.AddGroup(B_HORIZONTAL, 10)
70 			.Add(fReplaceAllButton)
71 			.AddGlue()
72 			.Add(fCancelButton)
73 			.Add(fReplaceButton)
74 		.End()
75 		.SetInsets(10, 10, 10, 10)
76 	);
77 
78 	fReplaceButton->MakeDefault(true);
79 
80 	fHandler = _handler;
81 
82 	const char* searchtext = searchString->String();
83 	const char* replacetext = replaceString->String();
84 
85 	fSearchString->SetText(searchtext);
86 	fReplaceString->SetText(replacetext);
87 	fSearchString->MakeFocus(true);
88 
89 	fCaseSensBox->SetValue(caseState ? B_CONTROL_ON : B_CONTROL_OFF);
90 	fWrapBox->SetValue(wrapState ? B_CONTROL_ON : B_CONTROL_OFF);
91 	fBackSearchBox->SetValue(backState ? B_CONTROL_ON : B_CONTROL_OFF);
92 }
93 
94 
95 void
96 ReplaceWindow::MessageReceived(BMessage* msg)
97 {
98 	switch (msg->what) {
99 		case MSG_REPLACE:
100 			_SendMessage(MSG_REPLACE);
101 			break;
102 		case CHANGE_WINDOW:
103 			_ChangeUI();
104 			break;
105 		case MSG_REPLACE_ALL:
106 			_SendMessage(MSG_REPLACE_ALL);
107 			break;
108 
109 		case MSG_HIDE_WINDOW:
110 			if (!IsHidden())
111 				Hide();
112 			break;
113 		default:
114 			BWindow::MessageReceived(msg);
115 			break;
116 	}
117 }
118 
119 
120 void
121 ReplaceWindow::_ChangeUI()
122 {
123 	fWrapBox->SetEnabled(fUIchange);
124 	fWrapBox->SetValue(fUIchange ? B_CONTROL_OFF : B_CONTROL_ON);
125 
126 	fBackSearchBox->SetEnabled(fUIchange);
127 
128 	fReplaceButton->SetEnabled(fUIchange);
129 	if (fUIchange)
130 		fReplaceButton->MakeDefault(true);
131 	else
132 		fReplaceAllButton->MakeDefault(true);
133 
134 	fUIchange = !fUIchange;
135 }
136 
137 
138 void
139 ReplaceWindow::DispatchMessage(BMessage* message, BHandler* handler)
140 {
141 	if (message->what == B_KEY_DOWN) {
142 		int8 key;
143 		if (message->FindInt8("byte", 0, &key) == B_OK) {
144 			if (key == B_ESCAPE) {
145 				message->MakeEmpty();
146 				message->what = MSG_HIDE_WINDOW;
147 
148 				// This is a hack, but it actually does what is expected,
149 				// unlike the hack above. This kind of key filtering probably
150 				// ought to be handled by a BMessageFilter, though.
151 				BMessenger (this).SendMessage(MSG_HIDE_WINDOW);
152 			}
153 		}
154 	}
155 
156 	BWindow::DispatchMessage(message, handler);
157 }
158 
159 
160 bool
161 ReplaceWindow::QuitRequested()
162 {
163 	BMessenger messenger(fHandler);
164 	messenger.SendMessage(MSG_REPLACE_WINDOW_QUIT);
165 
166 	return true;
167 }
168 
169 
170 void
171 ReplaceWindow::Show()
172 {
173 	fSearchString->TextView()->SelectAll();
174 	BWindow::Show();
175 }
176 
177 
178 void
179 ReplaceWindow::_SendMessage(uint32 what)
180 {
181 	BMessage message(what);
182 
183 	// Add the strings
184 	message.AddString("FindText", fSearchString->Text());
185 	message.AddString("ReplaceText", fReplaceString->Text());
186 
187 	// Add searchparameters from checkboxes
188 	message.AddBool("casesens", fCaseSensBox->Value() == B_CONTROL_ON);
189 	message.AddBool("wrap", fWrapBox->Value() == B_CONTROL_ON);
190 	message.AddBool("backsearch", fBackSearchBox->Value() == B_CONTROL_ON);
191 	message.AddBool("allwindows", fAllWindowsBox->Value() == B_CONTROL_ON);
192 
193 	fHandler->Looper()->PostMessage(&message, fHandler);
194 
195 	PostMessage(MSG_HIDE_WINDOW);
196 }
197 
198