xref: /haiku/src/apps/mail/FindWindow.cpp (revision ab05d36868610c8bce69e732e9cb3befb3d52c6b)
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 
DoFind(BWindow * window,const char * text)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 
FindPanel()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 
~FindPanel()130 FindPanel::~FindPanel()
131 {
132 	sPreviousFind = fTextControl->Text();
133 }
134 
135 
AttachedToWindow()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 
MouseDown(BPoint point)153 void FindPanel::MouseDown(BPoint point)
154 {
155 	Window()->Activate();
156 	BView::MouseDown(point);
157 }
158 
159 
Draw(BRect)160 void FindPanel::Draw(BRect)
161 {
162 //	TextBevel(*this, mBTextView->Frame());
163 }
164 
165 
KeyDown(const char *,int32)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 
MessageReceived(BMessage * msg)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 			break;
196 	}
197 }
198 
199 
Find()200 void FindPanel::Find()
201 {
202 	fTextControl->TextView()->SelectAll();
203 	const char* text = fTextControl->Text();
204 	if (text == NULL || text[0] == 0) return;
205 
206 	BWindow* window = NULL;
207 	long i = 0;
208 	while ((bool)(window = be_app->WindowAt(i++))) {
209 		// Send the text to a waiting window
210 		if (window != FindWindow::fFindWindow)
211 			break;	// Found a window
212 	}
213 
214 	if (window)
215 		FindWindow::DoFind(window, text);
216 }
217 
218 
FindWindow()219 FindWindow::FindWindow()
220 	: BWindow(FindWindow::fLastPosition, B_TRANSLATE("Find"),
221 		B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
222 			| B_WILL_ACCEPT_FIRST_CLICK | B_CLOSE_ON_ESCAPE
223 			| B_AUTO_UPDATE_SIZE_LIMITS)
224 {
225 	SetLayout(new BGroupLayout(B_VERTICAL));
226 	fFindPanel = new FindPanel();
227 	AddChild(fFindPanel);
228 	fFindWindow = this;
229 	Show();
230 }
231 
232 
~FindWindow()233 FindWindow::~FindWindow()
234 {
235 	FindWindow::fLastPosition = Frame();
236 	fFindWindow = NULL;
237 }
238 
239 
Find(BWindow * window)240 void FindWindow::Find(BWindow* window)
241 {
242 	// eliminate unused parameter warning
243 	(void)window;
244 
245 	if (fFindWindow == NULL) {
246 		fFindWindow = new FindWindow();
247 	} else
248 		fFindWindow->Activate();
249 }
250 
251 
FindAgain(BWindow * window)252 void FindWindow::FindAgain(BWindow* window)
253 {
254 	if (fFindWindow) {
255 		fFindWindow->Lock();
256 		fFindWindow->fFindPanel->Find();
257 		fFindWindow->Unlock();
258 	} else if (sPreviousFind.Length() != 0)
259 		DoFind(window, sPreviousFind.String());
260 	else
261 		Find(window);
262 }
263 
264 
SetFindString(const char * string)265 void FindWindow::SetFindString(const char* string)
266 {
267 	sPreviousFind = string;
268 }
269 
270 
GetFindString()271 const char* FindWindow::GetFindString()
272 {
273 	return sPreviousFind.String();
274 }
275