1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2001, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN
23CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or
30registered trademarks of Be Incorporated in the United States and other
31countries. Other brand product names are registered trademarks or trademarks
32of 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
57enum {
58	M_FIND_STRING_CHANGED = 'fsch'
59};
60
61
62#define FINDBUTTON 'find'
63
64static BString sPreviousFind = "";
65
66FindWindow* FindWindow::fFindWindow = NULL;
67BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374));
68
69void 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
102FindPanel::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
130FindPanel::~FindPanel()
131{
132	sPreviousFind = fTextControl->Text();
133}
134
135
136void 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
153void FindPanel::MouseDown(BPoint point)
154{
155	Window()->Activate();
156	BView::MouseDown(point);
157}
158
159
160void FindPanel::Draw(BRect)
161{
162//	TextBevel(*this, mBTextView->Frame());
163}
164
165
166void 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
178void 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
199void 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
218FindWindow::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
230FindWindow::~FindWindow()
231{
232	FindWindow::fLastPosition = Frame();
233	fFindWindow = NULL;
234}
235
236
237void 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
249void 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
262void FindWindow::SetFindString(const char* string)
263{
264	sPreviousFind = string;
265}
266
267
268const char* FindWindow::GetFindString()
269{
270	return sPreviousFind.String();
271}
272
273