1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2001, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN 23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or 30 registered trademarks of Be Incorporated in the United States and other 31 countries. Other brand product names are registered trademarks or trademarks 32 of 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 58 enum { 59 M_FIND_STRING_CHANGED = 'fsch' 60 }; 61 62 63 #define FINDBUTTON 'find' 64 65 static BString sPreviousFind = ""; 66 67 FindWindow* FindWindow::fFindWindow = NULL; 68 BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374)); 69 70 void 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 103 FindPanel::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 130 FindPanel::~FindPanel() 131 { 132 sPreviousFind = fTextControl->Text(); 133 } 134 135 136 void 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 153 void FindPanel::MouseDown(BPoint point) 154 { 155 Window()->Activate(); 156 BView::MouseDown(point); 157 } 158 159 160 void FindPanel::Draw(BRect) 161 { 162 // TextBevel(*this, mBTextView->Frame()); 163 } 164 165 166 void 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 178 void 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 } 196 } 197 198 199 void FindPanel::Find() 200 { 201 fTextControl->TextView()->SelectAll(); 202 const char* text = fTextControl->Text(); 203 if (text == NULL || text[0] == 0) return; 204 205 BWindow* window = NULL; 206 long i = 0; 207 while ((bool)(window = be_app->WindowAt(i++))) { 208 // Send the text to a waiting window 209 if (window != FindWindow::fFindWindow) 210 break; // Found a window 211 } 212 213 if (window) 214 FindWindow::DoFind(window, text); 215 } 216 217 218 FindWindow::FindWindow() 219 : BWindow(FindWindow::fLastPosition, B_TRANSLATE("Find"), 220 B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE 221 | B_WILL_ACCEPT_FIRST_CLICK | B_CLOSE_ON_ESCAPE 222 | B_AUTO_UPDATE_SIZE_LIMITS) 223 { 224 SetLayout(new BGroupLayout(B_VERTICAL)); 225 fFindPanel = new FindPanel(); 226 AddChild(fFindPanel); 227 fFindWindow = this; 228 Show(); 229 } 230 231 232 FindWindow::~FindWindow() 233 { 234 FindWindow::fLastPosition = Frame(); 235 fFindWindow = NULL; 236 } 237 238 239 void FindWindow::Find(BWindow* window) 240 { 241 // eliminate unused parameter warning 242 (void)window; 243 244 if (fFindWindow == NULL) { 245 fFindWindow = new FindWindow(); 246 } else 247 fFindWindow->Activate(); 248 } 249 250 251 void FindWindow::FindAgain(BWindow* window) 252 { 253 if (fFindWindow) { 254 fFindWindow->Lock(); 255 fFindWindow->fFindPanel->Find(); 256 fFindWindow->Unlock(); 257 } else if (sPreviousFind.Length() != 0) 258 DoFind(window, sPreviousFind.String()); 259 else 260 Find(window); 261 } 262 263 264 void FindWindow::SetFindString(const char* string) 265 { 266 sPreviousFind = string; 267 } 268 269 270 const char* FindWindow::GetFindString() 271 { 272 return sPreviousFind.String(); 273 } 274 275