1/* 2Open Tracker License 3 4Terms and Conditions 5 6Copyright (c) 1991-2001, Be Incorporated. All rights reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a copy of 9this software and associated documentation files (the "Software"), to deal in 10the Software without restriction, including without limitation the rights to 11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12of the Software, and to permit persons to whom the Software is furnished to do 13so, subject to the following conditions: 14 15The above copyright notice and this permission notice applies to all licensees 16and shall be included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN 23CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25Except as contained in this notice, the name of Be Incorporated shall not be 26used in advertising or otherwise to promote the sale, use or other dealings in 27this Software without prior written authorization from Be Incorporated. 28 29BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or 30registered trademarks of Be Incorporated in the United States and other 31countries. Other brand product names are registered trademarks or trademarks 32of 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 <Locale.h> 50#include <String.h> 51#include <TextView.h> 52 53 54#define B_TRANSLATION_CONTEXT "Mail" 55 56 57enum { 58 M_FIND_STRING_CHANGED = 'fsch' 59}; 60 61 62#define FINDBUTTON 'find' 63 64static BString sPreviousFind = ""; 65 66FindWindow* FindWindow::fFindWindow = NULL; 67BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374)); 68 69void 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 102FindPanel::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->SetModificationMessage(new BMessage(M_FIND_STRING_CHANGED)); 113 fTextControl->SetText(sPreviousFind.String()); 114 fTextControl->MakeFocus(); 115 AddChild(fTextControl); 116 117 fFindButton = new BButton(BRect(0, 0, 90, 20),"FINDBUTTON", 118 B_TRANSLATE("Find"), 119 new BMessage(FINDBUTTON),B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 120 fFindButton->ResizeToPreferred(); 121 AddChild(fFindButton); 122 r = fFindButton->Bounds(); 123 124 fFindButton->MoveTo(Bounds().right - r.Width() - 8, 125 Bounds().bottom - r.Height() - 8); 126 fFindButton->SetEnabled(sPreviousFind.Length()); 127} 128 129 130FindPanel::~FindPanel() 131{ 132 sPreviousFind = fTextControl->Text(); 133} 134 135 136void FindPanel::AttachedToWindow() 137{ 138 BView::AttachedToWindow(); 139 SetViewColor(216, 216, 216); 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 153void FindPanel::MouseDown(BPoint point) 154{ 155 Window()->Activate(); 156 BView::MouseDown(point); 157} 158 159 160void FindPanel::Draw(BRect) 161{ 162// TextBevel(*this, mBTextView->Frame()); 163} 164 165 166void 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 178void 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 199void 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 218FindWindow::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{ 223 fFindPanel = new FindPanel(Bounds()); 224 AddChild(fFindPanel); 225 fFindWindow = this; 226 Show(); 227} 228 229 230FindWindow::~FindWindow() 231{ 232 FindWindow::fLastPosition = Frame(); 233 fFindWindow = NULL; 234} 235 236 237void FindWindow::Find(BWindow* window) 238{ 239 // eliminate unused parameter warning 240 (void)window; 241 242 if (fFindWindow == NULL) { 243 fFindWindow = new FindWindow(); 244 } else 245 fFindWindow->Activate(); 246} 247 248 249void FindWindow::FindAgain(BWindow* window) 250{ 251 if (fFindWindow) { 252 fFindWindow->Lock(); 253 fFindWindow->fFindPanel->Find(); 254 fFindWindow->Unlock(); 255 } else if (sPreviousFind.Length() != 0) 256 DoFind(window, sPreviousFind.String()); 257 else 258 Find(window); 259} 260 261 262void FindWindow::SetFindString(const char* string) 263{ 264 sPreviousFind = string; 265} 266 267 268const char* FindWindow::GetFindString() 269{ 270 return sPreviousFind.String(); 271} 272 273