Quantum GIS API Documentation
1.8
|
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 }