1 /* 2 * Copyright 2002-2009, 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 "ReplaceWindow.h" 13 14 #include <Button.h> 15 #include <Catalog.h> 16 #include <CheckBox.h> 17 #include <GroupLayoutBuilder.h> 18 #include <GridLayoutBuilder.h> 19 #include <Handler.h> 20 #include <Locale.h> 21 #include <LayoutBuilder.h> 22 #include <Message.h> 23 #include <Messenger.h> 24 #include <String.h> 25 #include <TextControl.h> 26 27 28 #undef B_TRANSLATION_CONTEXT 29 #define B_TRANSLATION_CONTEXT "FindandReplaceWindow" 30 31 ReplaceWindow::ReplaceWindow(BRect frame, BHandler* _handler, 32 BString* searchString, BString* replaceString, 33 bool caseState, bool wrapState, bool backState) 34 : BWindow(frame, "ReplaceWindow", B_MODAL_WINDOW, 35 B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS, 36 B_CURRENT_WORKSPACE) 37 { 38 AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED)); 39 40 fSearchString = new BTextControl("", B_TRANSLATE("Find:"), NULL, NULL); 41 fReplaceString = new BTextControl("", B_TRANSLATE("Replace with:"), 42 NULL, NULL); 43 fCaseSensBox = new BCheckBox("", B_TRANSLATE("Case-sensitive"), NULL); 44 fWrapBox = new BCheckBox("", B_TRANSLATE("Wrap-around search"), NULL); 45 fBackSearchBox = new BCheckBox("", B_TRANSLATE("Search backwards"), NULL); 46 fAllWindowsBox = new BCheckBox("", B_TRANSLATE("Replace in all windows"), 47 new BMessage(CHANGE_WINDOW)); 48 fUIchange = false; 49 50 fReplaceAllButton = new BButton("", B_TRANSLATE("Replace all"), 51 new BMessage(MSG_REPLACE_ALL)); 52 fCancelButton = new BButton("", B_TRANSLATE("Cancel"), 53 new BMessage(B_QUIT_REQUESTED)); 54 fReplaceButton = new BButton("", B_TRANSLATE("Replace"), 55 new BMessage(MSG_REPLACE)); 56 57 SetLayout(new BGroupLayout(B_HORIZONTAL)); 58 AddChild(BGroupLayoutBuilder(B_VERTICAL, 4) 59 .Add(BGridLayoutBuilder(6, 2) 60 .Add(fSearchString->CreateLabelLayoutItem(), 0, 0) 61 .Add(fSearchString->CreateTextViewLayoutItem(), 1, 0) 62 .Add(fReplaceString->CreateLabelLayoutItem(), 0, 1) 63 .Add(fReplaceString->CreateTextViewLayoutItem(), 1, 1) 64 .Add(fCaseSensBox, 1, 2) 65 .Add(fWrapBox, 1, 3) 66 .Add(fBackSearchBox, 1, 4) 67 .Add(fAllWindowsBox, 1, 5) 68 ) 69 .AddGroup(B_HORIZONTAL, 10) 70 .Add(fReplaceAllButton) 71 .AddGlue() 72 .Add(fCancelButton) 73 .Add(fReplaceButton) 74 .End() 75 .SetInsets(10, 10, 10, 10) 76 ); 77 78 fReplaceButton->MakeDefault(true); 79 80 fHandler = _handler; 81 82 const char* searchtext = searchString->String(); 83 const char* replacetext = replaceString->String(); 84 85 fSearchString->SetText(searchtext); 86 fReplaceString->SetText(replacetext); 87 fSearchString->MakeFocus(true); 88 89 fCaseSensBox->SetValue(caseState ? B_CONTROL_ON : B_CONTROL_OFF); 90 fWrapBox->SetValue(wrapState ? B_CONTROL_ON : B_CONTROL_OFF); 91 fBackSearchBox->SetValue(backState ? B_CONTROL_ON : B_CONTROL_OFF); 92 } 93 94 95 void 96 ReplaceWindow::MessageReceived(BMessage* msg) 97 { 98 switch (msg->what) { 99 case MSG_REPLACE: 100 _SendMessage(MSG_REPLACE); 101 break; 102 case CHANGE_WINDOW: 103 _ChangeUI(); 104 break; 105 case MSG_REPLACE_ALL: 106 _SendMessage(MSG_REPLACE_ALL); 107 break; 108 109 default: 110 BWindow::MessageReceived(msg); 111 break; 112 } 113 } 114 115 116 void 117 ReplaceWindow::_ChangeUI() 118 { 119 fWrapBox->SetEnabled(fUIchange); 120 fWrapBox->SetValue(fUIchange ? B_CONTROL_OFF : B_CONTROL_ON); 121 122 fBackSearchBox->SetEnabled(fUIchange); 123 124 fReplaceButton->SetEnabled(fUIchange); 125 if (fUIchange) 126 fReplaceButton->MakeDefault(true); 127 else 128 fReplaceAllButton->MakeDefault(true); 129 130 fUIchange = !fUIchange; 131 } 132 133 134 void 135 ReplaceWindow::DispatchMessage(BMessage* message, BHandler* handler) 136 { 137 if (message->what == B_KEY_DOWN) { 138 int8 key; 139 if (message->FindInt8("byte", 0, &key) == B_OK) { 140 if (key == B_ESCAPE) { 141 message->MakeEmpty(); 142 message->what = B_QUIT_REQUESTED; 143 144 // This is a hack, but it actually does what is expected, 145 // unlike the hack above. This kind of key filtering probably 146 // ought to be handled by a BMessageFilter, though. 147 BMessenger (this).SendMessage(B_QUIT_REQUESTED); 148 } 149 } 150 } 151 152 BWindow::DispatchMessage(message, handler); 153 } 154 155 156 void 157 ReplaceWindow::_SendMessage(uint32 what) 158 { 159 BMessage message(what); 160 161 // Add the strings 162 message.AddString("FindText", fSearchString->Text()); 163 message.AddString("ReplaceText", fReplaceString->Text()); 164 165 // Add searchparameters from checkboxes 166 message.AddBool("casesens", fCaseSensBox->Value() == B_CONTROL_ON); 167 message.AddBool("wrap", fWrapBox->Value() == B_CONTROL_ON); 168 message.AddBool("backsearch", fBackSearchBox->Value() == B_CONTROL_ON); 169 message.AddBool("allwindows", fAllWindowsBox->Value() == B_CONTROL_ON); 170 171 fHandler->Looper()->PostMessage(&message, fHandler); 172 173 PostMessage(B_QUIT_REQUESTED); 174 } 175 176