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