Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qgscontexthelp.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscontexthelp.cpp
3  Display context help for a dialog
4  -------------------
5  begin : 2005-06-19
6  copyright : (C) 2005 by Gary E.Sherman
7  email : sherman at mrcc.com
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 /* $Id$ */
19 
20 #include <QString>
21 #include <QProcess>
22 #include <QTcpSocket>
23 #include <QTextStream>
24 
25 #include "qgscontexthelp.h"
26 #include "qgsapplication.h"
27 #include "qgslogger.h"
28 
29 
30 // Note: QGSCONTEXTHELP_REUSE must be defined (or not) in qgscontexthelp.h.
31 // The flag determines if an existing viewer process should be reused or
32 // terminated and restarted in order to make the viewer be the top window.
33 
34 QgsContextHelp *QgsContextHelp::gContextHelp = NULL; // Singleton instance
35 
36 void QgsContextHelp::run( QString context )
37 {
38  if ( gContextHelp == NULL )
39  {
40  // Create singleton instance if it does not exist
41  gContextHelp = new QgsContextHelp( context );
42  }
43  else
44  {
45  gContextHelp->showContext( context );
46  }
47 }
48 
50 {
51  mProcess = start( context );
52 #ifdef QGSCONTEXTHELP_REUSE
53  // Create socket to communicate with process
54  mSocket = new QTcpSocket( this );
55  connect( mProcess, SIGNAL( readyReadStandardOutput() ), SLOT( readPort() ) );
56 #else
57  // Placeholder for new process if terminating and restarting
58  mNextProcess = NULL;
59 #endif
60 }
61 
63 {
64 #ifdef QGSCONTEXTHELP_REUSE
65  delete mSocket;
66 #else
67  // Should be NULL here unless previous process termination failed
68  delete mNextProcess;
69 #endif
70  delete mProcess;
71 }
72 
73 QProcess *QgsContextHelp::start( QString context )
74 {
75  // Get the path to the help viewer
76  QString helpPath = QgsApplication::helpAppPath();
77  QgsDebugMsg( QString( "Help path is %1" ).arg( helpPath ) );
78 
79  QProcess *process = new QProcess;
80  process->start( helpPath, QStringList( context ) );
81 
82  // Delete this object if the process terminates
83  connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( processExited() ) );
84 
85  // Delete the process if the application quits
86  connect( qApp, SIGNAL( aboutToQuit() ), process, SLOT( terminate() ) );
87 
88  return process;
89 }
90 
92 {
93 #ifdef QGSCONTEXTHELP_REUSE
94  // Get port and connect socket to process
95  QString p = mProcess->readAllStandardOutput();
96  quint16 port = p.toUShort();
97  mSocket->connectToHost( "localhost", port );
98  disconnect( mProcess, SIGNAL( readyReadStandardOutput() ), this, SLOT( readPort() ) );
99 #endif
100 }
101 
102 void QgsContextHelp::showContext( QString context )
103 {
104  // Refresh help process with new context
105 #ifdef QGSCONTEXTHELP_REUSE
106  // Send context to process
107  QTextStream os( mSocket );
108  os << context << "\n";
109  QgsDebugMsg( QString( "Sending help process context %1" ).arg( context ) );
110 #else
111  // Should be NULL here unless previous process termination failed
112  // (if it did fail, we abandon the process and delete the object reference)
113  delete mNextProcess;
114  // Start new help viewer process (asynchronous)
115  mNextProcess = start( context );
116  // Terminate existing help viewer process (asynchronous)
117  mProcess->terminate();
118 #endif
119 }
120 
122 {
123 #ifndef QGSCONTEXTHELP_REUSE
124  if ( mNextProcess )
125  {
126  // New process becomes current process when prior process terminates
127  delete mProcess;
129  mNextProcess = NULL;
130  }
131  else
132 #endif
133  {
134  // Delete this object if the process terminates
135  delete gContextHelp;
136  gContextHelp = NULL;
137  }
138 }