Changeset 13810


Ignore:
Timestamp:
Jan 20, 2013, 1:31:58 AM (8 years ago)
Author:
jordan
Message:

(trunk) #1220 'change top folder names' -- add file-renaming to the Qt client

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/extras/rpc-spec.txt

    r13807 r13810  
    430430   ---------------------------------+-------------------------------------------------
    431431   "ids"                            | array      the torrent torrent list, as described in 3.1
    432                                     |            (though, this function doesn't make sense for >1 torrent)
     432                                    |            (must only be 1 torrent)
    433433   "path"                           | string     the path to the file or folder that will be renamed
    434434   "name"                           | string     the file or folder's new name
    435435
    436    Response arguments: none
     436   Response arguments: "path", "name", and "id", holding the torrent ID integer
    437437
    438438
  • trunk/libtransmission/rpcimpl.c

    r13807 r13810  
    354354}
    355355
    356 static void
    357 torrentRenamePathDone (tr_torrent  * tor        UNUSED,
    358                        const char  * oldpath    UNUSED,
    359                        const char  * newname    UNUSED,
    360                        int           error,
    361                        void        * user_data)
    362 {
    363   *(int*)user_data = error;
    364 }
    365 
    366 static const char *
    367 torrentRenamePath (tr_session               * session,
    368                    tr_variant               * args_in,
    369                    tr_variant               * args_out UNUSED,
    370                    struct tr_rpc_idle_data  * idle_data UNUSED)
    371 {
    372   const char * oldpath;
    373   const char * newname;
    374   const char * ret = NULL;
    375 
    376   if (!tr_variantDictFindStr (args_in, TR_KEY_path, &oldpath, NULL))
    377     {
    378       ret = "no path specified";
    379     }
    380   else if (!tr_variantDictFindStr (args_in, TR_KEY_name, &newname, NULL))
    381     {
    382       ret = "no name specified";
    383     }
    384   else
    385     {
    386       int torrentCount;
    387       tr_torrent ** torrents = getTorrents (session, args_in, &torrentCount);
    388 
    389       if (torrentCount != 1)
    390         {
    391           ret = "torent-rename-path requires 1 torrent";
    392         }
    393       else
    394         {
    395           int error = -1;
    396           tr_torrentRenamePath (torrents[0], oldpath, newname, torrentRenamePathDone, &error);
    397           assert (error != -1);
    398 
    399           if (error != 0)
    400             ret = tr_strerror (error);
    401         }
    402 
    403       tr_free (torrents);
    404     }
    405 
    406   return ret;
    407 }
    408 
    409356static const char*
    410357torrentReannounce (tr_session               * session,
     
    479426
    480427static void
    481 addFiles (const tr_torrent * tor,
    482           tr_variant *          list)
     428addFiles (const tr_torrent * tor, tr_variant * list)
    483429{
    484430    tr_file_index_t i;
     
    13671313
    13681314static void
     1315torrentRenamePathDone (tr_torrent  * tor,
     1316                       const char  * oldpath,
     1317                       const char  * newname,
     1318                       int           error,
     1319                       void        * user_data)
     1320{
     1321  const char * result;
     1322  struct tr_rpc_idle_data * data = user_data;
     1323
     1324  tr_variantDictAddInt (data->args_out, TR_KEY_id, tr_torrentId(tor));
     1325  tr_variantDictAddStr (data->args_out, TR_KEY_path, oldpath);
     1326  tr_variantDictAddStr (data->args_out, TR_KEY_name, newname);
     1327
     1328  if (error == 0)
     1329    result = NULL;
     1330  else
     1331    result = tr_strerror (error);
     1332
     1333  tr_idle_function_done (data, result);
     1334}
     1335
     1336static const char*
     1337torrentRenamePath (tr_session               * session,
     1338                   tr_variant               * args_in,
     1339                   tr_variant               * args_out UNUSED,
     1340                   struct tr_rpc_idle_data  * idle_data)
     1341{
     1342  int torrentCount;
     1343  tr_torrent ** torrents;
     1344  const char * oldpath = NULL;
     1345  const char * newname = NULL;
     1346
     1347  tr_variantDictFindStr (args_in, TR_KEY_path, &oldpath, NULL);
     1348  tr_variantDictFindStr (args_in, TR_KEY_name, &newname, NULL);
     1349  torrents = getTorrents (session, args_in, &torrentCount);
     1350
     1351  if (torrentCount == 1)
     1352    tr_torrentRenamePath (torrents[0], oldpath, newname, torrentRenamePathDone, idle_data);
     1353  else
     1354    tr_idle_function_done (idle_data, "torrent-rename-path requires 1 torrent");
     1355
     1356  /* cleanup */
     1357  tr_free (torrents);
     1358  return NULL; /* ignored */
     1359}
     1360
     1361/***
     1362****
     1363***/
     1364
     1365static void
    13691366portTested (tr_session       * session UNUSED,
    13701367            bool               did_connect UNUSED,
     
    13951392static const char*
    13961393portTest (tr_session               * session,
    1397           tr_variant                  * args_in UNUSED,
    1398           tr_variant                  * args_out UNUSED,
     1394          tr_variant               * args_in UNUSED,
     1395          tr_variant               * args_out UNUSED,
    13991396          struct tr_rpc_idle_data  * idle_data)
    14001397{
     
    16131610static const char*
    16141611torrentAdd (tr_session               * session,
    1615             tr_variant                  * args_in,
    1616             tr_variant                  * args_out UNUSED,
     1612            tr_variant               * args_in,
     1613            tr_variant               * args_out UNUSED,
    16171614            struct tr_rpc_idle_data  * idle_data)
    16181615{
     
    19871984    { "torrent-get",           true,  torrentGet          },
    19881985    { "torrent-remove",        true,  torrentRemove       },
    1989     { "torrent-rename-path",   true, torrentRenamePath   },
     1986    { "torrent-rename-path",   false, torrentRenamePath   },
    19901987    { "torrent-set",           true,  torrentSet          },
    19911988    { "torrent-set-location",  true,  torrentSetLocation  },
     
    20702067
    20712068        buf = tr_variantToBuf (&response, TR_VARIANT_FMT_JSON_LEAN);
    2072       (*callback)(session, buf, callback_user_data);
     2069        (*callback)(session, buf, callback_user_data);
    20732070        evbuffer_free (buf);
    20742071
     
    20872084        data->callback = callback;
    20882085        data->callback_user_data = callback_user_data;
    2089       (*methods[i].func)(session, args_in, data->args_out, data);
     2086        (*methods[i].func)(session, args_in, data->args_out, data);
    20902087    }
    20912088}
  • trunk/libtransmission/torrent.c

    r13807 r13810  
    34923492  ***/
    34933493
     3494  tor->anyDate = tr_time ();
     3495
    34943496  /* callback */
    34953497  if (data->callback != NULL)
  • trunk/qt/details.cc

    r13779 r13810  
    203203    foreach( int id, myIds ) {
    204204        const Torrent * tor = myModel.getTorrentFromId( id );
    205         if( tor )
     205        if( tor ) {
    206206            disconnect( tor, SIGNAL(torrentChanged(int)), this, SLOT(onTorrentChanged()) );
     207            disconnect( tor, SIGNAL(torrentFileListRebuilt(int)), this, SLOT(onTorrentFileListRebuilt()) );
     208        }
    207209    }
    208210
     
    214216    foreach( int id, myIds ) {
    215217        const Torrent * tor = myModel.getTorrentFromId( id );
    216         if( tor )
     218        if( tor ) {
    217219            connect( tor, SIGNAL(torrentChanged(int)), this, SLOT(onTorrentChanged()) );
     220            connect( tor, SIGNAL(torrentFileListRebuilt(int)), this, SLOT(onTorrentFileListRebuilt()) );
     221        }
    218222    }
    219223
     
    294298        QTimer::singleShot( 100, this, SLOT(refresh()));
    295299    }
     300}
     301
     302void
     303Details :: onTorrentFileListRebuilt( )
     304{
     305  myFilesDirty = true;
     306  onTorrentChanged( );
    296307}
    297308
     
    830841    myPeers = peers2;
    831842
     843    if( !single || myFilesDirty )
     844        myFileTreeView->clear( );
    832845    if( single )
    833846        myFileTreeView->update( torrents[0]->files( ) , myChangedTorrents );
    834     else
    835         myFileTreeView->clear( );
     847    myFilesDirty = false;
    836848
    837849    myChangedTorrents = false;
     
    13081320             this,           SLOT(  onFileWantedChanged(const QSet<int>&, bool)));
    13091321
     1322    connect( myFileTreeView, SIGNAL( pathEdited(const QString&, const QString&)),
     1323             this,           SLOT (onPathEdited(const QString&, const QString&)));
     1324
    13101325    return myFileTreeView;
    13111326}
     
    13421357  getNewData ();
    13431358}
     1359
     1360void
     1361Details :: onPathEdited (const QString& oldpath, const QString& newname)
     1362{
     1363  mySession.torrentRenamePath (myIds, oldpath, newname);
     1364}
  • trunk/qt/details.h

    r11452 r13810  
    5050    private slots:
    5151        void onTorrentChanged( );
     52        void onTorrentFileListRebuilt( );
    5253        void onTimer( );
    5354
     
    136137        FileTreeView * myFileTreeView;
    137138
     139        bool myFilesDirty;
     140
    138141    private slots:
    139142        void refreshPref( int key );
     
    141144        void onFilePriorityChanged( const QSet<int>& fileIndices, int );
    142145        void onFileWantedChanged( const QSet<int>& fileIndices, bool );
     146        void onPathEdited (const QString& oldpath, const QString& newname);
    143147        void onHonorsSessionLimitsToggled( bool );
    144148        void onDownloadLimitedToggled( bool );
  • trunk/qt/file-tree.cc

    r13395 r13810  
    319319    int i( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
    320320
     321    if( index.column( ) == COL_NAME )
     322        i |= Qt::ItemIsEditable;
     323
    321324    if( index.column( ) == COL_WANTED )
    322325        i |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
    323326
    324327    return (Qt::ItemFlags)i;
     328}
     329
     330bool
     331FileTreeModel :: setData (const QModelIndex& index, const QVariant& newname, int role)
     332{
     333  if (role == Qt::EditRole)
     334    {
     335      QString oldpath;
     336      QModelIndex walk = index;
     337      FileTreeItem * item = static_cast<FileTreeItem*>(index.internalPointer());
     338
     339      while (item && !item->name().isEmpty())
     340        {
     341          if (oldpath.isEmpty())
     342            oldpath = item->name();
     343          else
     344            oldpath = item->name() + "/" + oldpath;
     345          item = item->parent ();
     346        }
     347
     348      emit pathEdited (oldpath, newname.toString());
     349    }
     350
     351  return false; // don't update the view until the session confirms the change
    325352}
    326353
     
    682709    connect( &myModel, SIGNAL(wantedChanged(const QSet<int>&, bool)),
    683710             this,     SIGNAL(wantedChanged(const QSet<int>&, bool)));
     711
     712    connect( &myModel, SIGNAL(pathEdited(const QString&, const QString&)),
     713             this,     SIGNAL(pathEdited(const QString&, const QString&)));
    684714}
    685715
  • trunk/qt/file-tree.h

    r13384 r13810  
    102102        int rowCount( const QModelIndex& parent = QModelIndex( ) ) const;
    103103        int columnCount( const QModelIndex &parent = QModelIndex( ) ) const;
     104        virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
    104105
    105106    signals:
    106107        void priorityChanged( const QSet<int>& fileIndices, int );
    107108        void wantedChanged( const QSet<int>& fileIndices, bool );
     109        void pathEdited (const QString& oldpath, const QString& newname);
    108110
    109111    public:
     
    155157        void priorityChanged( const QSet<int>& fileIndices, int );
    156158        void wantedChanged( const QSet<int>& fileIndices, bool );
     159        void pathEdited (const QString& oldpath, const QString& newname);
    157160
    158161    protected:
  • trunk/qt/session.cc

    r13799 r13810  
    2828#include <QStyle>
    2929#include <QTextStream>
     30#include <QTimer>
    3031
    3132#include <curl/curl.h>
     
    6162        TAG_PORT_TEST,
    6263        TAG_MAGNET_LINK,
     64        TAG_RENAME_PATH,
    6365
    6466        FIRST_UNIQUE_TAG
     
    247249    mySession( 0 ),
    248250    myConfigDir( QString::fromUtf8( configDir ) ),
    249     myNAM( 0 )
     251    myNAM( 0 ),
     252    myResponseTimer (this)
    250253{
    251254    myStats.ratio = TR_RATIO_NA;
     
    258261
    259262    connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(updatePref(int)) );
     263
     264    connect (&myResponseTimer, SIGNAL(timeout()), this, SLOT(onResponseTimer()));
     265    myResponseTimer.setSingleShot (true);
    260266}
    261267
     
    496502
    497503void
     504Session :: torrentRenamePath (const QSet<int>& ids, const QString& oldpath, const QString& newname)
     505{
     506  tr_variant top;
     507  tr_variantInitDict (&top, 2);
     508  tr_variantDictAddStr (&top, TR_KEY_method, "torrent-rename-path");
     509  tr_variantDictAddInt (&top, TR_KEY_tag, TAG_RENAME_PATH);
     510  tr_variant * args (tr_variantDictAddDict(&top, TR_KEY_arguments, 3));
     511  addOptionalIds (args, ids);
     512  tr_variantDictAddStr (args, TR_KEY_path, oldpath.toUtf8().constData());
     513  tr_variantDictAddStr (args, TR_KEY_name, newname.toUtf8().constData());
     514  exec (&top);
     515  tr_variantFree (&top);
     516}
     517
     518void
    498519Session :: refreshTorrents( const QSet<int>& ids )
    499520{
     
    636657
    637658void
    638 Session :: localSessionCallback( tr_session * session, struct evbuffer * json, void * self )
    639 {
    640     Q_UNUSED( session );
    641 
    642     ((Session*)self)->parseResponse( (const char*) evbuffer_pullup( json, -1 ), evbuffer_get_length( json ) );
     659Session :: localSessionCallback( tr_session * session, struct evbuffer * json, void * vself )
     660{
     661  Q_UNUSED (session);
     662
     663  Session * self = static_cast<Session*>(vself);
     664
     665  self->myIdleJSON.append (QString ((const char*) evbuffer_pullup (json, -1)));
     666
     667  if (!self->myResponseTimer.isActive())
     668    self->myResponseTimer.start(50);
    643669}
    644670
     
    714740
    715741    reply->deleteLater();
     742}
     743
     744void
     745Session :: onResponseTimer ()
     746{
     747  QStringList responses = myIdleJSON;
     748  myIdleJSON.clear();
     749
     750  foreach (QString response, responses)
     751    {
     752      const QByteArray utf8 (response.toUtf8());
     753      parseResponse (utf8.constData(), utf8.length());
     754    }
    716755}
    717756
     
    768807                }
    769808
     809                case TAG_RENAME_PATH:
     810                  {
     811                    int64_t id = 0;
     812                    const char * result = 0;
     813                    if( tr_variantDictFindStr (&top, TR_KEY_result, &result, 0) && strcmp (result, "success") )
     814                      {
     815                        const char * path = "";
     816                        const char * name = "";
     817                        tr_variantDictFindStr (args, TR_KEY_path, &path, 0);
     818                        tr_variantDictFindStr (args, TR_KEY_name, &name, 0);
     819                        const QString title = tr("Error Renaming Path");
     820                        const QString text = tr("<p><b>Unable to rename \"%1\" as \"%2\": %3.</b></p> <p>Please correct the errors and try again.</p>").arg(path).arg(name).arg(result);
     821                        QMessageBox * d = new QMessageBox( QMessageBox::Information, title, text,
     822                                                           QMessageBox::Close,
     823                                                           QApplication::activeWindow());
     824                        connect( d, SIGNAL(rejected()), d, SLOT(deleteLater()) );
     825                        d->show( );
     826                      }
     827                    else if (tr_variantDictFindInt (args, TR_KEY_id, &id) && id)
     828                      {
     829                        // let's get the updated file list
     830                        char * req = tr_strdup_printf ("{ \"arguments\": { \"fields\": [ \"files\", \"id\" ], \"ids\": %d }, \"method\": \"torrent-get\", \"tag\": %d }",
     831                                                       int(id),
     832                                                       int(TAG_SOME_TORRENTS));
     833                        exec (req);
     834                        tr_free (req);
     835                      }
     836
     837                    break;
     838                }
     839
    770840                case TAG_PORT_TEST: {
    771841                    bool isOpen = 0;
     
    773843                        tr_variantDictFindBool( args, TR_KEY_port_is_open, &isOpen );
    774844                    emit portTested( (bool)isOpen );
     845                    break;
    775846                }
    776847
  • trunk/qt/session.h

    r13683 r13810  
    2020#include <QNetworkAccessManager>
    2121#include <QString>
     22#include <QStringList>
     23#include <QTimer>
    2224#include <QUrl>
    2325
     
    102104        void torrentSet( const QSet<int>& ids, const tr_quark key, const QPair<int,QString>& val);
    103105        void torrentSetLocation( const QSet<int>& ids, const QString& path, bool doMove );
    104 
     106        void torrentRenamePath( const QSet<int>& ids, const QString& oldpath, const QString& newname );
    105107
    106108    public slots:
     
    130132    private slots:
    131133        void onFinished( QNetworkReply * reply );
     134        void onResponseTimer( );
    132135
    133136    signals:
     
    151154        QString myConfigDir;
    152155        QString mySessionId;
     156        QStringList myIdleJSON;
    153157        QUrl myUrl;
    154158        QNetworkAccessManager * myNAM;
     
    156160        struct tr_session_stats myCumulativeStats;
    157161        QString mySessionVersion;
     162        QTimer myResponseTimer;
    158163};
    159164
  • trunk/qt/torrent.cc

    r13722 r13810  
    574574      updateMimeIcon ();
    575575      changed = true;
     576      emit torrentFileListRebuilt (id ());
    576577    }
    577578
  • trunk/qt/torrent.h

    r13721 r13810  
    189189        void torrentChanged( int id );
    190190        void torrentCompleted( int id );
     191        void torrentFileListRebuilt( int id );
    191192
    192193    private:
Note: See TracChangeset for help on using the changeset viewer.