summaryrefslogtreecommitdiffstats
path: root/tools/assistant/lib/qassistantclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/assistant/lib/qassistantclient.cpp')
-rw-r--r--tools/assistant/lib/qassistantclient.cpp334
1 files changed, 334 insertions, 0 deletions
diff --git a/tools/assistant/lib/qassistantclient.cpp b/tools/assistant/lib/qassistantclient.cpp
new file mode 100644
index 000000000..fc772b55b
--- /dev/null
+++ b/tools/assistant/lib/qassistantclient.cpp
@@ -0,0 +1,334 @@
+/**********************************************************************
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the TQAssistantClient library.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing retquirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qassistantclient.h"
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include <qprocess.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+class TQAssistantClientPrivate
+{
+ friend class TQAssistantClient;
+ TQStringList arguments;
+};
+
+static TQMap<const TQAssistantClient*,TQAssistantClientPrivate*> *dpointers = 0;
+
+static TQAssistantClientPrivate *data( const TQAssistantClient *client, bool create=FALSE )
+{
+ if( !dpointers )
+ dpointers = new TQMap<const TQAssistantClient*,TQAssistantClientPrivate*>;
+ TQAssistantClientPrivate *d = (*dpointers)[client];
+ if( !d && create ) {
+ d = new TQAssistantClientPrivate;
+ dpointers->insert( client, d );
+ }
+ return d;
+}
+
+/*!
+ \class TQAssistantClient
+ \brief The TQAssistantClient class provides a means of using TQt
+ Assistant as an application's help tool.
+
+ Using TQt Assistant is simple: Create a TQAssistantClient instance,
+ then call showPage() as often as necessary to show your help
+ pages. When you call showPage(), TQt Assistant will be launched if
+ it isn't already running.
+
+ The TQAssistantClient instance can open (openAssistant()) or close
+ (closeAssistant()) TQt Assistant whenever retquired. If TQt Assistant
+ is open, isOpen() returns TRUE.
+
+ One TQAssistantClient instance interacts with one TQt Assistant
+ instance, so every time you call openAssistant(), showPage() or
+ closeAssistant() they are applied to the particular TQt Assistant
+ instance associated with the TQAssistantClient.
+
+ When you call openAssistant() the assistantOpened() signal is
+ emitted. Similarly when closeAssistant() is called,
+ assistantClosed() is emitted. In either case, if an error occurs,
+ error() is emitted.
+
+ This class is not included in the TQt library itself. To use it you
+ must link against \c libqassistantclient.a (Unix) or \c
+ qassistantclient.lib (Windows), which is built into \c INSTALL/lib
+ if you built the TQt tools (\c INSTALL is the directory where TQt is
+ installed). If you use qmake, then you can simply add the following
+ line to your pro file:
+
+ \code
+ LIBS += -lqassistantclient
+ \endcode
+
+ See also "Adding Documentation to TQt Assistant" in the \link
+ assistant.book TQt Assistant manual\endlink.
+*/
+
+/*!
+ \fn void TQAssistantClient::assistantOpened()
+
+ This signal is emitted when TQt Assistant is open and the
+ client-server communication is set up.
+*/
+
+/*!
+ \fn void TQAssistantClient::assistantClosed()
+
+ This signal is emitted when the connection to TQt Assistant is
+ closed. This happens when the user exits TQt Assistant, or when an
+ error in the server or client occurs, or if closeAssistant() is
+ called.
+*/
+
+/*!
+ \fn void TQAssistantClient::error( const TQString &msg )
+
+ This signal is emitted if TQt Assistant cannot be started or if an
+ error occurs during the initialization of the connection between
+ TQt Assistant and the calling application. The \a msg provides an
+ explanation of the error.
+*/
+
+/*!
+ Constructs an assistant client object. The \a path specifies the
+ path to the TQt Assistant executable. If \a path is an empty
+ string the system path (\c{%PATH%} or \c $PATH) is used.
+
+ The assistant client object is a child of \a parent and is called
+ \a name.
+*/
+TQAssistantClient::TQAssistantClient( const TQString &path, TQObject *parent, const char *name )
+ : TQObject( parent, name ), host ( "localhost" )
+{
+ if ( path.isEmpty() )
+ assistantCommand = "assistant";
+ else {
+ TQFileInfo fi( path );
+ if ( fi.isDir() )
+ assistantCommand = path + "/assistant";
+ else
+ assistantCommand = path;
+ }
+
+#if defined(Q_OS_MACX)
+ assistantCommand += ".app/Contents/MacOS/assistant";
+#elif defined(Q_WS_WIN)
+ if (!assistantCommand.endsWith(".exe"))
+ assistantCommand += ".exe";
+#endif
+ socket = new TQSocket( this );
+ connect( socket, SIGNAL( connected() ),
+ SLOT( socketConnected() ) );
+ connect( socket, SIGNAL( connectionClosed() ),
+ SLOT( socketConnectionClosed() ) );
+ connect( socket, SIGNAL( error( int ) ),
+ SLOT( socketError( int ) ) );
+ opened = FALSE;
+ proc = new TQProcess( this );
+ port = 0;
+ pageBuffer = "";
+ connect( proc, SIGNAL( readyReadStderr() ),
+ this, SLOT( readStdError() ) );
+}
+
+/*!
+ Destroys the assistant client object and frees up all allocated
+ resources.
+*/
+TQAssistantClient::~TQAssistantClient()
+{
+ if ( proc && proc->isRunning() ) {
+ proc->tryTerminate();
+ proc->kill();
+ }
+
+ if( dpointers ) {
+ TQAssistantClientPrivate *d = (*dpointers)[ this ];
+ if( d ) {
+ dpointers->remove( this );
+ delete d;
+ if( dpointers->isEmpty() ) {
+ delete dpointers;
+ dpointers = 0;
+ }
+ }
+ }
+}
+
+/*!
+ This function opens TQt Assistant and sets up the client-server
+ communiction between the application and TQt Assistant. If it is
+ already open, this function does nothing. If an error occurs,
+ error() is emitted.
+
+ \sa assistantOpened()
+*/
+void TQAssistantClient::openAssistant()
+{
+ if ( proc->isRunning() )
+ return;
+ proc->clearArguments();
+ proc->addArgument( assistantCommand );
+ proc->addArgument( "-server" );
+ if( !pageBuffer.isEmpty() ) {
+ proc->addArgument( "-file" );
+ proc->addArgument( pageBuffer );
+ }
+
+ TQAssistantClientPrivate *d = data( this );
+ if( d ) {
+ TQStringList::ConstIterator it = d->arguments.begin();
+ while( it!=d->arguments.end() ) {
+ proc->addArgument( *it );
+ ++it;
+ }
+ }
+
+ if ( !proc->launch( TQString::null ) ) {
+ emit error( tr( "Cannot start TQt Assistant '%1'" )
+ .arg( proc->arguments().join( " " ) ) );
+ return;
+ }
+ connect( proc, SIGNAL( readyReadStdout() ),
+ this, SLOT( readPort() ) );
+}
+
+void TQAssistantClient::readPort()
+{
+ TQString p = proc->readLineStdout();
+ Q_UINT16 port = p.toUShort();
+ if ( port == 0 ) {
+ emit error( tr( "Cannot connect to TQt Assistant." ) );
+ return;
+ }
+ socket->connectToHost( host, port );
+ disconnect( proc, SIGNAL( readyReadStdout() ),
+ this, SLOT( readPort() ) );
+}
+
+/*!
+ Use this function to close TQt Assistant.
+
+ \sa assistantClosed()
+*/
+void TQAssistantClient::closeAssistant()
+{
+ if ( !opened )
+ return;
+ proc->tryTerminate();
+ proc->kill();
+}
+
+/*!
+ Call this function to make TQt Assistant show a particular \a page.
+ The \a page is a filename (e.g. \c myhelpfile.html). See "Adding
+ Documentation to TQt Assistant" in the \link assistant.book TQt
+ Assistant manual\endlink for further information.
+
+ If TQt Assistant hasn't been \link openAssistant() opened\endlink
+ yet, this function will do nothing. You can use isOpen() to
+ determine whether TQt Assistant is up and running, or you can
+ connect to the asssistantOpened() signal.
+
+ \sa isOpen(), assistantOpened()
+*/
+void TQAssistantClient::showPage( const TQString &page )
+{
+ if ( !opened ) {
+ pageBuffer = page;
+ openAssistant();
+ pageBuffer = TQString::null;
+ return;
+ }
+ TQTextStream os( socket );
+ os << page << "\n";
+}
+
+/*!
+ \property TQAssistantClient::open
+ \brief Whether TQt Assistant is open.
+
+*/
+bool TQAssistantClient::isOpen() const
+{
+ return opened;
+}
+
+void TQAssistantClient::socketConnected()
+{
+ opened = TRUE;
+ if ( !pageBuffer.isEmpty() )
+ showPage( pageBuffer );
+ emit assistantOpened();
+}
+
+void TQAssistantClient::socketConnectionClosed()
+{
+ opened = FALSE;
+ emit assistantClosed();
+}
+
+void TQAssistantClient::socketError( int i )
+{
+ if ( i == TQSocket::ErrConnectionRefused )
+ emit error( tr( "Could not connect to Assistant: Connection refused" ) );
+ else if ( i == TQSocket::ErrHostNotFound )
+ emit error( tr( "Could not connect to Assistant: Host not found" ) );
+ else
+ emit error( tr( "Communication error" ) );
+}
+
+void TQAssistantClient::readStdError()
+{
+ TQString errmsg;
+ while ( proc->canReadLineStderr() ) {
+ errmsg += proc->readLineStderr();
+ errmsg += "\n";
+ }
+ if (!errmsg.isEmpty())
+ emit error( tr( errmsg.simplifyWhiteSpace() ) );
+}
+
+/*!
+ Sets the command line arguments used when TQt Assistant is
+ started to \a args.
+*/
+void TQAssistantClient::setArguments( const TQStringList &args )
+{
+ TQAssistantClientPrivate *d = data( this, TRUE );
+ d->arguments = args;
+}