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