Quantum GIS API Documentation
1.7.4
|
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 /* $Id$ */ 00019 00020 #include <QString> 00021 #include <QProcess> 00022 #include <QTcpSocket> 00023 #include <QTextStream> 00024 00025 #include "qgscontexthelp.h" 00026 #include "qgsapplication.h" 00027 #include "qgslogger.h" 00028 00029 00030 // Note: QGSCONTEXTHELP_REUSE must be defined (or not) in qgscontexthelp.h. 00031 // The flag determines if an existing viewer process should be reused or 00032 // terminated and restarted in order to make the viewer be the top window. 00033 00034 QgsContextHelp *QgsContextHelp::gContextHelp = NULL; // Singleton instance 00035 00036 void QgsContextHelp::run( QString context ) 00037 { 00038 if ( gContextHelp == NULL ) 00039 { 00040 // Create singleton instance if it does not exist 00041 gContextHelp = new QgsContextHelp( context ); 00042 } 00043 else 00044 { 00045 gContextHelp->showContext( context ); 00046 } 00047 } 00048 00049 QgsContextHelp::QgsContextHelp( QString context ) 00050 { 00051 mProcess = start( context ); 00052 #ifdef QGSCONTEXTHELP_REUSE 00053 // Create socket to communicate with process 00054 mSocket = new QTcpSocket( this ); 00055 connect( mProcess, SIGNAL( readyReadStandardOutput() ), SLOT( readPort() ) ); 00056 #else 00057 // Placeholder for new process if terminating and restarting 00058 mNextProcess = NULL; 00059 #endif 00060 } 00061 00062 QgsContextHelp::~QgsContextHelp() 00063 { 00064 #ifdef QGSCONTEXTHELP_REUSE 00065 delete mSocket; 00066 #else 00067 // Should be NULL here unless previous process termination failed 00068 delete mNextProcess; 00069 #endif 00070 delete mProcess; 00071 } 00072 00073 QProcess *QgsContextHelp::start( QString context ) 00074 { 00075 // Get the path to the help viewer 00076 QString helpPath = QgsApplication::helpAppPath(); 00077 QgsDebugMsg( QString( "Help path is %1" ).arg( helpPath ) ); 00078 00079 QProcess *process = new QProcess; 00080 process->start( helpPath, QStringList( context ) ); 00081 00082 // Delete this object if the process terminates 00083 connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( processExited() ) ); 00084 00085 // Delete the process if the application quits 00086 connect( qApp, SIGNAL( aboutToQuit() ), process, SLOT( terminate() ) ); 00087 00088 return process; 00089 } 00090 00091 void QgsContextHelp::readPort() 00092 { 00093 #ifdef QGSCONTEXTHELP_REUSE 00094 // Get port and connect socket to process 00095 QString p = mProcess->readAllStandardOutput(); 00096 quint16 port = p.toUShort(); 00097 mSocket->connectToHost( "localhost", port ); 00098 disconnect( mProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readPort() ) ); 00099 #endif 00100 } 00101 00102 void QgsContextHelp::showContext( QString context ) 00103 { 00104 // Refresh help process with new context 00105 #ifdef QGSCONTEXTHELP_REUSE 00106 // Send context to process 00107 QTextStream os( mSocket ); 00108 os << context << "\n"; 00109 QgsDebugMsg( QString( "Sending help process context %1" ).arg( context ) ); 00110 #else 00111 // Should be NULL here unless previous process termination failed 00112 // (if it did fail, we abandon the process and delete the object reference) 00113 delete mNextProcess; 00114 // Start new help viewer process (asynchronous) 00115 mNextProcess = start( context ); 00116 // Terminate existing help viewer process (asynchronous) 00117 mProcess->terminate(); 00118 #endif 00119 } 00120 00121 void QgsContextHelp::processExited() 00122 { 00123 #ifndef QGSCONTEXTHELP_REUSE 00124 if ( mNextProcess ) 00125 { 00126 // New process becomes current process when prior process terminates 00127 delete mProcess; 00128 mProcess = mNextProcess; 00129 mNextProcess = NULL; 00130 } 00131 else 00132 #endif 00133 { 00134 // Delete this object if the process terminates 00135 delete gContextHelp; 00136 gContextHelp = NULL; 00137 } 00138 }