Commit ca98b10a authored by Robert Knight's avatar Robert Knight
Browse files

* Separate emulation back-end from view.  Removed all references to TEWidget ( the terminal display )
  from the emulation classes.  Connection of widget input keyboard/mouse notification to emulation
  is now done in TESession::addView().
  Added warnings for things which have/may have broken temporarily due to this change.
* Removed the concept of 'connected' / 'not connected' from the emulation classes.  Their behaviour
  is now independant of whether or not views are connected to the emulation.
* Added ScreenWindow::scrollBy() method which scrolls a screen window relative to its current position.
* Fix signal/slot connection in emulation when creating a new screen window.


svn path=/branches/work/konsole-split-view/; revision=642513
parent 7c47cfad
......@@ -86,7 +86,8 @@ void KonsoleApp::detachView(TESession* session)
void KonsoleApp::createSession(const QString& key , ViewManager* view)
{
TESession* session = _sessionManager->createSession(key);
session->setConnect(true);
session->setListenToKeyPress(true);
//session->setConnect(true);
// create view before starting the session process so that the session doesn't suffer
// a change in terminal size right after the session starts. some applications such as GNU Screen
......
Sunday - 11th March 07
======================
- Reimplement scrolling of view using keyboard
KDE 3 shortcuts:
Shift+Up - Scroll up one line
Shift+Down - Scroll down one line
Shift+PageUp - Scroll up one page ( == 1/2 number of visible lines in view )
Shift+PageDown - Scroll down one page ( == 1/2 number of visible lines in view )
This used to be done in TEmuVt102::scrollView() , TEmuVt102::scrollViewPages() but
that doesn't make sense when there is more than one view for each session,
and only the active view should be scrolled.
Tuesday - 16th Jan 07
=====================
- More reliable syncing of menus when selected view changes.
......@@ -63,6 +78,10 @@ Monday - 8th Jan 07
front-end
=========================================================================================
- [LATER] Resizing a split view is currently quite slow, presumably because of the work
done in TEWidget::resizeEvent() for each view.
Find some way to fix this situation.
- [DONE] Kill views when the associated session dies
- [DONE] Single top-bottom split-view menu action
- [DONE] Use correct color scheme in terminal display
......@@ -73,11 +92,6 @@ Monday - 8th Jan 07
- Prompt user when closing a session. Ensure the same close prompt
is shown no matter how the user closes the session.
- Resizing a split view is currently quite slow, presumably because of the work
done in TEWidget::resizeEvent() for each view.
Find some way to fix this situation.
- Update colour scheme of all views when user selects a new scheme via the Settings menu.
- Tab context menu
......
......@@ -112,6 +112,18 @@ int ScreenWindow::currentLine() const
return _currentLine;
}
void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount )
{
if ( mode == ScrollLines )
{
scrollTo( currentLine() + amount );
}
else if ( mode == ScrollPages )
{
scrollTo( currentLine() + amount * ( windowLines() / 2 ) );
}
}
void ScreenWindow::scrollTo( int line )
{
const int delta = line - _currentLine;
......
......@@ -130,6 +130,23 @@ public:
/** Scrolls the window so that @p line is at the top of the window */
void scrollTo( int line );
enum RelativeScrollMode
{
ScrollLines,
ScrollPages
};
/**
* Scrolls the window relative to its current position on the screen.
*
* @param mode Specifies whether @p amount refers to the number of lines or the number
* of pages to scroll.
* @param amount The number of lines or pages ( depending on @p mode ) to scroll by. If
* this number is positive, the view is scrolled down. If this number is negative, the view
* is scrolled up.
*/
void scrollBy( RelativeScrollMode mode , int amount );
/**
* Specifies whether the window should automatically move to the bottom
* of the screen when new output is added.
......
......@@ -211,6 +211,7 @@ void TESession::ptyError()
emit done(this);
}
#warning "Remove me. Behaviour of TESession should be the same whether there are any views connected to the session or not. The concept of a 'primary view' was used in porting from the old one-display-widget-per-session setup."
TEWidget* TESession::primaryView()
{
if (!_views.isEmpty())
......@@ -231,7 +232,20 @@ void TESession::addView(TEWidget* widget)
_views.append(widget);
if ( _emulation != 0 )
_emulation->addView(widget);
{
// connect emulation - view signals and slots
connect( widget , SIGNAL(keyPressedSignal(QKeyEvent*)) , _emulation ,
SLOT(onKeyPress(QKeyEvent*)) );
connect( widget , SIGNAL(mouseSignal(int,int,int,int)) , _emulation ,
SLOT(onMouse(int,int,int,int)) );
connect( widget , SIGNAL(sendStringToEmu(const char*)) , _emulation ,
SLOT(sendString(const char*)) );
// allow emulation to notify view when the foreground process indicates whether
// or not it is interested in mouse signals
connect( _emulation , SIGNAL(programUsesMouse(bool)) , widget ,
SLOT(setUsesMouse(bool)) );
}
widget->setScreenWindow(_emulation->createWindow());
......@@ -247,6 +261,7 @@ void TESession::addView(TEWidget* widget)
this,SLOT(onContentSizeChange(int,int)));
QObject::connect( widget ,SIGNAL(destroyed(QObject*)) , this , SLOT(viewDestroyed(QObject*)) );
}
void TESession::viewDestroyed(QObject* view)
......@@ -263,7 +278,18 @@ void TESession::removeView(TEWidget* widget)
_views.removeAll(widget);
if ( _emulation != 0 )
_emulation->removeView(widget);
{
// disconnect
// - key presses signals from widget
// - mouse activity signals from widget
// - string sending signals from widget
//
// ... and any other signals connected in addView()
disconnect( widget, 0, _emulation, 0);
// disconnect state change signals emitted by emulation
disconnect( _emulation , 0 , widget , 0);
}
}
/*void TESession::changeWidget(TEWidget* w)
......@@ -494,7 +520,7 @@ void TESession::notifySessionState(int state)
if (state==NOTIFYBELL)
{
primaryView()->Bell(_emulation->isConnected(),i18n("Bell in session '%1'", _title));
primaryView()->Bell( true /*_emulation->isConnected()*/ ,i18n("Bell in session '%1'", _title));
}
else if (state==NOTIFYACTIVITY)
{
......@@ -605,12 +631,12 @@ TESession::~TESession()
viewIter.next()->deleteLater();
}
void TESession::setConnect(bool c)
/*void TESession::setConnect(bool c)
{
connected=c;
_emulation->setConnect(c);
setListenToKeyPress(c);
}
}*/
void TESession::setListenToKeyPress(bool l)
{
......
......@@ -115,7 +115,7 @@ public:
*/
bool hasChildren();
void setConnect(bool r); // calls setListenToKeyPress(r)
//void setConnect(bool r); // calls setListenToKeyPress(r)
void setListenToKeyPress(bool l);
TEmulation* getEmulation(); // to control emulation
bool isSecure();
......
......@@ -432,7 +432,7 @@ TEWidget::TEWidget(QWidget *parent)
blinkCursorT = new QTimer(this);
connect(blinkCursorT, SIGNAL(timeout()), this, SLOT(blinkCursorEvent()));
setMouseMarks(true);
setUsesMouse(true);
setColorTable(base_color_table); // init color table
qApp->installEventFilter( this ); //FIXME: see below
......@@ -2268,7 +2268,7 @@ void TEWidget::setWordCharacters(QString wc)
word_characters = wc;
}
void TEWidget::setMouseMarks(bool on)
void TEWidget::setUsesMouse(bool on)
{
mouse_marks = on;
setCursor( mouse_marks ? Qt::IBeamCursor : Qt::ArrowCursor );
......
......@@ -170,7 +170,6 @@ public:
*/
void setVTFont(const QFont& font);
void setMouseMarks(bool on);
static void setAntialias( bool enable ) { s_antialias = enable; }
static bool antialias() { return s_antialias; }
static void setStandalone( bool standalone ) { s_standalone = standalone; }
......@@ -210,6 +209,22 @@ public Q_SLOTS:
*/
void outputSuspended(bool suspended);
/**
* Sets whether the program whoose output is being displayed in the view
* is interested in mouse events.
*
* If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
* or otherwise moves the mouse inside the view.
* The user interaction needed to create selections will also change, and the user will be required
* to hold down the shift key to create a selection or perform other mouse activities inside the
* view area - since the program running in the terminal is being allowed to handle normal mouse
* events itself.
*
* @param usesMouse Set to true if the program running in the terminal is interested in mouse events
* or false otherwise.
*/
void setUsesMouse(bool usesMouse);
Q_SIGNALS:
void keyPressedSignal(QKeyEvent *e);
......
......@@ -54,7 +54,6 @@
// Konsole
#include "TEmuVt102.h"
#include "TEWidget.h"
#include "TEScreen.h"
/* VT102 Terminal Emulation
......@@ -97,6 +96,7 @@ TEmuVt102::TEmuVt102() : TEmulation()
reset();
}
#if 0
void TEmuVt102::setReceiveViewInput(TEWidget* view , bool enable)
{
if (enable)
......@@ -114,7 +114,9 @@ void TEmuVt102::setReceiveViewInput(TEWidget* view , bool enable)
this, SLOT(sendString(const char*)));
}
}
#endif
#if 0
void TEmuVt102::addView(TEWidget* view)
{
TEmulation::addView(view);
......@@ -126,7 +128,7 @@ void TEmuVt102::removeView(TEWidget* view)
TEmulation::removeView(view);
setReceiveViewInput(view,false);
}
#endif
/*!
......@@ -939,7 +941,7 @@ void TEmuVt102::reportAnswerBack()
void TEmuVt102::onMouse( int cb, int cx, int cy , int eventType )
{ char tmp[20];
if (!connected || cx<1 || cy<1) return;
if ( cx<1 || cy<1 ) return;
// normal buttons are passed as 0x20 + button,
// mouse wheel (buttons 4,5) as 0x5c + button
if (cb >= 4) cb += 0x3c;
......@@ -985,26 +987,6 @@ void TEmuVt102::onScrollLock()
scrollLock(switchlock);
}
void TEmuVt102::scrollView( int lines )
{
QListIterator<TEWidget* > viewIter(_views);
while (viewIter.hasNext())
viewIter.next()->doScroll( lines );
}
void TEmuVt102::scrollViewPages( int pages )
{
QListIterator< TEWidget* > viewIter(_views);
while (viewIter.hasNext())
{
TEWidget* display = viewIter.next();
display->doScroll( pages * (display->Lines() / 2) );
}
}
#define encodeMode(M,B) BITS(B,getMode(M))
#define encodeStat(M,B) BITS(B,((ev->modifiers() & (M)) == (M)))
......@@ -1032,25 +1014,24 @@ void TEmuVt102::onKeyPress( QKeyEvent* ev )
encodeStat(Qt::AltModifier , BITS_Alt ),
&cmd, txt, &metaspecified ))
//printf("cmd: %d, %s, %d\n",cmd,txt,len);
if (connected)
{
switch(cmd) // ... and execute if found.
{
case CMD_scrollPageUp : scrollViewPages(-1); return;
case CMD_scrollPageDown : scrollViewPages(+1); return;
case CMD_scrollLineUp : scrollView(-1 ); return;
case CMD_scrollLineDown : scrollView(+1 ); return;
#warning "Add functionality elsewhere to handle scrolling of views when up/down/page-up/page-down keys are pressed."
//case CMD_scrollPageUp : scrollViewPages(-1); return;
//case CMD_scrollPageDown : scrollViewPages(+1); return;
//case CMD_scrollLineUp : scrollView(-1 ); return;
//case CMD_scrollLineDown : scrollView(+1 ); return;
case CMD_scrollLock : onScrollLock( ); return;
}
}
if (holdScreen)
{
switch(ev->key())
{
case Qt::Key_Down : scrollView(+1); return;
case Qt::Key_Up : scrollView(-1); return;
case Qt::Key_PageUp : scrollViewPages(-1); return;
case Qt::Key_PageDown : scrollViewPages(+1); return;
//case Qt::Key_Down : scrollView(+1); return;
//case Qt::Key_Up : scrollView(-1); return;
//case Qt::Key_PageUp : scrollViewPages(-1); return;
//case Qt::Key_PageDown : scrollViewPages(+1); return;
}
}
......@@ -1231,13 +1212,6 @@ void TEmuVt102::resetModes()
holdScreen = false;
}
void TEmuVt102::setViewMouseMarks(bool marks)
{
QListIterator< TEWidget* > viewIter(_views);
while (viewIter.hasNext())
viewIter.next()->setMouseMarks(marks);
}
void TEmuVt102::setMode(int m)
{
currParm.mode[m] = true;
......@@ -1247,7 +1221,7 @@ void TEmuVt102::setMode(int m)
case MODE_Mouse1001:
case MODE_Mouse1002:
case MODE_Mouse1003:
if (connected) setViewMouseMarks(false);
emit programUsesMouse(false);
break;
case MODE_AppScreen : screen[1]->clearSelection();
......@@ -1270,7 +1244,7 @@ void TEmuVt102::resetMode(int m)
case MODE_Mouse1001 :
case MODE_Mouse1002 :
case MODE_Mouse1003 :
if (connected) setViewMouseMarks(true);
emit programUsesMouse(true);
break;
case MODE_AppScreen : screen[0]->clearSelection();
......@@ -1299,7 +1273,8 @@ bool TEmuVt102::getMode(int m)
return currParm.mode[m];
}
void TEmuVt102::setConnect(bool c)
#warning "Code to handle signal/slot connections has already been moved elsewhere, but mouse mode refreshing part below has not yet been looked at. Neither has the part inside the HAVE_XKB define which calls scrolllock_set_xyz."
/*void TEmuVt102::setConnect(bool c)
{
TEmulation::setConnect(c);
......@@ -1335,7 +1310,7 @@ void TEmuVt102::setConnect(bool c)
this, SLOT(sendString(const char*)));
}
}
}
}*/
char TEmuVt102::getErase()
{
......
......@@ -80,26 +80,12 @@ public:
/** Constructs a new emulation */
TEmuVt102();
~TEmuVt102();
/** Reimplemented to enable handling of mouse input from the view */
virtual void addView(TEWidget* view);
/** Reimplemented to disconnect mouse input signals from the view */
virtual void removeView(TEWidget* view);
/**
* Converts information about a key press event into a character sequence which is emitted via
* sndBlock()
*/
public Q_SLOTS:
virtual void sendString(const char*);
virtual void onKeyPress(QKeyEvent*);
public Q_SLOTS: // signals incoming from TEWidget
/**
* Converts information about a mouse event into an xterm-compatible escape
* sequence and emits the character sequence via sendString()
*/
void onMouse(int cb, int cx, int cy, int eventType);
virtual void onMouse( int buttons, int column, int line , int eventType );
Q_SIGNALS:
/**
......@@ -138,9 +124,9 @@ public:
void reset();
void onRcvChar(int cc);
public Q_SLOTS:
void sendString(const char *);
public Q_SLOTS:
public:
bool getMode (int m);
......@@ -165,14 +151,17 @@ private:
//respectively.
void scrollViewPages( int pages );
//Enables or disables mouse marking in all the views on this emulation
void setViewMouseMarks( bool marks );
//REMOVED Enables or disables mouse marking in all the views on this emulation
//REMOVED void setViewMouseMarks( bool marks );
//REMOVED
//
//Enables or disables Vt102 specific handling of input from the view
//(including xterm-style mouse input for example)
//
//See also - TEmulation::connectView()
void setReceiveViewInput( TEWidget* view , bool enable );
//void setReceiveViewInput( TEWidget* view , bool enable );
void resetToken();
#define MAXPBUF 80
......
......@@ -89,7 +89,6 @@
// Konsole
#include "TEScreen.h"
#include "TEWidget.h"
#include "TerminalCharacterDecoder.h"
#include "ScreenWindow.h"
#include "TEmulation.h"
......@@ -107,7 +106,6 @@
TEmulation::TEmulation() :
currentScreen(0),
connected(false),
listenToKeyPress(false),
m_codec(0),
decoder(0),
......@@ -134,7 +132,7 @@ ScreenWindow* TEmulation::createWindow()
//FIXME - Used delayed updates when the selection changes
connect(window , SIGNAL(selectionChanged()),
this , SIGNAL(updateViews()));
this , SLOT(bulkStart()));
connect(this , SIGNAL(updateViews()),
window , SLOT(notifyOutputChanged()) );
......@@ -144,39 +142,6 @@ ScreenWindow* TEmulation::createWindow()
/*!
*/
void TEmulation::connectView(TEWidget* view)
{
#warning "Temporary - ideally the emulation should not be responsible for connecting its updateViews notification to the views themselves."
//QObject::connect(this,SIGNAL(updateViews()),
// view,SLOT(updateImage()));
//QObject::connect(this,SIGNAL(updateViews()),
// view,SLOT(updateLineProperties()));
QObject::connect(view,SIGNAL(keyPressedSignal(QKeyEvent*)),
this,SLOT(onKeyPress(QKeyEvent*)));
/*
QObject::connect(view,SIGNAL(changedHistoryCursor(int)),
this,SLOT(onHistoryCursorChange(int)));
QObject::connect(view,SIGNAL(beginSelectionSignal(const int,const int,const bool)),
this,SLOT(onSelectionBegin(const int,const int,const bool)) );
QObject::connect(view,SIGNAL(extendSelectionSignal(const int,const int)),
this,SLOT(onSelectionExtend(const int,const int)) );
QObject::connect(view,SIGNAL(endSelectionSignal(const bool)),
this,SLOT(setSelection(const bool)) );
QObject::connect(view,SIGNAL(copySelectionSignal()),
this,SLOT(copySelection()) );
QObject::connect(view,SIGNAL(clearSelectionSignal()),
this,SLOT(clearSelection()) );
QObject::connect(view,SIGNAL(isBusySelecting(bool)),
this,SLOT(isBusySelecting(bool)) );
QObject::connect(view,SIGNAL(testIsSelected(const int, const int, bool &)),
this,SLOT(testIsSelected(const int, const int, bool &)) );
*/
}
/*!
*/
TEmulation::~TEmulation()
{
QListIterator<ScreenWindow*> windowIter(_windows);
......@@ -215,7 +180,6 @@ void TEmulation::setHistory(const HistoryType& t)
{
screen[0]->setScroll(t);
if (!connected) return;
showBulk();
}
......@@ -312,6 +276,16 @@ void TEmulation::onKeyPress( QKeyEvent* ev )
}
}
void TEmulation::sendString(const char*)
{
// default implementation does nothing
}
void TEmulation::onMouse(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
{
// default implementation does nothing
}
// Unblocking, Byte to Unicode translation --------------------------------- --
/*
......@@ -449,11 +423,9 @@ void TEmulation::clearSelection() {
void TEmulation::isBusySelecting(bool busy)
{
if (!connected) return;
currentScreen->setBusySelecting(busy);
}
void TEmulation::copySelection() {
if (!connected) return;
QString t = currentScreen->selectedText(true);
QApplication::clipboard()->setText(t);
}
......@@ -578,24 +550,6 @@ bool TEmulation::findTextNext( const QString &str, bool forward, bool isCaseSens
/*!
*/
void TEmulation::addView(TEWidget* widget)
{
Q_ASSERT( !_views.contains(widget) );
_views << widget;
connectView(widget);
}
void TEmulation::removeView(TEWidget* widget)
{
Q_ASSERT( _views.contains(widget) );
_views.removeAll(widget);
disconnect(widget);
}
void TEmulation::showBulk()
{
bulk_timer1.stop();
......@@ -665,15 +619,6 @@ void TEmulation::bulkStart()
}
}
void TEmulation::setConnect(bool c)
{
connected = c;
if ( connected)
{
showBulk();
}
}
char TEmulation::getErase()
{
return '\b';
......@@ -701,10 +646,10 @@ void TEmulation::onImageSizeChange(int lines, int columns)
screen[0]->resizeImage(lines,columns);
screen[1]->resizeImage(lines,columns);
if (!connected) return;
emit ImageSizeChanged(columns, lines); // propagate event
#warning "Look into removing the showBulk() call."
// temporary - schedule an update
//bulkStart();
showBulk();
......@@ -717,8 +662,6 @@ QSize TEmulation::imageSize()
void TEmulation::onHistoryCursorChange(int cursor)
{
if (!connected) return;
currentScreen->setHistCursor(cursor);
bulkStart();
......
......@@ -58,26 +58,11 @@ class TEmulation : public QObject
{ Q_OBJECT
public:
//Construct a new emulation and adds connects it to the view 'gui'
/** Constructs a new terminal emulation */
TEmulation();
// TEmulation(TEWidget* gui);
~TEmulation();
/**
* Adds a new view for this emulation.
*
* When the emulation output changes, the view will be updated to display the new output.
*/
virtual void addView(TEWidget* widget);
/**
* Removes a view from this emulation.
*
* @p widget will no longer be updated when the emulation output changes.
*/