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 <LayoutBuilder.h>
50#include <Locale.h>
51#include <String.h>
52#include <TextView.h>
53
54
55#define B_TRANSLATION_CONTEXT "Mail"
56
57
58enum {
59	M_FIND_STRING_CHANGED = 'fsch'
60};
61
62
63#define FINDBUTTON 'find'
64
65static BString sPreviousFind = "";
66
67FindWindow* FindWindow::fFindWindow = NULL;
68BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374));
69
70void 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
103FindPanel::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
130FindPanel::~FindPanel()
131{
132	sPreviousFind = fTextControl->Text();
133}
134
135
136void 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
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			break;
196	}
197}
198
199
200void 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
219FindWindow::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
233FindWindow::~FindWindow()
234{
235	FindWindow::fLastPosition = Frame();
236	fFindWindow = NULL;
237}
238
239
240void 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
252void 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
265void FindWindow::SetFindString(const char* string)
266{
267	sPreviousFind = string;
268}
269
270
271const char* FindWindow::GetFindString()
272{
273	return sPreviousFind.String();
274}
275