xref: /haiku/src/apps/mail/FindWindow.cpp (revision 62f5ba006a08b0df30631375878effaf67ae5dbc)
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 CONNECTION
23 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 registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 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 TR_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->SetText(sPreviousFind.String());
113 	fTextControl->MakeFocus();
114 	AddChild(fTextControl);
115 
116 	fFindButton = new BButton(BRect(0, 0, 90, 20),"FINDBUTTON", TR("Find"),
117 		new BMessage(FINDBUTTON),B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
118 	fFindButton->ResizeToPreferred();
119 	AddChild(fFindButton);
120 	r = fFindButton->Bounds();
121 
122 	fFindButton->MoveTo(Bounds().right - r.Width() - 8,
123 		Bounds().bottom - r.Height() - 8);
124 	fFindButton->SetEnabled(sPreviousFind.Length());
125 }
126 
127 
128 FindPanel::~FindPanel()
129 {
130 	sPreviousFind = fTextControl->Text();
131 }
132 
133 
134 void FindPanel::AttachedToWindow()
135 {
136 	BView::AttachedToWindow();
137 	SetViewColor(216, 216, 216);
138 	Window()->SetDefaultButton(fFindButton);
139 	fFindButton->SetTarget(this);
140 
141 	fTextControl->SetTarget(this);
142 	fTextControl->ResizeToPreferred();
143 	fTextControl->ResizeTo(Bounds().Width() - 20,
144 		fTextControl->Frame().Height());
145 
146 	fTextControl->MakeFocus(true);
147 	fTextControl->TextView()->SelectAll();
148 }
149 
150 
151 void FindPanel::MouseDown(BPoint point)
152 {
153 	Window()->Activate();
154 	BView::MouseDown(point);
155 }
156 
157 
158 void FindPanel::Draw(BRect)
159 {
160 //	TextBevel(*this, mBTextView->Frame());
161 }
162 
163 
164 void FindPanel::KeyDown(const char*, int32)
165 {
166 	int32 length = fTextControl->TextView()->TextLength();
167 	bool enabled = fFindButton->IsEnabled();
168 
169 	if (length > 0 && !enabled)
170 		fFindButton->SetEnabled(true);
171 	else if (length == 0 && enabled)
172 		fFindButton->SetEnabled(false);
173 }
174 
175 
176 void FindPanel::MessageReceived(BMessage* msg)
177 {
178 	switch (msg->what) {
179 		case M_FIND_STRING_CHANGED: {
180 			if (strlen(fTextControl->Text()) == 0)
181 				fFindButton->SetEnabled(false);
182 			else
183 				fFindButton->SetEnabled(true);
184 			break;
185 		}
186 		case FINDBUTTON: {
187 			Find();
188 			Window()->PostMessage(B_QUIT_REQUESTED);
189 			break;
190 		}
191 		default:
192 			BView::MessageReceived(msg);
193 	}
194 }
195 
196 
197 void FindPanel::Find()
198 {
199 	fTextControl->TextView()->SelectAll();
200 	const char* text = fTextControl->Text();
201 	if (text == NULL || text[0] == 0) return;
202 
203 	BWindow* window = NULL;
204 	long i = 0;
205 	while ((bool)(window = be_app->WindowAt(i++))) {
206 		// Send the text to a waiting window
207 		if (window != FindWindow::fFindWindow)
208 			break;	// Found a window
209 	}
210 
211 	if (window)
212 		FindWindow::DoFind(window, text);
213 }
214 
215 
216 FindWindow::FindWindow()
217 	: BWindow(FindWindow::fLastPosition, TR("Find"), B_FLOATING_WINDOW,
218 		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
219 			| B_CLOSE_ON_ESCAPE)
220 {
221 	fFindPanel = new FindPanel(Bounds());
222 	AddChild(fFindPanel);
223 	fFindWindow = this;
224 	Show();
225 }
226 
227 
228 FindWindow::~FindWindow()
229 {
230 	FindWindow::fLastPosition = Frame();
231 	fFindWindow = NULL;
232 }
233 
234 
235 void FindWindow::Find(BWindow* window)
236 {
237 	// eliminate unused parameter warning
238 	(void)window;
239 
240 	if (fFindWindow == NULL) {
241 		fFindWindow = new FindWindow();
242 	} else
243 		fFindWindow->Activate();
244 }
245 
246 
247 void FindWindow::FindAgain(BWindow* window)
248 {
249 	if (fFindWindow) {
250 		fFindWindow->Lock();
251 		fFindWindow->fFindPanel->Find();
252 		fFindWindow->Unlock();
253 	} else if (sPreviousFind.Length() != 0)
254 		DoFind(window, sPreviousFind.String());
255 	else
256 		Find(window);
257 }
258 
259 
260 void FindWindow::SetFindString(const char* string)
261 {
262 	sPreviousFind = string;
263 }
264 
265 
266 const char* FindWindow::GetFindString()
267 {
268 	return sPreviousFind.String();
269 }
270 
271