added dynamic menu for choosing download directory for files being transfered, and change the name of the destination file

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6156 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-02-27 16:59:16 +00:00
parent a086fd6d88
commit 5b4739352e
7 changed files with 180 additions and 10 deletions

View File

@ -1619,6 +1619,43 @@ std::string ftController::getPartialsDirectory()
return mPartialsPath;
}
bool ftController::setDestinationDirectory(const std::string& hash,const std::string& dest_dir)
{
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
std::map<std::string, ftFileControl*>::iterator it = mDownloads.find(hash);
if (it == mDownloads.end())
return false;
std::cerr << "(II) Changing destination of file " << it->second->mDestination << std::endl;
it->second->mDestination = dest_dir + '/' + it->second->mName ;
std::cerr << "(II) ...to " << it->second->mDestination << std::endl;
return true ;
}
bool ftController::setDestinationName(const std::string& hash,const std::string& dest_name)
{
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
std::map<std::string, ftFileControl*>::iterator it = mDownloads.find(hash);
if (it == mDownloads.end())
return false;
std::cerr << "(II) Changing destination of file " << it->second->mDestination << std::endl;
std::string dest_path ;
RsDirUtil::removeTopDir(it->second->mDestination, dest_path); /* remove fname */
it->second->mDestination = dest_path + '/' + dest_name ;
it->second->mName = dest_name ;
std::cerr << "(II) ...to " << it->second->mDestination << std::endl;
return true ;
}
bool ftController::FileDetails(const std::string &hash, FileInfo &info)
{
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/

View File

@ -146,6 +146,8 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
bool FileClearCompleted();
bool FlagFileComplete(std::string hash);
bool getFileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info);
bool setDestinationName(const std::string& hash,const std::string& dest_name) ;
bool setDestinationDirectory(const std::string& hash,const std::string& dest_name) ;
// Download speed
bool getPriority(const std::string& hash,DwlSpeed& p);

View File

@ -288,6 +288,14 @@ bool ftServer::FileRequest(const std::string& fname, const std::string& hash, ui
return true ;
}
bool ftServer::setDestinationName(const std::string& hash,const std::string& name)
{
return mFtController->setDestinationName(hash,name);
}
bool ftServer::setDestinationDirectory(const std::string& hash,const std::string& directory)
{
return mFtController->setDestinationDirectory(hash,directory);
}
bool ftServer::setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s)
{
return mFtController->setChunkStrategy(hash,s);

View File

@ -129,6 +129,8 @@ virtual bool FileRequest(const std::string& fname, const std::string& hash, uint
virtual bool FileCancel(const std::string& hash);
virtual bool FileControl(const std::string& hash, uint32_t flags);
virtual bool FileClearCompleted();
virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) ;
virtual bool setDestinationName(const std::string& hash,const std::string& new_name) ;
virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s) ;
virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ;
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ;

View File

@ -121,6 +121,8 @@ class RsFiles
/// Returns false is we already have the file. Otherwise, initiates the dl and returns true.
virtual bool FileRequest(const std::string& fname, const std::string& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<std::string>& srcIds) = 0;
virtual bool FileCancel(const std::string& hash) = 0;
virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) = 0;
virtual bool setDestinationName(const std::string& hash,const std::string& new_name) = 0;
virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy) = 0;
virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) = 0;
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() = 0;

View File

@ -24,6 +24,8 @@
#endif
#include <QMenu>
#include <QInputDialog>
#include <QFileDialog>
#include <QStandardItemModel>
#include <QTreeView>
#include <QShortcut>
@ -182,7 +184,7 @@ TransfersDialog::TransfersDialog(QWidget *parent)
m_bProcessSettings = false;
connect( ui.downloadList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( downloadListCostumPopupMenu( QPoint ) ) );
connect( ui.downloadList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( downloadListCustomPopupMenu( QPoint ) ) );
// Set Download list model
DLListModel = new QStandardItemModel(0,ID + 1);
@ -397,6 +399,10 @@ TransfersDialog::TransfersDialog(QWidget *parent)
connect(chunkRandomAct, SIGNAL(triggered()), this, SLOT(chunkRandom()));
playAct = new QAction(QIcon(IMAGE_PLAY), tr( "Play" ), this );
connect( playAct , SIGNAL( triggered() ), this, SLOT( openTransfer() ) );
renameFileAct = new QAction(QIcon(IMAGE_PRIORITYNORMAL), tr("Rename file..."), this);
connect(renameFileAct, SIGNAL(triggered()), this, SLOT(renameFile()));
specifyDestinationDirectoryAct = new QAction(QIcon(IMAGE_SEARCH),tr("Specify..."),this) ;
connect(specifyDestinationDirectoryAct,SIGNAL(triggered()),this,SLOT(chooseDestinationDirectory())) ;
// load settings
processSettings(true);
@ -489,7 +495,7 @@ void TransfersDialog::processSettings(bool bLoad)
// RsAutoUpdatePage::keyPressEvent(e) ;
//}
void TransfersDialog::downloadListCostumPopupMenu( QPoint /*point*/ )
void TransfersDialog::downloadListCustomPopupMenu( QPoint /*point*/ )
{
std::set<std::string> items;
std::set<std::string>::iterator it;
@ -500,7 +506,7 @@ void TransfersDialog::downloadListCostumPopupMenu( QPoint /*point*/ )
/* check which item is selected
* - if it is completed - play should appear in menu
*/
std::cerr << "TransfersDialog::downloadListCostumPopupMenu()" << std::endl;
std::cerr << "TransfersDialog::downloadListCustomPopupMenu()" << std::endl;
FileInfo info;
@ -543,7 +549,7 @@ void TransfersDialog::downloadListCostumPopupMenu( QPoint /*point*/ )
chunkMenu.addAction(chunkStreamingAct);
chunkMenu.addAction(chunkRandomAct);
QMenu contextMnu( this );
QMenu contextMnu( this );
if (addPlayOption)
contextMnu.addAction(playAct);
@ -581,8 +587,35 @@ void TransfersDialog::downloadListCostumPopupMenu( QPoint /*point*/ )
contextMnu.addMenu(&priorityQueueMenu) ;
if(all_downloading)
{
contextMnu.addMenu( &chunkMenu);
if(single)
contextMnu.addAction(renameFileAct) ;
QMenu *directoryMenu = contextMnu.addMenu(QIcon(IMAGE_OPENFOLDER),tr("Set destination directory")) ;
directoryMenu->addAction(specifyDestinationDirectoryAct);
// Now get the list of existing directories.
std::list<SharedDirInfo> dirs ;
rsFiles->getSharedDirectories(dirs) ;
for(std::list<SharedDirInfo>::const_iterator it(dirs.begin());it!=dirs.end();++it)
{
// check for existence of directory name
QFile directory(QString::fromUtf8((*it).filename.c_str())) ;
if(!directory.exists()) continue ;
if(!(directory.permissions() & QFile::WriteOwner)) continue ;
QAction *act = new QAction(QString::fromUtf8((*it).virtualname.c_str()),directoryMenu) ;
act->setData(QString::fromUtf8((*it).filename.c_str())) ;
connect(act,SIGNAL(triggered()),this,SLOT(setDestinationDirectory())) ;
directoryMenu->addAction(act) ;
}
}
if(!all_paused)
contextMnu.addAction( pauseAct);
if(!all_downld)
@ -642,6 +675,36 @@ void TransfersDialog::downloadListCostumPopupMenu( QPoint /*point*/ )
contextMnu.exec(QCursor::pos());
}
void TransfersDialog::chooseDestinationDirectory()
{
QString dest_dir = QFileDialog::getExistingDirectory(this,tr("Choose directory")) ;
if(dest_dir.isNull())
return ;
std::set<std::string> items ;
getSelectedItems(&items, NULL);
for(std::set<std::string>::const_iterator it(items.begin());it!=items.end();++it)
{
std::cerr << "Setting new directory " << dest_dir.toUtf8().data() << " to file " << *it << std::endl;
rsFiles->setDestinationDirectory(*it,dest_dir.toUtf8().data() ) ;
}
}
void TransfersDialog::setDestinationDirectory()
{
std::string dest_dir(qobject_cast<QAction*>(sender())->data().toString().toUtf8().data()) ;
std::set<std::string> items ;
getSelectedItems(&items, NULL);
for(std::set<std::string>::const_iterator it(items.begin());it!=items.end();++it)
{
std::cerr << "Setting new directory " << dest_dir << " to file " << *it << std::endl;
rsFiles->setDestinationDirectory(*it,dest_dir) ;
}
}
int TransfersDialog::addItem(int row, const FileInfo &fileInfo, const std::map<std::string, std::string> &versions)
{
QString fileHash = QString::fromStdString(fileInfo.hash);
@ -711,13 +774,13 @@ int TransfersDialog::addItem(int row, const FileInfo &fileInfo, const std::map<s
DLListModel->setItem(row, PROGRESS, new ProgressItem(NULL));
DLListModel->setItem(row, PRIORITY, new PriorityItem(NULL));
QString fileName = QString::fromUtf8(fileInfo.fname.c_str());
DLListModel->setData(DLListModel->index(row, NAME), fileName);
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong) fileInfo.size));
DLListModel->setData(DLListModel->index(row, ID), fileHash);
DLListModel->setData(DLListModel->index(row, NAME), FilesDefs::getIconFromFilename(fileName), Qt::DecorationRole);
}
QString fileName = QString::fromUtf8(fileInfo.fname.c_str());
DLListModel->setData(DLListModel->index(row, NAME), fileName);
DLListModel->setData(DLListModel->index(row, NAME), FilesDefs::getIconFromFilename(fileName), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, COMPLETED), QVariant((qlonglong)completed));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)fileDlspeed));
@ -1499,11 +1562,62 @@ void TransfersDialog::changeSpeed(int speed)
rsFiles->changeDownloadSpeed(*it, speed);
}
}
static bool checkFileName(const QString& name)
{
if(name.contains('/')) return false ;
if(name.contains('\\')) return false ;
if(name.contains('|')) return false ;
if(name.contains(':')) return false ;
if(name.contains('?')) return false ;
if(name.contains('>')) return false ;
if(name.contains('<')) return false ;
if(name.contains('*')) return false ;
if(name.length() == 0)
return false ;
if(name.length() > 255)
return false ;
return true ;
}
void TransfersDialog::renameFile()
{
std::set<std::string> items;
getSelectedItems(&items, NULL);
if(items.size() != 1)
{
std::cerr << "Can't rename more than one file. This should not be called." << std::endl;
return ;
}
std::string hash = *(items.begin()) ;
FileInfo info ;
if (!rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info))
return ;
bool ok = true ;
bool first = true ;
QString new_name ;
do
{
new_name = QInputDialog::getText(NULL,tr("Change file name"),first?tr("Please enter a new file name"):tr("Please enter a new--and valid--filename"),QLineEdit::Normal,QString::fromUtf8(info.fname.c_str()),&ok) ;
if(!ok)
return ;
first = false ;
}
while(!checkFileName(new_name)) ;
rsFiles->setDestinationName(hash, new_name.toUtf8().data());
}
void TransfersDialog::changeQueuePosition(QueueMove mv)
{
// std::cerr << "In changeQueuePosition (gui)"<< std::endl ;
// std::cerr << "In changeQueuePosition (gui)"<< std::endl ;
std::set<std::string> items;
std::set<std::string>::iterator it;
getSelectedItems(&items, NULL);

View File

@ -77,7 +77,7 @@ public slots:
private slots:
/** Create the context popup menu and it's submenus */
void downloadListCostumPopupMenu( QPoint point );
void downloadListCustomPopupMenu( QPoint point );
void cancel();
void forceCheck();
@ -86,6 +86,9 @@ private slots:
void copyLink();
void pasteLink();
void renameFile();
void setDestinationDirectory();
void chooseDestinationDirectory();
// void rootdecorated();
// void rootisnotdecorated();
@ -167,6 +170,8 @@ private:
QAction *detailsfileAct;
QAction *toggleShowCacheTransfersAct;
QAction *openCollectionAct;
QAction *renameFileAct;
QAction *specifyDestinationDirectoryAct;
bool m_bProcessSettings;
void processSettings(bool bLoad);