Commit 52db452a authored by Robert Knight's avatar Robert Knight
Browse files

Don't switch tabs when a non-active session finishes ( Bug #146639 ). Begin...

Don't switch tabs when a non-active session finishes ( Bug #146639 ).  Begin implementation of Send Input to All in new front-end.

svn path=/trunk/KDE/kdebase/apps/konsole/; revision=674139
parent 13c7c0df
......@@ -274,7 +274,7 @@ void Emulation::sendKeyEvent( QKeyEvent* ev )
}
}
void Emulation::sendString(const char*)
void Emulation::sendString(const char*,int)
{
// default implementation does nothing
}
......
......@@ -230,9 +230,13 @@ public slots:
virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
/**
* Sends a string of characters to the foreground terminal process
* Sends a string of characters to the foreground terminal process.
*
* @param string The characters to send.
* @param length Length of @p string or if set to a negative value, @p string will
* be treated as a null-terminated string and its length will be determined automatically.
*/
virtual void sendString(const char *) = 0;
virtual void sendString(const char* string, int length = -1) = 0;
/** Processes an incoming block of text. */
void receiveData(const char* txt,int len);
......
......@@ -855,4 +855,119 @@ int Session::processId() const
return _shellProcess->pid();
}
SessionGroup::SessionGroup()
: _masterMode(0)
{
}
SessionGroup::~SessionGroup()
{
// disconnect all
connectAll(false);
}
int SessionGroup::masterMode() const { return _masterMode; }
QList<Session*> SessionGroup::sessions() const { return _sessions.keys(); }
bool SessionGroup::masterStatus(Session* session) const { return _sessions[session]; }
void SessionGroup::addSession(Session* session)
{
_sessions.insert(session,false);
QListIterator<Session*> masterIter(masters());
while ( masterIter.hasNext() )
connectPair(masterIter.next(),session);
}
void SessionGroup::removeSession(Session* session)
{
setMasterStatus(session,false);
QListIterator<Session*> masterIter(masters());
while ( masterIter.hasNext() )
disconnectPair(masterIter.next(),session);
_sessions.remove(session);
}
void SessionGroup::setMasterMode(int mode)
{
_masterMode = mode;
connectAll(false);
connectAll(true);
}
QList<Session*> SessionGroup::masters() const
{
return _sessions.keys(true);
}
void SessionGroup::connectAll(bool connect)
{
QListIterator<Session*> masterIter(masters());
while ( masterIter.hasNext() )
{
Session* master = masterIter.next();
QListIterator<Session*> otherIter(_sessions.keys());
while ( otherIter.hasNext() )
{
Session* other = otherIter.next();
if ( other != master )
{
if ( connect )
connectPair(master,other);
else
disconnectPair(master,other);
}
}
}
}
void SessionGroup::setMasterStatus(Session* session , bool master)
{
bool wasMaster = _sessions[session];
_sessions[session] = master;
if ( !wasMaster && !master
|| wasMaster && master )
return;
QListIterator<Session*> iter(_sessions.keys());
while ( iter.hasNext() )
{
Session* other = iter.next();
if ( other != session )
{
if ( master )
connectPair(session,other);
else
disconnectPair(session,other);
}
}
}
void SessionGroup::connectPair(Session* master , Session* other)
{
qDebug() << __FUNCTION__;
if ( _masterMode & CopyInputToAll )
{
qDebug() << "Connection session " << master->nameTitle() << "to" << other->nameTitle();
connect( master->emulation() , SIGNAL(sendData(const char*,int)) , other->emulation() ,
SLOT(sendString(const char*,int)) );
}
}
void SessionGroup::disconnectPair(Session* master , Session* other)
{
qDebug() << __FUNCTION__;
if ( _masterMode & CopyInputToAll )
{
qDebug() << "Disconnecting session " << master->nameTitle() << "from" << other->nameTitle();
disconnect( master->emulation() , SIGNAL(sendData(const char*,int)) , other->emulation() ,
SLOT(sendString(const char*,int)) );
}
}
#include "Session.moc"
......@@ -508,6 +508,80 @@ private:
};
/**
* Provides a group of sessions which is divided into master and slave sessions.
* Activity in master sessions can be propagated to all sessions within the group.
* The type of activity which is propagated and method of propagation is controlled
* by the masterMode() flags.
*/
class SessionGroup : public QObject
{
Q_OBJECT
public:
/** Constructs an empty session group. */
SessionGroup();
/** Destroys the session group and removes all connections between master and slave sessions. */
~SessionGroup();
/** Adds a session to the group. */
void addSession( Session* session );
/** Removes a session from the group. */
void removeSession( Session* session );
/** Returns the list of sessions currently in the group. */
QList<Session*> sessions() const;
/**
* Sets whether a particular session is a master within the group.
* Changes or activity in the group's master sessions may be propagated
* to all the sessions in the group, depending on the current masterMode()
*
* @param session The session whoose master status should be changed.
* @param master True to make this session a master or false otherwise
*/
void setMasterStatus( Session* session , bool master );
/** Returns the master status of a session. See setMasterStatus() */
bool masterStatus( Session* session ) const;
/**
* This enum describes the options for propagating certain activity or
* changes in the group's master sessions to all sessions in the group.
*/
enum MasterMode
{
/**
* Any input key presses in the master sessions are sent to all
* sessions in the group.
*/
CopyInputToAll = 1
};
/**
* Specifies which activity in the group's master sessions is propagated
* to all sessions in the group.
*
* @param mode A bitwise OR of MasterMode flags.
*/
void setMasterMode( int mode );
/**
* Returns a bitwise OR of the active MasterMode flags for this group.
* See setMasterMode()
*/
int masterMode() const;
private:
void connectPair(Session* master , Session* other);
void disconnectPair(Session* master , Session* other);
void connectAll(bool connect);
QList<Session*> masters() const;
// maps sessions to their master status
QHash<Session*,bool> _sessions;
int _masterMode;
};
}
#endif
......@@ -254,13 +254,16 @@ void ViewManager::detachActiveView()
void ViewManager::sessionFinished()
{
// switch to the previous view before deleting the session views to prevent flicker
// occurring as a result of an interval between removing the active view and switching
// to the previous view
previousView();
Session* session = qobject_cast<Session*>(sender());
if ( _sessionMap[qobject_cast<TerminalDisplay*>(activeView())] == session )
{
// switch to the previous view before deleting the session views to prevent flicker
// occurring as a result of an interval between removing the active view and switching
// to the previous view
previousView();
}
Q_ASSERT(session);
QList<TerminalDisplay*> children = _viewSplitter->findChildren<TerminalDisplay*>();
......@@ -406,7 +409,8 @@ SessionController* ViewManager::createController(Session* session , TerminalDisp
connect( controller , SIGNAL(focused(SessionController*)) , this , SIGNAL(activeViewChanged(SessionController*)) );
connect( session , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
connect( view , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
connect( controller , SIGNAL(sendInputToAll(bool)) , this , SLOT(sendInputToAll()) );
return controller;
}
......@@ -644,6 +648,22 @@ QList<ViewProperties*> ViewManager::viewProperties() const
return list;
}
void ViewManager::sendInputToAll()
{
SessionGroup* group = new SessionGroup();
group->setMasterMode( SessionGroup::CopyInputToAll );
Session* activeSession = _sessionMap[qobject_cast<TerminalDisplay*>(activeView())];
if ( activeSession != 0 )
{
QListIterator<Session*> iter( SessionManager::instance()->sessions() );
while ( iter.hasNext() )
group->addSession(iter.next());
group->setMasterStatus(activeSession,true);
}
}
uint qHash(QPointer<TerminalDisplay> display)
{
return qHash((TerminalDisplay*)display);
......
......@@ -175,6 +175,9 @@ private slots:
void updateViewsForSession(Session* session);
// sends input from active view to all sessions
void sendInputToAll();
private:
void setupActions();
void focusActiveView();
......
......@@ -808,9 +808,12 @@ void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
/*!
*/
void Vt102Emulation::sendString(const char* s)
void Vt102Emulation::sendString(const char* s , int length)
{
emit sendData(s,strlen(s));
if ( length >= 0 )
emit sendData(s,length);
else
emit sendData(s,strlen(s));
}
// Replies ----------------------------------------------------------------- --
......
......@@ -94,7 +94,7 @@ public:
public slots:
// reimplemented
virtual void sendString(const char*);
virtual void sendString(const char*,int length = -1);
virtual void sendText(const QString& text);
virtual void sendKeyEvent(QKeyEvent*);
virtual void sendMouseEvent( int buttons, int column, int line , int eventType );
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment