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 CONNECTION 23 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 registered trademarks 30 of Be Incorporated in the United States and other countries. Other brand product 31 names are registered trademarks or trademarks of their respective holders. 32 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 <Locale.h> 50 #include <String.h> 51 #include <TextView.h> 52 53 54 #define TR_CONTEXT "Mail" 55 56 57 enum { 58 M_FIND_STRING_CHANGED = 'fsch' 59 }; 60 61 62 #define FINDBUTTON 'find' 63 64 static BString sPreviousFind = ""; 65 66 FindWindow* FindWindow::fFindWindow = NULL; 67 BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374)); 68 69 void FindWindow::DoFind(BWindow* window, const char* text) 70 { 71 if (window == NULL) { 72 long i = 0; 73 while ((window = be_app->WindowAt(i++)) != NULL) { 74 // Send the text to a waiting window 75 if (window != fFindWindow) 76 if (dynamic_cast<TMailWindow*>(window) != NULL) 77 break; // Found a window 78 } 79 } 80 81 /* ask that window who is in the front */ 82 window = dynamic_cast<TMailWindow*>(window)->FrontmostWindow(); 83 if (window == NULL) 84 return; 85 86 // Found a window, send a find message 87 88 if (!window->Lock()) 89 return; 90 BView* focus = window->FindView("m_content"); 91 window->Unlock(); 92 93 if (focus) 94 { 95 BMessage msg(M_FIND); 96 msg.AddString("findthis",text); 97 window->PostMessage(&msg, focus); 98 } 99 } 100 101 102 FindPanel::FindPanel(BRect rect) 103 : 104 BBox(rect, "FindPanel", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW) 105 { 106 BRect r = Bounds().InsetByCopy(10, 10); 107 108 fTextControl = new BTextControl(r, "BTextControl", NULL, 109 sPreviousFind.String(), new BMessage(M_FIND_STRING_CHANGED), 110 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 111 112 fTextControl->SetText(sPreviousFind.String()); 113 fTextControl->MakeFocus(); 114 AddChild(fTextControl); 115 116 fFindButton = new BButton(BRect(0, 0, 90, 20),"FINDBUTTON", TR("Find"), 117 new BMessage(FINDBUTTON),B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 118 fFindButton->ResizeToPreferred(); 119 AddChild(fFindButton); 120 r = fFindButton->Bounds(); 121 122 fFindButton->MoveTo(Bounds().right - r.Width() - 8, 123 Bounds().bottom - r.Height() - 8); 124 fFindButton->SetEnabled(sPreviousFind.Length()); 125 } 126 127 128 FindPanel::~FindPanel() 129 { 130 sPreviousFind = fTextControl->Text(); 131 } 132 133 134 void FindPanel::AttachedToWindow() 135 { 136 BView::AttachedToWindow(); 137 SetViewColor(216, 216, 216); 138 Window()->SetDefaultButton(fFindButton); 139 fFindButton->SetTarget(this); 140 141 fTextControl->SetTarget(this); 142 fTextControl->ResizeToPreferred(); 143 fTextControl->ResizeTo(Bounds().Width() - 20, 144 fTextControl->Frame().Height()); 145 146 fTextControl->MakeFocus(true); 147 fTextControl->TextView()->SelectAll(); 148 } 149 150 151 void FindPanel::MouseDown(BPoint point) 152 { 153 Window()->Activate(); 154 BView::MouseDown(point); 155 } 156 157 158 void FindPanel::Draw(BRect) 159 { 160 // TextBevel(*this, mBTextView->Frame()); 161 } 162 163 164 void FindPanel::KeyDown(const char*, int32) 165 { 166 int32 length = fTextControl->TextView()->TextLength(); 167 bool enabled = fFindButton->IsEnabled(); 168 169 if (length > 0 && !enabled) 170 fFindButton->SetEnabled(true); 171 else if (length == 0 && enabled) 172 fFindButton->SetEnabled(false); 173 } 174 175 176 void FindPanel::MessageReceived(BMessage* msg) 177 { 178 switch (msg->what) { 179 case M_FIND_STRING_CHANGED: { 180 if (strlen(fTextControl->Text()) == 0) 181 fFindButton->SetEnabled(false); 182 else 183 fFindButton->SetEnabled(true); 184 break; 185 } 186 case FINDBUTTON: { 187 Find(); 188 Window()->PostMessage(B_QUIT_REQUESTED); 189 break; 190 } 191 default: 192 BView::MessageReceived(msg); 193 } 194 } 195 196 197 void FindPanel::Find() 198 { 199 fTextControl->TextView()->SelectAll(); 200 const char* text = fTextControl->Text(); 201 if (text == NULL || text[0] == 0) return; 202 203 BWindow* window = NULL; 204 long i = 0; 205 while ((bool)(window = be_app->WindowAt(i++))) { 206 // Send the text to a waiting window 207 if (window != FindWindow::fFindWindow) 208 break; // Found a window 209 } 210 211 if (window) 212 FindWindow::DoFind(window, text); 213 } 214 215 216 FindWindow::FindWindow() 217 : BWindow(FindWindow::fLastPosition, TR("Find"), B_FLOATING_WINDOW, 218 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK 219 | B_CLOSE_ON_ESCAPE) 220 { 221 fFindPanel = new FindPanel(Bounds()); 222 AddChild(fFindPanel); 223 fFindWindow = this; 224 Show(); 225 } 226 227 228 FindWindow::~FindWindow() 229 { 230 FindWindow::fLastPosition = Frame(); 231 fFindWindow = NULL; 232 } 233 234 235 void FindWindow::Find(BWindow* window) 236 { 237 // eliminate unused parameter warning 238 (void)window; 239 240 if (fFindWindow == NULL) { 241 fFindWindow = new FindWindow(); 242 } else 243 fFindWindow->Activate(); 244 } 245 246 247 void FindWindow::FindAgain(BWindow* window) 248 { 249 if (fFindWindow) { 250 fFindWindow->Lock(); 251 fFindWindow->fFindPanel->Find(); 252 fFindWindow->Unlock(); 253 } else if (sPreviousFind.Length() != 0) 254 DoFind(window, sPreviousFind.String()); 255 else 256 Find(window); 257 } 258 259 260 void FindWindow::SetFindString(const char* string) 261 { 262 sPreviousFind = string; 263 } 264 265 266 const char* FindWindow::GetFindString() 267 { 268 return sPreviousFind.String(); 269 } 270 271