diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 070f82d52d..2163c14ed5 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -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) diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index 9fd7c526cf..8f1c744bd5 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -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 diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 9a9dc01e48..b4cdf1b729 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -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); +} +