1
#include"filetransdlg.h"
5
#include<qpushbutton.h>
7
#include<qfiledialog.h>
9
#include<qprogressbar.h>
18
#include<qpopupmenu.h>
21
#include"psiaccount.h"
24
#include"iconwidget.h"
25
#include"busywidget.h"
26
#include"filetransfer.h"
28
#include"psiiconset.h"
31
#if QT_VERSION >= 0x030200
1
#include "filetransdlg.h"
7
#include <qpushbutton.h>
10
#include <q3progressbar.h>
12
#include <q3listview.h>
15
#include <qdatetime.h>
18
#include <q3popupmenu.h>
19
#include <QResizeEvent>
21
#include <QVBoxLayout>
23
#include <QHBoxLayout>
27
#include "psiaccount.h"
30
#include "iconwidget.h"
32
#include "busywidget.h"
33
#include "filetransfer.h"
34
#include "accountscombobox.h"
36
#include "psiiconset.h"
39
#include "psitooltip.h"
40
#include "psicontactlist.h"
41
#include "accountlabel.h"
32
43
typedef Q_UINT64 LARGE_TYPE;
34
typedef Q_UINT32 LARGE_TYPE;
37
45
#define CSMAX (sizeof(LARGE_TYPE)*8)
39
static int calcShift(Q_LLONG big)
47
static int calcShift(qlonglong big)
41
49
LARGE_TYPE val = 1;
51
static int calcComplement(Q_LLONG big, int shift)
59
static int calcComplement(qlonglong big, int shift)
53
61
int block = 1 << shift;
54
Q_LLONG rem = big % block;
62
qlonglong rem = big % block;
58
66
return (block - (int)rem);
61
static int calcTotalSteps(Q_LLONG big, int shift)
69
static int calcTotalSteps(qlonglong big, int shift)
65
73
return ((big - 1) >> shift) + 1;
68
static int calcProgressStep(Q_LLONG big, int complement, int shift)
76
static int calcProgressStep(qlonglong big, int complement, int shift)
70
78
return ((big + complement) >> shift);
437
447
void FileTransferHandler::trySend()
439
449
int blockSize = d->ft->dataSizeNeeded();
440
QByteArray a(blockSize);
441
int r = d->f.readBlock(a.data(), a.size());
450
QByteArray a(blockSize, 0);
453
r = d->f.read(a.data(), a.size());
446
error(ErrFile, 0, "");
458
error(ErrFile, 0, d->f.errorString());
449
461
if(r < (int)a.size())
467
479
connect(d->ft, SIGNAL(connected()), SLOT(ft_connected()));
468
480
connect(d->ft, SIGNAL(readyRead(const QByteArray &)), SLOT(ft_readyRead(const QByteArray &)));
469
481
connect(d->ft, SIGNAL(bytesWritten(int)), SLOT(ft_bytesWritten(int)));
470
connect(d->ft, SIGNAL(error(int)), SLOT(ft_error(int)));
482
connect(d->ft, SIGNAL(error(int)), SLOT(ft_error(int)),Qt::QueuedConnection);
473
485
//----------------------------------------------------------------------------
482
494
AccountsComboBox *cb_ident;
483
QLabel *lb_ident, *lb_time;
496
AccountLabel* lb_ident;
486
500
FileTransferHandler *ft;
487
501
QString fileName;
494
508
FileRequestDlg::FileRequestDlg(const Jid &j, PsiCon *psi, PsiAccount *pa)
495
:FileTransUI(0, 0, false, psi_dialog_flags | WDestructiveClose)
509
: QDialog(0, psi_dialog_flags)
511
setAttribute(Qt::WA_DeleteOnClose);
498
515
FileRequestDlg(j, psi, pa, l);
502
FileRequestDlg::FileRequestDlg(const Jid &jid, PsiCon *psi, PsiAccount *pa, const QStringList& files)
503
:FileTransUI(0, 0, false, psi_dialog_flags | WDestructiveClose)
519
FileRequestDlg::FileRequestDlg(const Jid &jid, PsiCon *psi, PsiAccount *pa, const QStringList& files, bool direct)
520
: QDialog(0, psi_dialog_flags)
522
setAttribute(Qt::WA_DeleteOnClose);
510
530
d->sending = true;
511
532
updateIdentity(pa);
513
QHBox *hb = new QHBox(this);
514
new QLabel(tr("Identity: "), hb);
534
Q3HBox *hb = new Q3HBox(this);
535
d->lb_identity = new QLabel(tr("Identity: "), hb);
515
536
d->cb_ident = d->psi->accountsComboBox(hb);
516
537
connect(d->cb_ident, SIGNAL(activated(PsiAccount *)), SLOT(updateIdentity(PsiAccount *)));
517
538
d->cb_ident->setAccount(pa);
518
539
replaceWidget(lb_accountlabel, hb);
519
540
setTabOrder(d->cb_ident, le_to);
541
connect(d->psi, SIGNAL(accountCountChanged()), this, SLOT(updateIdentityVisibility()));
542
updateIdentityVisibility();
521
544
d->te = new ChatView(this);
522
545
d->te->setReadOnly(false);
523
d->te->setTextFormat(PlainText);
546
d->te->setTextFormat(Qt::PlainText);
524
547
replaceWidget(te_desc, d->te);
525
548
setTabOrder(le_fname, d->te);
526
549
setTabOrder(d->te, pb_stop);
528
setCaption(tr("Send File"));
551
setWindowTitle(tr("Send File"));
530
setIcon(IconsetFactory::icon("psi/upload"));
553
setWindowIcon(IconsetFactory::icon("psi/upload").icon());
533
556
le_to->setText(d->jid.full());
567
590
le_fname->setText(QDir::convertSeparators(fi.filePath()));
568
591
lb_size->setText(tr("%1 byte(s)").arg(fi.size())); // TODO: large file support
572
599
FileRequestDlg::FileRequestDlg(const QDateTime &ts, FileTransfer *ft, PsiAccount *pa)
573
:FileTransUI(0, 0, false, psi_dialog_flags | WDestructiveClose)
600
: QDialog(0, psi_dialog_flags)
602
setAttribute(Qt::WA_DeleteOnClose);
578
608
d->jid = ft->peer();
584
614
d->fileSize = ft->fileSize();
587
QHBox *hb = new QHBox(this);
588
new QLabel(tr("Identity: "), hb);
589
d->lb_ident = d->pa->accountLabel(hb);
617
Q3HBox *hb = new Q3HBox(this);
618
d->lb_identity = new QLabel(tr("Identity: "), hb);
619
d->lb_ident = new AccountLabel(hb);
620
d->lb_ident->setAccount(d->pa);
590
621
d->lb_ident->setSizePolicy(QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ));
591
622
new QLabel(tr("Time:"), hb);
592
d->lb_time = new QLabel(ts.time().toString(LocalDate), hb);
623
d->lb_time = new QLabel(ts.time().toString(Qt::LocalDate), hb);
593
624
d->lb_time->setFrameStyle( QFrame::Panel | QFrame::Sunken );
625
connect(d->pa->psi(), SIGNAL(accountCountChanged()), this, SLOT(updateIdentityVisibility()));
626
updateIdentityVisibility();
595
628
replaceWidget(lb_accountlabel, hb);
597
630
d->te = new ChatView(this);
598
d->te->setTextFormat(PlainText);
631
d->te->setTextFormat(Qt::PlainText);
599
632
replaceWidget(te_desc, d->te);
600
633
setTabOrder(le_fname, d->te);
601
634
setTabOrder(d->te, pb_stop);
603
636
lb_to->setText(tr("From:"));
604
setCaption(tr("Receive File"));
637
setWindowTitle(tr("Receive File"));
606
setIcon(IconsetFactory::icon("psi/download"));
639
setWindowIcon(IconsetFactory::icon("psi/download").icon());
609
642
le_to->setText(d->jid.full());
678
711
connect(d->pa, SIGNAL(disconnected()), this, SLOT(pa_disconnected()));
714
void FileRequestDlg::updateIdentityVisibility()
716
bool visible = d->pa->psi()->contactList()->enabledAccounts().count() > 1;
718
d->cb_ident->setVisible(visible);
720
d->lb_ident->setVisible(visible);
721
d->lb_identity->setVisible(visible);
681
724
void FileRequestDlg::pa_disconnected()
683
726
//if(busy->isActive()) {
714
757
if(option.lastPath.isEmpty())
715
758
option.lastPath = QDir::homeDirPath();
716
QString str = QFileDialog::getOpenFileName(option.lastPath, tr("All files (*)"), this, 0, tr("Choose a file"));
759
QString str = QFileDialog::getOpenFileName(this, tr("Choose a file"), option.lastPath, tr("All files (*)"));
717
760
if(!str.isEmpty()) {
718
761
QFileInfo fi(str);
719
762
if(!fi.exists()) {
767
810
QString fname, savename;
768
bool overwrite = false;
770
if(option.lastSavePath.isEmpty())
771
option.lastSavePath = QDir::homeDirPath();
772
fname = QFileDialog::getSaveFileName(QDir(option.lastSavePath).filePath(d->fileName), tr("All files (*)"), this, 0, tr("Save As"));
773
if(!fname.isEmpty()) {
776
int x = QMessageBox::information(this, tr("Error"), tr("File already exists. Overwrite?"), tr("&Yes"), tr("&No"));
781
option.lastSavePath = fi.dirPath();
782
savename = fname + ".part";
783
fname = fi.fileName();
811
if(option.lastSavePath.isEmpty())
812
option.lastSavePath = QDir::homeDirPath();
813
fname = QFileDialog::getSaveFileName(this, tr("Save As"), QDir(option.lastSavePath).filePath(d->fileName), tr("All files (*)"));
817
option.lastSavePath = fi.dirPath();
818
savename = fname + ".part";
819
fname = fi.fileName();
791
821
if(active_file_check(savename)) {
792
822
QMessageBox::information(this, tr("Error"), tr("This file is being transferred already!"));
796
Q_LLONG resume_offset = 0;
826
qlonglong resume_offset = 0;
798
828
// supports resume? check for a .part
799
829
if(d->ft->resumeSupported()) {
800
830
QFileInfo fi(savename);
949
void niceUnit(Q_LLONG n, Q_LLONG *div, QString *unit)
981
void niceUnit(qlonglong n, qlonglong *div, QString *unit)
951
Q_LLONG gb = 1024 * 1024 * 1024;
952
Q_LLONG mb = 1024 * 1024;
983
qlonglong gb = 1024 * 1024 * 1024;
984
qlonglong mb = 1024 * 1024;
956
988
*unit = QString("GB");
987
1019
return QString::number(x);
990
bool setProgress(int _progress, Q_LLONG _sent, int _bps)
1022
bool setProgress(int _progress, qlonglong _sent, int _bps)
992
1024
progress = _progress;
997
Q_LLONG rest_long = size - sent;
1029
qlonglong rest_long = size - sent;
998
1030
rest_long /= bps;
999
1031
int maxtime = (23 * 60 * 60) + (59 * 60) + (59); // 23h59m59s
1000
1032
if(rest_long > maxtime)
1086
1118
p->setPen(cg.highlightedText());
1087
p->setClipRect(xoff, yoff, dist, ysize, QPainter::CoordPainter);
1119
p->setClipRect(xoff, yoff, dist, ysize);
1088
1120
p->drawText(center - (textwidth / 2), ty, s);
1092
1124
p->setPen(cg.text());
1093
p->setClipRect(xoff + dist, yoff, width - 2 - dist, ysize, QPainter::CoordPainter);
1125
p->setClipRect(xoff + dist, yoff, width - 2 - dist, ysize);
1094
1126
p->drawText(center - (textwidth / 2), ty, s);
1261
class FileTransView : public QListView, public QToolTip
1293
class FileTransView : public Q3ListView
1265
1297
FileTransView(QWidget *parent=0, const char *name=0)
1266
:QListView(parent, name), QToolTip(viewport())
1298
:Q3ListView(parent, name)
1268
connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), this, SLOT(qlv_contextMenuRequested(QListViewItem *, const QPoint &, int)));
1300
connect(this, SIGNAL(contextMenuRequested(Q3ListViewItem *, const QPoint &, int)), this, SLOT(qlv_contextMenuRequested(Q3ListViewItem *, const QPoint &, int)));
1271
void maybeTip(const QPoint &pos)
1303
bool maybeTip(const QPoint &pos)
1273
1305
FileTransItem *i = static_cast<FileTransItem*>(itemAt(pos));
1276
1308
QRect r(itemRect(i));
1277
tip(r, i->makeTip());
1309
PsiToolTip::showText(mapToGlobal(pos), i->makeTip(), this);
1280
1313
void resizeEvent(QResizeEvent *e)
1282
QListView::resizeEvent(e);
1315
Q3ListView::resizeEvent(e);
1284
1317
if(e->oldSize().width() != e->size().width())
1321
bool event(QEvent* e)
1323
if (e->type() == QEvent::ToolTip) {
1324
QPoint pos = ((QHelpEvent*) e)->pos();
1325
e->setAccepted(maybeTip(pos));
1328
return Q3ListView::event(e);
1289
1332
void itemCancel(int id);
1291
1334
void itemClear(int id);
1294
void qlv_contextMenuRequested(QListViewItem *item, const QPoint &pos, int)
1337
void qlv_contextMenuRequested(Q3ListViewItem *item, const QPoint &pos, int)
1299
1342
FileTransItem *i = static_cast<FileTransItem*>(item);
1302
1345
p.insertItem(tr("&Cancel"), 0);
1303
1346
p.insertSeparator();
1304
1347
//p.insertItem(tr("&Open Destination Folder"), 1);
1418
QPtrList<FileTransItem> getFinished()
1461
Q3PtrList<FileTransItem> getFinished()
1420
QPtrList<FileTransItem> list;
1421
QListViewItemIterator it(lv);
1422
for(QListViewItem *i; (i = it.current()); ++it) {
1463
Q3PtrList<FileTransItem> list;
1464
Q3ListViewItemIterator it(lv);
1465
for(Q3ListViewItem *i; (i = it.current()); ++it) {
1423
1466
FileTransItem *fi = static_cast<FileTransItem*>(i);
1425
1468
list.append(fi);
1505
1548
connect(&d->t, SIGNAL(timeout()), SLOT(updateItems()));
1507
setCaption(tr("Transfer Manager"));
1550
setWindowTitle(tr("Transfer Manager"));
1508
1551
#ifndef Q_WS_MAC
1509
setIcon(IconsetFactory::icon("psi/filemanager"));
1552
setWindowIcon(IconsetFactory::icon("psi/filemanager").icon());
1512
1555
QVBoxLayout *vb = new QVBoxLayout(this, 11, 6);
1546
int FileTransDlg::addItem(const QString &filename, Q_LLONG size, const QString &peer, bool sending)
1589
int FileTransDlg::addItem(const QString &filename, qlonglong size, const QString &peer, bool sending)
1548
1591
int id = d->findFreeId();
1549
1592
FileTransItem *i = new FileTransItem(d->lv, filename, size, peer, sending);
1559
void FileTransDlg::setProgress(int id, int step, int total, Q_LLONG sent, int bytesPerSecond, bool updateAll)
1602
void FileTransDlg::setProgress(int id, int step, int total, qlonglong sent, int bytesPerSecond, bool updateAll)
1561
1604
FileTransItem *i = d->findItem(id);
1603
void FileTransDlg::takeTransfer(FileTransferHandler *h, int p, Q_LLONG sent)
1646
void FileTransDlg::takeTransfer(FileTransferHandler *h, int p, qlonglong sent)
1606
UserListItem *u = h->account()->findFirstRelavent(h->peer());
1649
UserListItem *u = h->account()->findFirstRelevant(h->peer());
1608
peer = jidnick(u->jid().full(), u->name());
1651
peer = JIDUtil::nickOrJid(u->name(),u->jid().full());
1610
1653
peer = h->peer().full();
1623
1666
d->updateProgress(i, true);
1626
connect(h, SIGNAL(progress(int, Q_LLONG)), SLOT(ft_progress(int, Q_LLONG)));
1669
connect(h, SIGNAL(progress(int, qlonglong)), SLOT(ft_progress(int, qlonglong)));
1627
1670
connect(h, SIGNAL(error(int, int, const QString &)), SLOT(ft_error(int, int, const QString &)));
1631
1674
void FileTransDlg::clearFinished()
1633
QPtrList<FileTransItem> list = d->getFinished();
1676
Q3PtrList<FileTransItem> list = d->getFinished();
1635
1678
// remove related transfer mappings
1636
QPtrListIterator<FileTransItem> it(list);
1679
Q3PtrListIterator<FileTransItem> it(list);
1637
1680
for(FileTransItem *fi; (fi = it.current()); ++it) {
1638
1681
TransferMapping *i = d->findMapping(fi->id);
1639
1682
d->transferList.removeRef(i);
1666
1709
if(x == FileTransferHandler::ErrTransfer)
1669
str = tr("File I/O error");
1712
str = tr("File I/O error (%1)").arg(s);
1670
1713
setError(id, str);
1673
1716
void FileTransDlg::updateItems()
1675
1718
// operate on a copy so that we can delete items in updateProgress
1676
QPtrList<TransferMapping> list = d->transferList;
1677
QPtrListIterator<TransferMapping> it(list);
1719
Q3PtrList<TransferMapping> list = d->transferList;
1720
Q3PtrListIterator<TransferMapping> it(list);
1678
1721
for(TransferMapping *i; (i = it.current()); ++it) {
1716
1759
void FileTransDlg::killTransfers(PsiAccount *pa)
1718
QPtrList<TransferMapping> list = d->transferList;
1719
QPtrListIterator<TransferMapping> it(list);
1761
Q3PtrList<TransferMapping> list = d->transferList;
1762
Q3PtrListIterator<TransferMapping> it(list);
1720
1763
for(TransferMapping *i; (i = it.current()); ++it) {
1721
1764
// this account?
1722
1765
if(i->h->account() == pa) {