Quantum GIS API Documentation  1.8
src/core/qgscontexthelp.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           qgscontexthelp.cpp
00003                     Display context help for a dialog
00004                              -------------------
00005     begin                : 2005-06-19
00006     copyright            : (C) 2005 by Gary E.Sherman
00007     email                : sherman at mrcc.com
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include <QString>
00020 #include <QProcess>
00021 #include <QTcpSocket>
00022 #include <QTextStream>
00023 
00024 #include "qgscontexthelp.h"
00025 #include "qgsapplication.h"
00026 #include "qgslogger.h"
00027 
00028 
00029 // Note: QGSCONTEXTHELP_REUSE must be defined (or not) in qgscontexthelp.h.
00030 // The flag determines if an existing viewer process should be reused or
00031 // terminated and restarted in order to make the viewer be the top window.
00032 
00033 QgsContextHelp *QgsContextHelp::gContextHelp = NULL;  // Singleton instance
00034 
00035 void QgsContextHelp::run( QString context )
00036 {
00037   if ( gContextHelp == NULL )
00038   {
00039     // Create singleton instance if it does not exist
00040     gContextHelp = new QgsContextHelp( context );
00041   }
00042   else
00043   {
00044     gContextHelp->showContext( context );
00045   }
00046 }
00047 
00048 QgsContextHelp::QgsContextHelp( QString context )
00049 {
00050   mProcess = start( context );
00051 #ifdef QGSCONTEXTHELP_REUSE
00052   // Create socket to communicate with process
00053   mSocket = new QTcpSocket( this );
00054   connect( mProcess, SIGNAL( readyReadStandardOutput() ), SLOT( readPort() ) );
00055 #else
00056   // Placeholder for new process if terminating and restarting
00057   mNextProcess = NULL;
00058 #endif
00059 }
00060 
00061 QgsContextHelp::~QgsContextHelp()
00062 {
00063 #ifdef QGSCONTEXTHELP_REUSE
00064   delete mSocket;
00065 #else
00066   // Should be NULL here unless previous process termination failed
00067   delete mNextProcess;
00068 #endif
00069   delete mProcess;
00070 }
00071 
00072 QProcess *QgsContextHelp::start( QString context )
00073 {
00074   // Get the path to the help viewer
00075   QString helpPath = QgsApplication::helpAppPath();
00076   QgsDebugMsg( QString( "Help path is %1" ).arg( helpPath ) );
00077 
00078   QProcess *process = new QProcess;
00079   process->start( helpPath, QStringList( context ) );
00080 
00081   // Delete this object if the process terminates
00082   connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( processExited() ) );
00083 
00084   // Delete the process if the application quits
00085   connect( qApp, SIGNAL( aboutToQuit() ), process, SLOT( terminate() ) );
00086 
00087   return process;
00088 }
00089 
00090 void QgsContextHelp::readPort()
00091 {
00092 #ifdef QGSCONTEXTHELP_REUSE
00093   // Get port and connect socket to process
00094   QString p = mProcess->readAllStandardOutput();
00095   quint16 port = p.toUShort();
00096   mSocket->connectToHost( "localhost", port );
00097   disconnect( mProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readPort() ) );
00098 #endif
00099 }
00100 
00101 void QgsContextHelp::showContext( QString context )
00102 {
00103   // Refresh help process with new context
00104 #ifdef QGSCONTEXTHELP_REUSE
00105   // Send context to process
00106   QTextStream os( mSocket );
00107   os << context << "\n";
00108   QgsDebugMsg( QString( "Sending help process context %1" ).arg( context ) );
00109 #else
00110   // Should be NULL here unless previous process termination failed
00111   // (if it did fail, we abandon the process and delete the object reference)
00112   delete mNextProcess;
00113   // Start new help viewer process (asynchronous)
00114   mNextProcess = start( context );
00115   // Terminate existing help viewer process (asynchronous)
00116   mProcess->terminate();
00117 #endif
00118 }
00119 
00120 void QgsContextHelp::processExited()
00121 {
00122 #ifndef QGSCONTEXTHELP_REUSE
00123   if ( mNextProcess )
00124   {
00125     // New process becomes current process when prior process terminates
00126     delete mProcess;
00127     mProcess = mNextProcess;
00128     mNextProcess = NULL;
00129   }
00130   else
00131 #endif
00132   {
00133     // Delete this object if the process terminates
00134     delete gContextHelp;
00135     gContextHelp = NULL;
00136   }
00137 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines