source: trunk/qt/torrent-model.cc @ 14150

Last change on this file since 14150 was 14150, checked in by jordan, 9 years ago

support qt5 in transmission-qt

  • Property svn:keywords set to Date Rev Author Id
File size: 6.3 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: torrent-model.cc 14150 2013-07-27 21:58:14Z jordan $
11 */
12
13#include <cassert>
14#include <iostream>
15
16#include <libtransmission/transmission.h>
17#include <libtransmission/variant.h>
18
19#include "torrent-delegate.h"
20#include "torrent-model.h"
21
22void
23TorrentModel :: clear( )
24{
25    beginResetModel ();
26
27    myIdToRow.clear( );
28    myIdToTorrent.clear( );
29    foreach( Torrent * tor, myTorrents ) delete tor;
30    myTorrents.clear( );
31
32    endResetModel ();
33}
34
35int
36TorrentModel :: rowCount( const QModelIndex& parent ) const
37{
38    Q_UNUSED( parent );
39
40    return myTorrents.size( );
41}
42
43QVariant
44TorrentModel :: data (const QModelIndex& index, int role) const
45{
46  QVariant var;
47
48  const Torrent * t = myTorrents.value (index.row(), 0);
49  if (t != 0)
50    {
51      switch (role)
52        {
53          case Qt::DisplayRole:
54            var.setValue (t->name());
55            break;
56
57          case Qt::DecorationRole:
58            var.setValue (t->getMimeTypeIcon());
59            break;
60
61          case TorrentRole:
62            var = qVariantFromValue(t);
63            break;
64
65          default:
66            //std::cerr << "Unhandled role: " << role << std::endl;
67            break;
68        }
69    }
70
71  return var;
72}
73
74/***
75****
76***/
77
78void
79TorrentModel :: addTorrent( Torrent * t )
80{
81    myIdToTorrent.insert( t->id( ), t );
82    myIdToRow.insert( t->id( ), myTorrents.size( ) );
83    myTorrents.append( t );
84}
85
86TorrentModel :: TorrentModel( Prefs& prefs ):
87    myPrefs( prefs )
88{
89}
90
91TorrentModel :: ~TorrentModel( )
92{
93    clear( );
94}
95
96/***
97****
98***/
99
100Torrent*
101TorrentModel :: getTorrentFromId( int id )
102{
103    id_to_torrent_t::iterator it( myIdToTorrent.find( id ) );
104    return it == myIdToTorrent.end() ? 0 : it.value( );
105}
106
107const Torrent*
108TorrentModel :: getTorrentFromId( int id ) const
109{
110    id_to_torrent_t::const_iterator it( myIdToTorrent.find( id ) );
111    return it == myIdToTorrent.end() ? 0 : it.value( );
112}
113
114/***
115****
116***/
117
118void
119TorrentModel :: onTorrentChanged( int torrentId )
120{
121    const int row( myIdToRow.value( torrentId, -1 ) );
122    if( row >= 0 ) {
123        QModelIndex qmi( index( row, 0 ) );
124        emit dataChanged( qmi, qmi );
125    }
126}
127
128void
129TorrentModel :: removeTorrents( tr_variant * torrents )
130{
131    int i = 0;
132    tr_variant * child;
133    while(( child = tr_variantListChild( torrents, i++ ))) {
134        int64_t intVal;
135        if( tr_variantGetInt( child, &intVal ) )
136            removeTorrent( intVal );
137    }
138}
139
140void
141TorrentModel :: updateTorrents( tr_variant * torrents, bool isCompleteList )
142{
143    QList<Torrent*> newTorrents;
144    QSet<int> oldIds;
145    QSet<int> addIds;
146    QSet<int> newIds;
147    int updatedCount = 0;
148
149    if ( isCompleteList )
150      oldIds = getIds( );
151
152    if( tr_variantIsList( torrents ) )
153    {
154        size_t i( 0 );
155        tr_variant * child;
156        while(( child = tr_variantListChild( torrents, i++ )))
157        {
158            int64_t id;
159            if( tr_variantDictFindInt( child, TR_KEY_id, &id ) )
160            {
161                newIds.insert( id );
162
163                Torrent * tor = getTorrentFromId( id );
164                if( tor == 0 )
165                {
166                    tor = new Torrent( myPrefs, id );
167                    tor->update( child );
168                    if( !tor->hasMetadata() )
169                        tor->setMagnet( true );
170                    newTorrents.append( tor );
171                    connect( tor, SIGNAL(torrentChanged(int)), this, SLOT(onTorrentChanged(int)));
172                }
173                else
174                {
175                    tor->update( child );
176                    ++updatedCount;
177                    if( tor->isMagnet() && tor->hasMetadata() )
178                    {
179                        addIds.insert( tor->id() );
180                        tor->setMagnet( false );
181                    }
182                }
183            }
184        }
185    }
186
187    if( !newTorrents.isEmpty( ) )
188    {
189        const int oldCount( rowCount( ) );
190        const int newCount( oldCount + newTorrents.size( ) );
191        QSet<int> ids;
192
193        beginInsertRows( QModelIndex(), oldCount, newCount - 1 );
194
195        foreach( Torrent * tor, newTorrents ) {
196            addTorrent( tor );
197            addIds.insert( tor->id( ) );
198        }
199        endInsertRows( );
200    }
201
202    if( !addIds.isEmpty() )
203        emit torrentsAdded( addIds );
204
205    if( isCompleteList )
206    {
207        QSet<int> removedIds( oldIds );
208        removedIds -= newIds;
209        foreach( int id, removedIds )
210            removeTorrent( id );
211    }
212}
213
214void
215TorrentModel :: removeTorrent( int id )
216{
217    const int row = myIdToRow.value( id, -1 );
218    if( row >= 0 )
219    {
220        Torrent * tor = myIdToTorrent.value( id, 0 );
221
222        beginRemoveRows( QModelIndex(), row, row );
223        // make the myIdToRow map consistent with list view/model
224        for( QMap<int,int>::iterator i = myIdToRow.begin(); i != myIdToRow.end(); ++i )
225            if( i.value() > row )
226                --i.value();
227        myIdToRow.remove( id );
228        myIdToTorrent.remove( id );
229        myTorrents.remove( myTorrents.indexOf( tor ) );
230        endRemoveRows( );
231
232        delete tor;
233    }
234}
235
236void
237TorrentModel :: getTransferSpeed (Speed   & uploadSpeed,
238                                  size_t  & uploadPeerCount,
239                                  Speed   & downloadSpeed,
240                                  size_t  & downloadPeerCount)
241{
242  Speed upSpeed, downSpeed;
243  size_t upCount=0, downCount=0;
244
245  foreach (const Torrent * const tor, myTorrents)
246    {
247      upSpeed += tor->uploadSpeed ();
248      upCount += tor->peersWeAreUploadingTo ();
249      downSpeed += tor->downloadSpeed ();
250      downCount += tor->webseedsWeAreDownloadingFrom();
251      downCount += tor->peersWeAreDownloadingFrom();
252    }
253
254  uploadSpeed = upSpeed;
255  uploadPeerCount = upCount;
256  downloadSpeed = downSpeed;
257  downloadPeerCount = downCount;
258}
259
260QSet<int>
261TorrentModel :: getIds () const
262{
263  QSet<int> ids;
264
265  ids.reserve (myTorrents.size());
266  foreach (const Torrent * tor, myTorrents)
267    ids.insert (tor->id());
268
269  return ids;
270}
271
272bool
273TorrentModel :: hasTorrent( const QString& hashString ) const
274{
275    foreach( const Torrent * tor, myTorrents )
276        if( tor->hashString( ) == hashString )
277            return true;
278    return false;
279}
Note: See TracBrowser for help on using the repository browser.