/*************************************:*************************** * RetroShare is distributed under the following license: * * Copyright (C) 2006 - 2009 RetroShare Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. ****************************************************************/ #include #include "RemoteDirModel.h" #include "rsiface/rsfiles.h" #include "rsiface/rstypes.h" #include #include #include #include #include #include #include #include "util/misc.h" /***** * #define RDM_DEBUG ****/ RemoteDirModel::RemoteDirModel(bool mode, QObject *parent) : QAbstractItemModel(parent), RemoteMode(mode), nIndex(1), indexSet(1) /* ass zero index cant be used */, ageIndicator(IND_ALWAYS) { setSupportedDragActions(Qt::CopyAction); treeStyle(); } void RemoteDirModel::treeStyle() { categoryIcon.addPixmap(QPixmap(":/images/folder16.png"), QIcon::Normal, QIcon::Off); categoryIcon.addPixmap(QPixmap(":/images/folder_video.png"), QIcon::Normal, QIcon::On); peerIcon = QIcon(":/images/user/identity16.png"); } bool RemoteDirModel::hasChildren(const QModelIndex &parent) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::hasChildren() :" << parent.internalPointer(); std::cerr << ": "; #endif if (!parent.isValid()) { #ifdef RDM_DEBUG std::cerr << "root -> true "; std::cerr << std::endl; #endif return true; } void *ref = parent.internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_CHILDREN; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { /* error */ #ifdef RDM_DEBUG std::cerr << "lookup failed -> false"; std::cerr << std::endl; #endif return false; } if (details.type == DIR_TYPE_FILE) { #ifdef RDM_DEBUG std::cerr << "lookup FILE -> false"; std::cerr << std::endl; #endif return false; } /* PERSON/DIR*/ #ifdef RDM_DEBUG std::cerr << "lookup PER/DIR #" << details.count; std::cerr << std::endl; #endif return (details.count > 0); /* do we have children? */ } int RemoteDirModel::rowCount(const QModelIndex &parent) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::rowCount(): " << parent.internalPointer(); std::cerr << ": "; #endif void *ref = (parent.isValid())? parent.internalPointer() : NULL ; DirDetails details; uint32_t flags = DIR_FLAGS_CHILDREN; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { #ifdef RDM_DEBUG std::cerr << "lookup failed -> 0"; std::cerr << std::endl; #endif return 0; } if (details.type == DIR_TYPE_FILE) { #ifdef RDM_DEBUG std::cerr << "lookup FILE: 0"; std::cerr << std::endl; #endif return 0; } /* else PERSON/DIR*/ #ifdef RDM_DEBUG std::cerr << "lookup PER/DIR #" << details.count; std::cerr << std::endl; #endif return details.count; } int RemoteDirModel::columnCount(const QModelIndex &parent) const { return 5; } QString RemoteDirModel::getFlagsString(uint32_t flags) { switch(flags & (DIR_FLAGS_NETWORK_WIDE|DIR_FLAGS_BROWSABLE)) { case DIR_FLAGS_NETWORK_WIDE: return QString("Anonymous") ; case DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE: return QString("Anonymous and browsable by friends") ; case DIR_FLAGS_BROWSABLE: return QString("Only browsable by friends") ; default: return QString() ; } } QString RemoteDirModel::getAgeIndicatorString(const DirDetails &details) const { QString ret(""); QString nind("NEW"); QString oind("OLD"); uint32_t age = details.age; switch (ageIndicator) { case IND_LAST_DAY: if (age < 24 * 60 * 60) return nind; break; case IND_LAST_WEEK: if (age < 7 * 24 * 60 * 60) return nind; break; case IND_LAST_MONTH: if (age < 30 * 24 * 60 * 60) return nind; break; // case IND_OLDER: // if (age >= 30 * 24 * 60 * 60) return oind; // break; case IND_ALWAYS: return ret; default: return ret; } return ret; } QVariant RemoteDirModel::data(const QModelIndex &index, int role) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::data(): " << index.internalPointer(); std::cerr << ": "; std::cerr << std::endl; #endif if (!index.isValid()) return QVariant(); /* get the data from the index */ void *ref = index.internalPointer(); int coln = index.column(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { return QVariant(); } if (role == RemoteDirModel::FileNameRole) { FileInfo finfo; rsFiles->FileDetails(details.hash, 0, finfo); return QString::fromStdString(finfo.path) ; } if (role == Qt::TextColorRole) { FileInfo finfo; rsFiles->FileDetails(details.hash, 0, finfo); if(details.min_age > ageIndicator) return Qt::gray ; else return Qt::black ; } if (role == Qt::DecorationRole) { FileInfo finfo; rsFiles->FileDetails(details.hash, 0, finfo); if (details.type == DIR_TYPE_PERSON) { switch(coln) { case 0: if(details.min_age > ageIndicator) { return QIcon(":/images/folder_grey.png"); } else if (ageIndicator == IND_LAST_DAY ) { return QIcon(":/images/folder_green.png"); } else if (ageIndicator == IND_LAST_WEEK ) { return QIcon(":/images/folder_yellow.png"); } else if (ageIndicator == IND_LAST_MONTH ) { return QIcon(":/images/folder_red.png"); } else { return (QIcon(peerIcon)); } break; } } else if (details.type == DIR_TYPE_DIR) { switch(coln) { case 0: if(details.min_age > ageIndicator) { return QIcon(":/images/folder_grey.png"); } else if (ageIndicator == IND_LAST_DAY ) { return QIcon(":/images/folder_green.png"); } else if (ageIndicator == IND_LAST_WEEK ) { return QIcon(":/images/folder_yellow.png"); } else if (ageIndicator == IND_LAST_MONTH ) { return QIcon(":/images/folder_red.png"); } else { return(QIcon(categoryIcon)); } break; } } else if (details.type == DIR_TYPE_FILE) /* File */ { // extensions predefined //QString name; switch(coln) { case 0: QString ext = QFileInfo(QString::fromStdString(details.name)).suffix(); if (ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "gif" || ext == "bmp" || ext == "ico" || ext == "svg") { //setIcon(0, QIcon(":/images/FileTypePicture.png")); QIcon icon(":/images/FileTypePicture.png"); return icon; } else if (ext == "avi" || ext == "AVI" || ext == "mpg" || ext == "mpeg" || ext == "wmv" || ext == "ogm" || ext == "mkv" || ext == "mp4" || ext == "flv" || ext == "mov" || ext == "vob" || ext == "qt" || ext == "rm" || ext == "3gp") { //setIcon(0, QIcon(":/images/videofile.png")); QIcon icon(":/images/FileTypeVideo.png"); return icon; } else if (ext == "ogg" || ext == "mp3" || ext == "wav" || ext == "wma" || ext == "xpm") { //setIcon(0, QIcon(":/images/soundfile.png")); QIcon icon(":/images/FileTypeAudio.png"); return icon; } else if (ext == "tar" || ext == "bz2" || ext == "zip" || ext == "gz" || ext == "7z" || ext == "rar" || ext == "rpm" || ext == "deb") { //setIcon(0, QIcon(":/images/compressedfile.png")); QIcon icon(":/images/FileTypeArchive.png"); return icon; } else if (ext == "app" || ext == "bat" || ext == "cgi" || ext == "com" || ext == "bin" || ext == "exe" || ext == "js" || ext == "pif" || ext == "py" || ext == "pl" || ext == "sh" || ext == "vb" || ext == "ws") { return(QIcon(":/images/FileTypeProgram.png")); } else if (ext == "iso" || ext == "nrg" || ext == "mdf" ) { //setIcon(0, QIcon(":/images/txtfile.png")); QIcon icon(":/images/FileTypeCDImage.png"); return icon; } else if (ext == "txt" || ext == "cpp" || ext == "c" || ext == "h") { //setIcon(0, QIcon(":/images/txtfile.png")); QIcon icon(":/images/FileTypeDocument.png"); return icon; } else if (ext == "doc" || ext == "rtf" || ext == "sxw" || ext == "xls" || ext == "sxc" || ext == "odt" || ext == "ods") { //setIcon(0, QIcon(":/images/docfile.png")); QIcon icon(":/images/FileTypeDocument.png"); return icon; } else if (ext == "html" || ext == "htm" || ext == "php") { //setIcon(0, QIcon(":/images/netfile.png")); QIcon icon(":/images/FileTypeDocument.png"); return icon; } else { //setIcon(0, QIcon(":/images/file.png")); QIcon icon(":/images/FileTypeAny.png"); return icon; } break; } } else { return QVariant(); } } /************* Qt::EditRole Qt::ToolTipRole Qt::StatusTipRole Qt::WhatsThisRole Qt::SizeHintRole ****************/ if (role == Qt::DisplayRole) { /* * Person: name, id, 0, 0; * File : name, size, rank, (0) ts * Dir : name, (0) count, (0) path, (0) ts */ if (details.type == DIR_TYPE_PERSON) /* Person */ { switch(coln) { case 0: return QString::fromStdString(details.name); break; case 1: return QString() ; break; default: return QString() ; break; } } else if (details.type == DIR_TYPE_FILE) /* File */ { switch(coln) { case 0: return QString::fromUtf8(details.name.c_str()); break; case 1: { std::ostringstream out; return misc::friendlyUnit(details.count); } break; case 2: { std::ostringstream out; return misc::userFriendlyDuration(details.age); } break; case 3: { return getFlagsString(details.flags); } break; case 4: { QString ind(""); if (ageIndicator != IND_ALWAYS) ind = getAgeIndicatorString(details); return ind; } break; default: return QString(tr("FILE")); break; } } else if (details.type == DIR_TYPE_DIR) /* Dir */ { switch(coln) { case 0: return QString::fromUtf8(details.name.c_str()); break; case 1: //return QString(""); { std::ostringstream out; out << details.count; return QString::fromStdString(out.str()); } break; case 2: return QString::fromUtf8("Folder"); break; case 3: return getFlagsString(details.flags); break; // case 4: // { // if (ageIndicator == IND_DEFAULT) // return QString(""); // QModelIndex pidx = parent(index); // QModelIndex pidxs = pidx.sibling(pidx.row(), 4); // if (pidxs.isValid() && pidxs.data() != tr("")) // return pidxs.data(); // else { // QString ind(""); // getAgeIndicatorRec(details, ind); // return ind; // } // } // break; default: return QString(tr("DIR")); break; } } } /* end of DisplayRole */ return QVariant(); if (role == Qt::TextAlignmentRole) { if(coln == 1) { return int( Qt::AlignLeft | Qt::AlignVCenter); } } return QVariant(); } void RemoteDirModel::getAgeIndicatorRec(DirDetails &details, QString &ret) const { if (details.type == DIR_TYPE_FILE) { ret = getAgeIndicatorString(details); return; } else if (details.type == DIR_TYPE_DIR && ret == tr("")) { std::list::iterator it; for (it = details.children.begin(); it != details.children.end(); it++) { void *ref = it->ref; DirDetails childDetails; uint32_t flags; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (rsFiles->RequestDirDetails(ref, childDetails, flags) && ret == tr("")) getAgeIndicatorRec(childDetails, ret); } } } QVariant RemoteDirModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::SizeHintRole) { int defw = 50; int defh = 21; if (section < 2) { defw = 200; } return QSize(defw, defh); } if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { switch(section) { case 0: if (RemoteMode) { return QString(tr("Friends Directories")); } else { return QString(tr("My Directories")); } break; case 1: return QString(tr("Size")); break; case 2: return QString(tr("Age")); break; case 3: return QString(tr("Share Type")); break; case 4: return QString(tr("What's new")); break; } return QString("Column %1").arg(section); } else return QString("Row %1").arg(section); } QModelIndex RemoteDirModel::index(int row, int column, const QModelIndex & parent) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::index(): " << parent.internalPointer(); std::cerr << ": row:" << row << " col:" << column << " "; #endif if(row < 0) return QModelIndex() ; void *ref = (parent.isValid()) ? parent.internalPointer() : NULL; /******** if (!RemoteMode) { remote = &(rsiface->getLocalDirectoryList()); } ********/ DirDetails details; uint32_t flags = DIR_FLAGS_CHILDREN; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { #ifdef RDM_DEBUG std::cerr << "lookup failed -> invalid"; std::cerr << std::endl; #endif return QModelIndex(); } /* now iterate through the details to * get the reference number */ std::list::iterator it; int i = 0; for(it = details.children.begin(); ((i < row) && (it != details.children.end())); ++it,++i) ; if (it == details.children.end()) { #ifdef RDM_DEBUG std::cerr << "wrong number of children -> invalid"; std::cerr << std::endl; #endif return QModelIndex(); } #ifdef RDM_DEBUG std::cerr << "success index(" << row << "," << column << "," << it->ref << ")"; std::cerr << std::endl; #endif /* we can just grab the reference now */ return createIndex(row, column, it->ref); } QModelIndex RemoteDirModel::parent( const QModelIndex & index ) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::parent(): " << index.internalPointer(); std::cerr << ": "; #endif /* create the index */ if (!index.isValid()) { #ifdef RDM_DEBUG std::cerr << "Invalid Index -> invalid"; std::cerr << std::endl; #endif /* Parent is invalid too */ return QModelIndex(); } void *ref = index.internalPointer(); DirDetails details; uint32_t flags = (RemoteMode)?DIR_FLAGS_REMOTE:DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { #ifdef RDM_DEBUG std::cerr << "Failed Lookup -> invalid"; std::cerr << std::endl; #endif return QModelIndex(); } if (!(details.parent)) { #ifdef RDM_DEBUG std::cerr << "success. parent is Root/NULL --> invalid"; std::cerr << std::endl; #endif return QModelIndex(); } #ifdef RDM_DEBUG std::cerr << "success index(" << details.prow << ",0," << details.parent << ")"; std::cerr << std::endl; #endif return createIndex(details.prow, 0, details.parent); } Qt::ItemFlags RemoteDirModel::flags( const QModelIndex & index ) const { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::flags()"; std::cerr << std::endl; #endif if (!index.isValid()) return (Qt::ItemIsSelectable); // Error. void *ref = index.internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) return Qt::ItemIsSelectable; // Error. switch(details.type) { case DIR_TYPE_PERSON: return Qt::ItemIsEnabled; case DIR_TYPE_DIR: return Qt::ItemIsSelectable | Qt::ItemIsEnabled; default: ; case DIR_TYPE_FILE: return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled; } } // The other flags... //Qt::ItemIsUserCheckable //Qt::ItemIsEditable //Qt::ItemIsDropEnabled //Qt::ItemIsTristate /* Callback from */ void RemoteDirModel::preMods() { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::preMods()" << std::endl; #endif //modelAboutToBeReset(); // reset(); layoutAboutToBeChanged(); } /* Callback from */ void RemoteDirModel::postMods() { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::postMods()" << std::endl; #endif //modelReset(); layoutChanged(); //reset(); } //void RemoteDirModel::update (const QModelIndex &index ) //{ //#ifdef RDM_DEBUG // //std::cerr << "Directory Request(" << id << ") : "; // //std::cerr << path << std::endl; //#endif // //rsFiles -> RequestDirectories(id, path, 1); //} void RemoteDirModel::downloadSelected(QModelIndexList list) { if (!RemoteMode) { #ifdef RDM_DEBUG std::cerr << "Cannot download from local" << std::endl; #endif } /* so for all the selected .... get the name out, * make it into something the RsControl can understand */ std::vector dirVec; getDirDetailsFromSelect(list, dirVec); /* Fire off requests */ for (int i = 0, n = dirVec.size(); i < n; ++i) { if (!RemoteMode) { continue; /* don't try to download local stuff */ } const DirDetails& details = dirVec[i]; /* if it is a file */ if (details.type == DIR_TYPE_FILE) { std::cerr << "RemoteDirModel::downloadSelected() Calling File Request"; std::cerr << std::endl; std::list srcIds; srcIds.push_back(details.id); rsFiles -> FileRequest(details.name, details.hash, details.count, "", RS_FILE_HINTS_NETWORK_WIDE, srcIds); } /* if it is a dir, copy all files included*/ else if (details.type == DIR_TYPE_DIR) { int prefixLen = details.path.rfind(details.name); if (prefixLen < 0) continue; downloadDirectory(details, prefixLen); } } } /* recursively download a directory */ void RemoteDirModel::downloadDirectory(const DirDetails & dirDetails, int prefixLen) { if (dirDetails.type & DIR_TYPE_FILE) { std::list srcIds; QString cleanPath = QDir::cleanPath((rsFiles->getDownloadDirectory() + "/" + dirDetails.path.substr(prefixLen)).c_str()); srcIds.push_back(dirDetails.id); rsFiles->FileRequest(dirDetails.name, dirDetails.hash, dirDetails.count, cleanPath.toStdString(), RS_FILE_HINTS_NETWORK_WIDE, srcIds); } else if (dirDetails.type & DIR_TYPE_DIR) { std::list::const_iterator it; QDir dwlDir(rsFiles->getDownloadDirectory().c_str()); QString cleanPath = QDir::cleanPath(QString(dirDetails.path.c_str()).right(dirDetails.path.length() - prefixLen)); if (!dwlDir.mkpath(cleanPath)) return; for (it = dirDetails.children.begin(); it != dirDetails.children.end(); it++) { if (!it->ref) continue; DirDetails subDirDetails; uint32_t flags = DIR_FLAGS_CHILDREN | DIR_FLAGS_REMOTE; if (!rsFiles->RequestDirDetails(it->ref, subDirDetails, flags)) continue; downloadDirectory(subDirDetails, prefixLen); } } } void RemoteDirModel::getDirDetailsFromSelect (QModelIndexList list, std::vector & dirVec) { dirVec.clear(); /* Fire off requests */ QModelIndexList::iterator it; for(it = list.begin(); it != list.end(); it++) { if(it->column()==1) { void *ref = it -> internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) { flags |= DIR_FLAGS_REMOTE; } else { flags |= DIR_FLAGS_LOCAL; } if (!rsFiles->RequestDirDetails(ref, details, flags)) { continue; } dirVec.push_back(details); } } } /**************************************************************************** * OLD RECOMMEND SYSTEM - DISABLED * */ void RemoteDirModel::getFileInfoFromIndexList(const QModelIndexList& list, std::list& file_details) { file_details.clear() ; #ifdef RDM_DEBUG std::cerr << "recommendSelected()" << std::endl; #endif if (RemoteMode) { #ifdef RDM_DEBUG std::cerr << "Cannot recommend remote! (should download)" << std::endl; #endif } /* Fire off requests */ std::set already_in ; for(QModelIndexList::const_iterator it(list.begin()); it != list.end(); ++it) if(it->column()==0) { void *ref = it -> internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) continue; if(details.type == DIR_TYPE_PERSON) continue ; #ifdef RDM_DEBUG std::cerr << "::::::::::::FileRecommend:::: " << std::endl; std::cerr << "Name: " << details.name << std::endl; std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Size: " << details.count << std::endl; std::cerr << "Path: " << details.path << std::endl; #endif // Note: for directories, the returned hash, is the peer id, so if we collect // dirs, we need to be a bit more conservative for the if(already_in.find(details.hash+details.name) == already_in.end()) { file_details.push_back(details) ; already_in.insert(details.hash+details.name) ; } } #ifdef RDM_DEBUG std::cerr << "::::::::::::Done FileRecommend" << std::endl; #endif } #if 0 void RemoteDirModel::recommendSelectedOnly(QModelIndexList list) { #ifdef RDM_DEBUG std::cerr << "recommendSelectedOnly()" << std::endl; #endif if (RemoteMode) { #ifdef RDM_DEBUG std::cerr << "Cannot recommend remote! (should download)" << std::endl; #endif } rsFiles->ClearInRecommend(); /* Fire off requests */ QModelIndexList::iterator it; for(it = list.begin(); it != list.end(); it++) { void *ref = it -> internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) { flags |= DIR_FLAGS_REMOTE; continue; /* don't recommend remote stuff */ } else { flags |= DIR_FLAGS_LOCAL; } if (!rsFiles->RequestDirDetails(ref, details, flags)) { continue; } #ifdef RDM_DEBUG std::cerr << "::::::::::::FileRecommend:::: " << std::endl; std::cerr << "Name: " << details.name << std::endl; std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Size: " << details.count << std::endl; std::cerr << "Path: " << details.path << std::endl; #endif rsFiles -> FileRecommend(details.name, details.hash, details.count); rsFiles -> SetInRecommend(details.name, true); } #ifdef RDM_DEBUG std::cerr << "::::::::::::Done FileRecommend" << std::endl; #endif } #endif /**************************************************************************** * OLD RECOMMEND SYSTEM - DISABLED ******/ void RemoteDirModel::openSelected(QModelIndexList qmil, bool openFolder) { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::openSelected()" << std::endl; #endif if (RemoteMode) { #ifdef RDM_DEBUG std::cerr << "Cannot open remote. Download first." << std::endl; #endif return; } std::list dirs_to_open; std::list files_info; std::list::iterator it; getFileInfoFromIndexList(qmil, files_info); for (it = files_info.begin(); it != files_info.end(); it++) { if ((*it).type & DIR_TYPE_PERSON) continue; std::string fullpath, name; rsFiles->ConvertSharedFilePath((*it).path, fullpath); int len = fullpath.length(); if (len && (fullpath[len - 1] != '/')) fullpath += '/'; if ((*it).type & DIR_TYPE_FILE) { name = fullpath + (*it).name; } else if ((*it).type & DIR_TYPE_DIR) { name = fullpath; } if (!openFolder) { if ((*it).type & DIR_TYPE_FILE) { QDesktopServices::openUrl(QUrl::fromLocalFile(name.c_str())); } } else { if (dirs_to_open.end() == std::find(dirs_to_open.begin(), dirs_to_open.end(), fullpath)) { dirs_to_open.push_back(fullpath); } } } if (openFolder) { std::list::iterator dit; for (dit = dirs_to_open.begin(); dit != dirs_to_open.end(); dit++) { std::cerr << "Opennign this folder: " << (*dit).c_str() << std::endl ; QDesktopServices::openUrl(QUrl::fromLocalFile((*dit).c_str())); } } #ifdef RDM_DEBUG std::cerr << "::::::::::::Done RemoteDirModel::openSelected()" << std::endl; #endif } void RemoteDirModel::getFilePaths(QModelIndexList list, std::list &fullpaths) { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::getFilePaths()" << std::endl; #endif if (RemoteMode) { #ifdef RDM_DEBUG std::cerr << "No File Paths for remote files" << std::endl; #endif return; } /* translate */ QModelIndexList::iterator it; for(it = list.begin(); it != list.end(); it++) { void *ref = it -> internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { #ifdef RDM_DEBUG std::cerr << "getFilePaths() Bad Request" << std::endl; #endif continue; } if (details.type != DIR_TYPE_FILE) { #ifdef RDM_DEBUG std::cerr << "getFilePaths() Not File" << std::endl; #endif continue; /* not file! */ } #ifdef RDM_DEBUG std::cerr << "::::::::::::File Details:::: " << std::endl; std::cerr << "Name: " << details.name << std::endl; std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Size: " << details.count << std::endl; std::cerr << "Path: " << details.path << std::endl; #endif std::string filepath = details.path + "/"; filepath += details.name; #ifdef RDM_DEBUG std::cerr << "Constructed FilePath: " << filepath << std::endl; #endif if (fullpaths.end() == std::find(fullpaths.begin(), fullpaths.end(), filepath)) { fullpaths.push_back(filepath); } } #ifdef RDM_DEBUG std::cerr << "::::::::::::Done getFilePaths" << std::endl; #endif } /* Drag and Drop Functionality */ QMimeData * RemoteDirModel::mimeData ( const QModelIndexList & indexes ) const { /* extract from each the member text */ std::string text; QModelIndexList::const_iterator it; std::map drags; std::map::iterator dit; for(it = indexes.begin(); it != indexes.end(); it++) { void *ref = it -> internalPointer(); DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) { flags |= DIR_FLAGS_REMOTE; } else { flags |= DIR_FLAGS_LOCAL; } if (!rsFiles->RequestDirDetails(ref, details, flags)) { continue; } #ifdef RDM_DEBUG std::cerr << "::::::::::::FileDrag:::: " << std::endl; std::cerr << "Name: " << details.name << std::endl; std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Size: " << details.count << std::endl; std::cerr << "Path: " << details.path << std::endl; #endif if (details.type != DIR_TYPE_FILE) { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::mimeData() Not File" << std::endl; #endif continue; /* not file! */ } if (drags.end() != (dit = drags.find(details.hash))) { #ifdef RDM_DEBUG std::cerr << "RemoteDirModel::mimeData() Duplicate" << std::endl; #endif continue; /* duplicate */ } drags[details.hash] = details.count; std::string line = details.name; line += "/"; line += details.hash; line += "/"; { std::ostringstream out; out << details.count; line += out.str(); line += "/"; } if (RemoteMode) { line += "Remote"; } else { line += "Local"; } line += "/\n"; text += line; } #ifdef RDM_DEBUG std::cerr << "Created MimeData:"; std::cerr << std::endl; std::cerr << text; std::cerr << std::endl; #endif QMimeData *data = new QMimeData(); data->setData("application/x-rsfilelist", QByteArray(text.c_str())); return data; } QStringList RemoteDirModel::mimeTypes () const { QStringList list; list.push_back("application/x-rsfilelist"); return list; } //============================================================================ bool RemoteDirModel::isDir ( const QModelIndex & index ) const { //if (RemoteMode) // only local files can be opened // return ; void *ref = index.internalPointer(); if (!ref) return false; DirDetails details; uint32_t flags = DIR_FLAGS_DETAILS; if (RemoteMode) flags |= DIR_FLAGS_REMOTE; else flags |= DIR_FLAGS_LOCAL; if (!rsFiles->RequestDirDetails(ref, details, flags)) { return false;//not good, but.... } return (details.type == DIR_TYPE_DIR) ; }