xref: /haiku/src/apps/mail/FindWindow.cpp (revision 546208a53940a26c6379c48a7854ade1a8250fc5)
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 <Locale.h>
50 #include <String.h>
51 #include <TextView.h>
52 
53 
54 #define B_TRANSLATION_CONTEXT "Mail"
55 
56 
57 enum {
58 	M_FIND_STRING_CHANGED = 'fsch'
59 };
60 
61 
62 #define FINDBUTTON 'find'
63 
64 static BString sPreviousFind = "";
65 
66 FindWindow* FindWindow::fFindWindow = NULL;
67 BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374));
68 
69 void FindWindow::DoFind(BWindow* window, const char* text)
70 {
71 	if (window == NULL) {
72 		long i = 0;
73 		while ((window = be_app->WindowAt(i++)) != NULL) {
74 			// Send the text to a waiting window
75 			if (window != fFindWindow)
76 				if (dynamic_cast<TMailWindow*>(window) != NULL)
77 					break;	// Found a window
78 		}
79 	}
80 
81 	/* ask that window who is in the front */
82 	window = dynamic_cast<TMailWindow*>(window)->FrontmostWindow();
83 	if (window == NULL)
84 		return;
85 
86 //	Found a window, send a find message
87 
88 	if (!window->Lock())
89 		return;
90 	BView* focus = window->FindView("m_content");
91 	window->Unlock();
92 
93 	if (focus)
94 	{
95 		BMessage msg(M_FIND);
96 		msg.AddString("findthis",text);
97 		window->PostMessage(&msg, focus);
98 	}
99 }
100 
101 
102 FindPanel::FindPanel(BRect rect)
103 	:
104 	BBox(rect, "FindPanel", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW)
105 {
106 	BRect r = Bounds().InsetByCopy(10, 10);
107 
108 	fTextControl = new BTextControl(r, "BTextControl", NULL,
109 		sPreviousFind.String(), new BMessage(M_FIND_STRING_CHANGED),
110 		B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
111 
112 	fTextControl->SetModificationMessage(new BMessage(M_FIND_STRING_CHANGED));
113 	fTextControl->SetText(sPreviousFind.String());
114 	fTextControl->MakeFocus();
115 	AddChild(fTextControl);
116 
117 	fFindButton = new BButton(BRect(0, 0, 90, 20),"FINDBUTTON",
118 		B_TRANSLATE("Find"),
119 		new BMessage(FINDBUTTON),B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
120 	fFindButton->ResizeToPreferred();
121 	AddChild(fFindButton);
122 	r = fFindButton->Bounds();
123 
124 	fFindButton->MoveTo(Bounds().right - r.Width() - 8,
125 		Bounds().bottom - r.Height() - 8);
126 	fFindButton->SetEnabled(sPreviousFind.Length());
127 }
128 
129 
130 FindPanel::~FindPanel()
131 {
132 	sPreviousFind = fTextControl->Text();
133 }
134 
135 
136 void FindPanel::AttachedToWindow()
137 {
138 	BView::AttachedToWindow();
139 	SetViewColor(216, 216, 216);
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 {
223 	fFindPanel = new FindPanel(Bounds());
224 	AddChild(fFindPanel);
225 	fFindWindow = this;
226 	Show();
227 }
228 
229 
230 FindWindow::~FindWindow()
231 {
232 	FindWindow::fLastPosition = Frame();
233 	fFindWindow = NULL;
234 }
235 
236 
237 void FindWindow::Find(BWindow* window)
238 {
239 	// eliminate unused parameter warning
240 	(void)window;
241 
242 	if (fFindWindow == NULL) {
243 		fFindWindow = new FindWindow();
244 	} else
245 		fFindWindow->Activate();
246 }
247 
248 
249 void FindWindow::FindAgain(BWindow* window)
250 {
251 	if (fFindWindow) {
252 		fFindWindow->Lock();
253 		fFindWindow->fFindPanel->Find();
254 		fFindWindow->Unlock();
255 	} else if (sPreviousFind.Length() != 0)
256 		DoFind(window, sPreviousFind.String());
257 	else
258 		Find(window);
259 }
260 
261 
262 void FindWindow::SetFindString(const char* string)
263 {
264 	sPreviousFind = string;
265 }
266 
267 
268 const char* FindWindow::GetFindString()
269 {
270 	return sPreviousFind.String();
271 }
272 
273