# # Machekku Open FileTransfer-Item Menu # # Version: 0.1 # Date: 2005-05-13 # # http://machekku.uaznia.net/jabber/psi/patches/ # # filetransdlg.cpp | 148 +++++++++++++++++++++++++++++++++++++++++++++++++------ # filetransdlg.h | 4 + # 2 files changed, 135 insertions(+), 17 deletions(-) # diff -X exclude -x src.pro -x *.diff -Naru psi_cvs-2005.05.08/psi/src/filetransdlg.cpp psi/psi/src/filetransdlg.cpp --- psi_cvs-2005.05.08/psi/src/filetransdlg.cpp Mon Feb 28 15:11:10 2005 +++ psi/psi/src/filetransdlg.cpp Fri May 13 04:38:04 2005 @@ -28,6 +28,10 @@ #include"psiiconset.h" #include"msgmle.h" +#ifdef Q_OS_WIN +# include +#endif + #if QT_VERSION >= 0x030200 typedef Q_UINT64 LARGE_TYPE; #else @@ -129,7 +133,7 @@ FileTransfer *ft; S5BConnection *c; Jid peer; - QString fileName, saveName; + QString fileName, saveName, fullPath; Q_LLONG fileSize, sent, offset, length; QString desc; bool sending; @@ -185,6 +189,7 @@ d->peer = to; QFileInfo fi(fname); d->fileName = fi.fileName(); + d->fullPath = fi.absFilePath(); d->fileSize = fi.size(); // TODO: large file support d->desc = desc; d->shift = calcShift(d->fileSize); @@ -253,6 +258,17 @@ return d->saveName; } +/*! + Returns full path of the file being sent + or full path where the file is being saved + (including ".part" before the transfer is finished) +*/ + +QString FileTransferHandler::fullPath() const +{ + return d->fullPath; +} + void FileTransferHandler::accept(const QString &saveName, const QString &fileName, Q_LLONG offset) { if(d->sending) @@ -262,6 +278,7 @@ d->offset = offset; d->length = d->fileSize; d->f.setName(saveName); + d->fullPath = QFileInfo(d->f).absFilePath(); d->ft->accept(offset); } @@ -920,6 +937,7 @@ QPixmap icon; bool sending; QString name; + QString path; Q_LLONG size; QString peer; QString rate; @@ -929,15 +947,18 @@ int timeRemaining; int id; int dist; - bool done; + bool done; // done = file is no longer being transferred: maybe it finished or maybe there was an error + bool finished; // finished = file transfer finished with a success :) QString error; - FileTransItem(QListView *parent, const QString &_name, Q_LLONG _size, const QString &_peer, bool _sending) + FileTransItem(QListView *parent, const QString &_name, const QString &_path, Q_LLONG _size, const QString &_peer, bool _sending) :QListViewItem(parent) { done = false; + finished = false; sending = _sending; name = _name; + path = _path; size = _size; peer = _peer; rate = FileTransDlg::tr("N/A"); @@ -1266,6 +1287,7 @@ :QListView(parent, name), QToolTip(viewport()) { connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), this, SLOT(qlv_contextMenuRequested(QListViewItem *, const QPoint &, int))); + connect(this, SIGNAL(doubleClicked(QListViewItem *, const QPoint &, int)), this, SLOT(qlv_doubleClicked(QListViewItem *, const QPoint &, int))); } void maybeTip(const QPoint &pos) @@ -1287,6 +1309,7 @@ signals: void itemCancel(int id); + void itemOpen(int id); void itemOpenDest(int id); void itemClear(int id); @@ -1301,17 +1324,25 @@ QPopupMenu p; p.insertItem(tr("&Cancel"), 0); p.insertSeparator(); - //p.insertItem(tr("&Open Destination Folder"), 1); +#ifdef Q_OS_WIN // FIX-ME: Open menu items - need to implement on other systems + p.insertItem(tr("&Open"), 3); + p.insertItem(tr("Open Containing &Folder"), 1); +#endif p.insertItem(tr("Cl&ear"), 2); - if(i->done) { + if ( i->done ) { p.setItemEnabled(0, false); } else { - //p.setItemEnabled(1, false); p.setItemEnabled(2, false); } + if ( !i->sending && !i->finished || i->path.isEmpty() ) { +#ifdef Q_OS_WIN // FIX-ME: Open menu items - need to implement on other systems + p.setItemEnabled(3, false); +#endif + } + int x = p.exec(pos); // TODO: what if item is deleted during exec? @@ -1324,6 +1355,28 @@ itemOpenDest(i->id); else if(x == 2) itemClear(i->id); + else if(x == 3) + itemOpen(i->id); + } + + /*! + Internal slot invoked when item \a item is doubleclicked. + It opens the file associated with this item + (unless it is still being received). + */ + + void qlv_doubleClicked(QListViewItem *item, const QPoint &, int) + { + if( !item ) + return; + + FileTransItem *i = static_cast(item); + + if( (i->sending || i->finished) && !i->path.isEmpty() ) { +#ifdef Q_OS_WIN // FIX-ME: Open menu items - need to implement on other systems + itemOpen(i->id); +#endif + } } private: @@ -1462,6 +1515,7 @@ if(done) { FileTransItem *fi = findItem(i->id); fi->done = true; + fi->finished = true; } parent->setProgress(i->id, i->p, i->h->totalSteps(), i->sent, bps, updateAll); @@ -1475,6 +1529,7 @@ } PsiAccount *pa = i->h->account(); + const int id = i->id; transferList.removeRef(i); if(recv) { @@ -1488,8 +1543,13 @@ if(!dir.rename(fi.fileName(), fname)) { // TODO: display some error about renaming } + else { + FileTransItem *fi = findItem(id); + fi->path = dir.absFilePath(fname); + } } + pa->playSound(option.onevent[eFTComplete]); } } @@ -1512,6 +1572,7 @@ QVBoxLayout *vb = new QVBoxLayout(this, 11, 6); d->lv = new FileTransView(this); connect(d->lv, SIGNAL(itemCancel(int)), SLOT(itemCancel(int))); + connect(d->lv, SIGNAL(itemOpen(int)), SLOT(itemOpen(int))); connect(d->lv, SIGNAL(itemOpenDest(int)), SLOT(itemOpenDest(int))); connect(d->lv, SIGNAL(itemClear(int)), SLOT(itemClear(int))); vb->addWidget(d->lv); @@ -1543,10 +1604,10 @@ delete d; } -int FileTransDlg::addItem(const QString &filename, Q_LLONG size, const QString &peer, bool sending) +int FileTransDlg::addItem(const QString &filename, const QString &fullpath, Q_LLONG size, const QString &peer, bool sending) { int id = d->findFreeId(); - FileTransItem *i = new FileTransItem(d->lv, filename, size, peer, sending); + FileTransItem *i = new FileTransItem(d->lv, filename, fullpath, size, peer, sending); if(sending) i->icon = IconsetFactory::icon("psi/upload").impix().pixmap(); else @@ -1611,7 +1672,7 @@ TransferMapping *i = new TransferMapping; i->h = h; - i->id = addItem(h->fileName(), h->fileSize(), peer, (h->mode() == FileTransferHandler::Sending)); + i->id = addItem(h->fileName(), h->fullPath(), h->fileSize(), peer, (h->mode() == FileTransferHandler::Sending)); i->p = p; i->sent = sent; d->transferList.append(i); @@ -1691,16 +1752,71 @@ delete fi; } +/*! + Opens a file which has id \a id on the list of file transfers. +*/ + +void FileTransDlg::itemOpen(int id) +{ + FileTransItem *fi = d->findItem(id); + + const QString path = fi->path; + + if ( path.isEmpty() ) + return; + +#ifdef Q_OS_WIN // FIX-ME: Open menu items - need to implement on other systems + + const QString ext = QFileInfo(path).extension(false); + const QString dangerousExtensions = ";exe;bat;com;reg;vbs;wsh;"; // TO-DO: any other ideas? + + if ( dangerousExtensions.find(QRegExp(";" + ext + ";")) >= 0 + && QMessageBox::question(this, tr("Warning"), QString(tr("Files with '%1' extension may be dangerous.\n" + "Are you sure you want to open this file?")).arg(ext), + QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes ) { + + return; + } + + int x; + + QT_WA( { + x = (int)ShellExecute( 0, 0, (TCHAR*)path.ucs2(), 0, 0, SW_SHOWNORMAL ); + } , { + x = (int)ShellExecuteA( 0, 0, path.local8Bit(), 0, 0, SW_SHOWNORMAL ); + } ); + + if ( x == SE_ERR_NOASSOC ) { + QMessageBox::critical(this, tr("Error"), QString("There is no application associated with '%1' file type.").arg(ext)); + } + +#endif + +} + +/*! + Opens a directory containing file + having id \a id on the list of file transfers. +*/ + void FileTransDlg::itemOpenDest(int id) { - TransferMapping *i = d->findMapping(id); + FileTransItem *fi = d->findItem(id); - QString path; - bool recv = (i->h->mode() == FileTransferHandler::Receiving); - if(recv) - path = QFileInfo(i->h->saveName()).dirPath(); - else - path = QFileInfo(i->h->fileName()).dirPath(); + const QString path = QFileInfo(fi->path).dirPath(); + + if ( path.isEmpty() ) + return; + +#ifdef Q_OS_WIN // FIX-ME: Open menu items - need to implement on other systems + + QT_WA( { + ShellExecute( 0, 0, (TCHAR*)path.ucs2(), 0, 0, SW_SHOWNORMAL ); + } , { + ShellExecuteA( 0, 0, path.local8Bit(), 0, 0, SW_SHOWNORMAL ); + } ); + +#endif //printf("item open dest: [%s]\n", path.latin1()); } diff -X exclude -x src.pro -x *.diff -Naru psi_cvs-2005.05.08/psi/src/filetransdlg.h psi/psi/src/filetransdlg.h --- psi_cvs-2005.05.08/psi/src/filetransdlg.h Wed Jun 30 13:51:30 2004 +++ psi/psi/src/filetransdlg.h Fri May 13 02:31:00 2005 @@ -36,6 +36,7 @@ int totalSteps() const; bool resumeSupported() const; QString saveName() const; + QString fullPath() const; void send(const Jid &to, const QString &fname, const QString &desc); void accept(const QString &saveName, const QString &fileName, Q_LLONG offset=0); @@ -114,7 +115,7 @@ FileTransDlg(PsiCon *); ~FileTransDlg(); - int addItem(const QString &filename, Q_LLONG size, const QString &peer, bool sending); + int addItem(const QString &filename, const QString &fullpath, Q_LLONG size, const QString &peer, bool sending); void setProgress(int id, int step, int total, Q_LLONG sent, int bytesPerSecond, bool updateAll=false); void setError(int id, const QString &reason); void removeItem(int id); @@ -129,6 +130,7 @@ void updateItems(); void itemCancel(int); + void itemOpen(int); void itemOpenDest(int); void itemClear(int);