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:
Stefano Ceccherini
2007-08-03 20:41:04 +00:00
parent 3da81905f1
commit 18f004cc71
3 changed files with 193 additions and 136 deletions
+114 -116
View File
@@ -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)
+11 -10
View File
@@ -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
+68 -10
View File
@@ -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);
}