Made some TermView functions (Paste, Copy, etc) public. Made
SetTitle and NotifyQuit virtual. TermWindow now uses a TermView subclass which closes the tab on NotifyQuit. Enabled tabbed terminal. There are still some small glitches, most probably related to BTabView bugs ? git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21813 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+114
-116
@@ -132,7 +132,8 @@ const static rgb_color kWhiteColor = { 255, 255, 255, 255 };
|
||||
|
||||
|
||||
TermView::TermView(BRect frame, const char *command, int32 historySize)
|
||||
: BView(frame, "termview", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED),
|
||||
: BView(frame, "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||
fShell(NULL),
|
||||
fFontWidth(0),
|
||||
fFontHeight(0),
|
||||
@@ -180,7 +181,8 @@ TermView::TermView(BRect frame, const char *command, int32 historySize)
|
||||
|
||||
|
||||
TermView::TermView(int rows, int columns, const char *command, int32 historySize)
|
||||
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED),
|
||||
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||
fShell(NULL),
|
||||
fFontWidth(0),
|
||||
fFontHeight(0),
|
||||
@@ -408,8 +410,6 @@ TermView::SetTermSize(int rows, int cols, bool resize)
|
||||
if (resize)
|
||||
ResizeTo(fTermColumns * fFontWidth - 1, fTermRows * fFontHeight -1);
|
||||
|
||||
Invalidate();
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@@ -524,6 +524,104 @@ TermView::SetTitle(const char *title)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Copy(BClipboard *clipboard)
|
||||
{
|
||||
if (!_HasSelection())
|
||||
return;
|
||||
|
||||
BString copyStr;
|
||||
fTextBuffer->GetStringFromRegion(copyStr, fSelStart, fSelEnd);
|
||||
|
||||
if (clipboard->Lock()) {
|
||||
BMessage *clipMsg = NULL;
|
||||
clipboard->Clear();
|
||||
|
||||
if ((clipMsg = clipboard->Data()) != NULL) {
|
||||
clipMsg->AddData("text/plain", B_MIME_TYPE, copyStr.String(),
|
||||
copyStr.Length());
|
||||
clipboard->Commit();
|
||||
}
|
||||
clipboard->Unlock();
|
||||
}
|
||||
|
||||
// Deselecting the current selection is not the behavior that
|
||||
// R5's Terminal app displays. We want to mimic the behavior, so we will
|
||||
// no longer do the deselection
|
||||
// if (!fMouseTracking)
|
||||
// _DeSelect();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Paste(BClipboard *clipboard)
|
||||
{
|
||||
if (clipboard->Lock()) {
|
||||
BMessage *clipMsg = clipboard->Data();
|
||||
char *text;
|
||||
ssize_t numBytes;
|
||||
if (clipMsg->FindData("text/plain", B_MIME_TYPE,
|
||||
(const void **)&text, &numBytes) == B_OK ) {
|
||||
// Clipboard text doesn't attached EOF?
|
||||
text[numBytes] = '\0';
|
||||
_WritePTY((uchar *)text, numBytes);
|
||||
}
|
||||
|
||||
clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::SelectAll()
|
||||
{
|
||||
int screen_top = fTop / fFontHeight;
|
||||
int viewheight = fTermRows;
|
||||
|
||||
int start_pos = screen_top -(fScrBufSize - viewheight * 2);
|
||||
|
||||
CurPos start, end;
|
||||
start.x = 0;
|
||||
end.x = fTermColumns -1;
|
||||
|
||||
if (start_pos > 0)
|
||||
start.y = start_pos;
|
||||
else
|
||||
start.y = 0;
|
||||
|
||||
end.y = fCurPos.y + screen_top;
|
||||
|
||||
_Select(start, end);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::Clear()
|
||||
{
|
||||
_DeSelect();
|
||||
fTextBuffer->Clear();
|
||||
|
||||
fTop = 0;
|
||||
ScrollTo(0, 0);
|
||||
|
||||
if (LockLooper()) {
|
||||
SetHighColor(fTextBackColor);
|
||||
|
||||
FillRect(Bounds());
|
||||
SetHighColor(fTextForeColor);
|
||||
UnlockLooper();
|
||||
}
|
||||
|
||||
// reset cursor pos
|
||||
SetCurPos(0, 0);
|
||||
|
||||
if (fScrollBar) {
|
||||
fScrollBar->SetRange(0, 0);
|
||||
fScrollBar->SetProportion(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Print one character
|
||||
void
|
||||
TermView::PutChar(uchar *string, ushort attr, int width)
|
||||
@@ -1692,9 +1790,6 @@ TermView::FrameResized(float width, float height)
|
||||
fTermColumns = cols;
|
||||
|
||||
fFrameResized = true;
|
||||
|
||||
// TODO: Fix this
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -1743,19 +1838,19 @@ TermView::MessageReceived(BMessage *msg)
|
||||
}
|
||||
|
||||
case B_COPY:
|
||||
_DoCopy();
|
||||
Copy(be_clipboard);
|
||||
break;
|
||||
|
||||
case B_PASTE:
|
||||
{
|
||||
int32 code;
|
||||
if (msg->FindInt32("index", &code) == B_OK)
|
||||
_DoPaste();
|
||||
Paste(be_clipboard);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_SELECT_ALL:
|
||||
_DoSelectAll();
|
||||
SelectAll();
|
||||
break;
|
||||
|
||||
case B_SET_PROPERTY:
|
||||
@@ -1794,7 +1889,7 @@ TermView::MessageReceived(BMessage *msg)
|
||||
}
|
||||
|
||||
case MENU_CLEAR_ALL:
|
||||
_DoClearAll();
|
||||
Clear();
|
||||
fShell->Write(ctrl_l, 1);
|
||||
break;
|
||||
|
||||
@@ -1867,110 +1962,6 @@ TermView::_DoFileDrop(entry_ref &ref)
|
||||
}
|
||||
|
||||
|
||||
//! Copy selected text to Clipboard.
|
||||
void
|
||||
TermView::_DoCopy()
|
||||
{
|
||||
if (!_HasSelection())
|
||||
return;
|
||||
|
||||
BString copyStr;
|
||||
fTextBuffer->GetStringFromRegion(copyStr, fSelStart, fSelEnd);
|
||||
|
||||
if (be_clipboard->Lock()) {
|
||||
BMessage *clipMsg = NULL;
|
||||
be_clipboard->Clear();
|
||||
|
||||
if ((clipMsg = be_clipboard->Data()) != NULL) {
|
||||
clipMsg->AddData("text/plain", B_MIME_TYPE, copyStr.String(),
|
||||
copyStr.Length());
|
||||
be_clipboard->Commit();
|
||||
}
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
|
||||
// Deselecting the current selection is not the behavior that
|
||||
// R5's Terminal app displays. We want to mimic the behavior, so we will
|
||||
// no longer do the deselection
|
||||
// if (!fMouseTracking)
|
||||
// _DeSelect();
|
||||
}
|
||||
|
||||
|
||||
//! Paste clipboard text at cursor position.
|
||||
void
|
||||
TermView::_DoPaste()
|
||||
{
|
||||
if (be_clipboard->Lock()) {
|
||||
BMessage *clipMsg = be_clipboard->Data();
|
||||
char *text;
|
||||
ssize_t numBytes;
|
||||
if (clipMsg->FindData("text/plain", B_MIME_TYPE,
|
||||
(const void **)&text, &numBytes) == B_OK ) {
|
||||
// Clipboard text doesn't attached EOF?
|
||||
text[numBytes] = '\0';
|
||||
_WritePTY((uchar *)text, numBytes);
|
||||
}
|
||||
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Select all displayed text and text /in buffer.
|
||||
void
|
||||
TermView::_DoSelectAll(void)
|
||||
{
|
||||
CurPos start, end;
|
||||
int screen_top;
|
||||
int viewheight, start_pos;
|
||||
|
||||
screen_top = fTop / fFontHeight;
|
||||
viewheight = fTermRows;
|
||||
|
||||
start_pos = screen_top -(fScrBufSize - viewheight * 2);
|
||||
|
||||
start.x = 0;
|
||||
end.x = fTermColumns -1;
|
||||
|
||||
if (start_pos > 0)
|
||||
start.y = start_pos;
|
||||
else
|
||||
start.y = 0;
|
||||
|
||||
end.y = fCurPos.y + screen_top;
|
||||
|
||||
_Select(start, end);
|
||||
}
|
||||
|
||||
// Clear display and text buffer, then moves Cursorr at home position.
|
||||
void
|
||||
TermView::_DoClearAll(void)
|
||||
{
|
||||
_DeSelect();
|
||||
fTextBuffer->Clear();
|
||||
|
||||
fTop = 0;
|
||||
ScrollTo(0, 0);
|
||||
|
||||
if (LockLooper()) {
|
||||
SetHighColor(fTextBackColor);
|
||||
|
||||
FillRect(Bounds());
|
||||
SetHighColor(fTextForeColor);
|
||||
UnlockLooper();
|
||||
}
|
||||
|
||||
// reset cursor pos
|
||||
SetCurPos(0, 0);
|
||||
|
||||
if (fScrollBar) {
|
||||
fScrollBar->SetRange(0, 0);
|
||||
fScrollBar->SetProportion(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Write strings to PTY device. If encoding system isn't UTF8, change
|
||||
encoding to UTF8 before writing PTY.
|
||||
*/
|
||||
@@ -2009,7 +2000,7 @@ TermView::MouseDown(BPoint where)
|
||||
_WritePTY((uchar *)copy.String(), copy.Length());
|
||||
} else {
|
||||
// copy text from clipboard.
|
||||
_DoPaste();
|
||||
Paste(be_clipboard);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2123,6 +2114,13 @@ TermView::MouseMoved(BPoint where, uint32 transit, const BMessage *message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::MouseUp(BPoint where)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Select a range of text
|
||||
void
|
||||
TermView::_Select(CurPos start, CurPos end)
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#define CURON 1
|
||||
|
||||
|
||||
class BClipboard;
|
||||
class BMessageRunner;
|
||||
class BPopUpMenu;
|
||||
class BScrollBar;
|
||||
class BString;
|
||||
class Shell;
|
||||
@@ -59,7 +59,14 @@ public:
|
||||
void SetScrollBar(BScrollBar *scrbar);
|
||||
BScrollBar *ScrollBar() const { return fScrollBar; };
|
||||
|
||||
void SetTitle(const char *title);
|
||||
virtual void SetTitle(const char *title);
|
||||
virtual void NotifyQuit(int32 reason);
|
||||
|
||||
// edit functions
|
||||
void Copy(BClipboard *clipboard);
|
||||
void Paste(BClipboard *clipboard);
|
||||
void SelectAll();
|
||||
void Clear();
|
||||
|
||||
// Output Charactor
|
||||
void PutChar(uchar *string, ushort attr, int width);
|
||||
@@ -112,8 +119,6 @@ public:
|
||||
bool Find(const BString &str, bool forwardSearch, bool matchCase, bool matchWord);
|
||||
void GetSelection(BString &str);
|
||||
|
||||
void NotifyQuit(int32 reason);
|
||||
|
||||
protected:
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
@@ -121,8 +126,10 @@ protected:
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void WindowActivated(bool active);
|
||||
virtual void KeyDown(const char*, int32);
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint, uint32, const BMessage *);
|
||||
virtual void MouseUp(BPoint where);
|
||||
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
@@ -151,12 +158,6 @@ private:
|
||||
void _ResizeScrBarRange (void);
|
||||
void _DoFileDrop(entry_ref &ref);
|
||||
|
||||
// edit menu function.
|
||||
void _DoCopy();
|
||||
void _DoPaste();
|
||||
void _DoSelectAll();
|
||||
void _DoClearAll();
|
||||
|
||||
void _WritePTY(const uchar *text, int num_byteses);
|
||||
|
||||
// Comunicate Input Method
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Dragger.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
@@ -49,6 +50,16 @@
|
||||
|
||||
const static float kViewOffset = 3;
|
||||
const static uint32 kNewTab = 'NTab';
|
||||
const static uint32 kCloseView = 'ClVw';
|
||||
|
||||
|
||||
class CustomTermView : public TermView {
|
||||
public:
|
||||
CustomTermView(int32 rows, int32 columns, const char *command = NULL, int32 historySize = 1000);
|
||||
virtual void NotifyQuit(int32 reason);
|
||||
virtual void SetTitle(const char *title);
|
||||
};
|
||||
|
||||
|
||||
TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
||||
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
||||
@@ -135,10 +146,9 @@ TermWindow::_SetupMenu()
|
||||
fFilemenu->AddItem(new BMenuItem("Switch Terminals", new BMessage(MENU_SWITCH_TERM),'G'));
|
||||
fFilemenu->AddItem(new BMenuItem("New Terminal" B_UTF8_ELLIPSIS, new BMessage(MENU_NEW_TERM), 'N'));
|
||||
|
||||
|
||||
// TODO: Tabs disabled until various problems are fixed.
|
||||
// n. 1: calling "exit" from a tab closes the whole app.
|
||||
//fFilemenu->AddItem(new BMenuItem("New Tab", new BMessage(kNewTab), 'T'));
|
||||
fFilemenu->AddItem(new BMenuItem("New Tab", new BMessage(kNewTab), 'T'));
|
||||
|
||||
fFilemenu->AddSeparatorItem();
|
||||
fFilemenu->AddItem(new BMenuItem("Page Setup...", new BMessage(MENU_PAGE_SETUP)));
|
||||
@@ -153,13 +163,13 @@ TermWindow::_SetupMenu()
|
||||
fEditmenu = new BMenu ("Edit");
|
||||
fEditmenu->AddItem (new BMenuItem ("Copy", new BMessage (B_COPY),'C'));
|
||||
fEditmenu->AddItem (new BMenuItem ("Paste", new BMessage (B_PASTE),'V'));
|
||||
fEditmenu->AddSeparatorItem ();
|
||||
fEditmenu->AddSeparatorItem();
|
||||
fEditmenu->AddItem (new BMenuItem ("Select All", new BMessage (B_SELECT_ALL), 'A'));
|
||||
fEditmenu->AddItem (new BMenuItem ("Clear All", new BMessage (MENU_CLEAR_ALL), 'L'));
|
||||
fEditmenu->AddSeparatorItem ();
|
||||
fEditmenu->AddSeparatorItem();
|
||||
fEditmenu->AddItem (new BMenuItem ("Find" B_UTF8_ELLIPSIS, new BMessage (MENU_FIND_STRING),'F'));
|
||||
fFindBackwardMenuItem = new BMenuItem ("Find Backward", new BMessage (MENU_FIND_BACKWARD), '[');
|
||||
fEditmenu->AddItem (fFindBackwardMenuItem);
|
||||
fEditmenu->AddItem(fFindBackwardMenuItem);
|
||||
fFindBackwardMenuItem->SetEnabled(false);
|
||||
fFindForwardMenuItem = new BMenuItem ("Find Forward", new BMessage (MENU_FIND_FORWARD), ']');
|
||||
fEditmenu->AddItem (fFindForwardMenuItem);
|
||||
@@ -202,6 +212,22 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
bool findresult;
|
||||
|
||||
switch (message->what) {
|
||||
case B_COPY:
|
||||
_ActiveTermView()->Copy(be_clipboard);
|
||||
break;
|
||||
|
||||
case B_PASTE:
|
||||
_ActiveTermView()->Paste(be_clipboard);
|
||||
break;
|
||||
|
||||
case B_SELECT_ALL:
|
||||
_ActiveTermView()->SelectAll();
|
||||
break;
|
||||
|
||||
case MENU_CLEAR_ALL:
|
||||
_ActiveTermView()->Clear();
|
||||
break;
|
||||
|
||||
case MENU_SWITCH_TERM: {
|
||||
be_app->PostMessage(MENU_SWITCH_TERM);
|
||||
break;
|
||||
@@ -210,6 +236,16 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
_NewTab(NULL);
|
||||
break;
|
||||
|
||||
case kCloseView:
|
||||
{
|
||||
// TODO: We assume that this message was sent from the current active tab.
|
||||
// Since the implementation of BTabView uses AddChild/RemoveChild on the
|
||||
// views, the current active tab is the only one who is attached, thus
|
||||
// the only one which could send a message.
|
||||
delete fTabView->RemoveTab(fTabView->Selection());
|
||||
break;
|
||||
}
|
||||
|
||||
case MENU_NEW_TERM: {
|
||||
app_info info;
|
||||
be_app->GetAppInfo(&info);
|
||||
@@ -558,7 +594,7 @@ TermWindow::_NewTab(const char *command)
|
||||
fullFont.SetSpacing(B_FIXED_SPACING);
|
||||
|
||||
// Make Terminal text view.
|
||||
TermView *view = new TermView(PrefHandler::Default()->getInt32(PREF_ROWS),
|
||||
CustomTermView *view = new CustomTermView(PrefHandler::Default()->getInt32(PREF_ROWS),
|
||||
PrefHandler::Default()->getInt32(PREF_COLS),
|
||||
command);
|
||||
|
||||
@@ -592,10 +628,6 @@ TermWindow::_NewTab(const char *command)
|
||||
// Bug in BTabView or in my code ?
|
||||
fTabView->Select(0);
|
||||
}
|
||||
|
||||
// TODO: How do I set this for the current active tab,
|
||||
// every time a different tab is chosen ?
|
||||
fEditmenu->SetTargetForItems(view);
|
||||
}
|
||||
|
||||
|
||||
@@ -608,3 +640,29 @@ TermWindow::_ActiveTermView()
|
||||
return (TermView *)((BScrollView *)fTabView->ViewForTab(fTabView->Selection()))->Target();
|
||||
}
|
||||
|
||||
|
||||
// CustomTermView
|
||||
CustomTermView::CustomTermView(int32 rows, int32 columns, const char *command, int32 historySize)
|
||||
:
|
||||
TermView(rows, columns, command, historySize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CustomTermView::NotifyQuit(int32 reason)
|
||||
{
|
||||
if (Window()) {
|
||||
BMessage message(kCloseView);
|
||||
message.AddInt32("reason", reason);
|
||||
Window()->PostMessage(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CustomTermView::SetTitle(const char *title)
|
||||
{
|
||||
//Window()->SetTitle(title);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user