00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <qtimer.h>
00020 #include <qlayout.h>
00021 #include <qtooltip.h>
00022 #include <qdatetime.h>
00023 #include <qcheckbox.h>
00024
00025 #include <kapplication.h>
00026 #include <kdebug.h>
00027 #include <kdialog.h>
00028 #include <kstringhandler.h>
00029 #include <kglobal.h>
00030 #include <klocale.h>
00031 #include <kiconloader.h>
00032 #include <kprocess.h>
00033 #include <kpushbutton.h>
00034 #include <kstandarddirs.h>
00035 #include <kstdguiitem.h>
00036 #include <klineedit.h>
00037 #include <kwin.h>
00038
00039 #include "jobclasses.h"
00040 #include "defaultprogress.h"
00041
00042 namespace KIO {
00043
00044 class DefaultProgress::DefaultProgressPrivate
00045 {
00046 public:
00047 bool keepOpenChecked;
00048 bool noCaptionYet;
00049 KPushButton *cancelClose;
00050 KPushButton *openFile;
00051 KPushButton *openLocation;
00052 QCheckBox *keepOpen;
00053 KURL location;
00054 QTime startTime;
00055 };
00056
00057 DefaultProgress::DefaultProgress( bool showNow )
00058 : ProgressBase( 0 ),
00059 m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00060 m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00061 {
00062 init();
00063
00064 if ( showNow ) {
00065 show();
00066 }
00067 }
00068
00069 DefaultProgress::DefaultProgress( QWidget* parent, const char* )
00070 : ProgressBase( parent ),
00071 m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00072 m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00073 {
00074 init();
00075 }
00076
00077 bool DefaultProgress::keepOpen() const
00078 {
00079 return d->keepOpenChecked;
00080 }
00081
00082 void DefaultProgress::init()
00083 {
00084 d = new DefaultProgressPrivate;
00085
00086 #ifdef Q_WS_X11 //FIXME(E): Remove once all the KWin::foo calls have been ported to QWS
00087
00088 KWin::setIcons( winId(),
00089 KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 32 ),
00090 KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 16 ) );
00091 #endif
00092
00093 QVBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00094 KDialog::spacingHint() );
00095 topLayout->addStrut( 360 );
00096
00097 QGridLayout *grid = new QGridLayout( 2, 3 );
00098 topLayout->addLayout(grid);
00099 grid->addColSpacing(1, KDialog::spacingHint());
00100
00101 grid->addWidget(new QLabel(i18n("Source:"), this), 0, 0);
00102
00103 sourceEdit = new KLineEdit(this);
00104 sourceEdit->setReadOnly(true);
00105 sourceEdit->setEnableSqueezedText(true);
00106 grid->addWidget(sourceEdit, 0, 2);
00107
00108 destInvite = new QLabel(i18n("Destination:"), this);
00109 grid->addWidget(destInvite, 1, 0);
00110
00111 destEdit = new KLineEdit(this);
00112 destEdit->setReadOnly (true);
00113 destEdit->setEnableSqueezedText(true);
00114 grid->addWidget(destEdit, 1, 2);
00115
00116 m_pProgressBar = new KProgress(this);
00117 topLayout->addWidget( m_pProgressBar );
00118
00119
00120 QHBoxLayout *hBox = new QHBoxLayout();
00121 topLayout->addLayout(hBox);
00122
00123 sizeLabel = new QLabel(this);
00124 hBox->addWidget(sizeLabel);
00125
00126 resumeLabel = new QLabel(this);
00127 hBox->addWidget(resumeLabel);
00128
00129 progressLabel = new QLabel( this );
00130
00131
00132 progressLabel->setAlignment( QLabel::AlignRight );
00133 hBox->addWidget( progressLabel );
00134
00135 hBox = new QHBoxLayout();
00136 topLayout->addLayout(hBox);
00137
00138 speedLabel = new QLabel(this);
00139 hBox->addWidget(speedLabel, 1);
00140
00141 QFrame *line = new QFrame( this );
00142 line->setFrameShape( QFrame::HLine );
00143 line->setFrameShadow( QFrame::Sunken );
00144 topLayout->addWidget( line );
00145
00146 d->keepOpen = new QCheckBox( i18n("&Keep this window open after transfer is complete"), this);
00147 connect( d->keepOpen, SIGNAL( toggled(bool) ), SLOT( slotKeepOpenToggled(bool) ) );
00148 topLayout->addWidget(d->keepOpen);
00149 d->keepOpen->hide();
00150
00151 hBox = new QHBoxLayout();
00152 topLayout->addLayout(hBox);
00153
00154 d->openFile = new KPushButton( i18n("Open &File"), this );
00155 connect( d->openFile, SIGNAL( clicked() ), SLOT( slotOpenFile() ) );
00156 hBox->addWidget( d->openFile );
00157 d->openFile->setEnabled(false);
00158 d->openFile->hide();
00159
00160 d->openLocation = new KPushButton( i18n("Open &Destination"), this );
00161 connect( d->openLocation, SIGNAL( clicked() ), SLOT( slotOpenLocation() ) );
00162 hBox->addWidget( d->openLocation );
00163 d->openLocation->hide();
00164
00165 hBox->addStretch(1);
00166
00167 d->cancelClose = new KPushButton( KStdGuiItem::cancel(), this );
00168 connect( d->cancelClose, SIGNAL( clicked() ), SLOT( slotStop() ) );
00169 hBox->addWidget( d->cancelClose );
00170
00171 resize( sizeHint() );
00172 setMaximumHeight(sizeHint().height());
00173
00174 d->keepOpenChecked = false;
00175 d->noCaptionYet = true;
00176 setCaption(i18n("Progress Dialog"));
00177 }
00178
00179 DefaultProgress::~DefaultProgress()
00180 {
00181 delete d;
00182 }
00183
00184 void DefaultProgress::slotTotalSize( KIO::Job*, KIO::filesize_t bytes )
00185 {
00186 if ( m_iTotalSize == bytes )
00187 return;
00188 m_iTotalSize = bytes;
00189 if (d->startTime.isNull())
00190 d->startTime.start();
00191 }
00192
00193
00194 void DefaultProgress::slotTotalFiles( KIO::Job*, unsigned long files )
00195 {
00196 if ( m_iTotalFiles == files )
00197 return;
00198 m_iTotalFiles = files;
00199 showTotals();
00200 }
00201
00202
00203 void DefaultProgress::slotTotalDirs( KIO::Job*, unsigned long dirs )
00204 {
00205 if ( m_iTotalDirs == dirs )
00206 return;
00207 m_iTotalDirs = dirs;
00208 showTotals();
00209 }
00210
00211 void DefaultProgress::showTotals()
00212 {
00213
00214
00215
00216 if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 )
00217 {
00218 QString tmps;
00219 if ( m_iTotalDirs > 1 )
00220
00221 tmps = i18n("%n folder", "%n folders", m_iTotalDirs) + " ";
00222 tmps += i18n("%n file", "%n files", m_iTotalFiles);
00223 progressLabel->setText( tmps );
00224 }
00225 }
00226
00227 void DefaultProgress::slotPercent( KIO::Job*, unsigned long percent )
00228 {
00229 QString tmp(i18n( "%1% of %2 ").arg( percent ).arg( KIO::convertSize(m_iTotalSize)));
00230 m_pProgressBar->setValue( percent );
00231 switch(mode) {
00232 case Copy:
00233 tmp.append(i18n(" (Copying)"));
00234 break;
00235 case Move:
00236 tmp.append(i18n(" (Moving)"));
00237 break;
00238 case Delete:
00239 tmp.append(i18n(" (Deleting)"));
00240 break;
00241 case Create:
00242 tmp.append(i18n(" (Creating)"));
00243 break;
00244 case Done:
00245 tmp.append(i18n(" (Done)"));
00246 break;
00247 }
00248
00249 setCaption( tmp );
00250 d->noCaptionYet = false;
00251 }
00252
00253
00254 void DefaultProgress::slotInfoMessage( KIO::Job*, const QString & msg )
00255 {
00256 speedLabel->setText( msg );
00257 speedLabel->setAlignment( speedLabel->alignment() & ~Qt::WordBreak );
00258 }
00259
00260
00261 void DefaultProgress::slotProcessedSize( KIO::Job*, KIO::filesize_t bytes ) {
00262 if ( m_iProcessedSize == bytes )
00263 return;
00264 m_iProcessedSize = bytes;
00265
00266 QString tmp;
00267 tmp = i18n( "%1 of %2 complete").arg( KIO::convertSize(bytes) ).arg( KIO::convertSize(m_iTotalSize));
00268 sizeLabel->setText( tmp );
00269 }
00270
00271
00272 void DefaultProgress::slotProcessedDirs( KIO::Job*, unsigned long dirs )
00273 {
00274 if ( m_iProcessedDirs == dirs )
00275 return;
00276 m_iProcessedDirs = dirs;
00277
00278 QString tmps;
00279 tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00280 tmps += " ";
00281 tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00282 progressLabel->setText( tmps );
00283 }
00284
00285
00286 void DefaultProgress::slotProcessedFiles( KIO::Job*, unsigned long files )
00287 {
00288 if ( m_iProcessedFiles == files )
00289 return;
00290 m_iProcessedFiles = files;
00291
00292 QString tmps;
00293 if ( m_iTotalDirs > 1 ) {
00294 tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00295 tmps += " ";
00296 }
00297 tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00298 progressLabel->setText( tmps );
00299 }
00300
00301
00302 void DefaultProgress::slotSpeed( KIO::Job*, unsigned long bytes_per_second )
00303 {
00304 if ( bytes_per_second == 0 ) {
00305 speedLabel->setText( i18n( "Stalled") );
00306 } else {
00307 QTime remaining = KIO::calculateRemaining( m_iTotalSize, m_iProcessedSize, bytes_per_second );
00308 speedLabel->setText( i18n( "%1/s ( %2 remaining )").arg( KIO::convertSize( bytes_per_second )).arg( remaining.toString() ) );
00309 }
00310 }
00311
00312
00313 void DefaultProgress::slotCopying( KIO::Job*, const KURL& from, const KURL& to )
00314 {
00315 if ( d->noCaptionYet ) {
00316 setCaption(i18n("Copy File(s) Progress"));
00317 d->noCaptionYet = false;
00318 }
00319 mode = Copy;
00320 sourceEdit->setText(from.prettyURL());
00321 setDestVisible( true );
00322 checkDestination( to );
00323 destEdit->setText(to.prettyURL());
00324 }
00325
00326
00327 void DefaultProgress::slotMoving( KIO::Job*, const KURL& from, const KURL& to )
00328 {
00329 if ( d->noCaptionYet ) {
00330 setCaption(i18n("Move File(s) Progress"));
00331 d->noCaptionYet = false;
00332 }
00333 mode = Move;
00334 sourceEdit->setText(from.prettyURL());
00335 setDestVisible( true );
00336 checkDestination( to );
00337 destEdit->setText(to.prettyURL());
00338 }
00339
00340
00341 void DefaultProgress::slotCreatingDir( KIO::Job*, const KURL& dir )
00342 {
00343 if ( d->noCaptionYet ) {
00344 setCaption(i18n("Creating Folder"));
00345 d->noCaptionYet = false;
00346 }
00347 mode = Create;
00348 sourceEdit->setText(dir.prettyURL());
00349 setDestVisible( false );
00350 }
00351
00352
00353 void DefaultProgress::slotDeleting( KIO::Job*, const KURL& url )
00354 {
00355 if ( d->noCaptionYet ) {
00356 setCaption(i18n("Delete File(s) Progress"));
00357 d->noCaptionYet = false;
00358 }
00359 mode = Delete;
00360 sourceEdit->setText(url.prettyURL());
00361 setDestVisible( false );
00362 }
00363
00364 void DefaultProgress::slotTransferring( KIO::Job*, const KURL& url )
00365 {
00366 if ( d->noCaptionYet ) {
00367 setCaption(i18n("Loading Progress"));
00368 d->noCaptionYet = false;
00369 }
00370 sourceEdit->setText(url.prettyURL());
00371 setDestVisible( false );
00372 }
00373
00374 void DefaultProgress::slotStating( KIO::Job*, const KURL& url )
00375 {
00376 setCaption(i18n("Examining File Progress"));
00377 sourceEdit->setText(url.prettyURL());
00378 setDestVisible( false );
00379 }
00380
00381 void DefaultProgress::slotMounting( KIO::Job*, const QString & dev, const QString & point )
00382 {
00383 setCaption(i18n("Mounting %1").arg(dev));
00384 sourceEdit->setText(point);
00385 setDestVisible( false );
00386 }
00387
00388 void DefaultProgress::slotUnmounting( KIO::Job*, const QString & point )
00389 {
00390 setCaption(i18n("Unmounting"));
00391 sourceEdit->setText(point);
00392 setDestVisible( false );
00393 }
00394
00395 void DefaultProgress::slotCanResume( KIO::Job*, KIO::filesize_t resume )
00396 {
00397 if ( resume ) {
00398 resumeLabel->setText( i18n("Resuming from %1").arg(KIO::number(resume)) );
00399 } else {
00400 resumeLabel->setText( i18n("Not resumable") );
00401 }
00402 }
00403
00404 void DefaultProgress::setDestVisible( bool visible )
00405 {
00406
00407
00408 if (visible)
00409 {
00410 destInvite->show();
00411 destEdit->show();
00412
00413 destInvite->setText( i18n("Destination:") );
00414 }
00415 else
00416 {
00417 destInvite->hide();
00418 destEdit->hide();
00419 destInvite->setText( QString::null );
00420 destEdit->setText( QString::null );
00421 }
00422 }
00423
00424 void DefaultProgress::slotClean() {
00425 if (d->keepOpenChecked) {
00426 mode = Done;
00427 slotPercent(0, 100);
00428 d->cancelClose->setGuiItem( KStdGuiItem::close() );
00429 d->openFile->setEnabled(true);
00430 slotProcessedSize(0, m_iTotalSize);
00431 d->keepOpen->setEnabled(false);
00432 if (!d->startTime.isNull()) {
00433 int s = d->startTime.elapsed();
00434 if (!s)
00435 s = 1;
00436 speedLabel->setText(i18n("%1/s (done)").arg(KIO::convertSize(1000 * m_iTotalSize / s)));
00437 }
00438 setOnlyClean(false);
00439 }
00440 else
00441 hide();
00442 }
00443
00444 void DefaultProgress::slotKeepOpenToggled(bool keepopen)
00445 {
00446 d->keepOpenChecked=keepopen;
00447 }
00448
00449 void DefaultProgress::checkDestination(const KURL& dest) {
00450 bool ok = true;
00451 if ( dest.isLocalFile() ) {
00452 QString path = dest.path( -1 );
00453 QStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" );
00454 for ( QStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it )
00455 if ( path.contains( *it ) )
00456 ok = false;
00457 }
00458
00459 if ( ok ) {
00460 d->openFile->show();
00461 d->openLocation->show();
00462 d->keepOpen->show();
00463 d->location=dest;
00464 }
00465 }
00466
00467 void DefaultProgress::slotOpenFile()
00468 {
00469 KProcess proc;
00470 proc << "konqueror" << d->location.prettyURL();
00471 proc.start(KProcess::DontCare);
00472 }
00473
00474 void DefaultProgress::slotOpenLocation()
00475 {
00476 KProcess proc;
00477 d->location.setFileName("");
00478 proc << "konqueror" << d->location.prettyURL();
00479 proc.start(KProcess::DontCare);
00480 }
00481
00482 void DefaultProgress::virtual_hook( int id, void* data )
00483 { ProgressBase::virtual_hook( id, data ); }
00484
00485 }
00486
00487 #include "defaultprogress.moc"