Explicitly check BApplication::WindowAt() against NULL, as suggested by Axel. Replacing AutoTextControl with a standard BTextControl and window flag B_CLOSE_ON_QUIT.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35000 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,248 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <[email protected]>
|
||||
*/
|
||||
#include "AutoTextControl.h"
|
||||
#include <Window.h>
|
||||
#include <String.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
AutoTextControlFilter::AutoTextControlFilter(AutoTextControl *box)
|
||||
: BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE,B_KEY_DOWN),
|
||||
fBox(box),
|
||||
fMessenger(NULL),
|
||||
fCurrentMessage(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AutoTextControlFilter::~AutoTextControlFilter(void)
|
||||
{
|
||||
}
|
||||
|
||||
filter_result
|
||||
AutoTextControlFilter::Filter(BMessage *msg, BHandler **target)
|
||||
{
|
||||
// This is really slick -- all that is needed to allow Escape key cancelling is
|
||||
// just calling SetEscapeCancel(true) for just *one* AutoTextControl in a window. *heh*
|
||||
int32 rawchar,mod;
|
||||
msg->FindInt32("raw_char",&rawchar);
|
||||
msg->FindInt32("modifiers",&mod);
|
||||
|
||||
|
||||
if (rawchar == B_ESCAPE) {
|
||||
if (mod & B_COMMAND_KEY)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
if (IsEscapeCancel()) {
|
||||
BLooper *loop = (*target)->Looper();
|
||||
|
||||
if (loop) {
|
||||
BMessenger msgr(loop);
|
||||
msgr.SendMessage(B_QUIT_REQUESTED);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BView *v = dynamic_cast<BView*>(*target);
|
||||
if (!v || strcmp("_input_",v->Name()) != 0)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
AutoTextControl *text = dynamic_cast<AutoTextControl*>(v->Parent());
|
||||
if (!text || text != fBox)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
// handle instances where numlock is off and the user tries to punch in
|
||||
// numbers. Instead of simply blocking the resulting keypresses,
|
||||
// transform them into legit ones and turn NumLock on for the user.
|
||||
|
||||
int32 scancode;
|
||||
if (msg->FindInt32("key",&scancode) != B_OK)
|
||||
scancode = -1;
|
||||
|
||||
HandleNoNumLock(scancode,rawchar,msg);
|
||||
|
||||
fCurrentMessage = msg;
|
||||
filter_result result = KeyFilter(rawchar,mod);
|
||||
fCurrentMessage = NULL;
|
||||
|
||||
if (fBox->fCharLimit && result == B_DISPATCH_MESSAGE) {
|
||||
// See to it that we still allow shortcut keys
|
||||
if (mod & B_COMMAND_KEY)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
// We don't use strlen() because it is not UTF-8 aware, which can affect
|
||||
// how many characters can be typed.
|
||||
if (isprint(rawchar) && (uint32)BString(text->Text()).CountChars() == text->fCharLimit)
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
filter_result
|
||||
AutoTextControlFilter::KeyFilter(const int32 &rawchar, const int32 &mod)
|
||||
{
|
||||
if (fMessenger)
|
||||
fMessenger->SendMessage(fBox->ModificationMessage());
|
||||
else if (fBox)
|
||||
fBox->Invoke();
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControlFilter::SetMessenger(BMessenger *msgr)
|
||||
{
|
||||
if (fMessenger)
|
||||
delete fMessenger;
|
||||
fMessenger = msgr;
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControlFilter::SendMessage(BMessage *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (fMessenger)
|
||||
fMessenger->SendMessage(msg);
|
||||
else
|
||||
delete msg;
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControlFilter::HandleNoNumLock(const int32 &code, int32 &rawchar, BMessage *msg)
|
||||
{
|
||||
switch(code) {
|
||||
case 101: {
|
||||
// Numlock .
|
||||
rawchar = '.';
|
||||
break;
|
||||
}
|
||||
case 100: {
|
||||
// Numlock 0
|
||||
rawchar = '0';
|
||||
break;
|
||||
}
|
||||
case 88: {
|
||||
rawchar = '1';
|
||||
break;
|
||||
}
|
||||
case 89: {
|
||||
rawchar = '2';
|
||||
break;
|
||||
}
|
||||
case 90: {
|
||||
rawchar = '3';
|
||||
break;
|
||||
}
|
||||
case 72: {
|
||||
rawchar = '4';
|
||||
break;
|
||||
}
|
||||
case 74: {
|
||||
rawchar = '6';
|
||||
break;
|
||||
}
|
||||
case 55: {
|
||||
rawchar = '7';
|
||||
break;
|
||||
}
|
||||
case 56: {
|
||||
rawchar = '8';
|
||||
break;
|
||||
}
|
||||
case 57: {
|
||||
rawchar = '9';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
msg->ReplaceInt32("raw_char",rawchar);
|
||||
|
||||
BString string;
|
||||
string << (char)rawchar;
|
||||
msg->ReplaceString("bytes",string);
|
||||
|
||||
msg->ReplaceInt8("byte",(int8)rawchar);
|
||||
|
||||
int32 mod;
|
||||
if (msg->FindInt32("modifiers",&mod)==B_OK) {
|
||||
uint32 mask = B_NUM_LOCK;
|
||||
|
||||
if (mod & B_CAPS_LOCK)
|
||||
mask |= B_CAPS_LOCK;
|
||||
|
||||
if (mod & B_SCROLL_LOCK)
|
||||
mask |= B_SCROLL_LOCK;
|
||||
|
||||
set_keyboard_locks(mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AutoTextControl::AutoTextControl(const BRect &frame, const char *name, const char *label,
|
||||
const char *text, BMessage *msg, uint32 resize,
|
||||
uint32 flags)
|
||||
: BTextControl(frame,name,label,text,msg,resize,flags),
|
||||
fFilter(NULL),
|
||||
fEscapeCancel(false),
|
||||
fCharLimit(0)
|
||||
{
|
||||
SetFilter(new AutoTextControlFilter(this));
|
||||
}
|
||||
|
||||
AutoTextControl::~AutoTextControl(void)
|
||||
{
|
||||
if (Window())
|
||||
Window()->RemoveCommonFilter(fFilter);
|
||||
|
||||
delete fFilter;
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControl::AttachedToWindow(void)
|
||||
{
|
||||
BTextControl::AttachedToWindow();
|
||||
if (fFilter)
|
||||
Window()->AddCommonFilter(fFilter);
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControl::DetachedFromWindow(void)
|
||||
{
|
||||
if (fFilter)
|
||||
Window()->RemoveCommonFilter(fFilter);
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControl::SetCharacterLimit(const uint32 &limit)
|
||||
{
|
||||
fCharLimit = limit;
|
||||
}
|
||||
|
||||
uint32
|
||||
AutoTextControl::GetCharacterLimit(const uint32 &limit)
|
||||
{
|
||||
return fCharLimit;
|
||||
}
|
||||
|
||||
void
|
||||
AutoTextControl::SetFilter(AutoTextControlFilter *filter)
|
||||
{
|
||||
if (fFilter) {
|
||||
if (Window())
|
||||
Window()->RemoveCommonFilter(fFilter);
|
||||
delete fFilter;
|
||||
}
|
||||
|
||||
fFilter = filter;
|
||||
if (Window())
|
||||
Window()->AddCommonFilter(fFilter);
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <[email protected]>
|
||||
*/
|
||||
#ifndef AUTOTEXT_H
|
||||
#define AUTOTEXT_H
|
||||
|
||||
#include <TextControl.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
class AutoTextControlFilter;
|
||||
|
||||
enum {
|
||||
M_PREVIOUS_FIELD='mprf',
|
||||
M_NEXT_FIELD='mnxf',
|
||||
M_ENTER_NAVIGATION='ennv'
|
||||
};
|
||||
|
||||
class AutoTextControl : public BTextControl
|
||||
{
|
||||
public:
|
||||
AutoTextControl(const BRect &frame, const char *name,
|
||||
const char *label, const char *text,
|
||||
BMessage *msg,
|
||||
uint32 resize = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
|
||||
virtual ~AutoTextControl(void);
|
||||
virtual void AttachedToWindow(void);
|
||||
virtual void DetachedFromWindow(void);
|
||||
void SetFilter(AutoTextControlFilter *filter);
|
||||
AutoTextControlFilter * GetFilter(void) { return fFilter; }
|
||||
|
||||
void SetCharacterLimit(const uint32 &limit);
|
||||
uint32 GetCharacterLimit(const uint32 &limit);
|
||||
|
||||
void SetEscapeCancel(const bool &value) { fEscapeCancel = value; }
|
||||
bool IsEscapeCancel(void) const { return fEscapeCancel; }
|
||||
private:
|
||||
friend class AutoTextControlFilter;
|
||||
|
||||
AutoTextControlFilter *fFilter;
|
||||
bool fEscapeCancel;
|
||||
uint32 fCharLimit;
|
||||
};
|
||||
|
||||
class AutoTextControlFilter : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
AutoTextControlFilter(AutoTextControl *checkview);
|
||||
~AutoTextControlFilter(void);
|
||||
virtual filter_result Filter(BMessage *msg, BHandler **target);
|
||||
virtual filter_result KeyFilter(const int32 &key, const int32 &mod);
|
||||
|
||||
AutoTextControl * TextControl(void) const { return fBox; }
|
||||
|
||||
void SetMessenger(BMessenger *msgr);
|
||||
BMessenger * GetMessenger(void) const { return fMessenger; }
|
||||
void SendMessage(BMessage *msg);
|
||||
BMessage * GetCurrentMessage(void) { return fCurrentMessage; }
|
||||
|
||||
protected:
|
||||
bool IsEscapeCancel(void) const { return fBox->IsEscapeCancel(); }
|
||||
|
||||
private:
|
||||
void HandleNoNumLock(const int32 &code, int32 &rawchar,
|
||||
BMessage *msg);
|
||||
|
||||
AutoTextControl *fBox;
|
||||
BMessenger *fMessenger;
|
||||
BMessage *fCurrentMessage;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,6 @@ All rights reserved.
|
||||
#include "MailApp.h"
|
||||
#include "MailWindow.h"
|
||||
#include "Messages.h"
|
||||
#include "AutoTextControl.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Box.h>
|
||||
@@ -60,29 +59,6 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
void TextBevel(BView& view, BRect r)
|
||||
{
|
||||
r.InsetBy(-1,-1);
|
||||
view.SetHighColor(96,96,96);
|
||||
view.MovePenTo(r.left,r.bottom);
|
||||
view.StrokeLine(BPoint(r.left,r.top));
|
||||
view.StrokeLine(BPoint(r.right,r.top));
|
||||
view.SetHighColor(216,216,216);
|
||||
view.StrokeLine(BPoint(r.right,r.bottom));
|
||||
view.StrokeLine(BPoint(r.left,r.bottom));
|
||||
r.InsetBy(-1,-1);
|
||||
view.SetHighColor(192,192,192);
|
||||
view.MovePenTo(r.left,r.bottom);
|
||||
view.StrokeLine(BPoint(r.left,r.top));
|
||||
view.StrokeLine(BPoint(r.right,r.top));
|
||||
view.SetHighColor(255,255,255);
|
||||
view.StrokeLine(BPoint(r.right,r.bottom));
|
||||
view.StrokeLine(BPoint(r.left,r.bottom));
|
||||
view.SetHighColor(0,0,0);
|
||||
}
|
||||
|
||||
// FindWindow is modeless...
|
||||
|
||||
#define FINDBUTTON 'find'
|
||||
|
||||
static BString sPreviousFind = "";
|
||||
@@ -94,7 +70,7 @@ void FindWindow::DoFind(BWindow *window, const char *text)
|
||||
{
|
||||
if (window == NULL) {
|
||||
long i=0;
|
||||
while ((bool)(window = be_app->WindowAt(i++))) {
|
||||
while ((window = be_app->WindowAt(i++)) != NULL) {
|
||||
// Send the text to a waiting window
|
||||
if (window != mFindWindow)
|
||||
if (dynamic_cast<TMailWindow *>(window) != NULL)
|
||||
@@ -128,13 +104,12 @@ FindPanel::FindPanel(BRect rect)
|
||||
{
|
||||
BRect r = Bounds().InsetByCopy(10,10);
|
||||
|
||||
mBTextControl = new AutoTextControl(r,"BTextControl",NULL,
|
||||
mBTextControl = new BTextControl(r, "BTextControl", NULL,
|
||||
sPreviousFind.String(), new BMessage(M_FIND_STRING_CHANGED),
|
||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||
|
||||
mBTextControl->SetText(sPreviousFind.String());
|
||||
mBTextControl->MakeFocus();
|
||||
mBTextControl->SetEscapeCancel(true);
|
||||
AddChild(mBTextControl);
|
||||
|
||||
mFindButton = new BButton(BRect(0,0,90,20),"FINDBUTTON",
|
||||
@@ -233,10 +208,9 @@ void FindPanel::Find()
|
||||
|
||||
|
||||
FindWindow::FindWindow()
|
||||
: BWindow(FindWindow::mLastPosition,
|
||||
TR("Find"),
|
||||
B_FLOATING_WINDOW,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK)
|
||||
: BWindow(FindWindow::mLastPosition, TR("Find"), B_FLOATING_WINDOW,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
|
||||
| B_CLOSE_ON_ESCAPE)
|
||||
{
|
||||
mFindPanel = new FindPanel(Bounds());
|
||||
AddChild(mFindPanel);
|
||||
|
||||
@@ -42,10 +42,10 @@ All rights reserved.
|
||||
|
||||
#include <AppDefs.h>
|
||||
#include <Box.h>
|
||||
#include <TextControl.h>
|
||||
#include <Window.h>
|
||||
|
||||
class FindPanel;
|
||||
class AutoTextControl;
|
||||
|
||||
|
||||
class FindWindow : public BWindow {
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
|
||||
protected:
|
||||
BButton* mFindButton;
|
||||
AutoTextControl* mBTextControl;
|
||||
BTextControl* mBTextControl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ UsePrivateHeaders storage ;
|
||||
AddResources Mail : pictures.rdef ;
|
||||
|
||||
Application Mail :
|
||||
AutoTextControl.cpp
|
||||
BmapButton.cpp
|
||||
ButtonBar.cpp
|
||||
ComboBox.cpp
|
||||
|
||||
Reference in New Issue
Block a user