xref: /haiku/src/apps/mail/FindWindow.cpp (revision 0995b563847c884054e912abbd2c5bc08d614f59)
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 "Mail.h"
42 #include "AutoTextControl.h"
43 
44 #include <TextView.h>
45 #include <Button.h>
46 #include <Application.h>
47 #include <String.h>
48 #include <Box.h>
49 
50 #include <MDRLanguage.h>
51 
52 enum {
53 	M_FIND_STRING_CHANGED = 'fsch'
54 };
55 
56 void TextBevel(BView& view, BRect r);
57 
58 // ============================================================================
59 void TextBevel(BView& view, BRect r)
60 {
61 	r.InsetBy(-1,-1);
62 	view.SetHighColor(96,96,96);
63 	view.MovePenTo(r.left,r.bottom);
64 	view.StrokeLine(BPoint(r.left,r.top));
65 	view.StrokeLine(BPoint(r.right,r.top));
66 	view.SetHighColor(216,216,216);
67 	view.StrokeLine(BPoint(r.right,r.bottom));
68 	view.StrokeLine(BPoint(r.left,r.bottom));
69 	r.InsetBy(-1,-1);
70 	view.SetHighColor(192,192,192);
71 	view.MovePenTo(r.left,r.bottom);
72 	view.StrokeLine(BPoint(r.left,r.top));
73 	view.StrokeLine(BPoint(r.right,r.top));
74 	view.SetHighColor(255,255,255);
75 	view.StrokeLine(BPoint(r.right,r.bottom));
76 	view.StrokeLine(BPoint(r.left,r.bottom));
77 	view.SetHighColor(0,0,0);
78 }
79 
80 //	FindWindow is modeless...
81 
82 #define FINDBUTTON 'find'
83 
84 static BString sPreviousFind = "";
85 
86 FindWindow* FindWindow::mFindWindow = NULL;
87 BRect FindWindow::mLastPosition(BRect(100,300,300,374));
88 
89 void FindWindow::DoFind(BWindow *window, const char *text)
90 {
91 	if (window == NULL) {
92 		long i=0;
93 		while ((bool)(window = be_app->WindowAt(i++))) {	// Send the text to a waiting window
94 			if (window != mFindWindow)
95 				if (dynamic_cast<TMailWindow *>(window) != NULL)
96 					break;	// Found a window
97 		}
98 	}
99 
100 	/* ask that window who is in the front */
101 	window = dynamic_cast<TMailWindow *>(window)->FrontmostWindow();
102 	if (window == NULL)
103 		return;
104 
105 //	Found a window, send a find message
106 
107 	if (!window->Lock())
108 		return;
109 	BView *focus = window->FindView("m_content");
110 	window->Unlock();
111 
112 	if (focus)
113 	{
114 		BMessage msg(M_FIND);
115 		msg.AddString("findthis",text);
116 		window->PostMessage(&msg, focus);
117 	}
118 }
119 
120 FindPanel::FindPanel(BRect rect)
121 	: BBox(rect, "FindPanel", B_FOLLOW_LEFT_RIGHT,
122 		B_WILL_DRAW)
123 {
124 	BRect r = Bounds().InsetByCopy(10,10);
125 
126 	mBTextControl = new AutoTextControl(r,"BTextControl",NULL,sPreviousFind.String(),
127 									new BMessage(M_FIND_STRING_CHANGED),
128 									B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
129 	mBTextControl->SetText(sPreviousFind.String());
130 	mBTextControl->MakeFocus();
131 	mBTextControl->SetEscapeCancel(true);
132 	AddChild(mBTextControl);
133 
134 	mFindButton = new BButton(BRect(0,0,90,20),"FINDBUTTON",
135 		MDR_DIALECT_CHOICE ("Find","検索"),
136 		new BMessage(FINDBUTTON),B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
137 	mFindButton->ResizeToPreferred();
138 	AddChild(mFindButton);
139 	r = mFindButton->Bounds();
140 
141 	mFindButton->MoveTo(Bounds().right - r.Width() - 8,
142 		Bounds().bottom - r.Height() - 8);
143 	mFindButton->SetEnabled(sPreviousFind.Length());
144 }
145 
146 FindPanel::~FindPanel()
147 {
148 	sPreviousFind = mBTextControl->Text();
149 }
150 
151 void FindPanel::AttachedToWindow()
152 {
153 	BView::AttachedToWindow();
154 	SetViewColor(216,216,216);
155 	Window()->SetDefaultButton(mFindButton);
156 	mFindButton->SetTarget(this);
157 
158 	mBTextControl->SetTarget(this);
159 	mBTextControl->ResizeToPreferred();
160 	mBTextControl->ResizeTo(Bounds().Width() - 20, mBTextControl->Frame().Height());
161 
162 	mBTextControl->MakeFocus(true);
163 	mBTextControl->TextView()->SelectAll();
164 }
165 
166 void FindPanel::MouseDown(BPoint point)
167 {
168 	Window()->Activate();
169 	BView::MouseDown(point);
170 }
171 
172 void FindPanel::Draw(BRect)
173 {
174 //	TextBevel(*this,mBTextView->Frame());
175 }
176 
177 void FindPanel::KeyDown(const char *, int32)
178 {
179 	int32 length = mBTextControl->TextView()->TextLength();
180 	bool enabled = mFindButton->IsEnabled();
181 
182 	if (length > 0 && !enabled)
183 		mFindButton->SetEnabled(true);
184 	else if (length == 0 && enabled)
185 		mFindButton->SetEnabled(false);
186 }
187 
188 void FindPanel::MessageReceived(BMessage *msg)
189 {
190 	switch (msg->what) {
191 		case M_FIND_STRING_CHANGED: {
192 			if (strlen(mBTextControl->Text()) == 0)
193 				mFindButton->SetEnabled(false);
194 			else
195 				mFindButton->SetEnabled(true);
196 			break;
197 		}
198 		case FINDBUTTON: {
199 			Find();
200 			Window()->PostMessage(B_QUIT_REQUESTED);
201 			break;
202 		}
203 		default:
204 			BView::MessageReceived(msg);
205 	}
206 }
207 
208 void FindPanel::Find()
209 {
210 	mBTextControl->TextView()->SelectAll();
211 	const char *text = mBTextControl->Text();
212 	if (text == NULL || text[0] == 0) return;
213 
214 	BWindow *window = NULL;
215 	long i=0;
216 	while ((bool)(window = be_app->WindowAt(i++))) {	// Send the text to a waiting window
217 		if (window != FindWindow::mFindWindow)
218 			break;	// Found a window
219 	}
220 
221 	if (window)
222 		FindWindow::DoFind(window, text);
223 }
224 
225 // ============================================================================
226 
227 
228 FindWindow::FindWindow()
229 	: BWindow(FindWindow::mLastPosition,
230 		MDR_DIALECT_CHOICE ("Find","検索"),
231 		B_FLOATING_WINDOW,
232 		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK)
233 {
234 	mFindPanel = new FindPanel(Bounds());
235 	AddChild(mFindPanel);
236 	mFindWindow = this;
237 	Show();
238 }
239 
240 FindWindow::~FindWindow()
241 {
242 	FindWindow::mLastPosition = Frame();
243 	mFindWindow = NULL;
244 }
245 
246 void FindWindow::Find(BWindow *window)
247 {
248 	// eliminate unused parameter warning
249 	(void)window;
250 
251 	if (mFindWindow == NULL) {
252 		mFindWindow = new FindWindow();
253 	} else
254 		mFindWindow->Activate();
255 }
256 
257 void FindWindow::FindAgain(BWindow *window)
258 {
259 	if (mFindWindow) {
260 		mFindWindow->Lock();
261 		mFindWindow->mFindPanel->Find();
262 		mFindWindow->Unlock();
263 	} else if (sPreviousFind.Length() != 0)
264 		DoFind(window, sPreviousFind.String());
265 	else
266 		Find(window);
267 }
268 
269 void FindWindow::SetFindString(const char *string)
270 {
271 	sPreviousFind = string;
272 }
273 
274 const char *FindWindow::GetFindString()
275 {
276 	return sPreviousFind.String();
277 }
278