xref: /haiku/src/apps/mail/FindWindow.cpp (revision 1a3518cf757c2da8006753f83962da5935bbc82b)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2001, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or
30 registered trademarks of Be Incorporated in the United States and other
31 countries. Other brand product names are registered trademarks or trademarks
32 of their respective holders. All rights reserved.
33 */
34 
35 // ===========================================================================
36 //	FindWindow.cpp
37 // 	Copyright 1996 by Peter Barrett, All rights reserved.
38 // ===========================================================================
39 
40 #include "FindWindow.h"
41 #include "MailApp.h"
42 #include "MailWindow.h"
43 #include "Messages.h"
44 
45 #include <Application.h>
46 #include <Box.h>
47 #include <Button.h>
48 #include <Catalog.h>
49 #include <LayoutBuilder.h>
50 #include <Locale.h>
51 #include <String.h>
52 #include <TextView.h>
53 
54 
55 #define B_TRANSLATION_CONTEXT "Mail"
56 
57 
58 enum {
59 	M_FIND_STRING_CHANGED = 'fsch'
60 };
61 
62 
63 #define FINDBUTTON 'find'
64 
65 static BString sPreviousFind = "";
66 
67 FindWindow* FindWindow::fFindWindow = NULL;
68 BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374));
69 
70 void FindWindow::DoFind(BWindow* window, const char* text)
71 {
72 	if (window == NULL) {
73 		long i = 0;
74 		while ((window = be_app->WindowAt(i++)) != NULL) {
75 			// Send the text to a waiting window
76 			if (window != fFindWindow)
77 				if (dynamic_cast<TMailWindow*>(window) != NULL)
78 					break;	// Found a window
79 		}
80 	}
81 
82 	/* ask that window who is in the front */
83 	window = dynamic_cast<TMailWindow*>(window)->FrontmostWindow();
84 	if (window == NULL)
85 		return;
86 
87 //	Found a window, send a find message
88 
89 	if (!window->Lock())
90 		return;
91 	BView* focus = window->FindView("m_content");
92 	window->Unlock();
93 
94 	if (focus)
95 	{
96 		BMessage msg(M_FIND);
97 		msg.AddString("findthis",text);
98 		window->PostMessage(&msg, focus);
99 	}
100 }
101 
102 
103 FindPanel::FindPanel()
104 	:
105 	BGroupView("FindPanel", B_VERTICAL)
106 {
107 	fTextControl = new BTextControl("BTextControl", NULL,
108 		sPreviousFind.String(), new BMessage(M_FIND_STRING_CHANGED));
109 
110 	fTextControl->SetModificationMessage(new BMessage(M_FIND_STRING_CHANGED));
111 	fTextControl->SetText(sPreviousFind.String());
112 	fTextControl->MakeFocus();
113 
114 	fFindButton = new BButton("FINDBUTTON", B_TRANSLATE("Find"),
115 		new BMessage(FINDBUTTON));
116 
117 	fFindButton->SetEnabled(sPreviousFind.Length());
118 
119 	BLayoutBuilder::Group<>(this, B_VERTICAL)
120 		.SetInsets(B_USE_WINDOW_SPACING)
121 		.Add(fTextControl)
122 		.AddGroup(B_HORIZONTAL)
123 			.AddGlue()
124 			.Add(fFindButton)
125 		.End()
126 	.End();
127 }
128 
129 
130 FindPanel::~FindPanel()
131 {
132 	sPreviousFind = fTextControl->Text();
133 }
134 
135 
136 void FindPanel::AttachedToWindow()
137 {
138 	BView::AttachedToWindow();
139 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
140 	Window()->SetDefaultButton(fFindButton);
141 	fFindButton->SetTarget(this);
142 
143 	fTextControl->SetTarget(this);
144 	fTextControl->ResizeToPreferred();
145 	fTextControl->ResizeTo(Bounds().Width() - 20,
146 		fTextControl->Frame().Height());
147 
148 	fTextControl->MakeFocus(true);
149 	fTextControl->TextView()->SelectAll();
150 }
151 
152 
153 void FindPanel::MouseDown(BPoint point)
154 {
155 	Window()->Activate();
156 	BView::MouseDown(point);
157 }
158 
159 
160 void FindPanel::Draw(BRect)
161 {
162 //	TextBevel(*this, mBTextView->Frame());
163 }
164 
165 
166 void FindPanel::KeyDown(const char*, int32)
167 {
168 	int32 length = fTextControl->TextView()->TextLength();
169 	bool enabled = fFindButton->IsEnabled();
170 
171 	if (length > 0 && !enabled)
172 		fFindButton->SetEnabled(true);
173 	else if (length == 0 && enabled)
174 		fFindButton->SetEnabled(false);
175 }
176 
177 
178 void FindPanel::MessageReceived(BMessage* msg)
179 {
180 	switch (msg->what) {
181 		case M_FIND_STRING_CHANGED: {
182 			if (strlen(fTextControl->Text()) == 0)
183 				fFindButton->SetEnabled(false);
184 			else
185 				fFindButton->SetEnabled(true);
186 			break;
187 		}
188 		case FINDBUTTON: {
189 			Find();
190 			Window()->PostMessage(B_QUIT_REQUESTED);
191 			break;
192 		}
193 		default:
194 			BView::MessageReceived(msg);
195 	}
196 }
197 
198 
199 void FindPanel::Find()
200 {
201 	fTextControl->TextView()->SelectAll();
202 	const char* text = fTextControl->Text();
203 	if (text == NULL || text[0] == 0) return;
204 
205 	BWindow* window = NULL;
206 	long i = 0;
207 	while ((bool)(window = be_app->WindowAt(i++))) {
208 		// Send the text to a waiting window
209 		if (window != FindWindow::fFindWindow)
210 			break;	// Found a window
211 	}
212 
213 	if (window)
214 		FindWindow::DoFind(window, text);
215 }
216 
217 
218 FindWindow::FindWindow()
219 	: BWindow(FindWindow::fLastPosition, B_TRANSLATE("Find"),
220 		B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
221 			| B_WILL_ACCEPT_FIRST_CLICK | B_CLOSE_ON_ESCAPE
222 			| B_AUTO_UPDATE_SIZE_LIMITS)
223 {
224 	SetLayout(new BGroupLayout(B_VERTICAL));
225 	fFindPanel = new FindPanel();
226 	AddChild(fFindPanel);
227 	fFindWindow = this;
228 	Show();
229 }
230 
231 
232 FindWindow::~FindWindow()
233 {
234 	FindWindow::fLastPosition = Frame();
235 	fFindWindow = NULL;
236 }
237 
238 
239 void FindWindow::Find(BWindow* window)
240 {
241 	// eliminate unused parameter warning
242 	(void)window;
243 
244 	if (fFindWindow == NULL) {
245 		fFindWindow = new FindWindow();
246 	} else
247 		fFindWindow->Activate();
248 }
249 
250 
251 void FindWindow::FindAgain(BWindow* window)
252 {
253 	if (fFindWindow) {
254 		fFindWindow->Lock();
255 		fFindWindow->fFindPanel->Find();
256 		fFindWindow->Unlock();
257 	} else if (sPreviousFind.Length() != 0)
258 		DoFind(window, sPreviousFind.String());
259 	else
260 		Find(window);
261 }
262 
263 
264 void FindWindow::SetFindString(const char* string)
265 {
266 	sPreviousFind = string;
267 }
268 
269 
270 const char* FindWindow::GetFindString()
271 {
272 	return sPreviousFind.String();
273 }
274 
275