1/*
2 * Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Mattias Sundblad
7 *		Andrew Bachmann
8 */
9
10
11#include "Constants.h"
12#include "FindWindow.h"
13
14#include <Button.h>
15#include <Catalog.h>
16#include <CheckBox.h>
17#include <GroupLayoutBuilder.h>
18#include <GridLayoutBuilder.h>
19#include <Locale.h>
20#include <LayoutBuilder.h>
21#include <String.h>
22#include <TextControl.h>
23
24
25#undef B_TRANSLATION_CONTEXT
26#define B_TRANSLATION_CONTEXT "FindandReplaceWindow"
27
28
29FindWindow::FindWindow(BRect frame, BHandler* _handler, BString* searchString,
30	bool caseState, bool wrapState, bool backState)
31	: BWindow(frame, B_TRANSLATE("Find"), B_FLOATING_WINDOW,
32		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
33		| B_AUTO_UPDATE_SIZE_LIMITS, B_CURRENT_WORKSPACE)
34{
35	AddShortcut('W', B_COMMAND_KEY, new BMessage(MSG_HIDE_WINDOW));
36
37	fSearchString = new BTextControl("", B_TRANSLATE("Find:"), NULL, NULL);
38	fCaseSensBox = new BCheckBox("", B_TRANSLATE("Case-sensitive"), NULL);
39	fWrapBox = new BCheckBox("", B_TRANSLATE("Wrap-around search"), NULL);
40	fBackSearchBox = new BCheckBox("", B_TRANSLATE("Search backwards"), NULL);
41	fCancelButton = new BButton("", B_TRANSLATE("Cancel"),
42		new BMessage(MSG_HIDE_WINDOW));
43	fSearchButton = new BButton("", B_TRANSLATE("Find"),
44		new BMessage(MSG_SEARCH));
45
46	SetLayout(new BGroupLayout(B_HORIZONTAL));
47	AddChild(BGroupLayoutBuilder(B_VERTICAL, 4)
48		.Add(BGridLayoutBuilder(6, 2)
49				.Add(fSearchString->CreateLabelLayoutItem(), 0, 0)
50				.Add(fSearchString->CreateTextViewLayoutItem(), 1, 0)
51				.Add(fCaseSensBox, 1, 1)
52				.Add(fWrapBox, 1, 2)
53				.Add(fBackSearchBox, 1, 3)
54				)
55		.AddGroup(B_HORIZONTAL, 10)
56			.AddGlue()
57			.Add(fCancelButton)
58			.Add(fSearchButton)
59		.End()
60		.SetInsets(10, 10, 10, 10)
61	);
62
63	fSearchButton->MakeDefault(true);
64	fHandler = _handler;
65
66	const char* text = searchString->String();
67
68	fSearchString->SetText(text);
69	fSearchString->MakeFocus(true);
70
71	fCaseSensBox->SetValue(caseState ? B_CONTROL_ON : B_CONTROL_OFF);
72	fWrapBox->SetValue(wrapState ? B_CONTROL_ON : B_CONTROL_OFF);
73	fBackSearchBox->SetValue(backState ? B_CONTROL_ON : B_CONTROL_OFF);
74}
75
76
77void
78FindWindow::MessageReceived(BMessage* msg)
79{
80	switch (msg->what) {
81		case MSG_HIDE_WINDOW:
82			if (!IsHidden())
83				Hide();
84			break;
85		case MSG_SEARCH:
86			_SendMessage();
87			break;
88
89		default:
90			BWindow::MessageReceived(msg);
91			break;
92	}
93}
94
95
96void
97FindWindow::DispatchMessage(BMessage* message, BHandler* handler)
98{
99	if (message->what == B_KEY_DOWN) {
100		int8 key;
101		if (message->FindInt8("byte", 0, &key) == B_OK) {
102			if (key == B_ESCAPE) {
103				message->MakeEmpty();
104				message->what = MSG_HIDE_WINDOW;
105			}
106		}
107	}
108
109	BWindow::DispatchMessage(message, handler);
110}
111
112
113bool
114FindWindow::QuitRequested()
115{
116	BMessenger messenger(fHandler);
117	messenger.SendMessage(MSG_FIND_WINDOW_QUIT);
118
119	return true;
120}
121
122
123void
124FindWindow::Show()
125{
126	fSearchString->TextView()->SelectAll();
127	BWindow::Show();
128}
129
130
131void
132FindWindow::_SendMessage()
133{
134	BMessage message(MSG_SEARCH);
135
136	// Add the string
137	message.AddString("findtext", fSearchString->Text());
138
139	// Add searchparameters from checkboxes
140	message.AddBool("casesens", fCaseSensBox->Value() == B_CONTROL_ON);
141	message.AddBool("wrap", fWrapBox->Value() == B_CONTROL_ON);
142	message.AddBool("backsearch", fBackSearchBox->Value() == B_CONTROL_ON);
143
144	fHandler->Looper()->PostMessage(&message, fHandler);
145
146	PostMessage(MSG_HIDE_WINDOW);
147}
148