diff --git a/libresapi/src/api/FileSharingHandler.cpp b/libresapi/src/api/FileSharingHandler.cpp index 856275d9c..a6296973d 100644 --- a/libresapi/src/api/FileSharingHandler.cpp +++ b/libresapi/src/api/FileSharingHandler.cpp @@ -500,7 +500,7 @@ void FileSharingHandler::handleDownload(Request& req, Response& resp) FileInfo finfo; mRsFiles->FileDetails(hash, RS_FILE_HINTS_REMOTE, finfo); - for(std::list::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) + for(std::vector::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) srcIds.push_back((*it).peerId); if(!mRsFiles->FileRequest(name, hash, static_cast(size), "", diff --git a/libresapi/src/api/TransfersHandler.cpp b/libresapi/src/api/TransfersHandler.cpp index f563f377c..c696411da 100644 --- a/libresapi/src/api/TransfersHandler.cpp +++ b/libresapi/src/api/TransfersHandler.cpp @@ -91,7 +91,7 @@ void TransfersHandler::handleControlDownload(Request &req, Response &resp) FileInfo finfo; mFiles->FileDetails(hash, RS_FILE_HINTS_REMOTE, finfo); - for(std::list::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) + for(std::vector::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) srcIds.push_back((*it).peerId); bool ok = req.mStream.isOK(); @@ -213,8 +213,7 @@ void TransfersHandler::handleUploads(Request & /* req */, Response &resp) FileInfo fi; if(mFiles->FileDetails(*lit, RS_FILE_HINTS_UPLOAD, fi)) { - std::list::iterator pit; - for(pit = fi.peers.begin(); pit != fi.peers.end(); ++pit) + for( std::vector::iterator pit = fi.peers.begin(); pit != fi.peers.end(); ++pit) { if (pit->peerId == ownId) //don't display transfer to ourselves continue ; diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 382d13cb6..32e7297c3 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -301,7 +301,7 @@ void ftController::searchForDirectSources() FileInfo info ; // Info needs to be re-allocated each time, to start with a clear list of peers (it's not cleared down there) if( mSearch->search(it->first, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info) ) - for( std::list::const_iterator pit = info.peers.begin(); pit != info.peers.end(); ++pit ) + for( std::vector::const_iterator pit = info.peers.begin(); pit != info.peers.end(); ++pit ) { bool bAllowDirectDL = false; switch (mFilePermDirectDLPolicy) { @@ -1029,7 +1029,7 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash } std::list::const_iterator it; - std::list::const_iterator pit; + std::vector::const_iterator pit; #ifdef CONTROL_DEBUG std::cerr << "ftController::FileRequest(" << fname << ","; diff --git a/libretroshare/src/retroshare/rstypes.h b/libretroshare/src/retroshare/rstypes.h index 9c098db59..cc04d2312 100644 --- a/libretroshare/src/retroshare/rstypes.h +++ b/libretroshare/src/retroshare/rstypes.h @@ -208,7 +208,7 @@ class FileInfo uint64_t transfered; double tfRate; /* in kbytes */ uint32_t downloadStatus; // FT_STATE_DOWNLOADING & co. See rstypes.h - std::list peers; + std::vector peers; DwlSpeed priority ; time_t lastTS; diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index ee85a1d92..bc2f08644 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -368,7 +368,7 @@ void SearchDialog::getSourceFriendsForHash(const RsFileHash& hash,std::listFileDetails(hash, RS_FILE_HINTS_REMOTE,finfo) ; - for(std::list::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) + for(std::vector::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) { std::cerr << " adding peerid " << (*it).peerId << std::endl ; srcIds.push_back((*it).peerId) ; diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index 196bc90ac..fb7b97917 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -76,10 +76,10 @@ #define IMAGE_STOP ":/images/stop.png" #define IMAGE_PREVIEW ":/images/preview.png" #define IMAGE_PRIORITY ":/images/filepriority.png" -#define IMAGE_PRIORITYLOW ":/images/prioritylow.png" -#define IMAGE_PRIORITYNORMAL ":/images/prioritynormal.png" -#define IMAGE_PRIORITYHIGH ":/images/priorityhigh.png" -#define IMAGE_PRIORITYAUTO ":/images/priorityauto.png" +#define IMAGE_PRIORITYLOW ":/images/prioritylow.png" +#define IMAGE_PRIORITYNORMAL ":/images/prioritynormal.png" +#define IMAGE_PRIORITYHIGH ":/images/priorityhigh.png" +#define IMAGE_PRIORITYAUTO ":/images/priorityauto.png" #define IMAGE_SEARCH ":/icons/svg/magnifying-glass.svg" #define IMAGE_EXPAND ":/images/edit_add24.png" #define IMAGE_COLLAPSE ":/images/edit_remove24.png" @@ -98,6 +98,472 @@ Q_DECLARE_METATYPE(FileProgressInfo) +class RsDownloadListModel : public QAbstractItemModel +{ + // Q_OBJECT + +public: + explicit RsDownloadListModel(QObject *parent = NULL) : QAbstractItemModel(parent) {} + ~RsDownloadListModel(){} + + int rowCount(const QModelIndex& parent = QModelIndex()) const + { + std::cerr << "in rowCount()" << std::endl; + + void *ref = (parent.isValid())?parent.internalPointer():NULL ; + + if(!ref) + return mDownloads.size() ; + + uint32_t entry = 0 ; + int source_id ; + + if(!convertRefPointerToTabEntry(ref,entry,source_id) || entry >= mDownloads.size()) + return 0 ; + + return mDownloads[entry].peers.size(); // costly + } + int columnCount(const QModelIndex &parent = QModelIndex()) const + { + return 14 ; + } + bool hasChildren(const QModelIndex &parent = QModelIndex()) const + { + std::cerr << "in hasChildren()" << std::endl; + + void *ref = (parent.isValid())?parent.internalPointer():NULL ; + uint32_t entry = 0; + int source_id=0 ; + + if(!ref) + return true ; + + if(!convertRefPointerToTabEntry(ref,entry,source_id) || entry >= mDownloads.size()) + return false ; + + return !mDownloads[entry].peers.empty(); // costly + } + + QModelIndex index(int row, int column, const QModelIndex & parent) const + { + std::cerr << "in index() row=" << row << " column=" << column << std::endl; + + if(row < 0) + return QModelIndex(); + + void *ref = (parent.isValid())?parent.internalPointer():NULL ; + uint32_t entry = 0; + int source_id=0 ; + void *subref = NULL ; + + if(!ref) // top level. The entry is that of a transfer + { + if(!convertTabEntryToRefPointer(row,-1,subref)) + return QModelIndex() ; + + std::cerr << "normal behavior (no parent). subref=" << subref << std::endl; + + return createIndex(row,column,subref) ; + } + + if(!convertRefPointerToTabEntry(ref,entry,source_id) || entry >= mDownloads.size() || int(mDownloads[entry].peers.size()) <= source_id) + return QModelIndex() ; + + if(source_id != -1) + std::cerr << "ERROR: parent.source_id != -1 in index()" << std::endl; + + if(!convertTabEntryToRefPointer(entry,row,subref)) + return QModelIndex() ; + + std::cerr << "normal behavior. subref=" << subref << std::endl; + + return createIndex(row,column,subref) ; + } + QModelIndex parent(const QModelIndex& child) const + { + std::cerr << "in parent()" << std::endl; + + void *ref = (child.isValid())?child.internalPointer():NULL ; + uint32_t entry = 0; + int source_id=0 ; + + if(!ref) + return QModelIndex() ; + + if(!convertRefPointerToTabEntry(ref,entry,source_id) || entry >= mDownloads.size() || int(mDownloads[entry].peers.size()) <= source_id) + return QModelIndex() ; + + if(source_id < 0) + return QModelIndex() ; + + void *subref =NULL; + + if(!convertTabEntryToRefPointer(entry,-1,subref)) + return QModelIndex() ; + + return createIndex(entry,0,subref) ; + } + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const + { + std::cerr << "in headerData()" << std::endl; + + if(role != Qt::DisplayRole) + return QVariant(); + + switch(section) + { + default: + case COLUMN_NAME: return tr("Name", "i.e: file name"); + case COLUMN_SIZE: return tr("Size", "i.e: file size"); + case COLUMN_COMPLETED: return tr("Completed", ""); + case COLUMN_DLSPEED: return tr("Speed", "i.e: Download speed"); + case COLUMN_PROGRESS: return tr("Progress / Availability", "i.e: % downloaded"); + case COLUMN_SOURCES: return tr("Sources", "i.e: Sources"); + case COLUMN_STATUS: return tr("Status"); + case COLUMN_PRIORITY: return tr("Speed / Queue position"); + case COLUMN_REMAINING: return tr("Remaining"); + case COLUMN_DOWNLOADTIME: return tr("Download time", "i.e: Estimated Time of Arrival / Time left"); + case COLUMN_ID: return tr("Hash"); + case COLUMN_LASTDL: return tr("Last Time Seen", "i.e: Last Time Receiced Data"); + case COLUMN_PATH: return tr("Path", "i.e: Where file is saved"); + } + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + std::cerr << "in data()" << std::endl; + + if(!index.isValid()) + return QVariant(); + + int coln = index.column() ; + + switch(role) + { + case Qt::SizeHintRole: return sizeHintRole(index.column()) ; + case Qt::TextAlignmentRole: + case Qt::TextColorRole: + case Qt::WhatsThisRole: + case Qt::EditRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return QVariant(); + } + + void *ref = (index.isValid())?index.internalPointer():NULL ; + uint32_t entry = 0; + int source_id=0 ; + + if(!ref) + { + std::cerr << "ref=NULL!" << std::endl; + return false ; + } + + if(!convertRefPointerToTabEntry(ref,entry,source_id) || entry >= mDownloads.size()) + { + std::cerr << "Bad pointer: " << (void*)ref << std::endl; + return false ; + } + + const FileInfo& finfo(mDownloads[entry]) ; + + switch(role) + { + case Qt::DisplayRole: return displayRole (finfo,source_id,index.column()) ; + case Qt::DecorationRole: return decorationRole(finfo,source_id,index.column()) ; + case Qt::UserRole: return userRole (finfo,source_id,index.column()) ; + default: + return QVariant(); + } + } + + QVariant sizeHintRole(int col) const + { + switch(col) + { + default: + case COLUMN_NAME: return QVariant( 170 ); + case COLUMN_SIZE: return QVariant( 70 ); + case COLUMN_COMPLETED: return QVariant( 75 ); + case COLUMN_DLSPEED: return QVariant( 75 ); + case COLUMN_PROGRESS: return QVariant( 170 ); + case COLUMN_SOURCES: return QVariant( 90 ); + case COLUMN_STATUS: return QVariant( 100 ); + case COLUMN_PRIORITY: return QVariant( 100 ); + case COLUMN_REMAINING: return QVariant( 100 ); + case COLUMN_DOWNLOADTIME: return QVariant( 100 ); + case COLUMN_ID: return QVariant( 100 ); + case COLUMN_LASTDL: return QVariant( 100 ); + case COLUMN_PATH: return QVariant( 100 ); + } + } + + + QVariant displayRole(const FileInfo& fileInfo,int source_id,int col) const + { + if(source_id == 0) + switch(col) + { + case COLUMN_NAME: return QVariant(QString::fromUtf8(fileInfo.fname.c_str())); + case COLUMN_COMPLETED: return QVariant((qlonglong)fileInfo.transfered); + case COLUMN_DLSPEED: return QVariant((double)((fileInfo.downloadStatus == FT_STATE_DOWNLOADING) ? (fileInfo.tfRate * 1024.0) : 0.0)); + case COLUMN_PROGRESS: return QVariant((float)((fileInfo.size == 0) ? 0 : (fileInfo.transfered * 100.0 / (float)fileInfo.size))); + case COLUMN_STATUS: + { + QString status; + switch (fileInfo.downloadStatus) + { + case FT_STATE_FAILED: status = tr("Failed"); break; + case FT_STATE_OKAY: status = tr("Okay"); break; + case FT_STATE_WAITING: status = tr("Waiting"); break; + case FT_STATE_DOWNLOADING: status = tr("Downloading"); break; + case FT_STATE_COMPLETE: status = tr("Complete"); break; + case FT_STATE_QUEUED: status = tr("Queued"); break; + case FT_STATE_PAUSED: status = tr("Paused"); break; + case FT_STATE_CHECKING_HASH:status = tr("Checking..."); break; + default: status = tr("Unknown"); break; + } + return QVariant(status); + } + + case COLUMN_PRIORITY: + { + double priority = PRIORITY_NULL; + + if (fileInfo.downloadStatus == FT_STATE_QUEUED) + priority = fileInfo.queue_position; + else if (fileInfo.downloadStatus == FT_STATE_COMPLETE) + priority = 0; + else + switch (fileInfo.priority) + { + case SPEED_LOW: priority = PRIORITY_SLOWER; break; + case SPEED_NORMAL: priority = PRIORITY_AVERAGE; break; + case SPEED_HIGH: priority = PRIORITY_FASTER; break; + default: priority = PRIORITY_AVERAGE; break; + } + + return QVariant(priority); + } + + case COLUMN_REMAINING: return QVariant((qlonglong)(fileInfo.size - fileInfo.transfered)); + case COLUMN_DOWNLOADTIME: return QVariant((qlonglong)(fileInfo.tfRate > 0)?( (fileInfo.size - fileInfo.transfered) / (fileInfo.tfRate * 1024.0) ) : 0); + case COLUMN_LASTDL: + { + qint64 qi64LastDL = fileInfo.lastTS ; + + if (qi64LastDL == 0) // file is complete, or any raison why the time has not been set properly + { + QFileInfo file; + + if (fileInfo.downloadStatus == FT_STATE_COMPLETE) + file = QFileInfo(QString::fromUtf8(fileInfo.path.c_str()), QString::fromUtf8(fileInfo.fname.c_str())); + else + file = QFileInfo(QString::fromUtf8(rsFiles->getPartialsDirectory().c_str()), QString::fromUtf8(fileInfo.hash.toStdString().c_str())); + + //Get Last Access on File + if (file.exists()) + qi64LastDL = file.lastModified().toTime_t(); + } + return QVariant(qi64LastDL) ; + } + case COLUMN_PATH: + { + QString strPath = QString::fromUtf8(fileInfo.path.c_str()); + QString strPathAfterDL = strPath; + strPathAfterDL.replace(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()),""); + + return QVariant(strPathAfterDL); + } + + default: + return QVariant("[ TODO ]"); + } + else + return QVariant("[ TODO ]"); + } + + virtual QVariant userRole(const FileInfo& fileInfo,int source_id,int col) const + { + switch(col) + { + case COLUMN_PROGRESS: + { + FileChunksInfo fcinfo; + if (!rsFiles->FileDownloadChunksDetails(fileInfo.hash, fcinfo)) + return -1; + + FileProgressInfo pinfo; + pinfo.cmap = fcinfo.chunks; + pinfo.type = FileProgressInfo::DOWNLOAD_LINE; + pinfo.progress = (fileInfo.size == 0) ? 0 : (fileInfo.transfered * 100.0 / fileInfo.size); + pinfo.nb_chunks = pinfo.cmap._map.empty() ? 0 : fcinfo.chunks.size(); + + for (uint32_t i = 0; i < fcinfo.chunks.size(); ++i) + switch(fcinfo.chunks[i]) + { + case FileChunksInfo::CHUNK_CHECKING: pinfo.chunks_in_checking.push_back(i); + break ; + case FileChunksInfo::CHUNK_ACTIVE: pinfo.chunks_in_progress.push_back(i); + break ; + case FileChunksInfo::CHUNK_DONE: + case FileChunksInfo::CHUNK_OUTSTANDING: + break ; + } + + return QVariant::fromValue(pinfo); + } + + default: + return QVariant(); + } + } + + virtual QVariant sortRole(const QModelIndex&,const DirDetails&,int) const + { + std::cerr << "Unimplemented: " << __PRETTY_FUNCTION__ << std::endl; + } + + QVariant decorationRole(const FileInfo& fileInfo,int source_id,int col) const + { + if(col == COLUMN_NAME) + return QVariant(FilesDefs::getIconFromFilename(QString::fromUtf8(fileInfo.fname.c_str()))); + else + return QVariant(); + } + + + void update_transfers() + { + std::list downHashes; + rsFiles->FileDownloads(downHashes); + + mDownloads.resize(downHashes.size()) ; + + std::cerr << "updating file list: found " << mDownloads.size() << " transfers." << std::endl; + + uint32_t i=0; + for(auto it(downHashes.begin());it!=downHashes.end();++it,++i) + { + FileInfo& fileInfo(mDownloads[i]); + rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, fileInfo); + } + beginResetModel(); + endResetModel(); + + QModelIndex topLeft = createIndex(0,0), bottomRight = createIndex(mDownloads.size(), COLUMN_COUNT-1); + emit dataChanged(topLeft, bottomRight); + + //shit code follow (rewrite this please) + // size_t old_size = neighs.size(), new_size = 0; + // std::list old_neighs = neighs; + // + // new_size = new_neighs.size(); + // //set model data to new cleaned up data + // neighs = new_neighs; + // neighs.sort(); + // neighs.unique(); //remove possible dups + // + // //reflect actual row count in model + // if(old_size < new_size) + // { + // beginInsertRows(QModelIndex(), old_size, new_size); + // insertRows(old_size, new_size - old_size); + // endInsertRows(); + // } + // else if(new_size < old_size) + // { + // beginRemoveRows(QModelIndex(), new_size, old_size); + // removeRows(old_size, old_size - new_size); + // endRemoveRows(); + // } + // //update data in ui, to avoid unnecessary redraw and ui updates, updating only changed elements + // //TODO: libretroshare should implement a way to obtain only changed elements via some signalling non-blocking api. + // { + // size_t ii1 = 0; + // for(auto i1 = neighs.begin(), end1 = neighs.end(), i2 = old_neighs.begin(), end2 = old_neighs.end(); i1 != end1; ++i1, ++i2, ii1++) + // { + // if(i2 == end2) + // break; + // if(*i1 != *i2) + // { + // QModelIndex topLeft = createIndex(ii1,0), bottomRight = createIndex(ii1, COLUMN_COUNT-1); + // emit dataChanged(topLeft, bottomRight); + // } + // } + // } + // if(new_size > old_size) + // { + // QModelIndex topLeft = createIndex(old_size ? old_size -1 : 0 ,0), bottomRight = createIndex(new_size -1, COLUMN_COUNT-1); + // emit dataChanged(topLeft, bottomRight); + // } + // //dirty solution for initial data fetch + // //TODO: do it properly! + // if(!old_size) + // { + // beginResetModel(); + // endResetModel(); + // } + + + } +private: + static const uint32_t TRANSFERS_NB_DOWNLOADS_BITS_32BITS = 22 ; // Means 2^22 simultaneous transfers + static const uint32_t TRANSFERS_NB_DOWNLOADS_BIT_MASK_32BITS = 0x003fffff ; // actual bit mask corresponding to previous number of bits + static const uint32_t TRANSFERS_NB_SOURCES_BITS_32BITS = 10 ; // Means 2^10 simultaneous sources + + static bool convertTabEntryToRefPointer(uint32_t entry,int source_id,void *& ref) + { + if(source_id < -1) + { + std::cerr << "(EE) inconsistent source id = " << source_id << " in convertTabEntryToRefPointer()" << std::endl; + return false; + } + // the pointer is formed the following way: + // + // [ 10 bits | 22 bits ] + // + // This means that the whoel software has the following build-in limitation: + // * 1023 sources + // * 4M simultaenous file transfers + + if(uint32_t(source_id+1) >= (1u<= (1u<< TRANSFERS_NB_DOWNLOADS_BITS_32BITS)) + { + std::cerr << "(EE) cannot convert download index " << entry << " and source " << source_id << " to pointer." << std::endl; + return false ; + } + + ref = reinterpret_cast( ( uint32_t(1+source_id) << TRANSFERS_NB_DOWNLOADS_BITS_32BITS ) + ( (entry+1) & TRANSFERS_NB_DOWNLOADS_BIT_MASK_32BITS)) ; + + return true; + } + + static bool convertRefPointerToTabEntry(void *ref,uint32_t& entry,int& source_id) + { + // we pack the couple (id of DL, id of source) into a single 32-bits pointer that is required by the AbstractItemModel class. + +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + uint32_t ntr = uint32_t( *reinterpret_cast(&ref) & TRANSFERS_NB_DOWNLOADS_BIT_MASK_32BITS ) ; + uint32_t src = ( *reinterpret_cast(&ref)) >> TRANSFERS_NB_DOWNLOADS_BITS_32BITS ; +#pragma GCC diagnostic pop + + if(ntr == 0) + { + std::cerr << "ERROR! ntr=0!"<< std::endl; + return false ; + } + + source_id = int(src) - 1 ; + entry = ntr - 1 ; + + return true; + } + + std::vector mDownloads ; // store the list of downloads, updated from rsFiles. +}; + class SortByNameItem : public QStandardItem { public: @@ -170,21 +636,23 @@ TransfersDialog::TransfersDialog(QWidget *parent) connect( ui.downloadList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( downloadListCustomPopupMenu( QPoint ) ) ); + DLListModel = new RsDownloadListModel ; + // Set Download list model - DLListModel = new QStandardItemModel(0,COLUMN_COUNT); - DLListModel->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name", "i.e: file name")); - DLListModel->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); - DLListModel->setHeaderData(COLUMN_COMPLETED, Qt::Horizontal, tr("Completed", "")); - DLListModel->setHeaderData(COLUMN_DLSPEED, Qt::Horizontal, tr("Speed", "i.e: Download speed")); - DLListModel->setHeaderData(COLUMN_PROGRESS, Qt::Horizontal, tr("Progress / Availability", "i.e: % downloaded")); - DLListModel->setHeaderData(COLUMN_SOURCES, Qt::Horizontal, tr("Sources", "i.e: Sources")); - DLListModel->setHeaderData(COLUMN_STATUS, Qt::Horizontal, tr("Status")); - DLListModel->setHeaderData(COLUMN_PRIORITY, Qt::Horizontal, tr("Speed / Queue position")); - DLListModel->setHeaderData(COLUMN_REMAINING, Qt::Horizontal, tr("Remaining")); - DLListModel->setHeaderData(COLUMN_DOWNLOADTIME, Qt::Horizontal, tr("Download time", "i.e: Estimated Time of Arrival / Time left")); - DLListModel->setHeaderData(COLUMN_ID, Qt::Horizontal, tr("Hash")); - DLListModel->setHeaderData(COLUMN_LASTDL, Qt::Horizontal, tr("Last Time Seen", "i.e: Last Time Receiced Data")); - DLListModel->setHeaderData(COLUMN_PATH, Qt::Horizontal, tr("Path", "i.e: Where file is saved")); +// DLListModel = new QStandardItemModel(0,COLUMN_COUNT); +// DLListModel->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name", "i.e: file name")); +// DLListModel->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); +// DLListModel->setHeaderData(COLUMN_COMPLETED, Qt::Horizontal, tr("Completed", "")); +// DLListModel->setHeaderData(COLUMN_DLSPEED, Qt::Horizontal, tr("Speed", "i.e: Download speed")); +// DLListModel->setHeaderData(COLUMN_PROGRESS, Qt::Horizontal, tr("Progress / Availability", "i.e: % downloaded")); +// DLListModel->setHeaderData(COLUMN_SOURCES, Qt::Horizontal, tr("Sources", "i.e: Sources")); +// DLListModel->setHeaderData(COLUMN_STATUS, Qt::Horizontal, tr("Status")); +// DLListModel->setHeaderData(COLUMN_PRIORITY, Qt::Horizontal, tr("Speed / Queue position")); +// DLListModel->setHeaderData(COLUMN_REMAINING, Qt::Horizontal, tr("Remaining")); +// DLListModel->setHeaderData(COLUMN_DOWNLOADTIME, Qt::Horizontal, tr("Download time", "i.e: Estimated Time of Arrival / Time left")); +// DLListModel->setHeaderData(COLUMN_ID, Qt::Horizontal, tr("Hash")); +// DLListModel->setHeaderData(COLUMN_LASTDL, Qt::Horizontal, tr("Last Time Seen", "i.e: Last Time Receiced Data")); +// DLListModel->setHeaderData(COLUMN_PATH, Qt::Horizontal, tr("Path", "i.e: Where file is saved")); DLLFilterModel = new QSortFilterProxyModel(this); DLLFilterModel->setSourceModel( DLListModel); @@ -211,39 +679,37 @@ TransfersDialog::TransfersDialog(QWidget *parent) selection = ui.downloadList->selectionModel(); ui.downloadList->setSelectionMode(QAbstractItemView::ExtendedSelection); - ui.downloadList->setRootIsDecorated(true); - - /* Set header resize modes and initial section sizes Downloads TreeView*/ +// /* Set header resize modes and initial section sizes Downloads TreeView*/ QHeaderView * dlheader = ui.downloadList->header () ; - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_NAME, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SIZE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_COMPLETED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DLSPEED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PROGRESS, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SOURCES, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_STATUS, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PRIORITY, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_REMAINING, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DOWNLOADTIME, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_ID, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_LASTDL, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PATH, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_NAME, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SIZE, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_COMPLETED, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DLSPEED, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PROGRESS, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SOURCES, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_STATUS, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PRIORITY, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_REMAINING, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DOWNLOADTIME, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_ID, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_LASTDL, QHeaderView::Interactive); +// QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PATH, QHeaderView::Interactive); - dlheader->resizeSection ( COLUMN_NAME, 170 ); - dlheader->resizeSection ( COLUMN_SIZE, 70 ); - dlheader->resizeSection ( COLUMN_COMPLETED, 75 ); - dlheader->resizeSection ( COLUMN_DLSPEED, 75 ); - dlheader->resizeSection ( COLUMN_PROGRESS, 170 ); - dlheader->resizeSection ( COLUMN_SOURCES, 90 ); - dlheader->resizeSection ( COLUMN_STATUS, 100 ); - dlheader->resizeSection ( COLUMN_PRIORITY, 100 ); - dlheader->resizeSection ( COLUMN_REMAINING, 100 ); - dlheader->resizeSection ( COLUMN_DOWNLOADTIME, 100 ); - dlheader->resizeSection ( COLUMN_ID, 100 ); - dlheader->resizeSection ( COLUMN_LASTDL, 100 ); - dlheader->resizeSection ( COLUMN_PATH, 100 ); +// dlheader->resizeSection ( COLUMN_NAME, 170 ); +// dlheader->resizeSection ( COLUMN_SIZE, 70 ); +// dlheader->resizeSection ( COLUMN_COMPLETED, 75 ); +// dlheader->resizeSection ( COLUMN_DLSPEED, 75 ); +// dlheader->resizeSection ( COLUMN_PROGRESS, 170 ); +// dlheader->resizeSection ( COLUMN_SOURCES, 90 ); +// dlheader->resizeSection ( COLUMN_STATUS, 100 ); +// dlheader->resizeSection ( COLUMN_PRIORITY, 100 ); +// dlheader->resizeSection ( COLUMN_REMAINING, 100 ); +// dlheader->resizeSection ( COLUMN_DOWNLOADTIME, 100 ); +// dlheader->resizeSection ( COLUMN_ID, 100 ); +// dlheader->resizeSection ( COLUMN_LASTDL, 100 ); +// dlheader->resizeSection ( COLUMN_PATH, 100 ); // set default column and sort order for download ui.downloadList->sortByColumn(COLUMN_NAME, Qt::AscendingOrder); @@ -867,6 +1333,7 @@ void TransfersDialog::setDestinationDirectory() } } +/* int TransfersDialog::addDLItem(int row, const FileInfo &fileInfo) { QString fileHash = QString::fromStdString(fileInfo.hash.toStdString()); @@ -915,7 +1382,7 @@ int TransfersDialog::addDLItem(int row, const FileInfo &fileInfo) else file = QFileInfo(QString::fromUtf8(rsFiles->getPartialsDirectory().c_str()), QString::fromUtf8(fileInfo.hash.toStdString().c_str())); - /*Get Last Access on File */ + //Get Last Access on File if (file.exists()) qi64LastDL = file.lastModified().toTime_t(); } @@ -987,8 +1454,7 @@ int TransfersDialog::addDLItem(int row, const FileInfo &fileInfo) int active = 0; if (fileInfo.downloadStatus != FT_STATE_COMPLETE) { - for (std::list::const_iterator pit = fileInfo.peers.begin() - ; pit != fileInfo.peers.end(); ++pit) + for (std::vector::const_iterator pit = fileInfo.peers.begin() ; pit != fileInfo.peers.end(); ++pit) { const TransferInfo &transferInfo = *pit; @@ -1009,7 +1475,7 @@ int TransfersDialog::addDLItem(int row, const FileInfo &fileInfo) used_rows.insert(row_id); - /* get the sources (number of online peers) */ + // get the sources (number of online peers) if (transferInfo.tfRate > 0 && fileInfo.downloadStatus == FT_STATE_DOWNLOADING) ++active; } @@ -1144,6 +1610,7 @@ int TransfersDialog::addPeerToDLItem(QStandardItem *dlItem, const RsPeerId& peer return childRow; } +*/ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) { @@ -1185,8 +1652,7 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) double peerULSpeedTotal = 0; bool bOnlyOne = ( fileInfo.peers.size() == 1 ); - for(std::list::const_iterator pit = fileInfo.peers.begin() - ; pit != fileInfo.peers.end(); ++pit) + for(std::vector::const_iterator pit = fileInfo.peers.begin() ; pit != fileInfo.peers.end(); ++pit) { const TransferInfo &transferInfo = *pit; @@ -1329,67 +1795,69 @@ void TransfersDialog::updateDisplay() void TransfersDialog::insertTransfers() { - /* disable for performance issues, enable after insert all transfers */ - ui.downloadList->setSortingEnabled(false); + DLListModel->update_transfers(); - /* get the download lists */ - std::list downHashes; - rsFiles->FileDownloads(downHashes); - - /* build set for quick search */ - std::set hashs; - - for (std::list::iterator it = downHashes.begin(); it != downHashes.end(); ++it) { - hashs.insert(*it); - } - - /* add downloads, first iterate all rows in list */ - - int rowCount = DLListModel->rowCount(); - - for (int row = 0; row < rowCount; ) { - RsFileHash hash ( DLListModel->item(row, COLUMN_ID)->data(Qt::UserRole).toString().toStdString()); - - std::set::iterator hashIt = hashs.find(hash); - if (hashIt == hashs.end()) { - // remove not existing downloads - DLListModel->removeRow(row); - rowCount = DLListModel->rowCount(); - continue; - } - - FileInfo fileInfo; - if (!rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, fileInfo)) { - DLListModel->removeRow(row); - rowCount = DLListModel->rowCount(); - continue; - } - - hashs.erase(hashIt); - - if (addDLItem(row, fileInfo) < 0) { - DLListModel->removeRow(row); - rowCount = DLListModel->rowCount(); - continue; - } - - ++row; - } - - /* then add new downloads to the list */ - - for (std::set::iterator hashIt = hashs.begin() - ; hashIt != hashs.end(); ++hashIt) - { - FileInfo fileInfo; - if (!rsFiles->FileDetails(*hashIt, RS_FILE_HINTS_DOWNLOAD, fileInfo)) { - continue; - } - - addDLItem(-1, fileInfo); - } - - ui.downloadList->setSortingEnabled(true); +// /* disable for performance issues, enable after insert all transfers */ +// ui.downloadList->setSortingEnabled(false); +// +// /* get the download lists */ +// std::list downHashes; +// rsFiles->FileDownloads(downHashes); +// +// /* build set for quick search */ +// std::set hashs; +// +// for (std::list::iterator it = downHashes.begin(); it != downHashes.end(); ++it) { +// hashs.insert(*it); +// } +// +// /* add downloads, first iterate all rows in list */ +// +// int rowCount = DLListModel->rowCount(); +// +// for (int row = 0; row < rowCount; ) { +// RsFileHash hash ( DLListModel->item(row, COLUMN_ID)->data(Qt::UserRole).toString().toStdString()); +// +// std::set::iterator hashIt = hashs.find(hash); +// if (hashIt == hashs.end()) { +// // remove not existing downloads +// DLListModel->removeRow(row); +// rowCount = DLListModel->rowCount(); +// continue; +// } +// +// FileInfo fileInfo; +// if (!rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, fileInfo)) { +// DLListModel->removeRow(row); +// rowCount = DLListModel->rowCount(); +// continue; +// } +// +// hashs.erase(hashIt); +// +// if (addDLItem(row, fileInfo) < 0) { +// DLListModel->removeRow(row); +// rowCount = DLListModel->rowCount(); +// continue; +// } +// +// ++row; +// } +// +// /* then add new downloads to the list */ +// +// for (std::set::iterator hashIt = hashs.begin() +// ; hashIt != hashs.end(); ++hashIt) +// { +// FileInfo fileInfo; +// if (!rsFiles->FileDetails(*hashIt, RS_FILE_HINTS_DOWNLOAD, fileInfo)) { +// continue; +// } +// +// addDLItem(-1, fileInfo); +// } +// +// ui.downloadList->setSortingEnabled(true); // Now show upload hashes // @@ -1402,7 +1870,7 @@ void TransfersDialog::insertTransfers() rsFiles->FileUploads(upHashes); /* build set for quick search */ - hashs.clear(); + std::set hashs; for(std::list::iterator it = upHashes.begin(); it != upHashes.end(); ++it) { hashs.insert(*it); @@ -1410,7 +1878,7 @@ void TransfersDialog::insertTransfers() /* add uploads, first iterate all rows in list */ - rowCount = ULListModel->rowCount(); + int rowCount = ULListModel->rowCount(); for (int row = 0; row < rowCount; ) { RsFileHash hash ( ULListModel->item(row, COLUMN_UHASH)->data(Qt::UserRole).toString().toStdString()); diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h index 30efe212d..4a7f5ed67 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h @@ -44,6 +44,7 @@ class FileProgressInfo; class SearchDialog; class LocalSharedFilesDialog; class RemoteSharedFilesDialog; +class RsDownloadListModel; class TransfersDialog : public RsAutoUpdatePage { @@ -166,7 +167,7 @@ signals: private: QString getPeerName(const RsPeerId &peer_id, QString &iconName, QString &tooltip) const ; - QStandardItemModel *DLListModel; + RsDownloadListModel *DLListModel; QSortFilterProxyModel *DLLFilterModel; QStandardItemModel *ULListModel; QItemSelectionModel *selection; @@ -260,8 +261,8 @@ private: public slots: // these four functions add entries to the transfers dialog, and return the row id of the entry modified/added - int addDLItem(int row, const FileInfo &fileInfo); - int addPeerToDLItem(QStandardItem* dlItem, const RsPeerId &peer_ID, const QString &coreID, double dlspeed, uint32_t status, const FileProgressInfo &peerInfo); +// int addDLItem(int row, const FileInfo &fileInfo); +// int addPeerToDLItem(QStandardItem* dlItem, const RsPeerId &peer_ID, const QString &coreID, double dlspeed, uint32_t status, const FileProgressInfo &peerInfo); int addULItem(int row, const FileInfo &fileInfo); int addPeerToULItem(QStandardItem* ulItem, const RsPeerId &peer_ID, const QString &coreID, qlonglong completed, double ulspeed, const FileProgressInfo &peerInfo); diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index d6bd38666..e20d3d9b8 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -1308,7 +1308,7 @@ static void processList(const QStringList &list, const QString &textSingular, co FileInfo finfo ; rsFiles->FileDetails(RsFileHash(link.hash().toStdString()), RS_FILE_HINTS_REMOTE, finfo) ; - for(std::list::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) + for(std::vector::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) { #ifdef DEBUG_RSLINK std::cerr << " adding peerid " << (*it).peerId << std::endl ; diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.cpp b/retroshare-gui/src/gui/feeds/SubFileItem.cpp index 250d85cad..0e3350127 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.cpp +++ b/retroshare-gui/src/gui/feeds/SubFileItem.cpp @@ -630,7 +630,7 @@ void SubFileItem::download() FileInfo finfo ; rsFiles->FileDetails(mFileHash,RS_FILE_HINTS_REMOTE,finfo) ; - for(std::list::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) + for(std::vector::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it) sources.push_back((*it).peerId) ; // TEMP diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp index b9b84b894..b3170efa4 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp @@ -248,7 +248,7 @@ void GxsChannelFilesStatusWidget::download() FileInfo fileInfo; rsFiles->FileDetails(mFile.mHash, RS_FILE_HINTS_REMOTE, fileInfo); - for(std::list::const_iterator it = fileInfo.peers.begin(); it != fileInfo.peers.end(); ++it) { + for(std::vector::const_iterator it = fileInfo.peers.begin(); it != fileInfo.peers.end(); ++it) { sources.push_back((*it).peerId); }