Added a listener interface to TermView. This allowed to get rid of
CustomTermView and of the messaging from view to window. It also simplified things in TermWindow. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39487 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
df942b3eb1
commit
92b0038ec0
|
@ -85,8 +85,6 @@ static const uint32 FULLSCREEN = 'fscr';
|
|||
static const uint32 MSG_FONT_CHANGED = 'fntc';
|
||||
static const uint32 SAVE_AS_DEFAULT = 'sadf';
|
||||
static const uint32 MSG_CHECK_CHILDREN = 'ckch';
|
||||
static const uint32 MSG_PREVIOUS_TAB = 'ptab';
|
||||
static const uint32 MSG_NEXT_TAB = 'ntab';
|
||||
static const uint32 MSG_REMOVE_RESIZE_VIEW_IF_NEEDED = 'rmrv';
|
||||
static const uint32 MSG_TERMINAL_BUFFER_CHANGED = 'bufc';
|
||||
static const uint32 MSG_SET_TERMNAL_TITLE = 'sett';
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Stefano Ceccherini <stefano.ceccherini@gmail.com>
|
||||
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
||||
* Kian Duffy, myob@users.sourceforge.net
|
||||
* Y.Hayakawa, hida@sawada.riec.tohoku.ac.jp
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
* Clemens Zeidler <haiku@Clemens-Zeidler.de>
|
||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
||||
*/
|
||||
|
||||
|
||||
|
@ -392,6 +392,9 @@ restrict_value(const Type& value, const Type& min, const Type& max)
|
|||
}
|
||||
|
||||
|
||||
// #pragma mark - CharClassifier
|
||||
|
||||
|
||||
class TermView::CharClassifier : public TerminalCharClassifier {
|
||||
public:
|
||||
CharClassifier(const char* specialWordChars)
|
||||
|
@ -420,13 +423,15 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// #pragma mark - TermView
|
||||
|
||||
|
||||
TermView::TermView(BRect frame, const ShellParameters& shellParameters,
|
||||
int32 historySize)
|
||||
: BView(frame, "termview", B_FOLLOW_ALL,
|
||||
:
|
||||
BView(frame, "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE),
|
||||
fListener(NULL),
|
||||
fColumns(COLUMNS_DEFAULT),
|
||||
fRows(ROWS_DEFAULT),
|
||||
fEncoding(M_UTF8),
|
||||
|
@ -446,8 +451,10 @@ TermView::TermView(BRect frame, const ShellParameters& shellParameters,
|
|||
|
||||
TermView::TermView(int rows, int columns,
|
||||
const ShellParameters& shellParameters, int32 historySize)
|
||||
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
|
||||
:
|
||||
BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE),
|
||||
fListener(NULL),
|
||||
fColumns(columns),
|
||||
fRows(rows),
|
||||
fEncoding(M_UTF8),
|
||||
|
@ -480,6 +487,7 @@ TermView::TermView(int rows, int columns,
|
|||
TermView::TermView(BMessage* archive)
|
||||
:
|
||||
BView(archive),
|
||||
fListener(NULL),
|
||||
fColumns(COLUMNS_DEFAULT),
|
||||
fRows(ROWS_DEFAULT),
|
||||
fEncoding(M_UTF8),
|
||||
|
@ -949,16 +957,6 @@ TermView::SetScrollBar(BScrollBar *scrollBar)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::SetTitle(const char *title)
|
||||
{
|
||||
// TODO: Do something different in case we're a replicant,
|
||||
// or in case we are inside a BTabView ?
|
||||
if (Window())
|
||||
Window()->SetTitle(title);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Copy(BClipboard *clipboard)
|
||||
{
|
||||
|
@ -1590,28 +1588,32 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||
|
||||
case B_LEFT_ARROW:
|
||||
if (rawChar == B_LEFT_ARROW) {
|
||||
if (mod & B_SHIFT_KEY) {
|
||||
BMessage message(MSG_PREVIOUS_TAB);
|
||||
message.AddPointer("termView", this);
|
||||
Window()->PostMessage(&message);
|
||||
if ((mod & B_SHIFT_KEY) != 0) {
|
||||
if (fListener != NULL) {
|
||||
fListener->PreviousTermView(this,
|
||||
(mod & B_COMMAND_KEY) != 0);
|
||||
}
|
||||
return;
|
||||
} else if ((mod & B_CONTROL_KEY) || (mod & B_COMMAND_KEY)) {
|
||||
}
|
||||
if ((mod & B_CONTROL_KEY) || (mod & B_COMMAND_KEY))
|
||||
toWrite = CTRL_LEFT_ARROW_KEY_CODE;
|
||||
} else
|
||||
else
|
||||
toWrite = LEFT_ARROW_KEY_CODE;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_RIGHT_ARROW:
|
||||
if (rawChar == B_RIGHT_ARROW) {
|
||||
if (mod & B_SHIFT_KEY) {
|
||||
BMessage message(MSG_NEXT_TAB);
|
||||
message.AddPointer("termView", this);
|
||||
Window()->PostMessage(&message);
|
||||
if ((mod & B_SHIFT_KEY) != 0) {
|
||||
if (fListener != NULL) {
|
||||
fListener->NextTermView(this,
|
||||
(mod & B_COMMAND_KEY) != 0);
|
||||
}
|
||||
return;
|
||||
} else if ((mod & B_CONTROL_KEY) || (mod & B_COMMAND_KEY)) {
|
||||
}
|
||||
if ((mod & B_CONTROL_KEY) || (mod & B_COMMAND_KEY))
|
||||
toWrite = CTRL_RIGHT_ARROW_KEY_CODE;
|
||||
} else
|
||||
else
|
||||
toWrite = RIGHT_ARROW_KEY_CODE;
|
||||
}
|
||||
break;
|
||||
|
@ -1951,8 +1953,10 @@ TermView::MessageReceived(BMessage *msg)
|
|||
case MSG_SET_TERMNAL_TITLE:
|
||||
{
|
||||
const char* title;
|
||||
if (msg->FindString("title", &title) == B_OK)
|
||||
SetTitle(title);
|
||||
if (msg->FindString("title", &title) == B_OK) {
|
||||
if (fListener != NULL)
|
||||
fListener->SetTermViewTitle(this, title);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_REPORT_MOUSE_EVENT:
|
||||
|
@ -1994,7 +1998,8 @@ TermView::MessageReceived(BMessage *msg)
|
|||
int32 reason;
|
||||
if (msg->FindInt32("reason", &reason) != B_OK)
|
||||
reason = 0;
|
||||
NotifyQuit(reason);
|
||||
if (fListener != NULL)
|
||||
fListener->NotifyTermViewQuit(this, reason);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -3001,26 +3006,16 @@ TermView::GetSelection(BString &str)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::NotifyQuit(int32 reason)
|
||||
{
|
||||
// implemented in subclasses
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::CheckShellGone()
|
||||
bool
|
||||
TermView::CheckShellGone() const
|
||||
{
|
||||
if (!fShell)
|
||||
return;
|
||||
return false;
|
||||
|
||||
// check, if the shell does still live
|
||||
pid_t pid = fShell->ProcessID();
|
||||
team_info info;
|
||||
if (get_team_info(pid, &info) == B_BAD_TEAM_ID) {
|
||||
// the shell is gone
|
||||
NotifyQuit(0);
|
||||
}
|
||||
return get_team_info(pid, &info) == B_BAD_TEAM_ID;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3293,3 +3288,34 @@ TermView::_CancelInputMethod()
|
|||
delete inlineInput;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Listener
|
||||
|
||||
|
||||
TermView::Listener::~Listener()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Listener::NotifyTermViewQuit(TermView* view, int32 reason)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Listener::SetTermViewTitle(TermView* view, const char* title)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Listener::PreviousTermView(TermView* view, bool move)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Listener::NextTermView(TermView* view, bool move)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
/*
|
||||
* Copyright 2001-2009, Haiku.
|
||||
* Copyright 2001-2010, Haiku.
|
||||
* Copyright (c) 2003-4 Kian Duffy <myob@users.sourceforge.net>
|
||||
* Parts Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
|
||||
*
|
||||
* Distributed under the terms of the MIT license.
|
||||
* Authors:
|
||||
* Stefano Ceccherini <stefano.ceccherini@gmail.com>
|
||||
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
||||
* Kian Duffy, myob@users.sourceforge.net
|
||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||
*/
|
||||
#ifndef TERMVIEW_H
|
||||
#define TERMVIEW_H
|
||||
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
|
@ -35,6 +37,9 @@ class TerminalBuffer;
|
|||
class Shell;
|
||||
|
||||
class TermView : public BView {
|
||||
public:
|
||||
class Listener;
|
||||
|
||||
public:
|
||||
TermView(BRect frame,
|
||||
const ShellParameters& shellParameters,
|
||||
|
@ -80,9 +85,6 @@ public:
|
|||
|
||||
void SetMouseClipboard(BClipboard *);
|
||||
|
||||
virtual void SetTitle(const char* title);
|
||||
virtual void NotifyQuit(int32 reason);
|
||||
|
||||
// edit functions
|
||||
void Copy(BClipboard* clipboard);
|
||||
void Paste(BClipboard* clipboard);
|
||||
|
@ -95,13 +97,16 @@ public:
|
|||
bool matchCase, bool matchWord);
|
||||
void GetSelection(BString& string);
|
||||
|
||||
void CheckShellGone();
|
||||
bool CheckShellGone() const;
|
||||
|
||||
void InitiateDrag();
|
||||
|
||||
void DisableResizeView(int32 disableCount = 1);
|
||||
static void AboutRequested();
|
||||
|
||||
void SetListener(Listener* listener)
|
||||
{ fListener = listener; }
|
||||
|
||||
protected:
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
@ -126,6 +131,9 @@ protected:
|
|||
BMessage* specifier, int32 form,
|
||||
const char* property);
|
||||
|
||||
private:
|
||||
class CharClassifier;
|
||||
|
||||
private:
|
||||
// point and text offset conversion
|
||||
inline int32 _LineAt(float y);
|
||||
|
@ -196,9 +204,9 @@ private:
|
|||
void _HandleInputMethodChanged(BMessage* message);
|
||||
void _HandleInputMethodLocationRequest();
|
||||
void _CancelInputMethod();
|
||||
private:
|
||||
class CharClassifier;
|
||||
|
||||
private:
|
||||
Listener* fListener;
|
||||
Shell* fShell;
|
||||
|
||||
BMessageRunner* fWinchRunner;
|
||||
|
@ -279,4 +287,18 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class TermView::Listener {
|
||||
public:
|
||||
virtual ~Listener();
|
||||
|
||||
// all hooks called in the window thread
|
||||
virtual void NotifyTermViewQuit(TermView* view,
|
||||
int32 reason);
|
||||
virtual void SetTermViewTitle(TermView* view,
|
||||
const char* title);
|
||||
virtual void PreviousTermView(TermView* view, bool move);
|
||||
virtual void NextTermView(TermView* view, bool move);
|
||||
};
|
||||
|
||||
|
||||
#endif // TERMVIEW_H
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "ShellParameters.h"
|
||||
#include "TermConst.h"
|
||||
#include "TermScrollView.h"
|
||||
#include "TermView.h"
|
||||
#include "TitlePlaceholderMapper.h"
|
||||
|
||||
|
||||
|
@ -63,18 +62,6 @@ const static uint32 kUpdateTitles = 'UPti';
|
|||
#define B_TRANSLATE_CONTEXT "Terminal TermWindow"
|
||||
|
||||
|
||||
// #pragma mark - CustomTermView
|
||||
|
||||
|
||||
class CustomTermView : public TermView {
|
||||
public:
|
||||
CustomTermView(int32 rows, int32 columns,
|
||||
const ShellParameters& shellParameters, int32 historySize = 1000);
|
||||
virtual void NotifyQuit(int32 reason);
|
||||
virtual void SetTitle(const char *title);
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - TermViewContainerView
|
||||
|
||||
|
||||
|
@ -213,18 +200,6 @@ TermWindow::~TermWindow()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::SetSessionTitle(TermView* termView, const char* title)
|
||||
{
|
||||
int32 index = _IndexOfTermView(termView);
|
||||
if (Session* session = (Session*)fSessions.ItemAt(index)) {
|
||||
session->title.pattern = title;
|
||||
session->title.patternUserDefined = true;
|
||||
_UpdateSessionTitle(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::SessionChanged()
|
||||
{
|
||||
|
@ -702,21 +677,6 @@ TermWindow::MessageReceived(BMessage *message)
|
|||
_CheckChildren();
|
||||
break;
|
||||
|
||||
case MSG_PREVIOUS_TAB:
|
||||
case MSG_NEXT_TAB:
|
||||
{
|
||||
TermView* termView;
|
||||
if (message->FindPointer("termView", (void**)&termView) == B_OK) {
|
||||
int32 count = fSessions.CountItems();
|
||||
int32 index = _IndexOfTermView(termView);
|
||||
if (count > 1 && index >= 0) {
|
||||
index += message->what == MSG_PREVIOUS_TAB ? -1 : 1;
|
||||
fTabView->Select((index + count) % count);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kSetActiveTab:
|
||||
{
|
||||
int32 index;
|
||||
|
@ -894,11 +854,12 @@ TermWindow::_AddTab(Arguments* args, const BString& currentDirectory)
|
|||
ShellParameters shellParameters(argc, argv, currentDirectory);
|
||||
|
||||
try {
|
||||
CustomTermView* view = new CustomTermView(
|
||||
TermView* view = new TermView(
|
||||
PrefHandler::Default()->getInt32(PREF_ROWS),
|
||||
PrefHandler::Default()->getInt32(PREF_COLS),
|
||||
shellParameters,
|
||||
PrefHandler::Default()->getInt32(PREF_HISTORY_SIZE));
|
||||
view->SetListener(this);
|
||||
|
||||
TermViewContainerView* containerView = new TermViewContainerView(view);
|
||||
BScrollView* scrollView = new TermScrollView("scrollView",
|
||||
|
@ -989,6 +950,22 @@ TermWindow::_RemoveTab(int32 index)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_NavigateTab(int32 index, int32 direction, bool move)
|
||||
{
|
||||
int32 count = fSessions.CountItems();
|
||||
if (count <= 1 || index < 0 || index >= count)
|
||||
return;
|
||||
|
||||
if (move) {
|
||||
// TODO: Move the tab!
|
||||
} else {
|
||||
index += direction;
|
||||
fTabView->Select((index + count) % count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TermViewContainerView*
|
||||
TermWindow::_ActiveTermViewContainerView() const
|
||||
{
|
||||
|
@ -1043,7 +1020,8 @@ TermWindow::_CheckChildren()
|
|||
int32 count = fSessions.CountItems();
|
||||
for (int32 i = count - 1; i >= 0; i--) {
|
||||
Session* session = (Session*)fSessions.ItemAt(i);
|
||||
session->containerView->GetTermView()->CheckShellGone();
|
||||
if (session->containerView->GetTermView()->CheckShellGone())
|
||||
NotifyTermViewQuit(session->containerView->GetTermView(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1119,6 +1097,44 @@ TermWindow::TabRightClicked(SmartTabView* tabView, BPoint point, int32 index)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::NotifyTermViewQuit(TermView* view, int32 reason)
|
||||
{
|
||||
// Since the notification can come from the view, we send a message to
|
||||
// ourselves to avoid deleting the caller synchronously.
|
||||
BMessage message(kCloseView);
|
||||
message.AddPointer("termView", view);
|
||||
message.AddInt32("reason", reason);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::SetTermViewTitle(TermView* view, const char* title)
|
||||
{
|
||||
int32 index = _IndexOfTermView(view);
|
||||
if (Session* session = (Session*)fSessions.ItemAt(index)) {
|
||||
session->title.pattern = title;
|
||||
session->title.patternUserDefined = true;
|
||||
_UpdateSessionTitle(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::PreviousTermView(TermView* view, bool move)
|
||||
{
|
||||
_NavigateTab(_IndexOfTermView(view), -1, move);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::NextTermView(TermView* view, bool move)
|
||||
{
|
||||
_NavigateTab(_IndexOfTermView(view), 1, move);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_ResizeView(TermView *view)
|
||||
{
|
||||
|
@ -1276,44 +1292,3 @@ TermWindow::_NewSessionIndex()
|
|||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
// CustomTermView
|
||||
CustomTermView::CustomTermView(int32 rows, int32 columns,
|
||||
const ShellParameters& shellParameters, int32 historySize)
|
||||
:
|
||||
TermView(rows, columns, shellParameters, historySize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CustomTermView::NotifyQuit(int32 reason)
|
||||
{
|
||||
BWindow* window = Window();
|
||||
// TODO: If we got this from a view in a tab not currently selected,
|
||||
// Window() will be NULL, as the view is detached.
|
||||
// So we send the message to the first application window
|
||||
// This isn't so cool, but should be safe, since a Terminal
|
||||
// application has only one window, at least for now.
|
||||
if (window == NULL)
|
||||
window = be_app->WindowAt(0);
|
||||
|
||||
if (window != NULL) {
|
||||
BMessage message(kCloseView);
|
||||
message.AddPointer("termView", this);
|
||||
message.AddInt32("reason", reason);
|
||||
window->PostMessage(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CustomTermView::SetTitle(const char* title)
|
||||
{
|
||||
dynamic_cast<TermWindow*>(Window())->SetSessionTitle(this, title);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <Window.h>
|
||||
|
||||
#include "SmartTabView.h"
|
||||
#include "TermView.h"
|
||||
|
||||
|
||||
class Arguments;
|
||||
|
@ -45,19 +46,17 @@ class BMenu;
|
|||
class BMenuBar;
|
||||
class FindWindow;
|
||||
class PrefWindow;
|
||||
class TermView;
|
||||
class TermViewContainerView;
|
||||
|
||||
|
||||
class TermWindow : public BWindow, private SmartTabView::Listener {
|
||||
class TermWindow : public BWindow, private SmartTabView::Listener,
|
||||
private TermView::Listener {
|
||||
public:
|
||||
TermWindow(BRect frame, const BString& title,
|
||||
bool isUserDefinedTitle, int32 windowIndex,
|
||||
uint32 workspaces, Arguments* args);
|
||||
virtual ~TermWindow();
|
||||
|
||||
void SetSessionTitle(TermView* termView,
|
||||
const char* title);
|
||||
void SessionChanged();
|
||||
|
||||
protected:
|
||||
|
@ -78,6 +77,14 @@ private:
|
|||
virtual void TabRightClicked(SmartTabView* tabView,
|
||||
BPoint point, int32 index);
|
||||
|
||||
// TermView::Listener
|
||||
virtual void NotifyTermViewQuit(TermView* view,
|
||||
int32 reason);
|
||||
virtual void SetTermViewTitle(TermView* view,
|
||||
const char* title);
|
||||
virtual void PreviousTermView(TermView* view, bool move);
|
||||
virtual void NextTermView(TermView* view, bool move);
|
||||
|
||||
private:
|
||||
struct Title {
|
||||
BString title;
|
||||
|
@ -108,11 +115,15 @@ private:
|
|||
void _GetPreferredFont(BFont &font);
|
||||
status_t _DoPageSetup();
|
||||
void _DoPrint();
|
||||
|
||||
void _NewTab();
|
||||
void _AddTab(Arguments* args,
|
||||
const BString& currentDirectory
|
||||
= BString());
|
||||
void _RemoveTab(int32 index);
|
||||
void _NavigateTab(int32 index, int32 direction,
|
||||
bool move);
|
||||
|
||||
bool _CanClose(int32 index);
|
||||
TermViewContainerView* _ActiveTermViewContainerView() const;
|
||||
TermViewContainerView* _TermViewContainerViewAt(int32 index) const;
|
||||
|
|
Loading…
Reference in New Issue