defaultprogress.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Matej Koss <koss@miesto.sk> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <tqtimer.h> 00020 #include <tqlayout.h> 00021 #include <tqtooltip.h> 00022 #include <tqdatetime.h> 00023 #include <tqcheckbox.h> 00024 00025 #include <tdeapplication.h> 00026 #include <kdebug.h> 00027 #include <kdialog.h> 00028 #include <kstringhandler.h> 00029 #include <tdeglobal.h> 00030 #include <tdelocale.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 <twin.h> 00040 #endif 00041 00042 #include "jobclasses.h" 00043 #include "defaultprogress.h" 00044 00045 namespace TDEIO { 00046 00047 class DefaultProgress::DefaultProgressPrivate 00048 { 00049 public: 00050 bool keepOpenChecked; 00051 bool noCaptionYet; 00052 KPushButton *cancelClose; 00053 KPushButton *openFile; 00054 KPushButton *openLocation; 00055 TQCheckBox *keepOpen; 00056 KURL location; 00057 TQTime 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( TQWidget* parent, const char* /*name*/ ) 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 // Set a useful icon for this window! 00091 KWin::setIcons( winId(), 00092 TDEGlobal::iconLoader()->loadIcon( "document-save", TDEIcon::NoGroup, 32 ), 00093 TDEGlobal::iconLoader()->loadIcon( "document-save", TDEIcon::NoGroup, 16 ) ); 00094 #endif 00095 00096 TQVBoxLayout *topLayout = new TQVBoxLayout( this, KDialog::marginHint(), 00097 KDialog::spacingHint() ); 00098 topLayout->addStrut( 360 ); // makes dlg at least that wide 00099 00100 TQGridLayout *grid = new TQGridLayout( 2, 3 ); 00101 topLayout->addLayout(TQT_TQLAYOUT(grid)); 00102 grid->addColSpacing(1, KDialog::spacingHint()); 00103 // filenames or action name 00104 grid->addWidget(new TQLabel(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 TQLabel(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 // processed info 00123 TQHBoxLayout *hBox = new TQHBoxLayout(); 00124 topLayout->addLayout(hBox); 00125 00126 sizeLabel = new TQLabel(this); 00127 hBox->addWidget(sizeLabel); 00128 00129 resumeLabel = new TQLabel(this); 00130 hBox->addWidget(resumeLabel); 00131 00132 progressLabel = new TQLabel( this ); 00133 /* progressLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding, 00134 TQSizePolicy::Preferred ) );*/ 00135 progressLabel->setAlignment( TQLabel::AlignRight ); 00136 hBox->addWidget( progressLabel ); 00137 00138 hBox = new TQHBoxLayout(); 00139 topLayout->addLayout(hBox); 00140 00141 speedLabel = new TQLabel(this); 00142 hBox->addWidget(speedLabel, 1); 00143 00144 TQFrame *line = new TQFrame( this ); 00145 line->setFrameShape( TQFrame::HLine ); 00146 line->setFrameShadow( TQFrame::Sunken ); 00147 topLayout->addWidget( line ); 00148 00149 d->keepOpen = new TQCheckBox( i18n("&Keep this window open after transfer is complete"), this); 00150 connect( d->keepOpen, TQT_SIGNAL( toggled(bool) ), TQT_SLOT( slotKeepOpenToggled(bool) ) ); 00151 topLayout->addWidget(d->keepOpen); 00152 d->keepOpen->hide(); 00153 00154 hBox = new TQHBoxLayout(); 00155 topLayout->addLayout(hBox); 00156 00157 d->openFile = new KPushButton( i18n("Open &File"), this ); 00158 connect( d->openFile, TQT_SIGNAL( clicked() ), TQT_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, TQT_SIGNAL( clicked() ), TQT_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, TQT_SIGNAL( clicked() ), TQT_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")); // show something better than tdeio_uiserver 00180 } 00181 00182 DefaultProgress::~DefaultProgress() 00183 { 00184 delete d; 00185 } 00186 00187 void DefaultProgress::slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ) 00188 { 00189 // size is measured in bytes 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( TDEIO::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( TDEIO::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 // Show the totals in the progress label, if we still haven't 00218 // processed anything. This is useful when the stat'ing phase 00219 // of CopyJob takes a long time (e.g. over networks). 00220 if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 ) 00221 { 00222 TQString tmps; 00223 if ( m_iTotalDirs > 1 ) 00224 // that we have a singular to translate looks weired but is only logical 00225 // xgettext: no-c-format 00226 tmps = i18n("%n folder", "%n folders", m_iTotalDirs) + " "; 00227 // xgettext: no-c-format 00228 tmps += i18n("%n file", "%n files", m_iTotalFiles); 00229 progressLabel->setText( tmps ); 00230 } 00231 } 00232 00233 //static 00234 TQString DefaultProgress::makePercentString( unsigned long percent, 00235 TDEIO::filesize_t totalSize, 00236 unsigned long totalFiles ) 00237 { 00238 if ( totalSize ) 00239 return i18n( "%1 % of %2 " ).arg( TQString::number(percent) , TDEIO::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( TDEIO::Job*, unsigned long percent ) 00247 { 00248 TQString 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( TDEIO::Job*, const TQString & msg ) 00274 { 00275 speedLabel->setText( msg ); 00276 speedLabel->setAlignment( speedLabel->alignment() & ~TQt::WordBreak ); 00277 } 00278 00279 00280 void DefaultProgress::slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t bytes ) { 00281 if ( m_iProcessedSize == bytes ) 00282 return; 00283 m_iProcessedSize = bytes; 00284 00285 TQString tmp = i18n( "%1 of %2 complete") 00286 .arg( TDEIO::convertSize(bytes) ) 00287 .arg( TDEIO::convertSize(m_iTotalSize)); 00288 sizeLabel->setText( tmp ); 00289 } 00290 00291 00292 void DefaultProgress::slotProcessedDirs( TDEIO::Job*, unsigned long dirs ) 00293 { 00294 if ( m_iProcessedDirs == dirs ) 00295 return; 00296 m_iProcessedDirs = dirs; 00297 00298 TQString 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( TDEIO::Job*, unsigned long files ) 00307 { 00308 if ( m_iProcessedFiles == files ) 00309 return; 00310 m_iProcessedFiles = files; 00311 00312 TQString 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( TDEIO::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( TDEIO::convertSize( speed )) 00328 .arg( TDEIO::convertSeconds( TDEIO::calculateRemainingSeconds( m_iTotalSize, m_iProcessedSize, speed ))) ); 00329 } 00330 } 00331 00332 00333 void DefaultProgress::slotCopying( TDEIO::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( TDEIO::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( TDEIO::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( TDEIO::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( TDEIO::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( TDEIO::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( TDEIO::Job*, const TQString & dev, const TQString & point ) 00402 { 00403 setCaption(i18n("Mounting %1").arg(dev)); 00404 sourceEdit->setText(point); 00405 setDestVisible( false ); 00406 } 00407 00408 void DefaultProgress::slotUnmounting( TDEIO::Job*, const TQString & point ) 00409 { 00410 setCaption(i18n("Unmounting")); 00411 sourceEdit->setText(point); 00412 setDestVisible( false ); 00413 } 00414 00415 void DefaultProgress::slotCanResume( TDEIO::Job*, TDEIO::filesize_t resume ) 00416 { 00417 if ( resume ) { 00418 resumeLabel->setText( i18n("Resuming from %1").arg(TDEIO::number(resume)) ); 00419 } else { 00420 resumeLabel->setText( i18n("Not resumable") ); 00421 } 00422 } 00423 00424 void DefaultProgress::setDestVisible( bool visible ) 00425 { 00426 // We can't hide the destInvite/destEdit labels, 00427 // because it screws up the TQGridLayout. 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( TQString::null ); 00440 destEdit->setText( TQString::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(TDEIO::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 TQString path = dest.path( -1 ); 00473 TQStringList tmpDirs = TDEGlobal::dirs()->resourceDirs( "tmp" ); 00474 for ( TQStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it ) 00475 if ( path.contains( *it ) ) 00476 ok = false; // it's in the tmp resource 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 TDEProcess proc; 00490 proc << "konqueror" << d->location.prettyURL(); 00491 proc.start(TDEProcess::DontCare); 00492 } 00493 00494 void DefaultProgress::slotOpenLocation() 00495 { 00496 TDEProcess proc; 00497 d->location.setFileName(""); 00498 proc << "konqueror" << d->location.prettyURL(); 00499 proc.start(TDEProcess::DontCare); 00500 } 00501 00502 void DefaultProgress::virtual_hook( int id, void* data ) 00503 { ProgressBase::virtual_hook( id, data ); } 00504 00505 } /* namespace */ 00506 00507 #include "defaultprogress.moc"