#include "FindWindow.h"
#include "MailApp.h"
#include "MailWindow.h"
#include "Messages.h"
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <String.h>
#include <TextView.h>
#define B_TRANSLATION_CONTEXT "Mail"
enum {
M_FIND_STRING_CHANGED = 'fsch'
};
#define FINDBUTTON 'find'
static BString sPreviousFind = "";
FindWindow* FindWindow::fFindWindow = NULL;
BRect FindWindow::fLastPosition(BRect(100, 300, 300, 374));
void FindWindow::DoFind(BWindow* window, const char* text)
{
if (window == NULL) {
long i = 0;
while ((window = be_app->WindowAt(i++)) != NULL) {
if (window != fFindWindow)
if (dynamic_cast<TMailWindow*>(window) != NULL)
break;
}
}
window = dynamic_cast<TMailWindow*>(window)->FrontmostWindow();
if (window == NULL)
return;
if (!window->Lock())
return;
BView* focus = window->FindView("m_content");
window->Unlock();
if (focus)
{
BMessage msg(M_FIND);
msg.AddString("findthis",text);
window->PostMessage(&msg, focus);
}
}
FindPanel::FindPanel()
:
BGroupView("FindPanel", B_VERTICAL)
{
fTextControl = new BTextControl("BTextControl", NULL,
sPreviousFind.String(), new BMessage(M_FIND_STRING_CHANGED));
fTextControl->SetModificationMessage(new BMessage(M_FIND_STRING_CHANGED));
fTextControl->SetText(sPreviousFind.String());
fTextControl->MakeFocus();
fFindButton = new BButton("FINDBUTTON", B_TRANSLATE("Find"),
new BMessage(FINDBUTTON));
fFindButton->SetEnabled(sPreviousFind.Length());
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_WINDOW_SPACING)
.Add(fTextControl)
.AddGroup(B_HORIZONTAL)
.AddGlue()
.Add(fFindButton)
.End()
.End();
}
FindPanel::~FindPanel()
{
sPreviousFind = fTextControl->Text();
}
void FindPanel::AttachedToWindow()
{
BView::AttachedToWindow();
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
Window()->SetDefaultButton(fFindButton);
fFindButton->SetTarget(this);
fTextControl->SetTarget(this);
fTextControl->ResizeToPreferred();
fTextControl->ResizeTo(Bounds().Width() - 20,
fTextControl->Frame().Height());
fTextControl->MakeFocus(true);
fTextControl->TextView()->SelectAll();
}
void FindPanel::MouseDown(BPoint point)
{
Window()->Activate();
BView::MouseDown(point);
}
void FindPanel::Draw(BRect)
{
}
void FindPanel::KeyDown(const char*, int32)
{
int32 length = fTextControl->TextView()->TextLength();
bool enabled = fFindButton->IsEnabled();
if (length > 0 && !enabled)
fFindButton->SetEnabled(true);
else if (length == 0 && enabled)
fFindButton->SetEnabled(false);
}
void FindPanel::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case M_FIND_STRING_CHANGED: {
if (strlen(fTextControl->Text()) == 0)
fFindButton->SetEnabled(false);
else
fFindButton->SetEnabled(true);
break;
}
case FINDBUTTON: {
Find();
Window()->PostMessage(B_QUIT_REQUESTED);
break;
}
default:
BView::MessageReceived(msg);
break;
}
}
void FindPanel::Find()
{
fTextControl->TextView()->SelectAll();
const char* text = fTextControl->Text();
if (text == NULL || text[0] == 0) return;
BWindow* window = NULL;
long i = 0;
while ((bool)(window = be_app->WindowAt(i++))) {
if (window != FindWindow::fFindWindow)
break;
}
if (window)
FindWindow::DoFind(window, text);
}
FindWindow::FindWindow()
: BWindow(FindWindow::fLastPosition, B_TRANSLATE("Find"),
B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
| B_WILL_ACCEPT_FIRST_CLICK | B_CLOSE_ON_ESCAPE
| B_AUTO_UPDATE_SIZE_LIMITS)
{
SetLayout(new BGroupLayout(B_VERTICAL));
fFindPanel = new FindPanel();
AddChild(fFindPanel);
fFindWindow = this;
Show();
}
FindWindow::~FindWindow()
{
FindWindow::fLastPosition = Frame();
fFindWindow = NULL;
}
void FindWindow::Find(BWindow* window)
{
(void)window;
if (fFindWindow == NULL) {
fFindWindow = new FindWindow();
} else
fFindWindow->Activate();
}
void FindWindow::FindAgain(BWindow* window)
{
if (fFindWindow) {
fFindWindow->Lock();
fFindWindow->fFindPanel->Find();
fFindWindow->Unlock();
} else if (sPreviousFind.Length() != 0)
DoFind(window, sPreviousFind.String());
else
Find(window);
}
void FindWindow::SetFindString(const char* string)
{
sPreviousFind = string;
}
const char* FindWindow::GetFindString()
{
return sPreviousFind.String();
}