src/qt3support/network/q3urloperator.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 "q3urloperator.h"
       
    43 
       
    44 #ifndef QT_NO_NETWORKPROTOCOL
       
    45 
       
    46 #include "qurlinfo.h"
       
    47 #include "q3networkprotocol.h"
       
    48 #include "qmap.h"
       
    49 #include "qdir.h"
       
    50 #include "q3ptrdict.h"
       
    51 #include "qpointer.h"
       
    52 #include "q3valuelist.h"
       
    53 
       
    54 #include "qapplication.h"
       
    55 
       
    56 QT_BEGIN_NAMESPACE
       
    57 
       
    58 //#define Q3URLOPERATOR_DEBUG
       
    59 
       
    60 class Q3UrlOperatorPrivate
       
    61 {
       
    62 public:
       
    63     Q3UrlOperatorPrivate()
       
    64     {
       
    65 	oldOps.setAutoDelete( false );
       
    66 	networkProtocol = 0;
       
    67 	nameFilter = QLatin1String("*");
       
    68 	currPut = 0;
       
    69     }
       
    70 
       
    71     ~Q3UrlOperatorPrivate()
       
    72     {
       
    73 	delete networkProtocol;
       
    74 	while ( oldOps.first() ) {
       
    75 	    oldOps.first()->free();
       
    76 	    oldOps.removeFirst();
       
    77 	}
       
    78     }
       
    79 
       
    80     QMap<QString, QUrlInfo> entryMap;
       
    81     Q3NetworkProtocol *networkProtocol;
       
    82     QString nameFilter;
       
    83     QDir dir;
       
    84 
       
    85     // maps needed for copy/move operations
       
    86     Q3PtrDict<Q3NetworkOperation> getOpPutOpMap;
       
    87     Q3PtrDict<Q3NetworkProtocol> getOpPutProtMap;
       
    88     Q3PtrDict<Q3NetworkProtocol> getOpGetProtMap;
       
    89     Q3PtrDict<Q3NetworkOperation> getOpRemoveOpMap;
       
    90     QPointer<Q3NetworkProtocol> currPut;
       
    91     QStringList waitingCopies;
       
    92     QString waitingCopiesDest;
       
    93     bool waitingCopiesMove;
       
    94     Q3PtrList< Q3NetworkOperation > oldOps;
       
    95 };
       
    96 
       
    97 /*!
       
    98     \class Q3UrlOperator
       
    99 
       
   100     \brief The Q3UrlOperator class provides common operations on URLs.
       
   101 
       
   102     \compat
       
   103 
       
   104     \module network
       
   105 
       
   106     This class operates on hierarchical structures (such as
       
   107     filesystems) using URLs. Its API facilitates all the common
       
   108     operations:
       
   109     \table
       
   110     \header \i Operation	\i Function
       
   111     \row \i List files		\i \l listChildren()
       
   112     \row \i Make a directory	\i \l mkdir()
       
   113     \row \i Remove a file	\i \l remove()
       
   114     \row \i Rename a file	\i \l rename()
       
   115     \row \i Get a file		\i \l get()
       
   116     \row \i Put a file		\i \l put()
       
   117     \row \i Copy a file		\i \l copy()
       
   118     \endtable
       
   119 
       
   120     You can obtain additional information about the URL with isDir()
       
   121     and info(). If a directory is to be traversed using
       
   122     listChildren(), a name filter can be set with setNameFilter().
       
   123 
       
   124     A Q3UrlOperator can be used like this, for example to download a
       
   125     file (and assuming that the FTP protocol is registered):
       
   126     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 0
       
   127 
       
   128     If you want to be notified about success/failure, progress, etc.,
       
   129     you can connect to Q3UrlOperator's signals, e.g. to start(),
       
   130     newChildren(), createdDirectory(), removed(), data(),
       
   131     dataTransferProgress(), startedNextCopy(),
       
   132     connectionStateChanged(), finished(), etc. A network operation can
       
   133     be stopped with stop().
       
   134 
       
   135     The class uses the functionality of registered network protocols
       
   136     to perform these operations. Depending of the protocol of the URL,
       
   137     it uses an appropriate network protocol class for the operations.
       
   138     Each of the operation functions of Q3UrlOperator creates a
       
   139     Q3NetworkOperation object that describes the operation and puts it
       
   140     into the operation queue for the network protocol used. If no
       
   141     suitable protocol could be found (because no implementation of the
       
   142     necessary network protocol is registered), the URL operator emits
       
   143     errors. Not every protocol supports every operation, but error
       
   144     handling deals with this problem.
       
   145 
       
   146     To register the available network protocols, use the
       
   147     qInitNetworkProtocols() function. The protocols currently
       
   148     supported are:
       
   149     \list
       
   150     \i \link Q3Ftp FTP\endlink,
       
   151     \i \link Q3Http HTTP\endlink,
       
   152     \i \link Q3LocalFs local file system\endlink.
       
   153     \endlist
       
   154 
       
   155     \sa Q3NetworkProtocol, Q3NetworkOperation
       
   156 */
       
   157 
       
   158 /*!
       
   159     \fn void Q3UrlOperator::newChildren( const Q3ValueList<QUrlInfo> &i, Q3NetworkOperation *op )
       
   160 
       
   161     This signal is emitted after listChildren() was called and new
       
   162     children (i.e. files) have been read from a list of files. \a i
       
   163     holds the information about the new files. \a op is a pointer
       
   164     to the operation object which contains all the information about
       
   165     the operation, including the state.
       
   166 
       
   167     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   168 */
       
   169 
       
   170 
       
   171 /*!
       
   172     \fn void Q3UrlOperator::finished( Q3NetworkOperation *op )
       
   173 
       
   174     This signal is emitted when an operation of some sort finishes,
       
   175     whether with success or failure. \a op is a pointer to the
       
   176     operation object, which contains all the information, including
       
   177     the state, of the operation which has been finished. Check the
       
   178     state and error code of the operation object to see whether or not
       
   179     the operation was successful.
       
   180 
       
   181     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   182 */
       
   183 
       
   184 /*!
       
   185     \fn void Q3UrlOperator::start( Q3NetworkOperation *op )
       
   186 
       
   187     Some operations (such as listChildren()) emit this signal when
       
   188     they start processing the operation. \a op is a pointer to the
       
   189     operation object which contains all the information about the
       
   190     operation, including the state.
       
   191 
       
   192     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   193 */
       
   194 
       
   195 /*!
       
   196     \fn void Q3UrlOperator::createdDirectory( const QUrlInfo &i, Q3NetworkOperation *op )
       
   197 
       
   198     This signal is emitted when mkdir() succeeds and the directory has
       
   199     been created. \a i holds the information about the new directory.
       
   200 
       
   201     \a op is a pointer to the operation object, which contains all the
       
   202     information about the operation, including the state.
       
   203     \c op->arg(0) holds the new directory's name.
       
   204 
       
   205     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   206 */
       
   207 
       
   208 /*!
       
   209     \fn void Q3UrlOperator::removed( Q3NetworkOperation *op )
       
   210 
       
   211     This signal is emitted when remove() has been successful and the
       
   212     file has been removed.
       
   213 
       
   214     \a op is a pointer to the operation object which contains all the
       
   215     information about the operation, including the state.
       
   216     \c op->arg(0) holds the name of the file that was removed.
       
   217 
       
   218     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   219 */
       
   220 
       
   221 /*!
       
   222     \fn void Q3UrlOperator::itemChanged( Q3NetworkOperation *op )
       
   223 
       
   224     This signal is emitted whenever a file which is a child of the URL
       
   225     has been changed, for example by successfully calling rename().
       
   226     \a op is a pointer to the operation object which contains all the
       
   227     information about the operation, including the state.
       
   228     \c op->arg(0) holds the original file name and \c op->arg(1) holds
       
   229     the new file name (if it was changed).
       
   230 
       
   231     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   232 */
       
   233 
       
   234 /*!
       
   235     \fn void Q3UrlOperator::data( const QByteArray &data, Q3NetworkOperation *op )
       
   236 
       
   237     This signal is emitted when new \a data has been received after calling
       
   238     get() or put().
       
   239     \a op is a pointer to the operation object which contains all
       
   240     the information about the operation, including the state.
       
   241     \c op->arg(0) holds the name of the file whose data is retrieved
       
   242     and op->rawArg(1) holds the (raw) data.
       
   243 
       
   244     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   245 */
       
   246 
       
   247 /*!
       
   248     \fn void Q3UrlOperator::dataTransferProgress( int bytesDone, int bytesTotal, Q3NetworkOperation *op )
       
   249 
       
   250     This signal is emitted during data transfer (using put() or
       
   251     get()). \a bytesDone specifies how many bytes of \a bytesTotal have
       
   252     been transferred. More information about the operation is stored in
       
   253     \a op, a pointer to the network operation that is processed.
       
   254     \a bytesTotal may be -1, which means that the total number of bytes
       
   255     is not known.
       
   256 
       
   257     \sa Q3NetworkOperation, Q3NetworkProtocol
       
   258 */
       
   259 
       
   260 /*!
       
   261     \fn void Q3UrlOperator::startedNextCopy( const Q3PtrList<Q3NetworkOperation> &lst )
       
   262 
       
   263     This signal is emitted if copy() starts a new copy operation. \a
       
   264     lst contains all Q3NetworkOperations related to this copy
       
   265     operation.
       
   266 
       
   267     \sa copy()
       
   268 */
       
   269 
       
   270 /*!
       
   271     \fn void Q3UrlOperator::connectionStateChanged( int state, const QString &data )
       
   272 
       
   273     This signal is emitted whenever the URL operator's connection
       
   274     state changes. \a state describes the new state, which is a
       
   275     \l{Q3NetworkProtocol::ConnectionState} value.
       
   276 
       
   277     \a data is a string that describes the change of the connection.
       
   278     This can be used to display a message to the user.
       
   279 */
       
   280 
       
   281 /*!
       
   282     Constructs a Q3UrlOperator with an empty (i.e. invalid) URL.
       
   283 */
       
   284 
       
   285 Q3UrlOperator::Q3UrlOperator()
       
   286     : Q3Url()
       
   287 {
       
   288 #ifdef Q3URLOPERATOR_DEBUG
       
   289     qDebug( "Q3UrlOperator: cstr 1" );
       
   290 #endif
       
   291     d = new Q3UrlOperatorPrivate;
       
   292 }
       
   293 
       
   294 /*!
       
   295     Constructs a Q3UrlOperator using \a url and parses this string.
       
   296 
       
   297     If you pass strings like "/home/qt" the "file" protocol is
       
   298     assumed.
       
   299 */
       
   300 
       
   301 Q3UrlOperator::Q3UrlOperator( const QString &url )
       
   302     : Q3Url( url )
       
   303 {
       
   304 #ifdef Q3URLOPERATOR_DEBUG
       
   305     qDebug( "Q3UrlOperator: cstr 2" );
       
   306 #endif
       
   307     d = new Q3UrlOperatorPrivate;
       
   308     getNetworkProtocol();
       
   309 }
       
   310 
       
   311 /*!
       
   312     Constructs a copy of \a url.
       
   313 */
       
   314 
       
   315 Q3UrlOperator::Q3UrlOperator( const Q3UrlOperator& url )
       
   316     : QObject(), Q3Url( url )
       
   317 {
       
   318 #ifdef Q3URLOPERATOR_DEBUG
       
   319     qDebug( "Q3UrlOperator: cstr 3" );
       
   320 #endif
       
   321     d = new Q3UrlOperatorPrivate;
       
   322     *d = *url.d;
       
   323 
       
   324     d->networkProtocol = 0;
       
   325     getNetworkProtocol();
       
   326     d->nameFilter = QLatin1String("*");
       
   327     d->currPut = 0;
       
   328 }
       
   329 
       
   330 /*!
       
   331     Constructs a Q3UrlOperator. The URL on which this Q3UrlOperator
       
   332     operates is constructed out of the arguments \a url, \a relUrl and
       
   333     \a checkSlash: see the corresponding Q3Url constructor for an
       
   334     explanation of these arguments.
       
   335 */
       
   336 
       
   337 Q3UrlOperator::Q3UrlOperator( const Q3UrlOperator& url, const QString& relUrl, bool checkSlash )
       
   338     : Q3Url( url, relUrl, checkSlash )
       
   339 {
       
   340 #ifdef Q3URLOPERATOR_DEBUG
       
   341     qDebug( "Q3UrlOperator: cstr 4" );
       
   342 #endif
       
   343     d = new Q3UrlOperatorPrivate;
       
   344     if ( relUrl == QLatin1String(".") )
       
   345 	*d = *url.d;
       
   346 
       
   347     d->networkProtocol = 0;
       
   348     getNetworkProtocol();
       
   349     d->currPut = 0;
       
   350 }
       
   351 
       
   352 /*!
       
   353     Destructor.
       
   354 */
       
   355 
       
   356 Q3UrlOperator::~Q3UrlOperator()
       
   357 {
       
   358 #ifdef Q3URLOPERATOR_DEBUG
       
   359     qDebug( "Q3UrlOperator: dstr" );
       
   360 #endif
       
   361     delete d;
       
   362 }
       
   363 
       
   364 /*!
       
   365     This private function is used by the simple operation functions,
       
   366     i.e. listChildren(), mkdir(), remove(), rename(), get() and put(),
       
   367     to really start the operation. \a op is a pointer to the network
       
   368     operation that should be started. Returns \a op on success;
       
   369     otherwise returns 0.
       
   370 */
       
   371 const Q3NetworkOperation *Q3UrlOperator::startOperation( Q3NetworkOperation *op )
       
   372 {
       
   373     if ( !d->networkProtocol )
       
   374         getNetworkProtocol();
       
   375     
       
   376     if ( d->networkProtocol && (d->networkProtocol->supportedOperations()&op->operation()) ) {
       
   377 	d->networkProtocol->addOperation( op );
       
   378 	if ( op->operation() == Q3NetworkProtocol::OpListChildren )
       
   379 	    clearEntries();
       
   380         return op;
       
   381     }
       
   382 
       
   383     // error
       
   384     QString msg;
       
   385     if ( !d->networkProtocol ) {
       
   386 	msg = tr( "The protocol `%1' is not supported" ).arg( protocol() );
       
   387     } else {
       
   388 	switch ( op->operation() ) {
       
   389 	case Q3NetworkProtocol::OpListChildren:
       
   390 	    msg = tr( "The protocol `%1' does not support listing directories" ).arg( protocol() );
       
   391 	    break;
       
   392 	case Q3NetworkProtocol::OpMkDir:
       
   393 	    msg = tr( "The protocol `%1' does not support creating new directories" ).arg( protocol() );
       
   394 	    break;
       
   395 	case Q3NetworkProtocol::OpRemove:
       
   396 	    msg = tr( "The protocol `%1' does not support removing files or directories" ).arg( protocol() );
       
   397 	    break;
       
   398 	case Q3NetworkProtocol::OpRename:
       
   399 	    msg = tr( "The protocol `%1' does not support renaming files or directories" ).arg( protocol() );
       
   400 	    break;
       
   401 	case Q3NetworkProtocol::OpGet:
       
   402 	    msg = tr( "The protocol `%1' does not support getting files" ).arg( protocol() );
       
   403 	    break;
       
   404 	case Q3NetworkProtocol::OpPut:
       
   405 	    msg = tr( "The protocol `%1' does not support putting files" ).arg( protocol() );
       
   406 	    break;
       
   407 	default:
       
   408 	    // this should never happen
       
   409 	    break;
       
   410 	}
       
   411     }
       
   412     op->setState( Q3NetworkProtocol::StFailed );
       
   413     op->setProtocolDetail( msg );
       
   414     op->setErrorCode( (int)Q3NetworkProtocol::ErrUnsupported );
       
   415     emit finished( op );
       
   416     deleteOperation( op );
       
   417     return 0;
       
   418 }
       
   419 
       
   420 /*!
       
   421     Starts listing the children of this URL (e.g. the files in the
       
   422     directory). The start() signal is emitted before the first entry
       
   423     is listed and finished() is emitted after the last one. The
       
   424     newChildren() signal is emitted for each list of new entries. If
       
   425     an error occurs, the signal finished() is emitted, so be sure to
       
   426     check the state of the network operation pointer.
       
   427 
       
   428     Because the operation may not be executed immediately, a pointer
       
   429     to the Q3NetworkOperation object created by this function is
       
   430     returned. This object contains all the data about the operation
       
   431     and is used to refer to this operation later (e.g. in the signals
       
   432     that are emitted by the Q3UrlOperator). The return value can also
       
   433     be 0 if the operation object couldn't be created.
       
   434 
       
   435     The path of this Q3UrlOperator must to point to a directory
       
   436     (because the children of this directory will be listed), not to a
       
   437     file.
       
   438 */
       
   439 
       
   440 const Q3NetworkOperation *Q3UrlOperator::listChildren()
       
   441 {
       
   442     if ( !checkValid() )
       
   443 	return 0;
       
   444 
       
   445     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpListChildren, QString(), QString(), QString() );
       
   446     return startOperation( res );
       
   447 }
       
   448 
       
   449 /*!
       
   450     Tries to create a directory (child) with the name \a dirname. If
       
   451     it is successful, a newChildren() signal with the new child is
       
   452     emitted, and the createdDirectory() signal with the information
       
   453     about the new child is also emitted. The finished() signal (with
       
   454     success or failure) is emitted after the operation has been
       
   455     processed, so check the state of the network operation object to
       
   456     see whether or not the operation was successful.
       
   457 
       
   458     Because the operation will not be executed immediately, a pointer
       
   459     to the Q3NetworkOperation object created by this function is
       
   460     returned. This object contains all the data about the operation
       
   461     and is used to refer to this operation later (e.g. in the signals
       
   462     that are emitted by the Q3UrlOperator). The return value can also
       
   463     be 0 if the operation object couldn't be created.
       
   464 
       
   465     The path of this Q3UrlOperator must to point to a directory (not a
       
   466     file) because the new directory will be created in this path.
       
   467 */
       
   468 
       
   469 const Q3NetworkOperation *Q3UrlOperator::mkdir( const QString &dirname )
       
   470 {
       
   471     if ( !checkValid() )
       
   472 	return 0;
       
   473 
       
   474     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpMkDir, dirname, QString(), QString() );
       
   475     return startOperation( res );
       
   476 }
       
   477 
       
   478 /*!
       
   479     Tries to remove the file (child) \a filename. If it succeeds the
       
   480     removed() signal is emitted. finished() (with success or failure)
       
   481     is also emitted after the operation has been processed, so check
       
   482     the state of the network operation object to see whether or not
       
   483     the operation was successful.
       
   484 
       
   485     Because the operation will not be executed immediately, a pointer
       
   486     to the Q3NetworkOperation object created by this function is
       
   487     returned. This object contains all the data about the operation
       
   488     and is used to refer to this operation later (e.g. in the signals
       
   489     that are emitted by the Q3UrlOperator). The return value can also
       
   490     be 0 if the operation object couldn't be created.
       
   491 
       
   492     The path of this Q3UrlOperator must point to a directory; because
       
   493     if \a filename is relative, it will try to remove it in this
       
   494     directory.
       
   495 */
       
   496 
       
   497 const Q3NetworkOperation *Q3UrlOperator::remove( const QString &filename )
       
   498 {
       
   499     if ( !checkValid() )
       
   500 	return 0;
       
   501 
       
   502     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpRemove, filename, QString(), QString() );
       
   503     return startOperation( res );
       
   504 }
       
   505 
       
   506 /*!
       
   507     Tries to rename the file (child) called \a oldname to \a newname.
       
   508     If it succeeds, the itemChanged() signal is emitted. finished()
       
   509     (with success or failure) is also emitted after the operation has
       
   510     been processed, so check the state of the network operation object
       
   511     to see whether or not the operation was successful.
       
   512 
       
   513     Because the operation may not be executed immediately, a pointer
       
   514     to the Q3NetworkOperation object created by this function is
       
   515     returned. This object contains all the data about the operation
       
   516     and is used to refer to this operation later (e.g. in the signals
       
   517     that are emitted by the Q3UrlOperator). The return value can also
       
   518     be 0 if the operation object couldn't be created.
       
   519 
       
   520     This path of this Q3UrlOperator must to point to a directory
       
   521     because \a oldname and \a newname are handled relative to this
       
   522     directory.
       
   523 */
       
   524 
       
   525 const Q3NetworkOperation *Q3UrlOperator::rename( const QString &oldname, const QString &newname )
       
   526 {
       
   527     if ( !checkValid() )
       
   528 	return 0;
       
   529 
       
   530     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpRename, oldname, newname, QString() );
       
   531     return startOperation( res );
       
   532 }
       
   533 
       
   534 /*!
       
   535     Copies the file \a from to \a to. If \a move is true, the file is
       
   536     moved (copied and removed). \a from must point to a file and \a to
       
   537     must point to a directory (into which \a from is copied) unless \a
       
   538     toPath is set to false. If \a toPath is set to false then the \a
       
   539     to variable is assumed to be the absolute file path (destination
       
   540     file path + file name). The copying is done using the get() and
       
   541     put() operations. If you want to be notified about the progress of
       
   542     the operation, connect to the dataTransferProgress() signal. Bear
       
   543     in mind that the get() and put() operations emit this signal
       
   544     through the Q3UrlOperator. The number of transferred bytes and the
       
   545     total bytes that you receive as arguments in this signal do not
       
   546     relate to the whole copy operation; they relate first to the
       
   547     get() and then to the put() operation. Always check what type of
       
   548     operation the signal comes from; this is given in the signal's
       
   549     last argument.
       
   550 
       
   551     At the end, finished() (with success or failure) is emitted, so
       
   552     check the state of the network operation object to see whether or
       
   553     not the operation was successful.
       
   554 
       
   555     Because a move or copy operation consists of multiple operations
       
   556     (get(), put() and maybe remove()), this function doesn't return a
       
   557     single Q3NetworkOperation, but rather a list of them. They are in
       
   558     the order: get(), put() and (if applicable) remove().
       
   559 
       
   560     \sa get(), put()
       
   561 */
       
   562 
       
   563 Q3PtrList<Q3NetworkOperation> Q3UrlOperator::copy( const QString &from, const QString &to, bool move, bool toPath )
       
   564 {
       
   565 #ifdef Q3URLOPERATOR_DEBUG
       
   566     qDebug( "Q3UrlOperator: copy %s %s %d", from.latin1(), to.latin1(), move );
       
   567 #endif
       
   568 
       
   569     Q3PtrList<Q3NetworkOperation> ops;
       
   570     ops.setAutoDelete( false );
       
   571 
       
   572     Q3UrlOperator *uFrom = new Q3UrlOperator( *this, from );
       
   573     Q3UrlOperator *uTo = new Q3UrlOperator( to );
       
   574 
       
   575     // prepare some string for later usage
       
   576     QString frm = *uFrom;
       
   577     QString file = uFrom->fileName();
       
   578 
       
   579     if (frm == to + file)
       
   580          return ops;
       
   581     
       
   582     file.prepend( QLatin1Char('/') );
       
   583 
       
   584     // uFrom and uTo are deleted when the Q3NetworkProtocol deletes itself via
       
   585     // autodelete
       
   586     uFrom->getNetworkProtocol();
       
   587     uTo->getNetworkProtocol();
       
   588     Q3NetworkProtocol *gProt = uFrom->d->networkProtocol;
       
   589     Q3NetworkProtocol *pProt = uTo->d->networkProtocol;
       
   590 
       
   591     uFrom->setPath( uFrom->dirPath() );
       
   592 
       
   593     if ( gProt && (gProt->supportedOperations()&Q3NetworkProtocol::OpGet) &&
       
   594 	 pProt && (pProt->supportedOperations()&Q3NetworkProtocol::OpPut) ) {
       
   595 
       
   596 	connect( gProt, SIGNAL(data(QByteArray,Q3NetworkOperation*)),
       
   597 		 this, SLOT(copyGotData(QByteArray,Q3NetworkOperation*)) );
       
   598 	connect( gProt, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)),
       
   599 		 this, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)) );
       
   600 	connect( gProt, SIGNAL(finished(Q3NetworkOperation*)),
       
   601 		 this, SLOT(continueCopy(Q3NetworkOperation*)) );
       
   602 	connect( gProt, SIGNAL(finished(Q3NetworkOperation*)),
       
   603 		 this, SIGNAL(finished(Q3NetworkOperation*)) );
       
   604 	connect( gProt, SIGNAL(connectionStateChanged(int,QString)),
       
   605 		 this, SIGNAL(connectionStateChanged(int,QString)) );
       
   606 
       
   607 	connect( pProt, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)),
       
   608 		 this, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)) );
       
   609 	connect( pProt, SIGNAL(finished(Q3NetworkOperation*)),
       
   610 		 this, SIGNAL(finished(Q3NetworkOperation*)) );
       
   611 	connect( pProt, SIGNAL(finished(Q3NetworkOperation*)),
       
   612 		 this, SLOT(finishedCopy()) );
       
   613 
       
   614 	Q3NetworkOperation *opGet = new Q3NetworkOperation( Q3NetworkProtocol::OpGet, frm, QString(), QString() );
       
   615 	ops.append( opGet );
       
   616 	gProt->addOperation( opGet );
       
   617 
       
   618 
       
   619 	QString toFile = to + file;
       
   620 	if (!toPath)
       
   621 	    toFile = to;
       
   622 
       
   623 	Q3NetworkOperation *opPut = new Q3NetworkOperation( Q3NetworkProtocol::OpPut, toFile, QString(), QString() );
       
   624 	ops.append( opPut );
       
   625 
       
   626 	d->getOpPutProtMap.insert( (void*)opGet, pProt );
       
   627 	d->getOpGetProtMap.insert( (void*)opGet, gProt );
       
   628 	d->getOpPutOpMap.insert( (void*)opGet, opPut );
       
   629 
       
   630 	if ( move && (gProt->supportedOperations()&Q3NetworkProtocol::OpRemove) ) {
       
   631 	    gProt->setAutoDelete( false );
       
   632 
       
   633 	    Q3NetworkOperation *opRm = new Q3NetworkOperation( Q3NetworkProtocol::OpRemove, frm, QString(), QString() );
       
   634 	    ops.append( opRm );
       
   635 	    d->getOpRemoveOpMap.insert( (void*)opGet, opRm );
       
   636 	} else {
       
   637 	    gProt->setAutoDelete( true );
       
   638 	}
       
   639 #ifdef Q3URLOPERATOR_DEBUG
       
   640 	qDebug( "Q3UrlOperator: copy operation should start now..." );
       
   641 #endif
       
   642 	return ops;
       
   643     } else {
       
   644 	QString msg;
       
   645 	if ( !gProt ) {
       
   646 	    msg = tr( "The protocol `%1' is not supported" ).arg( uFrom->protocol() );
       
   647 	} else if ( gProt->supportedOperations() & Q3NetworkProtocol::OpGet ) {
       
   648 	    msg = tr( "The protocol `%1' does not support copying or moving files or directories" ).arg( uFrom->protocol() );
       
   649 	} else if ( !pProt ) {
       
   650 	    msg = tr( "The protocol `%1' is not supported" ).arg( uTo->protocol() );
       
   651 	} else {
       
   652 	    msg = tr( "The protocol `%1' does not support copying or moving files or directories" ).arg( uTo->protocol() );
       
   653 	}
       
   654 	delete uFrom;
       
   655 	delete uTo;
       
   656 	Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpGet, frm, to, QString() );
       
   657 	res->setState( Q3NetworkProtocol::StFailed );
       
   658 	res->setProtocolDetail( msg );
       
   659 	res->setErrorCode( (int)Q3NetworkProtocol::ErrUnsupported );
       
   660 	emit finished( res );
       
   661 	deleteOperation( res );
       
   662     }
       
   663 
       
   664     return ops;
       
   665 }
       
   666 
       
   667 /*!
       
   668     \overload
       
   669 
       
   670     Copies the \a files to the directory \a dest. If \a move is true
       
   671     the files are moved, not copied. \a dest must point to a
       
   672     directory.
       
   673 
       
   674     This function calls copy() for each entry in \a files in turn. You
       
   675     don't get a result from this function; each time a new copy
       
   676     begins, startedNextCopy() is emitted, with a list of
       
   677     Q3NetworkOperations that describe the new copy operation.
       
   678 */
       
   679 
       
   680 void Q3UrlOperator::copy( const QStringList &files, const QString &dest,
       
   681 			 bool move )
       
   682 {
       
   683     d->waitingCopies = files;
       
   684     d->waitingCopiesDest = dest;
       
   685     d->waitingCopiesMove = move;
       
   686 
       
   687     finishedCopy();
       
   688 }
       
   689 
       
   690 /*!
       
   691     Returns true if the URL is a directory; otherwise returns false.
       
   692     This may not always work correctly, if the protocol of the URL is
       
   693     something other than file (local filesystem). If you pass a bool
       
   694     pointer as the \a ok argument, *\a ok is set to true if the result
       
   695     of this function is known to be correct, and to false otherwise.
       
   696 */
       
   697 
       
   698 bool Q3UrlOperator::isDir( bool *ok )
       
   699 {
       
   700     if ( ok )
       
   701 	*ok = true;
       
   702     if ( isLocalFile() ) {
       
   703 	if ( QFileInfo( path() ).isDir() )
       
   704 	    return true;
       
   705 	else
       
   706 	    return false;
       
   707     }
       
   708 
       
   709     if ( d->entryMap.contains( QLatin1String(".") ) ) {
       
   710 	return d->entryMap[ QLatin1String(".") ].isDir();
       
   711     }
       
   712     // #### can assume that we are a directory?
       
   713     if ( ok )
       
   714 	*ok = false;
       
   715     return true;
       
   716 }
       
   717 
       
   718 /*!
       
   719     Tells the network protocol to get data from \a location or, if
       
   720     it is empty, to get data from the location to which this
       
   721     URL points (see Q3Url::fileName() and Q3Url::encodedPathAndQuery()).
       
   722     What happens then depends on the network protocol. The data()
       
   723     signal is emitted when data comes in. Because it's unlikely that
       
   724     all data will come in at once, it is common for multiple data()
       
   725     signals to be emitted. The dataTransferProgress() signal is
       
   726     emitted while processing the operation. At the end, finished()
       
   727     (with success or failure) is emitted, so check the state of the
       
   728     network operation object to see whether or not the operation was
       
   729     successful.
       
   730 
       
   731     If \a location is empty, the path of this Q3UrlOperator
       
   732     should point to a file when you use this operation. If \a location
       
   733     is not empty, it can be a relative URL (a child of the path to
       
   734     which the Q3UrlOperator points) or an absolute URL.
       
   735 
       
   736     For example, to get a web page you might do something like this:
       
   737 
       
   738     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 1
       
   739 
       
   740     For most other operations, the path of the Q3UrlOperator must point
       
   741     to a directory. If you want to download a file you could do the
       
   742     following:
       
   743 
       
   744     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 2
       
   745 
       
   746     This will get the data of ftp://ftp.whatever.org/pub/a_file.txt.
       
   747 
       
   748     \e Never do anything like this:
       
   749     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 3
       
   750 
       
   751     If \a location is not empty and relative it must not contain any
       
   752     queries or references, just the name of a child. So if you need to
       
   753     specify a query or reference, do it as shown in the first example
       
   754     or specify the full URL (such as
       
   755     http://www.whatever.org/cgi-bin/search.pl?cmd=Hello) as \a location.
       
   756 
       
   757     \sa copy()
       
   758 */
       
   759 
       
   760 const Q3NetworkOperation *Q3UrlOperator::get( const QString &location )
       
   761 {
       
   762     Q3Url u( *this );
       
   763     if ( !location.isEmpty() )
       
   764 	u = Q3Url( *this, location );
       
   765 
       
   766     if ( !u.isValid() )
       
   767 	return 0;
       
   768 
       
   769     if ( !d->networkProtocol ) {
       
   770 	setProtocol( u.protocol() );
       
   771 	getNetworkProtocol();
       
   772     }
       
   773 
       
   774     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpGet, u, QString(), QString() );
       
   775     return startOperation( res );
       
   776 }
       
   777 
       
   778 /*!
       
   779     This function tells the network protocol to put \a data in \a
       
   780     location. If \a location is empty, it puts the \a data in the
       
   781     location to which the URL points. What happens depends on
       
   782     the network protocol. Depending on the network protocol, some
       
   783     data might come back after putting data, in which case the data()
       
   784     signal is emitted. The dataTransferProgress() signal is emitted
       
   785     during processing of the operation. At the end, finished() (with
       
   786     success or failure) is emitted, so check the state of the network
       
   787     operation object to see whether or not the operation was
       
   788     successful.
       
   789 
       
   790     If \a location is empty, the path of this Q3UrlOperator should
       
   791     point to a file when you use this operation. If \a location
       
   792     is not empty, it can be a relative (a child of the path to which
       
   793     the Q3UrlOperator points) or an absolute URL.
       
   794 
       
   795     For putting some data to a file you can do the following:
       
   796 
       
   797     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 4
       
   798 
       
   799     For most other operations, the path of the Q3UrlOperator must point
       
   800     to a directory. If you want to upload data to a file you could do
       
   801     the following:
       
   802 
       
   803     \snippet doc/src/snippets/code/src_qt3support_network_q3urloperator.cpp 5
       
   804 
       
   805     This will upload the data to ftp://ftp.whatever.com/home/me/filename.dat.
       
   806 
       
   807     \sa copy()
       
   808 */
       
   809 
       
   810 const Q3NetworkOperation *Q3UrlOperator::put( const QByteArray &data, const QString &location )
       
   811 {
       
   812     Q3Url u( *this );
       
   813     if ( !location.isEmpty() )
       
   814 	u = Q3Url( *this, location );
       
   815 
       
   816     if ( !u.isValid() )
       
   817 	return 0;
       
   818 
       
   819     if ( !d->networkProtocol ) {
       
   820 	setProtocol( u.protocol() );
       
   821 	getNetworkProtocol();
       
   822     }
       
   823 
       
   824     Q3NetworkOperation *res = new Q3NetworkOperation( Q3NetworkProtocol::OpPut, u, QString(), QString() );
       
   825     res->setRawArg( 1, data );
       
   826     return startOperation( res );
       
   827 }
       
   828 
       
   829 /*!
       
   830     Sets the name filter of the URL to \a nameFilter.
       
   831 
       
   832     \sa QDir::setNameFilter()
       
   833 */
       
   834 
       
   835 void Q3UrlOperator::setNameFilter( const QString &nameFilter )
       
   836 {
       
   837     d->nameFilter = nameFilter;
       
   838 }
       
   839 
       
   840 /*!
       
   841     Returns the name filter of the URL.
       
   842 
       
   843     \sa Q3UrlOperator::setNameFilter() QDir::nameFilter()
       
   844 */
       
   845 
       
   846 QString Q3UrlOperator::nameFilter() const
       
   847 {
       
   848     return d->nameFilter;
       
   849 }
       
   850 
       
   851 /*!
       
   852     Clears the cache of children.
       
   853 */
       
   854 
       
   855 void Q3UrlOperator::clearEntries()
       
   856 {
       
   857     d->entryMap.clear();
       
   858 }
       
   859 
       
   860 /*!
       
   861     Adds an entry to the cache of children.
       
   862 */
       
   863 
       
   864 void Q3UrlOperator::addEntry( const Q3ValueList<QUrlInfo> &i )
       
   865 {
       
   866     Q3ValueList<QUrlInfo>::ConstIterator it = i.begin();
       
   867     for ( ; it != i.end(); ++it )
       
   868 	d->entryMap[ ( *it ).name().stripWhiteSpace() ] = *it;
       
   869 }
       
   870 
       
   871 /*!
       
   872     Returns the URL information for the child \a entry, or returns an
       
   873     empty QUrlInfo object if there is no information available about
       
   874     \a entry. Information about \a entry is only available after a successfully
       
   875     finished listChildren() operation.
       
   876 */
       
   877 
       
   878 QUrlInfo Q3UrlOperator::info( const QString &entry ) const
       
   879 {
       
   880     if ( d->entryMap.contains( entry.stripWhiteSpace() ) ) {
       
   881 	return d->entryMap[ entry.stripWhiteSpace() ];
       
   882     } else if ( entry == QLatin1String(".") || entry == QLatin1String("..") ) {
       
   883 	 // return a faked QUrlInfo
       
   884 	 QUrlInfo inf;
       
   885 	 inf.setName( entry );
       
   886 	 inf.setDir( true );
       
   887 	 inf.setFile( false );
       
   888 	 inf.setSymLink( false );
       
   889 	 inf.setOwner( tr( "(unknown)" ) );
       
   890 	 inf.setGroup( tr( "(unknown)" ) );
       
   891 	 inf.setSize( 0 );
       
   892 	 inf.setWritable( false );
       
   893 	 inf.setReadable( true );
       
   894 	 return inf;
       
   895     }
       
   896     return QUrlInfo();
       
   897 }
       
   898 
       
   899 /*!
       
   900     Finds a network protocol for the URL and deletes the old network protocol.
       
   901 */
       
   902 
       
   903 void Q3UrlOperator::getNetworkProtocol()
       
   904 {
       
   905     delete d->networkProtocol;
       
   906     Q3NetworkProtocol *p = Q3NetworkProtocol::getNetworkProtocol( protocol() );
       
   907     if ( !p ) {
       
   908 	d->networkProtocol = 0;
       
   909 	return;
       
   910     }
       
   911 
       
   912     d->networkProtocol = (Q3NetworkProtocol *)p;
       
   913     d->networkProtocol->setUrl( this );
       
   914     connect( d->networkProtocol, SIGNAL(itemChanged(Q3NetworkOperation*)),
       
   915 	     this, SLOT(slotItemChanged(Q3NetworkOperation*)) );
       
   916 }
       
   917 
       
   918 /*!
       
   919     Deletes the currently used network protocol.
       
   920 */
       
   921 
       
   922 void Q3UrlOperator::deleteNetworkProtocol()
       
   923 {
       
   924     if (d->networkProtocol) {
       
   925         d->networkProtocol->deleteLater();
       
   926         d->networkProtocol = 0;
       
   927     }
       
   928 }
       
   929 
       
   930 /*!
       
   931     \reimp
       
   932 */
       
   933 
       
   934 void Q3UrlOperator::setPath( const QString& path )
       
   935 {
       
   936     Q3Url::setPath( path );
       
   937     if ( d->networkProtocol )
       
   938 	d->networkProtocol->setUrl( this );
       
   939 }
       
   940 
       
   941 /*!
       
   942     \reimp
       
   943 */
       
   944 
       
   945 void Q3UrlOperator::reset()
       
   946 {
       
   947     Q3Url::reset();
       
   948     deleteNetworkProtocol();
       
   949     d->nameFilter = QLatin1String("*");
       
   950 }
       
   951 
       
   952 /*!
       
   953     \reimp
       
   954 */
       
   955 
       
   956 bool Q3UrlOperator::parse( const QString &url )
       
   957 {
       
   958     bool b = Q3Url::parse( url );
       
   959     if ( !b ) {
       
   960 	return b;
       
   961     }
       
   962 
       
   963     getNetworkProtocol();
       
   964 
       
   965     return b;
       
   966 }
       
   967 
       
   968 /*!
       
   969     Assigns \a url to this object.
       
   970 */
       
   971 
       
   972 Q3UrlOperator& Q3UrlOperator::operator=( const Q3UrlOperator &url )
       
   973 {
       
   974     deleteNetworkProtocol();
       
   975     Q3Url::operator=( url );
       
   976 
       
   977     Q3PtrDict<Q3NetworkOperation> getOpPutOpMap = d->getOpPutOpMap;
       
   978     Q3PtrDict<Q3NetworkProtocol> getOpPutProtMap = d->getOpPutProtMap;
       
   979     Q3PtrDict<Q3NetworkProtocol> getOpGetProtMap = d->getOpGetProtMap;
       
   980     Q3PtrDict<Q3NetworkOperation> getOpRemoveOpMap = d->getOpRemoveOpMap;
       
   981 
       
   982     *d = *url.d;
       
   983 
       
   984     d->oldOps.setAutoDelete( false );
       
   985     d->getOpPutOpMap = getOpPutOpMap;
       
   986     d->getOpPutProtMap = getOpPutProtMap;
       
   987     d->getOpGetProtMap = getOpGetProtMap;
       
   988     d->getOpRemoveOpMap = getOpRemoveOpMap;
       
   989 
       
   990     d->networkProtocol = 0;
       
   991     getNetworkProtocol();
       
   992     return *this;
       
   993 }
       
   994 
       
   995 /*!
       
   996     Assigns \a url to this object.
       
   997 */
       
   998 
       
   999 Q3UrlOperator& Q3UrlOperator::operator=( const QString &url )
       
  1000 {
       
  1001     deleteNetworkProtocol();
       
  1002     Q3Url::operator=( url );
       
  1003     d->oldOps.setAutoDelete( false );
       
  1004     getNetworkProtocol();
       
  1005     return *this;
       
  1006 }
       
  1007 
       
  1008 /*!
       
  1009     \internal
       
  1010 */
       
  1011 
       
  1012 bool Q3UrlOperator::cdUp()
       
  1013 {
       
  1014     bool b = Q3Url::cdUp();
       
  1015     if ( d->networkProtocol )
       
  1016 	d->networkProtocol->setUrl( this );
       
  1017     return b;
       
  1018 }
       
  1019 
       
  1020 /*!
       
  1021     \internal
       
  1022 */
       
  1023 
       
  1024 bool Q3UrlOperator::checkValid()
       
  1025 {
       
  1026     // ######
       
  1027     if ( !isValid() ) {
       
  1028 	//emit error( ErrValid, tr( "The entered URL is not valid!" ) );
       
  1029 	return false;
       
  1030     } else
       
  1031 	return true;
       
  1032 }
       
  1033 
       
  1034 
       
  1035 /*!
       
  1036     \internal
       
  1037 */
       
  1038 
       
  1039 void Q3UrlOperator::copyGotData( const QByteArray &data_, Q3NetworkOperation *op )
       
  1040 {
       
  1041 #ifdef Q3URLOPERATOR_DEBUG
       
  1042     qDebug( "Q3UrlOperator: copyGotData: %d new bytes", data_.size() );
       
  1043 #endif
       
  1044     Q3NetworkOperation *put = d->getOpPutOpMap[ (void*)op ];
       
  1045     if ( put ) {
       
  1046 	QByteArray &s = put->raw( 1 );
       
  1047 	int size = s.size();
       
  1048 	s.resize( size + data_.size() );
       
  1049 	memcpy( s.data() + size, data_.data(), data_.size() );
       
  1050     }
       
  1051     emit data( data_, op );
       
  1052 }
       
  1053 
       
  1054 /*!
       
  1055     \internal
       
  1056 */
       
  1057 
       
  1058 void Q3UrlOperator::continueCopy( Q3NetworkOperation *op )
       
  1059 {
       
  1060     if ( op->operation() != Q3NetworkProtocol::OpGet )
       
  1061 	return;
       
  1062     if ( op->state()!=Q3NetworkProtocol::StDone &&  op->state()!=Q3NetworkProtocol::StFailed ) {
       
  1063 	return;
       
  1064     }
       
  1065 
       
  1066 #ifdef Q3URLOPERATOR_DEBUG
       
  1067     if ( op->state() != Q3NetworkProtocol::StFailed ) {
       
  1068 	qDebug( "Q3UrlOperator: continue copy (get finished, put will start)" );
       
  1069     }
       
  1070 #endif
       
  1071 
       
  1072     Q3NetworkOperation *put = d->getOpPutOpMap[ (void*)op ];
       
  1073     Q3NetworkProtocol *gProt = d->getOpGetProtMap[ (void*)op ];
       
  1074     Q3NetworkProtocol *pProt = d->getOpPutProtMap[ (void*)op ];
       
  1075     Q3NetworkOperation *rm = d->getOpRemoveOpMap[ (void*)op ];
       
  1076     d->getOpPutOpMap.take( op );
       
  1077     d->getOpGetProtMap.take( op );
       
  1078     d->getOpPutProtMap.take( op );
       
  1079     d->getOpRemoveOpMap.take( op );
       
  1080     if ( pProt )
       
  1081 	pProt->setAutoDelete( true );
       
  1082     if ( put && pProt ) {
       
  1083 	if ( op->state() != Q3NetworkProtocol::StFailed ) {
       
  1084 	    pProt->addOperation( put );
       
  1085 	    d->currPut = pProt;
       
  1086         if (rm) { // we need the result of the put operation
       
  1087             qApp->processEvents(); // process posted operations
       
  1088             if (put->state() == Q3NetworkProtocol::StFailed) {
       
  1089                 deleteOperation( rm );
       
  1090                 rm = 0;
       
  1091             }
       
  1092         }
       
  1093 	} else {
       
  1094 	    deleteOperation( put );
       
  1095 	}
       
  1096     }
       
  1097     if ( gProt ) {
       
  1098 	gProt->setAutoDelete( true );
       
  1099     }
       
  1100     if ( rm && gProt ) {
       
  1101 	if ( op->state() != Q3NetworkProtocol::StFailed ) {
       
  1102 	    gProt->addOperation( rm );
       
  1103 	} else {
       
  1104 	    deleteOperation( rm );
       
  1105 	}
       
  1106     }
       
  1107     disconnect( gProt, SIGNAL(data(QByteArray,Q3NetworkOperation*)),
       
  1108 		this, SLOT(copyGotData(QByteArray,Q3NetworkOperation*)) );
       
  1109     disconnect( gProt, SIGNAL(finished(Q3NetworkOperation*)),
       
  1110 		this, SLOT(continueCopy(Q3NetworkOperation*)) );
       
  1111 }
       
  1112 
       
  1113 /*!
       
  1114     \internal
       
  1115 */
       
  1116 
       
  1117 void Q3UrlOperator::finishedCopy()
       
  1118 {
       
  1119 #ifdef Q3URLOPERATOR_DEBUG
       
  1120     qDebug( "Q3UrlOperator: finished copy (finished putting)" );
       
  1121 #endif
       
  1122 
       
  1123     if ( d->waitingCopies.isEmpty() )
       
  1124 	return;
       
  1125 
       
  1126     QString cp = d->waitingCopies.first();
       
  1127     d->waitingCopies.remove( cp );
       
  1128     Q3PtrList<Q3NetworkOperation> lst = copy( cp, d->waitingCopiesDest, d->waitingCopiesMove );
       
  1129     emit startedNextCopy( lst );
       
  1130 }
       
  1131 
       
  1132 /*!
       
  1133     Stops the current network operation and removes all this
       
  1134     Q3UrlOperator's waiting network operations.
       
  1135 */
       
  1136 
       
  1137 void Q3UrlOperator::stop()
       
  1138 {
       
  1139     d->getOpPutOpMap.clear();
       
  1140     d->getOpRemoveOpMap.clear();
       
  1141     d->getOpGetProtMap.setAutoDelete( true );
       
  1142     d->getOpPutProtMap.setAutoDelete( true );
       
  1143     Q3PtrDictIterator<Q3NetworkProtocol> it( d->getOpPutProtMap );
       
  1144     for ( ; it.current(); ++it )
       
  1145 	it.current()->stop();
       
  1146     d->getOpPutProtMap.clear();
       
  1147     it = Q3PtrDictIterator<Q3NetworkProtocol>( d->getOpGetProtMap );
       
  1148     for ( ; it.current(); ++it )
       
  1149 	it.current()->stop();
       
  1150     d->getOpGetProtMap.clear();
       
  1151     if ( d->currPut ) {
       
  1152 	d->currPut->stop();
       
  1153 	delete (Q3NetworkProtocol *) d->currPut;
       
  1154 	d->currPut = 0;
       
  1155     }
       
  1156     d->waitingCopies.clear();
       
  1157     if ( d->networkProtocol )
       
  1158 	d->networkProtocol->stop();
       
  1159     getNetworkProtocol();
       
  1160 }
       
  1161 
       
  1162 /*!
       
  1163     \internal
       
  1164 */
       
  1165 
       
  1166 void Q3UrlOperator::deleteOperation( Q3NetworkOperation *op )
       
  1167 {
       
  1168     if ( op )
       
  1169 	d->oldOps.append( op );
       
  1170 }
       
  1171 
       
  1172 /*!
       
  1173     \internal
       
  1174     updates the entryMap after a network operation finished
       
  1175 */
       
  1176 
       
  1177 void Q3UrlOperator::slotItemChanged( Q3NetworkOperation *op )
       
  1178 {
       
  1179     if ( !op )
       
  1180 	return;
       
  1181 
       
  1182     switch ( op->operation() ) {
       
  1183     case Q3NetworkProtocol::OpRename :
       
  1184     {
       
  1185 	if ( op->arg( 0 ) == op->arg( 1 ) )
       
  1186 	    return;
       
  1187 
       
  1188 	QMap<QString, QUrlInfo>::iterator mi = d->entryMap.find( op->arg( 0 ) );
       
  1189 	if ( mi != d->entryMap.end() ) {
       
  1190 	    mi.data().setName( op->arg( 1 ) );
       
  1191 	    d->entryMap[ op->arg( 1 ) ] = mi.data();
       
  1192 	    d->entryMap.erase( mi );
       
  1193 	}
       
  1194 	break;
       
  1195     }
       
  1196     case Q3NetworkProtocol::OpRemove :
       
  1197     {
       
  1198 	QMap<QString, QUrlInfo>::iterator mi = d->entryMap.find( op->arg( 0 ) );
       
  1199 	if ( mi != d->entryMap.end() )
       
  1200 	    d->entryMap.erase( mi );
       
  1201 	break;
       
  1202     }
       
  1203     default:
       
  1204 	break;
       
  1205     }
       
  1206 }
       
  1207 
       
  1208 QT_END_NAMESPACE
       
  1209 
       
  1210 #include "moc_q3urloperator.cpp"
       
  1211 
       
  1212 #endif // QT_NO_NETWORKPROTOCOL