xref: /haiku/src/apps/terminal/FindWindow.cpp (revision 04a0e9c7b68cbe3a43d38e2bca8e860fd80936fb)
1  /*
2   * Copyright 2007-2013 Haiku, Inc. All rights reserved.
3   * Copyright 2003-2004 Kian Duffy, myob@users.sourceforge.net
4   * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai.
5   * All rights reserved. Distributed under the terms of the MIT license.
6   *
7   * Authors:
8   *		John Scipione, jscipione@gmail.com
9   */
10  
11  #include "FindWindow.h"
12  
13  
14  #include <Box.h>
15  #include <Button.h>
16  #include <Catalog.h>
17  #include <CheckBox.h>
18  #include <ControlLook.h>
19  #include <GridLayoutBuilder.h>
20  #include <GroupLayout.h>
21  #include <GroupLayoutBuilder.h>
22  #include <Locale.h>
23  #include <RadioButton.h>
24  #include <SpaceLayoutItem.h>
25  #include <String.h>
26  #include <TextControl.h>
27  
28  
29  const uint32 MSG_FIND_HIDE = 'Fhid';
30  const uint32 TOGGLE_FIND_CONTROL = 'MTFG';
31  const BRect kWindowFrame(10, 30, 250, 200);
32  
33  
34  #undef B_TRANSLATION_CONTEXT
35  #define B_TRANSLATION_CONTEXT "Terminal FindWindow"
36  
37  
38  FindWindow::FindWindow(BMessenger messenger, const BString& str,
39  	bool findSelection, bool matchWord, bool matchCase, bool forwardSearch)
40  	:
41  	BWindow(kWindowFrame, B_TRANSLATE("Find"), B_FLOATING_WINDOW,
42  		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE
43  		| B_AUTO_UPDATE_SIZE_LIMITS),
44  	fFindDlgMessenger(messenger)
45  {
46  	SetLayout(new BGroupLayout(B_VERTICAL));
47  
48  	BBox* separator = new BBox("separator");
49  	separator->SetExplicitMinSize(BSize(250.0, B_SIZE_UNSET));
50  	separator->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1.0));
51  
52  	BRadioButton* useSelection = NULL;
53  	const float spacing = be_control_look->DefaultItemSpacing();
54  	AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_SMALL_SPACING)
55  		.SetInsets(spacing, spacing, spacing, spacing)
56  		.Add(BGridLayoutBuilder(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING)
57  			.Add(fTextRadio = new BRadioButton(B_TRANSLATE("Use text:"),
58  				new BMessage(TOGGLE_FIND_CONTROL)), 0, 0)
59  			.Add(fFindLabel = new BTextControl(NULL, NULL, NULL), 1, 0)
60  			.Add(useSelection = new BRadioButton(B_TRANSLATE("Use selection"),
61  				new BMessage(TOGGLE_FIND_CONTROL)), 0, 1))
62  		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing / 4))
63  		.Add(separator)
64  		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing / 4))
65  		.Add(fForwardSearchBox = new BCheckBox(B_TRANSLATE("Search forward")))
66  		.Add(fMatchCaseBox = new BCheckBox(B_TRANSLATE("Match case")))
67  		.Add(fMatchWordBox = new BCheckBox(B_TRANSLATE("Match word")))
68  		.AddGroup(B_HORIZONTAL)
69  			.AddGlue()
70  			.Add(fFindButton = new BButton(B_TRANSLATE("Find"),
71  				new BMessage(MSG_FIND)))
72  			.End()
73  		.TopView());
74  
75  	fFindLabel->SetDivider(0.0);
76  
77  	if (!findSelection) {
78  		fFindLabel->SetText(str.String());
79  		fFindLabel->MakeFocus(true);
80  	} else {
81  		fFindLabel->SetEnabled(false);
82  	}
83  
84  	if (findSelection)
85  		useSelection->SetValue(B_CONTROL_ON);
86  	else
87  		fTextRadio->SetValue(B_CONTROL_ON);
88  
89  	if (forwardSearch)
90  		fForwardSearchBox->SetValue(B_CONTROL_ON);
91  
92  	if (matchCase)
93  		fMatchCaseBox->SetValue(B_CONTROL_ON);
94  
95  	if (matchWord)
96  		fMatchWordBox->SetValue(B_CONTROL_ON);
97  
98  	fFindButton->MakeDefault(true);
99  
100  	AddShortcut((uint32)'W', B_COMMAND_KEY, new BMessage(MSG_FIND_HIDE));
101  }
102  
103  
104  FindWindow::~FindWindow()
105  {
106  }
107  
108  
109  void
110  FindWindow::MessageReceived(BMessage *msg)
111  {
112  	switch (msg->what) {
113  		case B_QUIT_REQUESTED:
114  			Quit();
115  			break;
116  
117  		case MSG_FIND:
118  			_SendFindMessage();
119  			break;
120  
121  		case MSG_FIND_HIDE:
122  			Quit();
123  			break;
124  
125  		case TOGGLE_FIND_CONTROL:
126  			fFindLabel->SetEnabled(fTextRadio->Value() == B_CONTROL_ON);
127  			break;
128  
129  		default:
130  			BWindow::MessageReceived(msg);
131  			break;
132  	}
133  }
134  
135  
136  void
137  FindWindow::Quit()
138  {
139  	fFindDlgMessenger.SendMessage(MSG_FIND_CLOSED);
140  	BWindow::Quit();
141  }
142  
143  
144  void
145  FindWindow::_SendFindMessage()
146  {
147  	BMessage message(MSG_FIND);
148  
149  	if (fTextRadio->Value() == B_CONTROL_ON) {
150  		message.AddString("findstring", fFindLabel->Text());
151  		message.AddBool("findselection", false);
152  	} else
153  		message.AddBool("findselection", true);
154  
155  	//Add the other parameters
156  	// TODO: "usetext" is never checked for elsewhere and seems
157  	// redundant with "findselection", why is it here?
158  	message.AddBool("usetext", fTextRadio->Value() == B_CONTROL_ON);
159  	message.AddBool("forwardsearch", fForwardSearchBox->Value() == B_CONTROL_ON);
160  	message.AddBool("matchcase", fMatchCaseBox->Value() == B_CONTROL_ON);
161  	message.AddBool("matchword", fMatchWordBox->Value() == B_CONTROL_ON);
162  
163  	fFindDlgMessenger.SendMessage(&message);
164  }
165