src/qt3support/network/q3networkprotocol.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "q3networkprotocol.h"
       
    43 
       
    44 #ifndef QT_NO_NETWORKPROTOCOL
       
    45 
       
    46 #include "q3localfs.h"
       
    47 #include "q3urloperator.h"
       
    48 #include "qtimer.h"
       
    49 #include "qmap.h"
       
    50 #include "q3ptrqueue.h"
       
    51 #include "q3valuelist.h"
       
    52 #include "qurlinfo.h"
       
    53 #include <private/qobject_p.h>
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 //#define Q3NETWORKPROTOCOL_DEBUG
       
    58 #define NETWORK_OP_DELAY 1000
       
    59 
       
    60 extern Q_COMPAT_EXPORT Q3NetworkProtocolDict *q3networkProtocolRegister;
       
    61 
       
    62 Q3NetworkProtocolDict *q3networkProtocolRegister = 0;
       
    63 
       
    64 class Q3NetworkProtocolPrivate
       
    65 {
       
    66 public:
       
    67     Q3NetworkProtocolPrivate( Q3NetworkProtocol *p )
       
    68     {
       
    69 	url = 0;
       
    70 	opInProgress = 0;
       
    71 	opStartTimer = new QTimer( p );
       
    72 	removeTimer = new QTimer( p );
       
    73 	operationQueue.setAutoDelete( false );
       
    74 	autoDelete = false;
       
    75 	removeInterval = 10000;
       
    76 	oldOps.setAutoDelete( false );
       
    77     }
       
    78 
       
    79     ~Q3NetworkProtocolPrivate()
       
    80     {
       
    81 	removeTimer->stop();
       
    82 	if ( opInProgress ) {
       
    83 	    if ( opInProgress == operationQueue.head() )
       
    84 		operationQueue.dequeue();
       
    85 	    opInProgress->free();
       
    86 	}
       
    87 	while ( operationQueue.head() ) {
       
    88 	    operationQueue.head()->free();
       
    89 	    operationQueue.dequeue();
       
    90 	}
       
    91 	while ( oldOps.first() ) {
       
    92 	    oldOps.first()->free();
       
    93 	    oldOps.removeFirst();
       
    94 	}
       
    95 	delete opStartTimer;
       
    96     }
       
    97 
       
    98     Q3UrlOperator *url;
       
    99     Q3PtrQueue< Q3NetworkOperation > operationQueue;
       
   100     Q3NetworkOperation *opInProgress;
       
   101     QTimer *opStartTimer, *removeTimer;
       
   102     int removeInterval;
       
   103     bool autoDelete;
       
   104     Q3PtrList< Q3NetworkOperation > oldOps;
       
   105 };
       
   106 
       
   107 /*!
       
   108     \class Q3NetworkProtocol
       
   109     \brief The Q3NetworkProtocol class provides a common API for network protocols.
       
   110 
       
   111     \compat
       
   112 
       
   113     This is a base class which should be used for network protocols
       
   114     implementations that can then be used in Qt (e.g. in the file
       
   115     dialog) together with the Q3UrlOperator.
       
   116 
       
   117     The easiest way to implement a new network protocol is to
       
   118     reimplement the operation*() methods, e.g. operationGet(), etc.
       
   119     Only the supported operations should be reimplemented. To specify
       
   120     which operations are supported, also reimplement
       
   121     supportedOperations() and return an int that is OR'd together
       
   122     using the supported operations from the \l
       
   123     Q3NetworkProtocol::Operation enum.
       
   124 
       
   125     When you implement a network protocol this way, it is important to
       
   126     emit the correct signals. Also, always emit the finished() signal
       
   127     when an operation is done (on success \e and on failure). Qt
       
   128     relies on correctly emitted finished() signals.
       
   129 */
       
   130 
       
   131 /*!
       
   132     \fn void Q3NetworkProtocol::newChildren( const Q3ValueList<QUrlInfo> &i, Q3NetworkOperation *op )
       
   133 
       
   134     This signal is emitted after listChildren() was called and new
       
   135     children (files) have been read from the list of files. \a i holds
       
   136     the information about the new children. \a op is the pointer to
       
   137     the operation object which contains all the information about the
       
   138     operation, including the state, etc.
       
   139 
       
   140     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   141     enough to let the Q3UrlOperator, which is used by the network
       
   142     protocol, emit its corresponding signal.
       
   143 
       
   144     When implementing your own network protocol and reading children,
       
   145     you usually don't read one child at once, but rather a list of
       
   146     them. That's why this signal takes a list of QUrlInfo objects. If
       
   147     you prefer to read just one child at a time you can use the
       
   148     convenience signal newChild(), which takes a single QUrlInfo
       
   149     object.
       
   150 */
       
   151 
       
   152 /*!
       
   153     \fn void Q3NetworkProtocol::newChild( const QUrlInfo &i, Q3NetworkOperation *op )
       
   154 
       
   155     This signal is emitted if a new child (file) has been read.
       
   156     Q3NetworkProtocol automatically connects it to a slot which creates
       
   157     a list of QUrlInfo objects (with just one QUrlInfo \a i) and emits
       
   158     the newChildren() signal with this list. \a op is the pointer to
       
   159     the operation object which contains all the information about the
       
   160     operation that has finished, including the state, etc.
       
   161 
       
   162     This is just a convenience signal useful for implementing your own
       
   163     network protocol. In all other cases connect to the newChildren()
       
   164     signal with its list of QUrlInfo objects.
       
   165 */
       
   166 
       
   167 /*!
       
   168     \fn void Q3NetworkProtocol::finished( Q3NetworkOperation *op )
       
   169 
       
   170     This signal is emitted when an operation finishes. This signal is
       
   171     always emitted, for both success and failure. \a op is the pointer
       
   172     to the operation object which contains all the information about
       
   173     the operation, including the state, etc. Check the state and error
       
   174     code of the operation object to determine whether or not the
       
   175     operation was successful.
       
   176 
       
   177     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   178     enough to let the Q3UrlOperator, which is used by the network
       
   179     protocol, emit its corresponding signal.
       
   180 */
       
   181 
       
   182 /*!
       
   183     \fn void Q3NetworkProtocol::start( Q3NetworkOperation *op )
       
   184 
       
   185     Some operations (such as listChildren()) emit this signal when
       
   186     they start processing the operation. \a op is the pointer to the
       
   187     operation object which contains all the information about the
       
   188     operation, including the state, etc.
       
   189 
       
   190     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   191     enough to let the Q3UrlOperator, which is used by the network
       
   192     protocol, emit its corresponding signal.
       
   193 */
       
   194 
       
   195 /*!
       
   196     \fn void Q3NetworkProtocol::createdDirectory( const QUrlInfo &i, Q3NetworkOperation *op )
       
   197 
       
   198     This signal is emitted when mkdir() has been successful and the
       
   199     directory has been created. \a i holds the information about the
       
   200     new directory. \a op is the pointer to the operation object which
       
   201     contains all the information about the operation, including the
       
   202     state, etc. Using op->arg( 0 ), you can get the file name of the
       
   203     new directory.
       
   204 
       
   205     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   206     enough to let the Q3UrlOperator, which is used by the network
       
   207     protocol, emit its corresponding signal.
       
   208 */
       
   209 
       
   210 /*!
       
   211     \fn void Q3NetworkProtocol::removed( Q3NetworkOperation *op )
       
   212 
       
   213     This signal is emitted when remove() has been succesiisful and the
       
   214     file has been removed. \a op holds the file name of the removed
       
   215     file in the first argument, accessible with op->arg( 0 ). \a op is
       
   216     the pointer to the operation object which contains all the
       
   217     information about the operation, including the state, etc.
       
   218 
       
   219     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   220     enough to let the Q3UrlOperator, which is used by the network
       
   221     protocol, emit its corresponding signal.
       
   222 */
       
   223 
       
   224 /*!
       
   225     \fn void Q3NetworkProtocol::itemChanged( Q3NetworkOperation *op )
       
   226 
       
   227     This signal is emitted whenever a file which is a child of this
       
   228     URL has been changed, e.g. by successfully calling rename(). \a op
       
   229     holds the original and the new file names in the first and second
       
   230     arguments, accessible with op->arg( 0 ) and op->arg( 1 )
       
   231     respectively. \a op is the pointer to the operation object which
       
   232     contains all the information about the operation, including the
       
   233     state, etc.
       
   234 
       
   235     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   236     enough to let the Q3UrlOperator, which is used by the network
       
   237     protocol, emit its corresponding signal.
       
   238 */
       
   239 
       
   240 /*!
       
   241     \fn void Q3NetworkProtocol::data( const QByteArray &data,
       
   242     Q3NetworkOperation *op )
       
   243 
       
   244     This signal is emitted when new \a data has been received after
       
   245     calling get() or put(). \a op holds the name of the file from
       
   246     which data is retrieved or uploaded in its first argument, and the
       
   247     (raw) data in its second argument. You can get them with
       
   248     op->arg( 0 ) and op->rawArg( 1 ). \a op is the pointer to the
       
   249     operation object, which contains all the information about the
       
   250     operation, including the state, etc.
       
   251 
       
   252     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   253     enough to let the Q3UrlOperator (which is used by the network
       
   254     protocol) emit its corresponding signal.
       
   255 */
       
   256 
       
   257 /*!
       
   258     \fn void Q3NetworkProtocol::dataTransferProgress( int bytesDone, int bytesTotal, Q3NetworkOperation *op )
       
   259 
       
   260     This signal is emitted during the transfer of data (using put() or
       
   261     get()). \a bytesDone is how many bytes of \a bytesTotal have been
       
   262     transferred. \a bytesTotal may be -1, which means that the total
       
   263     number of bytes is not known. \a op is the pointer to the
       
   264     operation object which contains all the information about the
       
   265     operation, including the state, etc.
       
   266 
       
   267     When a protocol emits this signal, Q3NetworkProtocol is smart
       
   268     enough to let the Q3UrlOperator, which is used by the network
       
   269     protocol, emit its corresponding signal.
       
   270 */
       
   271 
       
   272 /*!
       
   273     \fn void Q3NetworkProtocol::connectionStateChanged( int state, const QString &data )
       
   274 
       
   275     This signal is emitted whenever the state of the connection of the
       
   276     network protocol is changed. \a state describes the new state,
       
   277     which is one of, \c ConHostFound, \c ConConnected or \c ConClosed.
       
   278     \a data is a message text.
       
   279 */
       
   280 
       
   281 /*!
       
   282     \enum Q3NetworkProtocol::State
       
   283 
       
   284     This enum contains the state that a Q3NetworkOperation can have.
       
   285 
       
   286     \value StWaiting  The operation is in the Q3NetworkProtocol's queue
       
   287     waiting to be prcessed.
       
   288 
       
   289     \value StInProgress  The operation is being processed.
       
   290 
       
   291     \value StDone  The operation has been processed successfully.
       
   292 
       
   293     \value StFailed  The operation has been processed but an error occurred.
       
   294 
       
   295     \value StStopped  The operation has been processed but has been
       
   296     stopped before it finished, and is waiting to be processed.
       
   297 
       
   298 */
       
   299 
       
   300 /*!
       
   301     \enum Q3NetworkProtocol::Operation
       
   302 
       
   303     This enum lists the possible operations that a network protocol
       
   304     can support. supportedOperations() returns an int of these that is
       
   305     OR'd together. Also, the type() of a Q3NetworkOperation is always
       
   306     one of these values.
       
   307 
       
   308     \value OpListChildren  List the children of a URL, e.g. of a directory.
       
   309     \value OpMkDir  Create a directory.
       
   310     \value OpRemove  Remove a child (e.g. a file).
       
   311     \value OpRename  Rename a child (e.g. a file).
       
   312     \value OpGet  Get data from a location.
       
   313     \value OpPut  Put data to a location.
       
   314     \omitvalue OpMkdir
       
   315 */
       
   316 
       
   317 /*!
       
   318     \enum Q3NetworkProtocol::ConnectionState
       
   319 
       
   320     When the connection state of a network protocol changes it emits
       
   321     the signal connectionStateChanged(). The first argument is one of
       
   322     the following values:
       
   323 
       
   324     \value ConHostFound  Host has been found.
       
   325     \value ConConnected  Connection to the host has been established.
       
   326     \value ConClosed  Connection has been closed.
       
   327 */
       
   328 
       
   329 /*!
       
   330     \enum Q3NetworkProtocol::Error
       
   331 
       
   332     When an operation fails (finishes unsuccessfully), the
       
   333     Q3NetworkOperation of the operation returns an error code which has
       
   334     one of the following values:
       
   335 
       
   336     \value NoError  No error occurred.
       
   337 
       
   338     \value ErrValid  The URL you are operating on is not valid.
       
   339 
       
   340     \value ErrUnknownProtocol  There is no protocol implementation
       
   341     available for the protocol of the URL you are operating on (e.g.
       
   342     if the protocol is http and no http implementation has been
       
   343     registered).
       
   344 
       
   345     \value ErrUnsupported  The operation is not supported by the
       
   346     protocol.
       
   347 
       
   348     \value ErrParse  The URL could not be parsed correctly.
       
   349 
       
   350     \value ErrLoginIncorrect  You needed to login but the username
       
   351     or password is wrong.
       
   352 
       
   353     \value ErrHostNotFound  The specified host (in the URL) couldn't
       
   354     be found.
       
   355 
       
   356     \value ErrListChildren  An error occurred while listing the
       
   357     children (files).
       
   358 
       
   359     \value ErrMkDir  An error occurred when creating a directory.
       
   360 
       
   361     \value ErrRemove  An error occurred when removing a child (file).
       
   362 
       
   363     \value ErrRename   An error occurred when renaming a child (file).
       
   364 
       
   365     \value ErrGet  An error occurred while getting (retrieving) data.
       
   366 
       
   367     \value ErrPut  An error occurred while putting (uploading) data.
       
   368 
       
   369     \value ErrFileNotExisting  A file which is needed by the operation
       
   370     doesn't exist.
       
   371 
       
   372     \value ErrPermissionDenied  Permission for doing the operation has
       
   373     been denied.
       
   374     \omitvalue ErrMkdir
       
   375     \omitvalue ErrListChlidren
       
   376 
       
   377     You should also use these error codes when implementing custom
       
   378     network protocols. If this is not possible, you can define your own
       
   379     error codes by using integer values that don't conflict with any
       
   380     of these values.
       
   381 */
       
   382 
       
   383 /*!
       
   384     Constructor of the network protocol base class. Does some
       
   385     initialization and connecting of signals and slots.
       
   386 */
       
   387 
       
   388 Q3NetworkProtocol::Q3NetworkProtocol()
       
   389     : QObject()
       
   390 {
       
   391     d = new Q3NetworkProtocolPrivate( this );
       
   392 
       
   393     connect( d->opStartTimer, SIGNAL(timeout()),
       
   394 	     this, SLOT(startOps()) );
       
   395     connect( d->removeTimer, SIGNAL(timeout()),
       
   396 	     this, SLOT(removeMe()) );
       
   397 
       
   398     if ( url() ) {
       
   399 	connect( this, SIGNAL(data(QByteArray,Q3NetworkOperation*)),
       
   400 		 url(), SIGNAL(data(QByteArray,Q3NetworkOperation*)) );
       
   401 	connect( this, SIGNAL(finished(Q3NetworkOperation*)),
       
   402 		 url(), SIGNAL(finished(Q3NetworkOperation*)) );
       
   403 	connect( this, SIGNAL(start(Q3NetworkOperation*)),
       
   404 		 url(), SIGNAL(start(Q3NetworkOperation*)) );
       
   405 	connect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   406 		 url(), SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)) );
       
   407 	connect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   408 		 url(), SLOT(addEntry(Q3ValueList<QUrlInfo>)) );
       
   409 	connect( this, SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)),
       
   410 		 url(), SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)) );
       
   411 	connect( this, SIGNAL(removed(Q3NetworkOperation*)),
       
   412 		 url(), SIGNAL(removed(Q3NetworkOperation*)) );
       
   413 	connect( this, SIGNAL(itemChanged(Q3NetworkOperation*)),
       
   414 		 url(), SIGNAL(itemChanged(Q3NetworkOperation*)) );
       
   415 	connect( this, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)),
       
   416 		 url(), SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)) );
       
   417 	connect( this, SIGNAL(connectionStateChanged(int,QString)),
       
   418 		 url(), SIGNAL(connectionStateChanged(int,QString)) );
       
   419     }
       
   420 
       
   421     connect( this, SIGNAL(finished(Q3NetworkOperation*)),
       
   422 	     this, SLOT(processNextOperation(Q3NetworkOperation*)) );
       
   423     connect( this, SIGNAL(newChild(QUrlInfo,Q3NetworkOperation*)),
       
   424 	     this, SLOT(emitNewChildren(QUrlInfo,Q3NetworkOperation*)) );
       
   425 
       
   426 }
       
   427 
       
   428 /*!
       
   429     Destructor.
       
   430 */
       
   431 
       
   432 Q3NetworkProtocol::~Q3NetworkProtocol()
       
   433 {
       
   434     delete d;
       
   435 }
       
   436 
       
   437 /*!
       
   438     Sets the Q3UrlOperator, on which the protocol works, to \a u.
       
   439 
       
   440     \sa Q3UrlOperator
       
   441 */
       
   442 
       
   443 void Q3NetworkProtocol::setUrl( Q3UrlOperator *u )
       
   444 {
       
   445     if ( url() ) {
       
   446 	disconnect( this, SIGNAL(data(QByteArray,Q3NetworkOperation*)),
       
   447 		    url(), SIGNAL(data(QByteArray,Q3NetworkOperation*)) );
       
   448 	disconnect( this, SIGNAL(finished(Q3NetworkOperation*)),
       
   449 		    url(), SIGNAL(finished(Q3NetworkOperation*)) );
       
   450 	disconnect( this, SIGNAL(start(Q3NetworkOperation*)),
       
   451 		    url(), SIGNAL(start(Q3NetworkOperation*)) );
       
   452 	disconnect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   453 		    url(), SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)) );
       
   454 	disconnect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   455 		    url(), SLOT(addEntry(Q3ValueList<QUrlInfo>)) );
       
   456 	disconnect( this, SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)),
       
   457 		    url(), SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)) );
       
   458 	disconnect( this, SIGNAL(removed(Q3NetworkOperation*)),
       
   459 		    url(), SIGNAL(removed(Q3NetworkOperation*)) );
       
   460 	disconnect( this, SIGNAL(itemChanged(Q3NetworkOperation*)),
       
   461 		    url(), SIGNAL(itemChanged(Q3NetworkOperation*)) );
       
   462 	disconnect( this, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)),
       
   463 		    url(), SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)) );
       
   464 	disconnect( this, SIGNAL(connectionStateChanged(int,QString)),
       
   465 		    url(), SIGNAL(connectionStateChanged(int,QString)) );
       
   466     }
       
   467 
       
   468 
       
   469     // ### if autoDelete is true, we should delete the Q3UrlOperator (something
       
   470     // like below; but that is not possible since it would delete this, too).
       
   471     //if ( d->autoDelete && (d->url!=u) ) {
       
   472     //    delete d->url; // destructor deletes the network protocol
       
   473     //}
       
   474     d->url = u;
       
   475 
       
   476     if ( url() ) {
       
   477 	connect( this, SIGNAL(data(QByteArray,Q3NetworkOperation*)),
       
   478 		 url(), SIGNAL(data(QByteArray,Q3NetworkOperation*)) );
       
   479 	connect( this, SIGNAL(finished(Q3NetworkOperation*)),
       
   480 		 url(), SIGNAL(finished(Q3NetworkOperation*)) );
       
   481 	connect( this, SIGNAL(start(Q3NetworkOperation*)),
       
   482 		 url(), SIGNAL(start(Q3NetworkOperation*)) );
       
   483 	connect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   484 		 url(), SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)) );
       
   485 	connect( this, SIGNAL(newChildren(Q3ValueList<QUrlInfo>,Q3NetworkOperation*)),
       
   486 		 url(), SLOT(addEntry(Q3ValueList<QUrlInfo>)) );
       
   487 	connect( this, SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)),
       
   488 		 url(), SIGNAL(createdDirectory(QUrlInfo,Q3NetworkOperation*)) );
       
   489 	connect( this, SIGNAL(removed(Q3NetworkOperation*)),
       
   490 		 url(), SIGNAL(removed(Q3NetworkOperation*)) );
       
   491 	connect( this, SIGNAL(itemChanged(Q3NetworkOperation*)),
       
   492 		 url(), SIGNAL(itemChanged(Q3NetworkOperation*)) );
       
   493 	connect( this, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)),
       
   494 		 url(), SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)) );
       
   495 	connect( this, SIGNAL(connectionStateChanged(int,QString)),
       
   496 		 url(), SIGNAL(connectionStateChanged(int,QString)) );
       
   497     }
       
   498 
       
   499     if ( !d->opInProgress && !d->operationQueue.isEmpty() )
       
   500 	d->opStartTimer->start( 0, true );
       
   501 }
       
   502 
       
   503 /*!
       
   504     For processing operations the network protocol base class calls
       
   505     this method quite often. This should be reimplemented by new
       
   506     network protocols. It should return true if the connection is OK
       
   507     (open); otherwise it should return false. If the connection is not
       
   508     open the protocol should open it.
       
   509 
       
   510     If the connection can't be opened (e.g. because you already tried
       
   511     but the host couldn't be found), set the state of \a op to
       
   512     Q3NetworkProtocol::StFailed and emit the finished() signal with
       
   513     this Q3NetworkOperation as argument.
       
   514 
       
   515     \a op is the operation that needs an open connection.
       
   516 */
       
   517 
       
   518 bool Q3NetworkProtocol::checkConnection( Q3NetworkOperation * )
       
   519 {
       
   520     return true;
       
   521 }
       
   522 
       
   523 /*!
       
   524     Returns an int that is OR'd together using the enum values of
       
   525     \l{Q3NetworkProtocol::Operation}, which describes which operations
       
   526     are supported by the network protocol. Should be reimplemented by
       
   527     new network protocols.
       
   528 */
       
   529 
       
   530 int Q3NetworkProtocol::supportedOperations() const
       
   531 {
       
   532     return 0;
       
   533 }
       
   534 
       
   535 /*!
       
   536     Adds the operation \a op to the operation queue. The operation
       
   537     will be processed as soon as possible. This method returns
       
   538     immediately.
       
   539 */
       
   540 
       
   541 void Q3NetworkProtocol::addOperation( Q3NetworkOperation *op )
       
   542 {
       
   543 #ifdef Q3NETWORKPROTOCOL_DEBUG
       
   544     qDebug( "Q3NetworkOperation: addOperation: %p %d", op, op->operation() );
       
   545 #endif
       
   546     d->operationQueue.enqueue( op );
       
   547     if ( !d->opInProgress )
       
   548 	d->opStartTimer->start( 0, true );
       
   549 }
       
   550 
       
   551 /*!
       
   552     Static method to register a network protocol for Qt. For example,
       
   553     if you have an implementation of NNTP (called Nntp) which is
       
   554     derived from Q3NetworkProtocol, call:
       
   555     \snippet doc/src/snippets/code/src_qt3support_network_q3networkprotocol.cpp 0
       
   556     after which your implementation is registered for future nntp
       
   557     operations.
       
   558 
       
   559     The name of the protocol is given in \a protocol and a pointer to
       
   560     the protocol factory is given in \a protocolFactory.
       
   561 */
       
   562 
       
   563 void Q3NetworkProtocol::registerNetworkProtocol( const QString &protocol,
       
   564 						Q3NetworkProtocolFactoryBase *protocolFactory )
       
   565 {
       
   566     if ( !q3networkProtocolRegister ) {
       
   567 	q3networkProtocolRegister = new Q3NetworkProtocolDict;
       
   568 	Q3NetworkProtocol::registerNetworkProtocol( QLatin1String("file"), new Q3NetworkProtocolFactory< Q3LocalFs > );
       
   569     }
       
   570 
       
   571     q3networkProtocolRegister->insert( protocol, protocolFactory );
       
   572 }
       
   573 
       
   574 /*!
       
   575     Static method to get a new instance of the network protocol \a
       
   576     protocol. For example, if you need to do some FTP operations, do
       
   577     the following:
       
   578     \snippet doc/src/snippets/code/src_qt3support_network_q3networkprotocol.cpp 1
       
   579     This returns a pointer to a new instance of an ftp implementation
       
   580     or null if no protocol for ftp was registered. The ownership of
       
   581     the pointer is transferred to you, so you must delete it if you
       
   582     don't need it anymore.
       
   583 
       
   584     Normally you should not work directly with network protocols, so
       
   585     you will not need to call this method yourself. Instead, use
       
   586     Q3UrlOperator, which makes working with network protocols much more
       
   587     convenient.
       
   588 
       
   589     \sa Q3UrlOperator
       
   590 */
       
   591 
       
   592 Q3NetworkProtocol *Q3NetworkProtocol::getNetworkProtocol( const QString &protocol )
       
   593 {
       
   594     if ( !q3networkProtocolRegister ) {
       
   595 	q3networkProtocolRegister = new Q3NetworkProtocolDict;
       
   596 	Q3NetworkProtocol::registerNetworkProtocol( QLatin1String("file"), new Q3NetworkProtocolFactory< Q3LocalFs > );
       
   597     }
       
   598 
       
   599     if ( protocol.isNull() )
       
   600 	return 0;
       
   601 
       
   602     Q3NetworkProtocolFactoryBase *factory = q3networkProtocolRegister->find( protocol );
       
   603     if ( factory )
       
   604 	return factory->createObject();
       
   605 
       
   606     return 0;
       
   607 }
       
   608 
       
   609 /*!
       
   610     Returns true if the only protocol registered is for working on the
       
   611     local filesystem; returns false if other network protocols are
       
   612     also registered.
       
   613 */
       
   614 
       
   615 bool Q3NetworkProtocol::hasOnlyLocalFileSystem()
       
   616 {
       
   617     if ( !q3networkProtocolRegister )
       
   618 	return false;
       
   619 
       
   620     Q3DictIterator< Q3NetworkProtocolFactoryBase > it( *q3networkProtocolRegister );
       
   621     for ( ; it.current(); ++it )
       
   622 	if ( it.currentKey() != QLatin1String("file") )
       
   623 	    return false;
       
   624     return true;
       
   625 }
       
   626 
       
   627 /*!
       
   628   \internal
       
   629   Starts processing network operations.
       
   630 */
       
   631 
       
   632 void Q3NetworkProtocol::startOps()
       
   633 {
       
   634 #ifdef Q3NETWORKPROTOCOL_DEBUG
       
   635     qDebug( "Q3NetworkOperation: start processing operations" );
       
   636 #endif
       
   637     processNextOperation( 0 );
       
   638 }
       
   639 
       
   640 /*!
       
   641   \internal
       
   642   Processes the operation \a op. It calls the
       
   643   corresponding operation[something]( Q3NetworkOperation * )
       
   644   methods.
       
   645 */
       
   646 
       
   647 void Q3NetworkProtocol::processOperation( Q3NetworkOperation *op )
       
   648 {
       
   649     if ( !op )
       
   650 	return;
       
   651 
       
   652     switch ( op->operation() ) {
       
   653     case OpListChildren:
       
   654 	operationListChildren( op );
       
   655 	break;
       
   656     case OpMkDir:
       
   657 	operationMkDir( op );
       
   658 	break;
       
   659     case OpRemove:
       
   660 	operationRemove( op );
       
   661 	break;
       
   662     case OpRename:
       
   663 	operationRename( op );
       
   664 	break;
       
   665     case OpGet:
       
   666 	operationGet( op );
       
   667 	break;
       
   668     case OpPut:
       
   669 	operationPut( op );
       
   670 	break;
       
   671     }
       
   672 }
       
   673 
       
   674 /*!
       
   675     When implementing a new network protocol, this method should be
       
   676     reimplemented if the protocol supports listing children (files);
       
   677     this method should then process this Q3NetworkOperation.
       
   678 
       
   679     \a op is the pointer to the operation object which contains all
       
   680     the information on the operation that has finished, including the
       
   681     state, etc.
       
   682 */
       
   683 
       
   684 void Q3NetworkProtocol::operationListChildren( Q3NetworkOperation * )
       
   685 {
       
   686 }
       
   687 
       
   688 /*!
       
   689     When implementing a new network protocol, this method should be
       
   690     reimplemented if the protocol supports making directories; this
       
   691     method should then process this Q3NetworkOperation.
       
   692 
       
   693     \a op is the pointer to the operation object which contains all
       
   694     the information on the operation that has finished, including the
       
   695     state, etc.
       
   696 */
       
   697 
       
   698 void Q3NetworkProtocol::operationMkDir( Q3NetworkOperation * )
       
   699 {
       
   700 }
       
   701 
       
   702 /*!
       
   703     When implementing a new network protocol, this method should be
       
   704     reimplemented if the protocol supports removing children (files);
       
   705     this method should then process this Q3NetworkOperation.
       
   706 
       
   707     \a op is the pointer to the operation object which contains all
       
   708     the information on the operation that has finished, including the
       
   709     state, etc.
       
   710 */
       
   711 
       
   712 void Q3NetworkProtocol::operationRemove( Q3NetworkOperation * )
       
   713 {
       
   714 }
       
   715 
       
   716 /*!
       
   717     When implementing a new network protocol, this method should be
       
   718     reimplemented if the protocol supports renaming children (files);
       
   719     this method should then process this Q3NetworkOperation.
       
   720 
       
   721     \a op is the pointer to the operation object which contains all
       
   722     the information on the operation that has finished, including the
       
   723     state, etc.
       
   724 */
       
   725 
       
   726 void Q3NetworkProtocol::operationRename( Q3NetworkOperation * )
       
   727 {
       
   728 }
       
   729 
       
   730 /*!
       
   731     When implementing a new network protocol, this method should be
       
   732     reimplemented if the protocol supports getting data; this method
       
   733     should then process the Q3NetworkOperation.
       
   734 
       
   735     \a op is the pointer to the operation object which contains all
       
   736     the information on the operation that has finished, including the
       
   737     state, etc.
       
   738 */
       
   739 
       
   740 void Q3NetworkProtocol::operationGet( Q3NetworkOperation * )
       
   741 {
       
   742 }
       
   743 
       
   744 /*!
       
   745     When implementing a new network protocol, this method should be
       
   746     reimplemented if the protocol supports putting (uploading) data;
       
   747     this method should then process the Q3NetworkOperation.
       
   748 
       
   749     \a op is the pointer to the operation object which contains all
       
   750     the information on the operation that has finished, including the
       
   751     state, etc.
       
   752 */
       
   753 
       
   754 void Q3NetworkProtocol::operationPut( Q3NetworkOperation * )
       
   755 {
       
   756 }
       
   757 
       
   758 /*! \internal
       
   759 */
       
   760 
       
   761 void Q3NetworkProtocol::operationPutChunk( Q3NetworkOperation * )
       
   762 {
       
   763 }
       
   764 
       
   765 /*!
       
   766   \internal
       
   767   Handles operations. Deletes the previous operation object and
       
   768   tries to process the next operation. It also checks the connection state
       
   769   and only processes the next operation, if the connection of the protocol
       
   770   is open. Otherwise it waits until the protocol opens the connection.
       
   771 */
       
   772 
       
   773 void Q3NetworkProtocol::processNextOperation( Q3NetworkOperation *old )
       
   774 {
       
   775 #ifdef Q3NETWORKPROTOCOL_DEBUG
       
   776     qDebug( "Q3NetworkOperation: process next operation, old: %p", old );
       
   777 #endif
       
   778     d->removeTimer->stop();
       
   779 
       
   780     if ( old )
       
   781 	d->oldOps.append( old );
       
   782     if ( d->opInProgress && d->opInProgress!=old )
       
   783 	d->oldOps.append( d->opInProgress );
       
   784 
       
   785     if ( d->operationQueue.isEmpty() ) {
       
   786 	d->opInProgress = 0;
       
   787 	if ( d->autoDelete )
       
   788 	    d->removeTimer->start( d->removeInterval, true );
       
   789 	return;
       
   790     }
       
   791 
       
   792     Q3NetworkOperation *op = d->operationQueue.head();
       
   793 
       
   794     d->opInProgress = op;
       
   795 
       
   796     if ( !checkConnection( op ) ) {
       
   797 	if ( op->state() != Q3NetworkProtocol::StFailed ) {
       
   798 	    d->opStartTimer->start( 0, true );
       
   799 	} else {
       
   800 	    d->operationQueue.dequeue();
       
   801 	    clearOperationQueue();
       
   802 	    emit finished( op );
       
   803 	}
       
   804 
       
   805 	return;
       
   806     }
       
   807 
       
   808     d->opInProgress = op;
       
   809     d->operationQueue.dequeue();
       
   810     processOperation( op );
       
   811 }
       
   812 
       
   813 /*!
       
   814     Returns the Q3UrlOperator on which the protocol works.
       
   815 */
       
   816 
       
   817 Q3UrlOperator *Q3NetworkProtocol::url() const
       
   818 {
       
   819     return d->url;
       
   820 }
       
   821 
       
   822 /*!
       
   823     Returns the operation, which is being processed, or 0 of no
       
   824     operation is being processed at the moment.
       
   825 */
       
   826 
       
   827 Q3NetworkOperation *Q3NetworkProtocol::operationInProgress() const
       
   828 {
       
   829     return d->opInProgress;
       
   830 }
       
   831 
       
   832 /*!
       
   833     Clears the operation queue.
       
   834 */
       
   835 
       
   836 void Q3NetworkProtocol::clearOperationQueue()
       
   837 {
       
   838     d->operationQueue.dequeue();
       
   839     d->operationQueue.setAutoDelete( true );
       
   840     d->operationQueue.clear();
       
   841 }
       
   842 
       
   843 /*!
       
   844     Stops the current operation that is being processed and clears all
       
   845     waiting operations.
       
   846 */
       
   847 
       
   848 void Q3NetworkProtocol::stop()
       
   849 {
       
   850     Q3NetworkOperation *op = d->opInProgress;
       
   851     clearOperationQueue();
       
   852     if ( op ) {
       
   853 	op->setState( StStopped );
       
   854 	op->setProtocolDetail( tr( "Operation stopped by the user" ) );
       
   855 	emit finished( op );
       
   856 	setUrl( 0 );
       
   857 	op->free();
       
   858     }
       
   859 }
       
   860 
       
   861 /*!
       
   862     Because it's sometimes hard to take care of removing network
       
   863     protocol instances, Q3NetworkProtocol provides an auto-delete
       
   864     mechanism. If you set \a b to true, the network protocol instance
       
   865     is removed after it has been inactive for \a i milliseconds (i.e.
       
   866     \a i milliseconds after the last operation has been processed).
       
   867     If you set \a b to false the auto-delete mechanism is switched
       
   868     off.
       
   869 
       
   870     If you switch on auto-delete, the Q3NetworkProtocol also deletes
       
   871     its Q3UrlOperator.
       
   872 */
       
   873 
       
   874 void Q3NetworkProtocol::setAutoDelete( bool b, int i )
       
   875 {
       
   876     d->autoDelete = b;
       
   877     d->removeInterval = i;
       
   878 }
       
   879 
       
   880 /*!
       
   881     Returns true if auto-deleting is enabled; otherwise returns false.
       
   882 
       
   883     \sa Q3NetworkProtocol::setAutoDelete()
       
   884 */
       
   885 
       
   886 bool Q3NetworkProtocol::autoDelete() const
       
   887 {
       
   888     return d->autoDelete;
       
   889 }
       
   890 
       
   891 /*!
       
   892   \internal
       
   893 */
       
   894 
       
   895 void Q3NetworkProtocol::removeMe()
       
   896 {
       
   897     if ( d->autoDelete ) {
       
   898 #ifdef Q3NETWORKPROTOCOL_DEBUG
       
   899 	qDebug( "Q3NetworkOperation:  autodelete of Q3NetworkProtocol %p", this );
       
   900 #endif
       
   901 	delete d->url; // destructor deletes the network protocol
       
   902     }
       
   903 }
       
   904 
       
   905 void Q3NetworkProtocol::emitNewChildren( const QUrlInfo &i, Q3NetworkOperation *op )
       
   906 {
       
   907     Q3ValueList<QUrlInfo> lst;
       
   908     lst << i;
       
   909     emit newChildren( lst, op );
       
   910 }
       
   911 
       
   912 class Q3NetworkOperationPrivate
       
   913 {
       
   914 public:
       
   915     Q3NetworkProtocol::Operation operation;
       
   916     Q3NetworkProtocol::State state;
       
   917     QMap<int, QString> args;
       
   918     QMap<int, QByteArray> rawArgs;
       
   919     QString protocolDetail;
       
   920     int errorCode;
       
   921     QTimer *deleteTimer;
       
   922 };
       
   923 
       
   924 /*!
       
   925     \class Q3NetworkOperation
       
   926 
       
   927     \brief The Q3NetworkOperation class provides common operations for network protocols.
       
   928 
       
   929     \compat
       
   930 
       
   931     An object is created to describe the operation and the current
       
   932     state for each operation that a network protocol should process.
       
   933 
       
   934     \sa Q3NetworkProtocol
       
   935 */
       
   936 
       
   937 /*!
       
   938     Constructs a network operation object. \a operation is the type of
       
   939     the operation, and \a arg0, \a arg1 and \a arg2 are the first
       
   940     three arguments of the operation. The state is initialized to
       
   941     Q3NetworkProtocol::StWaiting.
       
   942 
       
   943     \sa Q3NetworkProtocol::Operation Q3NetworkProtocol::State
       
   944 */
       
   945 
       
   946 Q3NetworkOperation::Q3NetworkOperation( Q3NetworkProtocol::Operation operation,
       
   947 				      const QString &arg0, const QString &arg1,
       
   948 				      const QString &arg2 )
       
   949 {
       
   950     d = new Q3NetworkOperationPrivate;
       
   951     d->deleteTimer = new QTimer( this );
       
   952     connect( d->deleteTimer, SIGNAL(timeout()),
       
   953 	     this, SLOT(deleteMe()) );
       
   954     d->operation = operation;
       
   955     d->state = Q3NetworkProtocol::StWaiting;
       
   956     d->args[ 0 ] = arg0;
       
   957     d->args[ 1 ] = arg1;
       
   958     d->args[ 2 ] = arg2;
       
   959     d->rawArgs[ 0 ] = QByteArray( 0 );
       
   960     d->rawArgs[ 1 ] = QByteArray( 0 );
       
   961     d->rawArgs[ 2 ] = QByteArray( 0 );
       
   962     d->protocolDetail.clear();
       
   963     d->errorCode = (int)Q3NetworkProtocol::NoError;
       
   964 }
       
   965 
       
   966 /*!
       
   967     Constructs a network operation object. \a operation is the type of
       
   968     the operation, and \a arg0, \a arg1 and \a arg2 are the first
       
   969     three raw data arguments of the operation. The state is
       
   970     initialized to Q3NetworkProtocol::StWaiting.
       
   971 
       
   972     \sa Q3NetworkProtocol::Operation Q3NetworkProtocol::State
       
   973 */
       
   974 
       
   975 Q3NetworkOperation::Q3NetworkOperation( Q3NetworkProtocol::Operation operation,
       
   976 				      const QByteArray &arg0, const QByteArray &arg1,
       
   977 				      const QByteArray &arg2 )
       
   978 {
       
   979     d = new Q3NetworkOperationPrivate;
       
   980     d->deleteTimer = new QTimer( this );
       
   981     connect( d->deleteTimer, SIGNAL(timeout()),
       
   982 	     this, SLOT(deleteMe()) );
       
   983     d->operation = operation;
       
   984     d->state = Q3NetworkProtocol::StWaiting;
       
   985     d->args[ 0 ].clear();
       
   986     d->args[ 1 ].clear();
       
   987     d->args[ 2 ].clear();
       
   988     d->rawArgs[ 0 ] = arg0;
       
   989     d->rawArgs[ 1 ] = arg1;
       
   990     d->rawArgs[ 2 ] = arg2;
       
   991     d->protocolDetail.clear();
       
   992     d->errorCode = (int)Q3NetworkProtocol::NoError;
       
   993 }
       
   994 
       
   995 /*!
       
   996     Destructor.
       
   997 */
       
   998 
       
   999 Q3NetworkOperation::~Q3NetworkOperation()
       
  1000 {
       
  1001     qDeleteInEventHandler(d->deleteTimer);
       
  1002     delete d;
       
  1003 }
       
  1004 
       
  1005 /*!
       
  1006     Sets the \a state of the operation object. This should be done by
       
  1007     the network protocol during processing; at the end it should be
       
  1008     set to Q3NetworkProtocol::StDone or Q3NetworkProtocol::StFailed,
       
  1009     depending on success or failure.
       
  1010 
       
  1011     \sa Q3NetworkProtocol::State
       
  1012 */
       
  1013 
       
  1014 void Q3NetworkOperation::setState( Q3NetworkProtocol::State state )
       
  1015 {
       
  1016     if ( d->deleteTimer->isActive() ) {
       
  1017 	d->deleteTimer->stop();
       
  1018 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1019     }
       
  1020     d->state = state;
       
  1021 }
       
  1022 
       
  1023 /*!
       
  1024     If the operation failed, the error message can be specified as \a
       
  1025     detail.
       
  1026 */
       
  1027 
       
  1028 void Q3NetworkOperation::setProtocolDetail( const QString &detail )
       
  1029 {
       
  1030     if ( d->deleteTimer->isActive() ) {
       
  1031 	d->deleteTimer->stop();
       
  1032 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1033     }
       
  1034     d->protocolDetail = detail;
       
  1035 }
       
  1036 
       
  1037 /*!
       
  1038     Sets the error code to \a ec.
       
  1039 
       
  1040     If the operation failed, the protocol should set an error code to
       
  1041     describe the error in more detail. If possible, one of the error
       
  1042     codes defined in Q3NetworkProtocol should be used.
       
  1043 
       
  1044     \sa setProtocolDetail() Q3NetworkProtocol::Error
       
  1045 */
       
  1046 
       
  1047 void Q3NetworkOperation::setErrorCode( int ec )
       
  1048 {
       
  1049     if ( d->deleteTimer->isActive() ) {
       
  1050 	d->deleteTimer->stop();
       
  1051 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1052     }
       
  1053     d->errorCode = ec;
       
  1054 }
       
  1055 
       
  1056 /*!
       
  1057     Sets the network operation's \a{num}-th argument to \a arg.
       
  1058 */
       
  1059 
       
  1060 void Q3NetworkOperation::setArg( int num, const QString &arg )
       
  1061 {
       
  1062     if ( d->deleteTimer->isActive() ) {
       
  1063 	d->deleteTimer->stop();
       
  1064 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1065     }
       
  1066     d->args[ num ] = arg;
       
  1067 }
       
  1068 
       
  1069 /*!
       
  1070     Sets the network operation's \a{num}-th raw data argument to \a arg.
       
  1071 */
       
  1072 
       
  1073 void Q3NetworkOperation::setRawArg( int num, const QByteArray &arg )
       
  1074 {
       
  1075     if ( d->deleteTimer->isActive() ) {
       
  1076 	d->deleteTimer->stop();
       
  1077 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1078     }
       
  1079     d->rawArgs[ num ] = arg;
       
  1080 }
       
  1081 
       
  1082 /*!
       
  1083     Returns the type of the operation.
       
  1084 */
       
  1085 
       
  1086 Q3NetworkProtocol::Operation Q3NetworkOperation::operation() const
       
  1087 {
       
  1088     if ( d->deleteTimer->isActive() ) {
       
  1089 	d->deleteTimer->stop();
       
  1090 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1091     }
       
  1092     return d->operation;
       
  1093 }
       
  1094 
       
  1095 /*!
       
  1096     Returns the state of the operation. You can determine whether an
       
  1097     operation is still waiting to be processed, is being processed,
       
  1098     has been processed successfully, or failed.
       
  1099 */
       
  1100 
       
  1101 Q3NetworkProtocol::State Q3NetworkOperation::state() const
       
  1102 {
       
  1103     if ( d->deleteTimer->isActive() ) {
       
  1104 	d->deleteTimer->stop();
       
  1105 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1106     }
       
  1107     return d->state;
       
  1108 }
       
  1109 
       
  1110 /*!
       
  1111     Returns the operation's \a{num}-th argument. If this argument was
       
  1112     not already set, an empty string is returned.
       
  1113 */
       
  1114 
       
  1115 QString Q3NetworkOperation::arg( int num ) const
       
  1116 {
       
  1117     if ( d->deleteTimer->isActive() ) {
       
  1118 	d->deleteTimer->stop();
       
  1119 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1120     }
       
  1121     return d->args[ num ];
       
  1122 }
       
  1123 
       
  1124 /*!
       
  1125     Returns the operation's \a{num}-th raw data argument. If this
       
  1126     argument was not already set, an empty bytearray is returned.
       
  1127 */
       
  1128 
       
  1129 QByteArray Q3NetworkOperation::rawArg( int num ) const
       
  1130 {
       
  1131     if ( d->deleteTimer->isActive() ) {
       
  1132 	d->deleteTimer->stop();
       
  1133 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1134     }
       
  1135     return d->rawArgs[ num ];
       
  1136 }
       
  1137 
       
  1138 /*!
       
  1139     Returns a detailed error message for the last error. This must
       
  1140     have been set using setProtocolDetail().
       
  1141 */
       
  1142 
       
  1143 QString Q3NetworkOperation::protocolDetail() const
       
  1144 {
       
  1145     if ( d->deleteTimer->isActive() ) {
       
  1146 	d->deleteTimer->stop();
       
  1147 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1148     }
       
  1149     return d->protocolDetail;
       
  1150 }
       
  1151 
       
  1152 /*!
       
  1153     Returns the error code for the last error that occurred.
       
  1154 */
       
  1155 
       
  1156 int Q3NetworkOperation::errorCode() const
       
  1157 {
       
  1158     if ( d->deleteTimer->isActive() ) {
       
  1159 	d->deleteTimer->stop();
       
  1160 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1161     }
       
  1162     return d->errorCode;
       
  1163 }
       
  1164 
       
  1165 /*!
       
  1166   \internal
       
  1167 */
       
  1168 
       
  1169 QByteArray& Q3NetworkOperation::raw( int num ) const
       
  1170 {
       
  1171     if ( d->deleteTimer->isActive() ) {
       
  1172 	d->deleteTimer->stop();
       
  1173 	d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1174     }
       
  1175     return d->rawArgs[ num ];
       
  1176 }
       
  1177 
       
  1178 /*!
       
  1179     Sets this object to delete itself when it hasn't been used for one
       
  1180     second.
       
  1181 
       
  1182     Because Q3NetworkOperation pointers are passed around a lot the
       
  1183     Q3NetworkProtocol generally does not have enough knowledge to
       
  1184     delete these at the correct time. If a Q3NetworkProtocol doesn't
       
  1185     need an operation any more it will call this function instead.
       
  1186 
       
  1187     Note: you should never need to call the method yourself.
       
  1188 */
       
  1189 
       
  1190 void Q3NetworkOperation::free()
       
  1191 {
       
  1192     d->deleteTimer->start( NETWORK_OP_DELAY );
       
  1193 }
       
  1194 
       
  1195 /*!
       
  1196   \internal
       
  1197   Internal slot for auto-deletion.
       
  1198 */
       
  1199 
       
  1200 void Q3NetworkOperation::deleteMe()
       
  1201 {
       
  1202     delete this;
       
  1203 }
       
  1204 
       
  1205 QT_END_NAMESPACE
       
  1206 
       
  1207 #include "moc_q3networkprotocol.cpp"
       
  1208 
       
  1209 #endif