xref: /haiku/src/apps/stylededit/ReplaceWindow.cpp (revision 844f23f9ba56cddecea216b7ecea2912394dead6)
1 /*
2  * Copyright 2002-2006, 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 <Messenger.h>
15 #include <Button.h>
16 #include <CheckBox.h>
17 #include <String.h>
18 #include <TextControl.h>
19 #include <Window.h>
20 
21 
22 ReplaceWindow::ReplaceWindow(BRect frame, BHandler *_handler, BString *searchString,
23 	BString *replaceString, bool *caseState, bool *wrapState, bool *backState)
24 	: BWindow(frame, "ReplaceWindow", B_MODAL_WINDOW,
25 		B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS,
26 		B_CURRENT_WORKSPACE)
27 {
28 	AddShortcut('W',B_COMMAND_KEY,new BMessage(B_QUIT_REQUESTED));
29 
30 	fReplaceView = new BView(Bounds(), "ReplaceView", B_FOLLOW_ALL, B_WILL_DRAW);
31 	fReplaceView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
32 	AddChild(fReplaceView);
33 
34 	char* findLabel = "Find:";
35 	float findWidth = fReplaceView->StringWidth(findLabel);
36 	fReplaceView->AddChild(fSearchString = new BTextControl(BRect(5, 10, 290, 50), "",
37 		findLabel, NULL, NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE));
38 
39 	char* replaceWithLabel = "Replace with:";
40 	float replaceWithWidth = fReplaceView->StringWidth(replaceWithLabel);
41 	fReplaceView->AddChild(fReplaceString = new BTextControl(BRect(5, 35, 290, 50), "",
42 		replaceWithLabel, NULL, NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP,
43 		B_WILL_DRAW | B_NAVIGABLE));
44 	float maxWidth = (replaceWithWidth > findWidth ? replaceWithWidth : findWidth) + 1;
45 	fSearchString->SetDivider(maxWidth);
46 	fReplaceString->SetDivider(maxWidth);
47 
48 	fReplaceView->AddChild(fCaseSensBox = new BCheckBox(BRect(maxWidth + 8, 60, 290, 52),
49 		"", "Case-sensitive", NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE));
50 	fReplaceView->AddChild(fWrapBox = new BCheckBox(BRect(maxWidth + 8, 80, 290, 70),
51 		"", "Wrap-around search", NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP,
52 		B_WILL_DRAW | B_NAVIGABLE));
53 	fReplaceView->AddChild(fBackSearchBox = new BCheckBox(BRect(maxWidth + 8, 100, 290, 95),
54 		"", "Search backwards", NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP,
55 		B_WILL_DRAW | B_NAVIGABLE));
56 	fReplaceView->AddChild(fAllWindowsBox = new BCheckBox(BRect(maxWidth + 8, 120, 290, 95),
57 		"", "Replace in all windows", new BMessage(CHANGE_WINDOW),
58 		B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE));
59 	fUIchange = false;
60 
61 	fReplaceView->AddChild(fReplaceAllButton = new BButton(BRect(10, 150, 98, 166),
62 		"", "Replace All", new BMessage(MSG_REPLACE_ALL), B_FOLLOW_LEFT | B_FOLLOW_TOP,
63 		B_WILL_DRAW | B_NAVIGABLE));
64 	fReplaceView->AddChild(fCancelButton = new BButton(BRect(141, 150, 211, 166),
65 		"", "Cancel", new BMessage(B_QUIT_REQUESTED), B_FOLLOW_LEFT | B_FOLLOW_TOP,
66 		B_WILL_DRAW | B_NAVIGABLE));
67 	fReplaceView->AddChild(fReplaceButton = new BButton(BRect(221, 150, 291, 166),
68 		"", "Replace", new BMessage(MSG_REPLACE), B_FOLLOW_LEFT | B_FOLLOW_TOP,
69 		B_WILL_DRAW | B_NAVIGABLE));
70 	fReplaceButton->MakeDefault(true);
71 
72 	fHandler = _handler;
73 
74 	const char *searchtext = searchString->String();
75 	const char *replacetext = replaceString->String();
76 
77 	fSearchString->SetText(searchtext);
78 	fReplaceString->SetText(replacetext);
79 	fSearchString->MakeFocus(true);
80 
81 	fCaseSensBox->SetValue(*caseState ? B_CONTROL_ON : B_CONTROL_OFF);
82 	fWrapBox->SetValue(*wrapState ? B_CONTROL_ON : B_CONTROL_OFF);
83 	fBackSearchBox->SetValue(*backState ? B_CONTROL_ON : B_CONTROL_OFF);
84 }
85 
86 
87 void
88 ReplaceWindow::MessageReceived(BMessage *msg)
89 {
90 	switch (msg->what){
91 		case MSG_REPLACE:
92 			_SendMessage(MSG_REPLACE);
93 			break;
94 		case CHANGE_WINDOW:
95 			_ChangeUI();
96 			break;
97 		case MSG_REPLACE_ALL:
98 			_SendMessage(MSG_REPLACE_ALL);
99 			break;
100 
101 		default:
102 			BWindow::MessageReceived(msg);
103 			break;
104 	}
105 }
106 
107 
108 void
109 ReplaceWindow::_ChangeUI()
110 {
111 	if (!fUIchange) {
112 		fReplaceAllButton->MakeDefault(true);
113 		fReplaceButton->SetEnabled(false);
114 		fWrapBox->SetValue(B_CONTROL_ON);
115 		fWrapBox->SetEnabled(false);
116 		fBackSearchBox->SetEnabled(false);
117 		fUIchange = true;
118 	} else {
119 		fReplaceButton->MakeDefault(true);
120 		fReplaceButton->SetEnabled(true);
121 		fReplaceAllButton->SetEnabled(true);
122 		fWrapBox->SetValue(B_CONTROL_OFF);
123 		fWrapBox->SetEnabled(true);
124 		fBackSearchBox->SetEnabled(true);
125 		fUIchange = false;
126 	}
127 }
128 
129 
130 void
131 ReplaceWindow::DispatchMessage(BMessage *message, BHandler *handler)
132 {
133 	if (message->what == B_KEY_DOWN) {
134 		int8 key;
135 		if (message->FindInt8("byte", 0, &key) == B_OK) {
136 			if (key == B_ESCAPE) {
137 				message->MakeEmpty();
138 				message->what = B_QUIT_REQUESTED;
139 
140 				// This is a hack, but it actually does what is expected,
141 				// unlike the hack above. This kind of key filtering probably
142 				// ought to be handled by a BMessageFilter, though.
143 				BMessenger (this).SendMessage(B_QUIT_REQUESTED);
144 			}
145 		}
146 	}
147 
148 	BWindow::DispatchMessage(message, handler);
149 }
150 
151 
152 void
153 ReplaceWindow::_SendMessage(uint32 what)
154 {
155 	BMessage message(what);
156 
157 	// Add the strings
158 	message.AddString("FindText", fSearchString->Text());
159 	message.AddString("ReplaceText", fReplaceString->Text());
160 
161 	// Add searchparameters from checkboxes
162 	message.AddBool("casesens", fCaseSensBox->Value() == B_CONTROL_ON);
163 	message.AddBool("wrap", fWrapBox->Value() == B_CONTROL_ON);
164 	message.AddBool("backsearch", fBackSearchBox->Value() == B_CONTROL_ON);
165 	message.AddBool("allwindows", fAllWindowsBox->Value() == B_CONTROL_ON);
166 
167 	fHandler->Looper()->PostMessage(&message, fHandler);
168 
169 	PostMessage(B_QUIT_REQUESTED);
170 }
171 
172