Override QuitRequested in FindWindow to notify the parent edit window of the find window's demise so it can reset its corresponding pointer. Otherwise the latter will potentially access the invalid pointer in question on subsequent find requests, leading to potential crashes.
148 lines
3.4 KiB
C++
148 lines
3.4 KiB
C++
/*
|
|
* Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Mattias Sundblad
|
|
* Andrew Bachmann
|
|
*/
|
|
|
|
|
|
#include "Constants.h"
|
|
#include "FindWindow.h"
|
|
|
|
#include <Button.h>
|
|
#include <Catalog.h>
|
|
#include <CheckBox.h>
|
|
#include <GroupLayoutBuilder.h>
|
|
#include <GridLayoutBuilder.h>
|
|
#include <Locale.h>
|
|
#include <LayoutBuilder.h>
|
|
#include <String.h>
|
|
#include <TextControl.h>
|
|
|
|
|
|
#undef B_TRANSLATION_CONTEXT
|
|
#define B_TRANSLATION_CONTEXT "FindandReplaceWindow"
|
|
|
|
|
|
FindWindow::FindWindow(BRect frame, BHandler* _handler, BString* searchString,
|
|
bool caseState, bool wrapState, bool backState)
|
|
: BWindow(frame, B_TRANSLATE("Find"), B_FLOATING_WINDOW,
|
|
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
|
|
| B_AUTO_UPDATE_SIZE_LIMITS, B_CURRENT_WORKSPACE)
|
|
{
|
|
AddShortcut('W', B_COMMAND_KEY, new BMessage(MSG_HIDE_WINDOW));
|
|
|
|
fSearchString = new BTextControl("", B_TRANSLATE("Find:"), NULL, NULL);
|
|
fCaseSensBox = new BCheckBox("", B_TRANSLATE("Case-sensitive"), NULL);
|
|
fWrapBox = new BCheckBox("", B_TRANSLATE("Wrap-around search"), NULL);
|
|
fBackSearchBox = new BCheckBox("", B_TRANSLATE("Search backwards"), NULL);
|
|
fCancelButton = new BButton("", B_TRANSLATE("Cancel"),
|
|
new BMessage(MSG_HIDE_WINDOW));
|
|
fSearchButton = new BButton("", B_TRANSLATE("Find"),
|
|
new BMessage(MSG_SEARCH));
|
|
|
|
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
|
AddChild(BGroupLayoutBuilder(B_VERTICAL, 4)
|
|
.Add(BGridLayoutBuilder(6, 2)
|
|
.Add(fSearchString->CreateLabelLayoutItem(), 0, 0)
|
|
.Add(fSearchString->CreateTextViewLayoutItem(), 1, 0)
|
|
.Add(fCaseSensBox, 1, 1)
|
|
.Add(fWrapBox, 1, 2)
|
|
.Add(fBackSearchBox, 1, 3)
|
|
)
|
|
.AddGroup(B_HORIZONTAL, 10)
|
|
.AddGlue()
|
|
.Add(fCancelButton)
|
|
.Add(fSearchButton)
|
|
.End()
|
|
.SetInsets(10, 10, 10, 10)
|
|
);
|
|
|
|
fSearchButton->MakeDefault(true);
|
|
fHandler = _handler;
|
|
|
|
const char* text = searchString->String();
|
|
|
|
fSearchString->SetText(text);
|
|
fSearchString->MakeFocus(true);
|
|
|
|
fCaseSensBox->SetValue(caseState ? B_CONTROL_ON : B_CONTROL_OFF);
|
|
fWrapBox->SetValue(wrapState ? B_CONTROL_ON : B_CONTROL_OFF);
|
|
fBackSearchBox->SetValue(backState ? B_CONTROL_ON : B_CONTROL_OFF);
|
|
}
|
|
|
|
|
|
void
|
|
FindWindow::MessageReceived(BMessage* msg)
|
|
{
|
|
switch (msg->what) {
|
|
case MSG_HIDE_WINDOW:
|
|
if (!IsHidden())
|
|
Hide();
|
|
break;
|
|
case MSG_SEARCH:
|
|
_SendMessage();
|
|
break;
|
|
|
|
default:
|
|
BWindow::MessageReceived(msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
FindWindow::DispatchMessage(BMessage* message, BHandler* handler)
|
|
{
|
|
if (message->what == B_KEY_DOWN) {
|
|
int8 key;
|
|
if (message->FindInt8("byte", 0, &key) == B_OK) {
|
|
if (key == B_ESCAPE) {
|
|
message->MakeEmpty();
|
|
message->what = MSG_HIDE_WINDOW;
|
|
}
|
|
}
|
|
}
|
|
|
|
BWindow::DispatchMessage(message, handler);
|
|
}
|
|
|
|
|
|
bool
|
|
FindWindow::QuitRequested()
|
|
{
|
|
BMessenger messenger(fHandler);
|
|
messenger.SendMessage(MSG_FIND_WINDOW_QUIT);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void
|
|
FindWindow::Show()
|
|
{
|
|
fSearchString->TextView()->SelectAll();
|
|
BWindow::Show();
|
|
}
|
|
|
|
|
|
void
|
|
FindWindow::_SendMessage()
|
|
{
|
|
BMessage message(MSG_SEARCH);
|
|
|
|
// Add the string
|
|
message.AddString("findtext", fSearchString->Text());
|
|
|
|
// Add searchparameters from checkboxes
|
|
message.AddBool("casesens", fCaseSensBox->Value() == B_CONTROL_ON);
|
|
message.AddBool("wrap", fWrapBox->Value() == B_CONTROL_ON);
|
|
message.AddBool("backsearch", fBackSearchBox->Value() == B_CONTROL_ON);
|
|
|
|
fHandler->Looper()->PostMessage(&message, fHandler);
|
|
|
|
PostMessage(MSG_HIDE_WINDOW);
|
|
}
|