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