kio Library API Documentation

renamedlg.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Stephan Kulow <coolo@kde.org> 00003 David Faure <faure@kde.org> 00004 2001 Holger Freyther <freyther@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00019 Boston, MA 02111-1307, USA. 00020 */ 00021 00022 #include "kio/renamedlg.h" 00023 #include "kio/renamedlgplugin.h" 00024 #include <stdio.h> 00025 #include <assert.h> 00026 00027 #include <qfileinfo.h> 00028 #include <qlabel.h> 00029 #include <qlayout.h> 00030 #include <qlineedit.h> 00031 #include <qdir.h> 00032 00033 #include <kmessagebox.h> 00034 #include <kpushbutton.h> 00035 #include <kapplication.h> 00036 #include <kio/global.h> 00037 #include <ktrader.h> 00038 #include <klibloader.h> 00039 #include <kdialog.h> 00040 #include <klocale.h> 00041 #include <kglobal.h> 00042 #include <kdebug.h> 00043 #include <kurl.h> 00044 #include <kmimetype.h> 00045 #include <kwin.h> 00046 #include <kseparator.h> 00047 #include <kstringhandler.h> 00048 #include <kstdguiitem.h> 00049 #include <kguiitem.h> 00050 #include <ksqueezedtextlabel.h> 00051 00052 using namespace KIO; 00053 00054 class RenameDlg::RenameDlgPrivate 00055 { 00056 public: 00057 RenameDlgPrivate(){ 00058 b0 = 0L; 00059 b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = 0L; 00060 m_pLineEdit=0L; 00061 m_pLayout=0L; 00062 } 00063 KPushButton *b0; 00064 QPushButton *b1; 00065 QPushButton *b2; 00066 QPushButton *b3; 00067 QPushButton *b4; 00068 QPushButton *b5; 00069 QPushButton *b6; 00070 QPushButton *b7; 00071 QPushButton *b8; //why isn't it an array 00072 QLineEdit* m_pLineEdit; 00073 QVBoxLayout* m_pLayout; // ### doesn't need to be here 00074 QString src; 00075 QString dest; 00076 QString mimeSrc; 00077 QString mimeDest; 00078 bool modal; 00079 bool plugin; 00080 }; 00081 00082 RenameDlg::RenameDlg(QWidget *parent, const QString & _caption, 00083 const QString &_src, const QString &_dest, 00084 RenameDlg_Mode _mode, 00085 KIO::filesize_t sizeSrc, 00086 KIO::filesize_t sizeDest, 00087 time_t ctimeSrc, 00088 time_t ctimeDest, 00089 time_t mtimeSrc, 00090 time_t mtimeDest, 00091 bool _modal) 00092 : QDialog ( parent, "KIO::RenameDialog" , _modal ) 00093 { 00094 d = new RenameDlgPrivate( ); 00095 d->modal = _modal; 00096 // Set "StaysOnTop", because this dialog is typically used in kio_uiserver, 00097 // i.e. in a separate process. 00098 // ####### This isn't the case anymore - remove? 00099 #ifndef Q_WS_QWS //FIXME(E): Implement for QT Embedded 00100 if (d->modal) 00101 KWin::setState( winId(), NET::StaysOnTop ); 00102 #endif 00103 00104 d->src = _src; 00105 d->dest = _dest; 00106 d->plugin = false; 00107 00108 00109 setCaption( _caption ); 00110 00111 d->b0 = new KPushButton( KStdGuiItem::cancel(), this ); 00112 connect(d->b0, SIGNAL(clicked()), this, SLOT(b0Pressed())); 00113 00114 if ( ! (_mode & M_NORENAME ) ) { 00115 d->b1 = new QPushButton( i18n( "&Rename" ), this ); 00116 d->b1->setEnabled(false); 00117 d->b8 = new QPushButton( i18n( "Suggest New &Name" ), this ); 00118 connect(d->b8, SIGNAL(clicked()), this, SLOT(b8Pressed())); 00119 connect(d->b1, SIGNAL(clicked()), this, SLOT(b1Pressed())); 00120 } 00121 00122 if ( ( _mode & M_MULTI ) && ( _mode & M_SKIP ) ) { 00123 d->b2 = new QPushButton( i18n( "&Skip" ), this ); 00124 connect(d->b2, SIGNAL(clicked()), this, SLOT(b2Pressed())); 00125 00126 d->b3 = new QPushButton( i18n( "&Auto Skip" ), this ); 00127 connect(d->b3, SIGNAL(clicked()), this, SLOT(b3Pressed())); 00128 } 00129 00130 if ( _mode & M_OVERWRITE ) { 00131 d->b4 = new QPushButton( i18n( "&Overwrite" ), this ); 00132 connect(d->b4, SIGNAL(clicked()), this, SLOT(b4Pressed())); 00133 00134 if ( _mode & M_MULTI ) { 00135 d->b5 = new QPushButton( i18n( "O&verwrite All" ), this ); 00136 connect(d->b5, SIGNAL(clicked()), this, SLOT(b5Pressed())); 00137 } 00138 } 00139 00140 if ( _mode & M_RESUME ) { 00141 d->b6 = new QPushButton( i18n( "&Resume" ), this ); 00142 connect(d->b6, SIGNAL(clicked()), this, SLOT(b6Pressed())); 00143 00144 if ( _mode & M_MULTI ) 00145 { 00146 d->b7 = new QPushButton( i18n( "R&esume All" ), this ); 00147 connect(d->b7, SIGNAL(clicked()), this, SLOT(b7Pressed())); 00148 } 00149 } 00150 00151 d->m_pLayout = new QVBoxLayout( this, KDialog::marginHint(), 00152 KDialog::spacingHint() ); 00153 d->m_pLayout->addStrut( 360 ); // makes dlg at least that wide 00154 00155 // User tries to overwrite a file with itself ? 00156 if ( _mode & M_OVERWRITE_ITSELF ) { 00157 QLabel *lb = new QLabel( i18n( "This action would overwrite '%1' with itself.\n" 00158 "Please enter a new file name:" ).arg( KStringHandler::csqueeze( d->src,100 ) ), this ); 00159 d->b1->setText(i18n("C&ontinue")); 00160 d->m_pLayout->addWidget( lb ); 00161 } 00162 else if ( _mode & M_OVERWRITE ) { 00163 00164 // Figure out the mimetype and load one plugin 00165 // (This is the only mode that is handled by plugins) 00166 pluginHandling(); 00167 KTrader::OfferList plugin_offers; 00168 if( d->mimeSrc != KMimeType::defaultMimeType() ){ 00169 plugin_offers = KTrader::self()->query(d->mimeSrc, "'RenameDlg/Plugin' in ServiceTypes"); 00170 00171 }else if(d->mimeDest != KMimeType::defaultMimeType() ) { 00172 plugin_offers = KTrader::self()->query(d->mimeDest, "'RenameDlg/Plugin' in ServiceTypes"); 00173 } 00174 if(!plugin_offers.isEmpty() ){ 00175 kdDebug(7024) << "Offers" << endl; 00176 KTrader::OfferList::ConstIterator it = plugin_offers.begin(); 00177 KTrader::OfferList::ConstIterator end = plugin_offers.end(); 00178 for( ; it != end; ++it ){ 00179 QString libName = (*it)->library(); 00180 if( libName.isEmpty() ){ 00181 kdDebug(7024) << "lib is empty" << endl; 00182 continue; 00183 } 00184 KLibrary *lib = KLibLoader::self()->library(libName.local8Bit() ); 00185 if(!lib) { 00186 continue; 00187 } 00188 KLibFactory *factory = lib->factory(); 00189 if(!factory){ 00190 lib->unload(); 00191 continue; 00192 } 00193 QObject *obj = factory->create( this, (*it)->name().latin1() ); 00194 if(!obj) { 00195 lib->unload(); 00196 continue; 00197 } 00198 RenameDlgPlugin *plugin = static_cast<RenameDlgPlugin *>(obj); 00199 if(!plugin ){ 00200 delete obj; 00201 continue; 00202 } 00203 if( plugin->initialize( _mode, _src, _dest, d->mimeSrc, 00204 d->mimeDest, sizeSrc, sizeDest, 00205 ctimeSrc, ctimeDest, 00206 mtimeSrc, mtimeDest ) ) { 00207 d->plugin = true; 00208 d->m_pLayout->addWidget(plugin ); 00209 kdDebug(7024) << "RenameDlgPlugin" << endl; 00210 break; 00211 } else { 00212 delete obj; 00213 } 00214 } 00215 00216 } 00217 00218 if( !d->plugin ){ 00219 // No plugin found, build default dialog 00220 QGridLayout * gridLayout = new QGridLayout( 0L, 9, 2, KDialog::marginHint(), 00221 KDialog::spacingHint() ); 00222 d->m_pLayout->addLayout(gridLayout); 00223 gridLayout->setColStretch(0,0); 00224 gridLayout->setColStretch(1,10); 00225 00226 QString sentence1; 00227 if (mtimeDest < mtimeSrc) 00228 sentence1 = i18n("An older item named '%1' already exists."); 00229 else if (mtimeDest == mtimeSrc) 00230 sentence1 = i18n("A similar file named '%1' already exists."); 00231 else 00232 sentence1 = i18n("A newer item named '%1' already exists."); 00233 00234 QLabel * lb1 = new KSqueezedTextLabel( sentence1.arg(d->dest), this ); 00235 gridLayout->addMultiCellWidget( lb1, 0, 0, 0, 1 ); // takes the complete first line 00236 00237 lb1 = new QLabel( this ); 00238 lb1->setPixmap( KMimeType::pixmapForURL( d->dest ) ); 00239 gridLayout->addMultiCellWidget( lb1, 1, 3, 0, 0 ); // takes the first column on rows 1-3 00240 00241 int row = 1; 00242 if ( sizeDest != (KIO::filesize_t)-1 ) 00243 { 00244 QLabel * lb = new QLabel( i18n("size %1").arg( KIO::convertSize(sizeDest) ), this ); 00245 gridLayout->addWidget( lb, row, 1 ); 00246 row++; 00247 00248 } 00249 if ( ctimeDest != (time_t)-1 ) 00250 { 00251 QDateTime dctime; dctime.setTime_t( ctimeDest ); 00252 QLabel * lb = new QLabel( i18n("created on %1").arg( KGlobal::locale()->formatDateTime(dctime) ), this ); 00253 gridLayout->addWidget( lb, row, 1 ); 00254 row++; 00255 } 00256 if ( mtimeDest != (time_t)-1 ) 00257 { 00258 QDateTime dmtime; dmtime.setTime_t( mtimeDest ); 00259 QLabel * lb = new QLabel( i18n("modified on %1").arg( KGlobal::locale()->formatDateTime(dmtime) ), this ); 00260 gridLayout->addWidget( lb, row, 1 ); 00261 row++; 00262 } 00263 00264 if ( !d->src.isEmpty() ) 00265 { 00266 // rows 1 to 3 are the details (size/ctime/mtime), row 4 is empty 00267 gridLayout->addRowSpacing( 4, 20 ); 00268 00269 QLabel * lb2 = new KSqueezedTextLabel( i18n("The source file is '%1'").arg(d->src), this ); 00270 gridLayout->addMultiCellWidget( lb2, 5, 5, 0, 1 ); // takes the complete first line 00271 00272 lb2 = new QLabel( this ); 00273 lb2->setPixmap( KMimeType::pixmapForURL( d->src ) ); 00274 gridLayout->addMultiCellWidget( lb2, 6, 8, 0, 0 ); // takes the first column on rows 6-8 00275 00276 row = 6; 00277 00278 if ( sizeSrc != (KIO::filesize_t)-1 ) 00279 { 00280 QLabel * lb = new QLabel( i18n("size %1").arg( KIO::convertSize(sizeSrc) ), this ); 00281 gridLayout->addWidget( lb, row, 1 ); 00282 row++; 00283 } 00284 if ( ctimeSrc != (time_t)-1 ) 00285 { 00286 QDateTime dctime; dctime.setTime_t( ctimeSrc ); 00287 QLabel * lb = new QLabel( i18n("created on %1").arg( KGlobal::locale()->formatDateTime(dctime) ), this ); 00288 gridLayout->addWidget( lb, row, 1 ); 00289 row++; 00290 } 00291 if ( mtimeSrc != (time_t)-1 ) 00292 { 00293 QDateTime dmtime; dmtime.setTime_t( mtimeSrc ); 00294 QLabel * lb = new QLabel( i18n("modified on %1").arg( KGlobal::locale()->formatDateTime(dmtime) ), this ); 00295 gridLayout->addWidget( lb, row, 1 ); 00296 row++; 00297 } 00298 } 00299 } 00300 } 00301 else 00302 { 00303 // This is the case where we don't want to allow overwriting, the existing 00304 // file must be preserved (e.g. when renaming). 00305 QString sentence1; 00306 if (mtimeDest < mtimeSrc) 00307 sentence1 = i18n("An older item named '%1' already exists."); 00308 else if (mtimeDest == mtimeSrc) 00309 sentence1 = i18n("A similar file named '%1' already exists."); 00310 else 00311 sentence1 = i18n("A newer item named '%1' already exists."); 00312 00313 QLabel *lb = new KSqueezedTextLabel ( sentence1.arg(d->dest), this ); 00314 d->m_pLayout->addWidget(lb); 00315 } 00316 QHBoxLayout* layout2 = new QHBoxLayout(); 00317 d->m_pLayout->addLayout( layout2 ); 00318 00319 d->m_pLineEdit = new QLineEdit( this ); 00320 layout2->addWidget( d->m_pLineEdit ); 00321 QString fileName = KURL(d->dest).fileName(); 00322 d->m_pLineEdit->setText( KIO::decodeFileName( fileName ) ); 00323 if (d->b1) 00324 connect(d->m_pLineEdit, SIGNAL(textChanged(const QString &)), 00325 SLOT(enableRenameButton(const QString &))); 00326 if ( d->b8 ) 00327 { 00328 layout2->addWidget( d->b8 ); 00329 setTabOrder( d->m_pLineEdit, d->b8 ); 00330 } 00331 00332 KSeparator* separator = new KSeparator( this ); 00333 d->m_pLayout->addWidget( separator ); 00334 00335 QHBoxLayout* layout = new QHBoxLayout(); 00336 d->m_pLayout->addLayout( layout ); 00337 00338 layout->addStretch(1); 00339 00340 if ( d->b1 ) 00341 { 00342 layout->addWidget( d->b1 ); 00343 setTabOrder( d->b1, d->b0 ); 00344 } 00345 if ( d->b2 ) 00346 { 00347 layout->addWidget( d->b2 ); 00348 setTabOrder( d->b2, d->b0 ); 00349 } 00350 if ( d->b3 ) 00351 { 00352 layout->addWidget( d->b3 ); 00353 setTabOrder( d->b3, d->b0 ); 00354 } 00355 if ( d->b4 ) 00356 { 00357 layout->addWidget( d->b4 ); 00358 setTabOrder( d->b4, d->b0 ); 00359 } 00360 if ( d->b5 ) 00361 { 00362 layout->addWidget( d->b5 ); 00363 setTabOrder( d->b5, d->b0 ); 00364 } 00365 if ( d->b6 ) 00366 { 00367 layout->addWidget( d->b6 ); 00368 setTabOrder( d->b6, d->b0 ); 00369 } 00370 if ( d->b7 ) 00371 { 00372 layout->addWidget( d->b7 ); 00373 setTabOrder( d->b7, d->b0 ); 00374 } 00375 00376 d->b0->setDefault( true ); 00377 layout->addWidget( d->b0 ); 00378 00379 resize( sizeHint() ); 00380 } 00381 00382 RenameDlg::~RenameDlg() 00383 { 00384 delete d; 00385 // no need to delete Pushbuttons,... qt will do this 00386 } 00387 00388 void RenameDlg::enableRenameButton(const QString &newDest) 00389 { 00390 if (newDest != d->dest) 00391 { 00392 d->b1->setEnabled(true); 00393 d->b1->setDefault(true); 00394 } 00395 else 00396 d->b1->setEnabled(false); 00397 } 00398 00399 KURL RenameDlg::newDestURL() 00400 { 00401 KURL newDest( d->dest ); 00402 QString fileName = d->m_pLineEdit->text(); 00403 newDest.setFileName( KIO::encodeFileName( fileName ) ); 00404 return newDest; 00405 } 00406 00407 void RenameDlg::b0Pressed() 00408 { 00409 done( 0 ); 00410 } 00411 00412 // Rename 00413 void RenameDlg::b1Pressed() 00414 { 00415 if ( d->m_pLineEdit->text().isEmpty() ) 00416 return; 00417 00418 KURL u = newDestURL(); 00419 if ( !u.isValid() ) 00420 { 00421 KMessageBox::error( this, i18n( "Malformed URL\n%1" ).arg( u.prettyURL() ) ); 00422 return; 00423 } 00424 00425 done( 1 ); 00426 } 00427 00428 static QString suggestName(const KURL& baseURL, const QString& oldName) 00429 { 00430 QString dotSuffix, suggestedName; 00431 QString basename = oldName; 00432 00433 int index = basename.find( '.' ); 00434 if ( index != -1 ) { 00435 dotSuffix = basename.mid( index ); 00436 basename.truncate( index ); 00437 } 00438 00439 int pos = basename.findRev( '_' ); 00440 if(pos != -1 ){ 00441 QString tmp = basename.mid( pos+1 ); 00442 bool ok; 00443 int number = tmp.toInt( &ok ); 00444 if ( !ok ) {// ok there is no number 00445 suggestedName = basename + "1" + dotSuffix; 00446 } 00447 else { 00448 // yes there's already a number behind the _ so increment it by one 00449 basename.replace( pos+1, tmp.length(), QString::number(number+1) ); 00450 suggestedName = basename + dotSuffix; 00451 } 00452 } 00453 else // no underscore yet 00454 suggestedName = basename + "_1" + dotSuffix ; 00455 00456 // Check if suggested name already exists 00457 bool exists = false; 00458 // TODO: network transparency. However, using NetAccess from a modal dialog 00459 // could be a problem, no? (given that it uses a modal widget itself....) 00460 if ( baseURL.isLocalFile() ) 00461 exists = QFileInfo( baseURL.path(+1) + suggestedName ).exists(); 00462 00463 if ( !exists ) 00464 return suggestedName; 00465 else // already exists -> recurse 00466 return suggestName( baseURL, suggestedName ); 00467 } 00468 00469 // Propose button clicked 00470 void RenameDlg::b8Pressed() 00471 { 00472 /* no name to play with */ 00473 if ( d->m_pLineEdit->text().isEmpty() ) 00474 return; 00475 00476 KURL destDirectory( d->dest ); 00477 destDirectory.setPath( destDirectory.directory() ); 00478 d->m_pLineEdit->setText( suggestName( destDirectory, d->m_pLineEdit->text() ) ); 00479 return; 00480 } 00481 00482 void RenameDlg::b2Pressed() 00483 { 00484 done( 2 ); 00485 } 00486 00487 void RenameDlg::b3Pressed() 00488 { 00489 done( 3 ); 00490 } 00491 00492 void RenameDlg::b4Pressed() 00493 { 00494 done( 4 ); 00495 } 00496 00497 void RenameDlg::b5Pressed() 00498 { 00499 done( 5 ); 00500 } 00501 00502 void RenameDlg::b6Pressed() 00503 { 00504 done( 6 ); 00505 } 00506 00507 void RenameDlg::b7Pressed() 00508 { 00509 done( 7 ); 00510 } 00517 void RenameDlg::pluginHandling() 00518 { 00519 d->mimeSrc = mime( d->src ); 00520 d->mimeDest = mime(d->dest ); 00521 00522 kdDebug(7024) << "Source Mimetype: "<< d->mimeSrc << endl; 00523 kdDebug(7024) << "Dest Mimetype: "<< d->mimeDest << endl; 00524 } 00525 QString RenameDlg::mime( const QString &src ) 00526 { 00527 KMimeType::Ptr type = KMimeType::findByURL(src ); 00528 //if( type->name() == KMimeType::defaultMimeType() ){ // ok no mimetype 00529 // QString ty = KIO::NetAccess::mimetype(d->src ); 00530 // return ty; 00531 return type->name(); 00532 } 00533 00534 00535 RenameDlg_Result KIO::open_RenameDlg( const QString & _caption, 00536 const QString & _src, const QString & _dest, 00537 RenameDlg_Mode _mode, 00538 QString& _new, 00539 KIO::filesize_t sizeSrc, 00540 KIO::filesize_t sizeDest, 00541 time_t ctimeSrc, 00542 time_t ctimeDest, 00543 time_t mtimeSrc, 00544 time_t mtimeDest) 00545 { 00546 Q_ASSERT(kapp); 00547 00548 RenameDlg dlg( 0L, _caption, _src, _dest, _mode, 00549 sizeSrc, sizeDest, ctimeSrc, ctimeDest, mtimeSrc, mtimeDest, 00550 true /*modal*/ ); 00551 int i = dlg.exec(); 00552 _new = dlg.newDestURL().path(); 00553 00554 return (RenameDlg_Result)i; 00555 } 00556 00557 #include "renamedlg.moc" 00558 00559 00560 00561 00562
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Aug 30 22:54:43 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003