Commit d9b8b2b2 authored by Robert Knight's avatar Robert Knight

Add comments

svn path=/branches/work/konsole-split-view/; revision=629916
parent d3d909f1
......@@ -129,6 +129,10 @@ void KonsoleMainWindow::showPreferencesDialog()
void KonsoleMainWindow::mergeWindows()
{
// merges all of the open Konsole windows into this window
// by merging the view manager associated with the other Konsole windows
// into this window's view manager
QListIterator<QWidget*> topLevelIter( KonsoleApp::topLevelWidgets() );
while (topLevelIter.hasNext())
......
......@@ -94,10 +94,6 @@ QString ProcessInfo::name(bool* ok) const
return _name;
}
void ProcessInfo::setPid(int pid)
{
_pid = pid;
......@@ -136,6 +132,8 @@ UnixProcessInfo::UnixProcessInfo(int pid,bool enableEnvironmentRead)
bool UnixProcessInfo::readProcessInfo(int pid , bool enableEnvironmentRead)
{
// indicies of various fields within the process status file which
// contain various information about the process
const int PARENT_PID_FIELD = 3;
const int PROCESS_NAME_FIELD = 1;
const int GROUP_PROCESS_FIELD = 7;
......@@ -143,7 +141,15 @@ bool UnixProcessInfo::readProcessInfo(int pid , bool enableEnvironmentRead)
QString parentPidString;
QString processNameString;
QString foregroundPidString;
// read process status file ( /proc/<pid/stat )
//
// the expected file format is a list of fields separated by spaces, using
// parenthesies to escape fields such as the process name which may itself contain
// spaces:
//
// FIELD FIELD (FIELD WITH SPACES) FIELD FIELD
//
QFile processInfo( QString("/proc/%1/stat").arg(pid) );
if ( processInfo.open(QIODevice::ReadOnly) )
{
......@@ -236,8 +242,11 @@ bool NullProcessInfo::readProcessInfo(int /*pid*/ , bool /*enableEnvironmentRead
bool UnixProcessInfo::readArguments(int pid)
{
QFile argumentsFile( QString("/proc/%1/cmdline").arg(pid) );
// read command-line arguments file found at /proc/<pid>/cmdline
// the expected format is a list of strings delimited by null characters,
// and ending in a double null character pair.
QFile argumentsFile( QString("/proc/%1/cmdline").arg(pid) );
if ( argumentsFile.open(QIODevice::ReadOnly) )
{
QTextStream stream(&argumentsFile);
......@@ -257,8 +266,11 @@ bool UnixProcessInfo::readArguments(int pid)
bool UnixProcessInfo::readEnvironment(int pid)
{
QFile environmentFile( QString("/proc/%1/environ").arg(pid) );
// read environment bindings file found at /proc/<pid>/environ
// the expected format is a list of KEY=VALUE strings delimited by null
// characters and ending in a double null character pair.
QFile environmentFile( QString("/proc/%1/environ").arg(pid) );
if ( environmentFile.open(QIODevice::ReadOnly) )
{
QTextStream stream(&environmentFile);
......
......@@ -34,6 +34,9 @@
* using ProcessInfo::newInstance(),
* passing the process identifier of the process you are interested in.
*
* After creating a new instance, call the update() method to take a
* snapshot of the current state of the process.
*
* Before calling any additional methods, check that the process state
* was read successfully using the isValid() method.
*
......@@ -186,6 +189,8 @@ private:
* Implementation of ProcessInfo which does nothing.
* Used on platforms where a suitable ProcessInfo subclass is not
* available.
*
* isValid() will always return false for instances of NullProcessInfo
*/
class NullProcessInfo : public ProcessInfo
{
......@@ -205,11 +210,16 @@ public:
UnixProcessInfo(int pid,bool readEnvironment = false);
protected:
// reads the /proc/<pid>/stat file to get status information
// about the process, also uses readEnvironment() and readArguments()
// to read other files in /proc/<pid>
virtual bool readProcessInfo(int pid , bool readEnvironment);
private:
bool readEnvironment(int pid);
bool readArguments(int pid);
bool readEnvironment(int pid); // read the /proc/<pid/environ file
// to get environment bindings
bool readArguments(int pid); // read the /proc/<pid>/cmdline file
// to get command-line arguments
};
......
......@@ -142,6 +142,7 @@ void SessionController::setupActions()
action->setText( i18n("Clear History") );
connect( action , SIGNAL(triggered()) , this , SLOT(clearHistory()) );
// debugging tools
action = collection->addAction("debug-process");
action->setText( "Get Foreground Process" );
connect( action , SIGNAL(triggered()) , this , SLOT(debugProcess()) );
......@@ -149,6 +150,8 @@ void SessionController::setupActions()
void SessionController::debugProcess()
{
// testing facility to retrieve process information about
// currently active process in the shell
ProcessInfo* sessionProcess = ProcessInfo::newInstance(_session->sessionPid());
sessionProcess->update();
......@@ -331,6 +334,9 @@ void SaveHistoryTask::execute()
mimeTypes << "text/html";
dialog->setMimeFilter(mimeTypes,"text/plain");
// iterate over each session in the task and display a dialog to allow the user to choose where
// to save that session's history.
// then start a KIO job to transfer the data from the history to the chosen URL
while ( iter.hasNext() )
{
SessionPtr session = iter.next();
......@@ -367,7 +373,10 @@ void SaveHistoryTask::execute()
SaveJob jobInfo;
jobInfo.session = session;
jobInfo.lastLineFetched = -1;
jobInfo.lastLineFetched = -1; // when each request for data comes in from the KIO subsystem
// lastLineFetched is used to keep track of how much of the history
// has already been sent, and where the next request should continue
// from
if ( dialog->currentMimeFilter() == "text/html" )
jobInfo.decoder = new HTMLDecoder();
......@@ -393,6 +402,7 @@ void SaveHistoryTask::jobDataRequested(KIO::Job* job , QByteArray& data)
SaveJob& info = _jobSession[job];
// transfer LINES_PER_REQUEST lines from the session's history to the save location
if ( info.session )
{
int sessionLines = info.session->getEmulation()->lines();
......
......@@ -343,6 +343,19 @@ ListViewContainer::ListViewContainer(QObject* parent)
_splitter = new QSplitter;
_stackWidget = new QStackedWidget(_splitter);
_listWidget = new SessionListWidget(_splitter);
// elide left is used because the most informative part of the session name is often
// the rightmost part
//
// this means you get entries looking like:
//
// ...dirA ...dirB ...dirC ( helpful )
//
// instead of
//
// johnSmith@comput... johnSmith@comput... ( not so helpful )
//
_listWidget->setTextElideMode( Qt::ElideLeft );
_listWidget->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
_listWidget->setDragDropMode(QAbstractItemView::DragDrop);
......
......@@ -133,6 +133,12 @@ void ViewManager::sessionFinished( TESession* session )
void ViewManager::focusActiveView()
{
// give the active view in a container the focus. this ensures
// that controller associated with that view is activated and the session-specific
// menu items are replaced with the ones for the newly focused view
// see the viewFocused() method
ViewContainer* container = _viewSplitter->activeContainer();
if ( container )
{
......@@ -164,8 +170,13 @@ void ViewManager::activeViewTitleChanged(ViewProperties* properties)
void ViewManager::viewFocused( SessionController* controller )
{
// if a view is given the focus which is different to the one for which menu items
// are currently being shown then unplug the current session-specific menu items
// and plug in the ones for the newly focused session
if ( _pluggedController != controller )
{
// remove existing session specific menu items if there are any
if ( _pluggedController )
{
_mainWindow->guiFactory()->removeClient(_pluggedController);
......@@ -230,6 +241,8 @@ void ViewManager::splitView(bool splitView)
SessionController* ViewManager::createController(TESession* session , TEWidget* view)
{
// create a new controller for the session, and ensure that this view manager
// is notified when the view gains the focus
SessionController* controller = new SessionController(session,view,this);
connect( controller , SIGNAL(focused(SessionController*)) , this , SLOT(viewFocused(SessionController*)) );
......@@ -244,8 +257,13 @@ void ViewManager::createView(TESession* session)
_viewSplitter->addContainer( createContainer() , Qt::Vertical );
}
// notify this view manager when the session finishes so that its view
// can be deleted
connect( session , SIGNAL(done(TESession*)) , this , SLOT(sessionFinished(TESession*)) );
// iterate over the view containers owned by this view manager
// and create a new terminal display for the session in each of them, along with
// a controller for the session/display pair
ViewContainer* const activeContainer = _viewSplitter->activeContainer();
QListIterator<ViewContainer*> containerIter(_viewSplitter->containers());
......@@ -269,8 +287,8 @@ void ViewManager::createView(TESession* session)
ViewContainer* ViewManager::createContainer()
{
/*TabbedViewContainer* container = new TabbedViewContainer(_viewSplitter);
ViewContainer* container = new TabbedViewContainer(_viewSplitter);
/*
if ( _mainWindow->factory() )
{
QMenu* menu = (QMenu*)_mainWindow->factory()->container("new-session-popup",_mainWindow);
......@@ -283,11 +301,10 @@ ViewContainer* ViewManager::createContainer()
kDebug() << __FILE__ << __LINE__ << ": ViewManager attempted to create a view before" <<
" the main window GUI was created - unable to create popup menus for container." << endl;
}
*/
// connect signals and slots
connect( container , SIGNAL(closeRequest(QWidget*)) , this , SLOT(viewCloseRequest(QWidget*)) );
*/
ViewContainer* container = new StackedViewContainer(_viewSplitter);
connect( container , SIGNAL(activeViewChanged(QWidget*)) , this , SLOT(viewActivated(QWidget*)));
return container;
......@@ -315,6 +332,12 @@ void ViewManager::viewCloseRequest(QWidget* view)
void ViewManager::merge(ViewManager* otherManager)
{
// iterate over the views in otherManager's active container and take them from that
// manager and put them in the active container in this manager
//
// TODO - This currently does not consider views in containers other than
// the active one in the other manager
//
ViewSplitter* otherSplitter = otherManager->_viewSplitter;
ViewContainer* otherContainer = otherSplitter->activeContainer();
......@@ -336,6 +359,9 @@ void ViewManager::merge(ViewManager* otherManager)
void ViewManager::takeView(ViewManager* otherManager , ViewContainer* otherContainer,
ViewContainer* newContainer, TEWidget* view)
{
// FIXME - the controller associated with the display which is being moved
// may have signals which are connected to otherManager. they need
// to be redirected to slots in this view manager
ViewProperties* properties = otherContainer->viewProperties(view);
otherContainer->removeView(view);
......
......@@ -37,10 +37,19 @@ class ViewContainer;
class ViewSplitter;
/**
* Manages the views and view container widgets in a KonsoleMainWindow.
* Manages the views and view container widgets in a Konsole window. Each Konsole window
* has one ViewManager.
* The view manager is responsible for creating new terminal displays for sessions and the
* controllers which connect the view and session to provide the menu actions associated with
* the view, as well as exposing basic information ( such as associated title and icon ) to
* the view.
*
* Each Konsole window contains a number of view containers, which are instances of ViewContainer.
* Each view container may contain one or more views, along with a navigation widget
* (eg. tabs or a list) which allows the user to choose between the views in that container.
*
* When a ViewManager is instantiated, it adds a container widget for terminal displays to the
* KonsoleMainWindow widget passed as an argument to the constructor.
* When a ViewManager is instantiated, it creates a new view container and adds it to the
* main window associated with the ViewManager which is specified in the constructor.
*
* To create new terminal displays inside the container widget, use the createView() method.
*
......@@ -109,12 +118,17 @@ private:
// newContainer owned by this manager
void takeView(ViewManager* otherManager , ViewContainer* otherContainer, ViewContainer* newContainer, TEWidget* view);
// creates a new container which can hold terminal displays
ViewContainer* createContainer();
// creates a new terminal display
TEWidget* createTerminalDisplay();
// applies the view-specific settings such as colour scheme associated
// with 'session' to 'view'
void loadViewSettings(TEWidget* view , TESession* session);
// creates a new controller for a session/display pair which provides the menu
// actions associated with that view, and exposes basic information
// about the session ( such as title and associated icon ) to the display.
SessionController* createController(TESession* session , TEWidget* display);
private:
......
Markdown is supported
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