# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 <kseparator.h>
    00046 #include <kstringhandler.h>
    00047 #include <kstdguiitem.h>
    00048 #include <kguiitem.h>
    00049 #include <ksqueezedtextlabel.h>
    00050
    00051 #ifdef Q_WS_X11
    00052 #include <kwin.h>
    00053 #endif
    00054
    00055 using namespace KIO;
    00056
    00057 class RenameDlg::RenameDlgPrivate
    00058 {
    00059  public:
    00060   RenameDlgPrivate(){
    00061     bCancel = 0;
    00062     bRename = bSkip = bAutoSkip = bOverwrite = bOverwriteAll = 0;
    00063     bResume = bResumeAll = bSuggestNewName = 0;
    00064     m_pLineEdit = 0;
    00065   }
    00066   KPushButton *bCancel;
    00067   QPushButton *bRename;
    00068   QPushButton *bSkip;
    00069   QPushButton *bAutoSkip;
    00070   QPushButton *bOverwrite;
    00071   QPushButton *bOverwriteAll;
    00072   QPushButton *bResume;
    00073   QPushButton *bResumeAll;
    00074   QPushButton *bSuggestNewName;
    00075   QLineEdit* m_pLineEdit;
    00076   KURL src;
    00077   KURL dest;
    00078   QString mimeSrc;
    00079   QString mimeDest;
    00080   bool modal;
    00081   bool plugin;
    00082 };
    00083
    00084 RenameDlg::RenameDlg(QWidget *parent, const QString & _caption,
    00085                      const QString &_src, const QString &_dest,
    00086                      RenameDlg_Mode _mode,
    00087                      KIO::filesize_t sizeSrc,
    00088                      KIO::filesize_t sizeDest,
    00089                      time_t ctimeSrc,
    00090                      time_t ctimeDest,
    00091                      time_t mtimeSrc,
    00092                      time_t mtimeDest,
    00093                      bool _modal)
    00094   : QDialog ( parent, "KIO::RenameDialog" , _modal )
    00095 {
    00096     d = new RenameDlgPrivate( );
    00097     d->modal = _modal;
    00098 #if 0
    00099     // Set "StaysOnTop", because this dialog is typically used in kio_uiserver,
    00100     // i.e. in a separate process.
    00101     // ####### This isn't the case anymore - remove?
    00102 #if !defined(Q_WS_QWS) && !defined(Q_WS_WIN) //FIXME(E): Implement for QT Embedded & win32
    00103     if (d->modal)
    00104         KWin::setState( winId(), NET::StaysOnTop );
    00105 #endif
    00106 #endif
    00107
    00108     d->src = _src;
    00109     d->dest = _dest;
    00110     d->plugin = false;
    00111
    00112
    00113     setCaption( _caption );
    00114
    00115     d->bCancel = new KPushButton( KStdGuiItem::cancel(), this );
    00116     connect(d->bCancel, SIGNAL(clicked()), this, SLOT(b0Pressed()));
    00117
    00118     if ( ! (_mode & M_NORENAME ) ) {
    00119         d->bRename = new QPushButton( i18n( "&Rename" ), this );
    00120         d->bRename->setEnabled(false);
    00121         d->bSuggestNewName = new QPushButton( i18n( "Suggest New &Name" ), this );
    00122         connect(d->bSuggestNewName, SIGNAL(clicked()), this, SLOT(b8Pressed()));
    00123         connect(d->bRename, SIGNAL(clicked()), this, SLOT(b1Pressed()));
    00124     }
    00125
    00126     if ( ( _mode & M_MULTI ) && ( _mode & M_SKIP ) ) {
    00127         d->bSkip = new QPushButton( i18n( "&Skip" ), this );
    00128         connect(d->bSkip, SIGNAL(clicked()), this, SLOT(b2Pressed()));
    00129
    00130         d->bAutoSkip = new QPushButton( i18n( "&Auto Skip" ), this );
    00131         connect(d->bAutoSkip, SIGNAL(clicked()), this, SLOT(b3Pressed()));
    00132     }
    00133
    00134     if ( _mode & M_OVERWRITE ) {
    00135         d->bOverwrite = new QPushButton( i18n( "&Overwrite" ), this );
    00136         connect(d->bOverwrite, SIGNAL(clicked()), this, SLOT(b4Pressed()));
    00137
    00138         if ( _mode & M_MULTI ) {
    00139             d->bOverwriteAll = new QPushButton( i18n( "O&verwrite All" ), this );
    00140             connect(d->bOverwriteAll, SIGNAL(clicked()), this, SLOT(b5Pressed()));
    00141         }
    00142     }
    00143
    00144     if ( _mode & M_RESUME ) {
    00145         d->bResume = new QPushButton( i18n( "&Resume" ), this );
    00146         connect(d->bResume, SIGNAL(clicked()), this, SLOT(b6Pressed()));
    00147
    00148         if ( _mode & M_MULTI )
    00149         {
    00150             d->bResumeAll = new QPushButton( i18n( "R&esume All" ), this );
    00151             connect(d->bResumeAll, SIGNAL(clicked()), this, SLOT(b7Pressed()));
    00152         }
    00153     }
    00154
    00155     QVBoxLayout* pLayout = new QVBoxLayout( this, KDialog::marginHint(),
    00156                                     KDialog::spacingHint() );
    00157     pLayout->addStrut( 360 );   // makes dlg at least that wide
    00158
    00159     // User tries to overwrite a file with itself ?
    00160     if ( _mode & M_OVERWRITE_ITSELF ) {
    00161         QLabel *lb = new QLabel( i18n( "This action would overwrite '%1' with itself.\n"
    00162                                        "Please enter a new file name:" ).arg( KStringHandler::csqueeze( d->src.pathOrURL(),100 ) ), this );
    00163         d->bRename->setText(i18n("C&ontinue"));
    00164         pLayout->addWidget( lb );
    00165     }
    00166     else if ( _mode & M_OVERWRITE ) {
    00167
    00168         // Figure out the mimetype and load one plugin
    00169         // (This is the only mode that is handled by plugins)
    00170         pluginHandling();
    00171         KTrader::OfferList plugin_offers;
    00172         if( d->mimeSrc != KMimeType::defaultMimeType()   ){
    00173             plugin_offers = KTrader::self()->query(d->mimeSrc, "'RenameDlg/Plugin' in ServiceTypes");
    00174
    00175         }else if(d->mimeDest != KMimeType::defaultMimeType() ) {
    00176             plugin_offers = KTrader::self()->query(d->mimeDest, "'RenameDlg/Plugin' in ServiceTypes");
    00177         }
    00178         if(!plugin_offers.isEmpty() ){
    00179             kdDebug(7024) << "Offers" << endl;
    00180             KTrader::OfferList::ConstIterator it = plugin_offers.begin();
    00181             KTrader::OfferList::ConstIterator end = plugin_offers.end();
    00182             for( ; it != end; ++it ){
    00183                 QString libName = (*it)->library();
    00184                 if( libName.isEmpty() ){
    00185                     kdDebug(7024) << "lib is empty" << endl;
    00186                     continue;
    00187                 }
    00188                 KLibrary *lib = KLibLoader::self()->library(libName.local8Bit() );
    00189                 if(!lib) {
    00190                     continue;
    00191                 }
    00192                 KLibFactory *factory = lib->factory();
    00193                 if(!factory){
    00194                     lib->unload();
    00195                     continue;
    00196                 }
    00197                 QObject *obj = factory->create( this, (*it)->name().latin1() );
    00198                 if(!obj) {
    00199                     lib->unload();
    00200                     continue;
    00201                 }
    00202                 RenameDlgPlugin *plugin = static_cast<RenameDlgPlugin *>(obj);
    00203                 if(!plugin ){
    00204                     delete obj;
    00205                     continue;
    00206                 }
    00207                 if( plugin->initialize( _mode, _src, _dest, d->mimeSrc,
    00208                                         d->mimeDest, sizeSrc, sizeDest,
    00209                                         ctimeSrc, ctimeDest,
    00210                                         mtimeSrc, mtimeDest ) ) {
    00211                     d->plugin = true;
    00212                     pLayout->addWidget(plugin );
    00213                     kdDebug(7024) << "RenameDlgPlugin" << endl;
    00214                     break;
    00215                 } else {
    00216                     delete obj;
    00217                 }
    00218             }
    00219
    00220         }
    00221
    00222         if( !d->plugin ){
    00223             // No plugin found, build default dialog
    00224             QGridLayout * gridLayout = new QGridLayout( 0L, 9, 2, KDialog::marginHint(),
    00225                                                         KDialog::spacingHint() );
    00226             pLayout->addLayout(gridLayout);
    00227             gridLayout->setColStretch(0,0);
    00228             gridLayout->setColStretch(1,10);
    00229
    00230             QString sentence1;
    00231             if (mtimeDest < mtimeSrc)
    00232                 sentence1 = i18n("An older item named '%1' already exists.");
    00233             else if (mtimeDest == mtimeSrc)
    00234                 sentence1 = i18n("A similar file named '%1' already exists.");
    00235             else
    00236                 sentence1 = i18n("A newer item named '%1' already exists.");
    00237
    00238             QLabel * lb1 = new KSqueezedTextLabel( sentence1.arg(d->dest.pathOrURL() ), this );
    00239             gridLayout->addMultiCellWidget( lb1, 0, 0, 0, 1 ); // takes the complete first line
    00240
    00241             lb1 = new QLabel( this );
    00242             lb1->setPixmap( KMimeType::pixmapForURL( d->dest ) );
    00243             gridLayout->addMultiCellWidget( lb1, 1, 3, 0, 0 ); // takes the first column on rows 1-3
    00244
    00245             int row = 1;
    00246             if ( sizeDest != (KIO::filesize_t)-1 )
    00247             {
    00248                 QLabel * lb = new QLabel( i18n("size %1").arg( KIO::convertSize(sizeDest) ), this );
    00249                 gridLayout->addWidget( lb, row, 1 );
    00250                 row++;
    00251
    00252             }
    00253             if ( ctimeDest != (time_t)-1 )
    00254             {
    00255                 QDateTime dctime; dctime.setTime_t( ctimeDest );
    00256                 QLabel * lb = new QLabel( i18n("created on %1").arg( KGlobal::locale()->formatDateTime(dctime) ), this );
    00257                 gridLayout->addWidget( lb, row, 1 );
    00258                 row++;
    00259             }
    00260             if ( mtimeDest != (time_t)-1 )
    00261             {
    00262                 QDateTime dmtime; dmtime.setTime_t( mtimeDest );
    00263                 QLabel * lb = new QLabel( i18n("modified on %1").arg( KGlobal::locale()->formatDateTime(dmtime) ), this );
    00264                 gridLayout->addWidget( lb, row, 1 );
    00265                 row++;
    00266             }
    00267
    00268             if ( !d->src.isEmpty() )
    00269             {
    00270                 // rows 1 to 3 are the details (size/ctime/mtime), row 4 is empty
    00271                 gridLayout->addRowSpacing( 4, 20 );
    00272
    00273                 QLabel * lb2 = new KSqueezedTextLabel( i18n("The source file is '%1'").arg(d->src.pathOrURL()), this );
    00274                 gridLayout->addMultiCellWidget( lb2, 5, 5, 0, 1 ); // takes the complete first line
    00275
    00276                 lb2 = new QLabel( this );
    00277                 lb2->setPixmap( KMimeType::pixmapForURL( d->src ) );
    00278                 gridLayout->addMultiCellWidget( lb2, 6, 8, 0, 0 ); // takes the first column on rows 6-8
    00279
    00280                 row = 6;
    00281
    00282                 if ( sizeSrc != (KIO::filesize_t)-1 )
    00283                 {
    00284                     QLabel * lb = new QLabel( i18n("size %1").arg( KIO::convertSize(sizeSrc) ), this );
    00285                     gridLayout->addWidget( lb, row, 1 );
    00286                     row++;
    00287                 }
    00288                 if ( ctimeSrc != (time_t)-1 )
    00289                 {
    00290                     QDateTime dctime; dctime.setTime_t( ctimeSrc );
    00291                     QLabel * lb = new QLabel( i18n("created on %1").arg( KGlobal::locale()->formatDateTime(dctime) ), this );
    00292                     gridLayout->addWidget( lb, row, 1 );
    00293                     row++;
    00294                 }
    00295                 if ( mtimeSrc != (time_t)-1 )
    00296                 {
    00297                     QDateTime dmtime; dmtime.setTime_t( mtimeSrc );
    00298                     QLabel * lb = new QLabel( i18n("modified on %1").arg( KGlobal::locale()->formatDateTime(dmtime) ), this );
    00299                     gridLayout->addWidget( lb, row, 1 );
    00300                     row++;
    00301                 }
    00302             }
    00303         }
    00304     }
    00305     else
    00306     {
    00307         // This is the case where we don't want to allow overwriting, the existing
    00308         // file must be preserved (e.g. when renaming).
    00309         QString sentence1;
    00310         if (mtimeDest < mtimeSrc)
    00311             sentence1 = i18n("An older item named '%1' already exists.");
    00312         else if (mtimeDest == mtimeSrc)
    00313             sentence1 = i18n("A similar file named '%1' already exists.");
    00314         else
    00315             sentence1 = i18n("A newer item named '%1' already exists.");
    00316
    00317         QLabel *lb = new KSqueezedTextLabel( sentence1.arg(d->dest.pathOrURL()), this );
    00318         pLayout->addWidget(lb);
    00319     }
    00320     QHBoxLayout* layout2 = new QHBoxLayout();
    00321     pLayout->addLayout( layout2 );
    00322
    00323     d->m_pLineEdit = new QLineEdit( this );
    00324     layout2->addWidget( d->m_pLineEdit );
    00325     QString fileName = d->dest.fileName();
    00326     d->m_pLineEdit->setText( KIO::decodeFileName( fileName ) );
    00327     if ( d->bRename || d->bOverwrite )
    00328         connect(d->m_pLineEdit, SIGNAL(textChanged(const QString &)),
    00329                 SLOT(enableRenameButton(const QString &)));
    00330     if ( d->bSuggestNewName )
    00331     {
    00332         layout2->addWidget( d->bSuggestNewName );
    00333         setTabOrder( d->m_pLineEdit, d->bSuggestNewName );
    00334     }
    00335
    00336     KSeparator* separator = new KSeparator( this );
    00337     pLayout->addWidget( separator );
    00338
    00339     QHBoxLayout* layout = new QHBoxLayout();
    00340     pLayout->addLayout( layout );
    00341
    00342     layout->addStretch(1);
    00343
    00344     if ( d->bRename )
    00345     {
    00346         layout->addWidget( d->bRename );
    00347         setTabOrder( d->bRename, d->bCancel );
    00348     }
    00349     if ( d->bSkip )
    00350     {
    00351         layout->addWidget( d->bSkip );
    00352         setTabOrder( d->bSkip, d->bCancel );
    00353     }
    00354     if ( d->bAutoSkip )
    00355     {
    00356         layout->addWidget( d->bAutoSkip );
    00357         setTabOrder( d->bAutoSkip, d->bCancel );
    00358     }
    00359     if ( d->bOverwrite )
    00360     {
    00361         layout->addWidget( d->bOverwrite );
    00362         setTabOrder( d->bOverwrite, d->bCancel );
    00363     }
    00364     if ( d->bOverwriteAll )
    00365     {
    00366         layout->addWidget( d->bOverwriteAll );
    00367         setTabOrder( d->bOverwriteAll, d->bCancel );
    00368     }
    00369     if ( d->bResume )
    00370     {
    00371         layout->addWidget( d->bResume );
    00372         setTabOrder( d->bResume, d->bCancel );
    00373     }
    00374     if ( d->bResumeAll )
    00375     {
    00376         layout->addWidget( d->bResumeAll );
    00377         setTabOrder( d->bResumeAll, d->bCancel );
    00378     }
    00379
    00380     d->bCancel->setDefault( true );
    00381     layout->addWidget( d->bCancel );
    00382
    00383     resize( sizeHint() );
    00384 }
    00385
    00386 RenameDlg::~RenameDlg()
    00387 {
    00388   delete d;
    00389   // no need to delete Pushbuttons,... qt will do this
    00390 }
    00391
    00392 void RenameDlg::enableRenameButton(const QString &newDest)
    00393 {
    00394   if ( newDest != KIO::decodeFileName( d->dest.fileName() ) && !newDest.isEmpty() )
    00395   {
    00396     d->bRename->setEnabled( true );
    00397     d->bRename->setDefault( true );
    00398     if ( d->bOverwrite )
    00399         d->bOverwrite->setEnabled( false ); // prevent confusion (#83114)
    00400   }
    00401   else
    00402   {
    00403     d->bRename->setEnabled( false );
    00404     if ( d->bOverwrite )
    00405         d->bOverwrite->setEnabled( true );
    00406   }
    00407 }
    00408
    00409 KURL RenameDlg::newDestURL()
    00410 {
    00411   KURL newDest( d->dest );
    00412   QString fileName = d->m_pLineEdit->text();
    00413   newDest.setFileName( KIO::encodeFileName( fileName ) );
    00414   return newDest;
    00415 }
    00416
    00417 void RenameDlg::b0Pressed()
    00418 {
    00419   done( 0 );
    00420 }
    00421
    00422 // Rename
    00423 void RenameDlg::b1Pressed()
    00424 {
    00425   if ( d->m_pLineEdit->text().isEmpty() )
    00426     return;
    00427
    00428   KURL u = newDestURL();
    00429   if ( !u.isValid() )
    00430   {
    00431     KMessageBox::error( this, i18n( "Malformed URL\n%1" ).arg( u.url() ) );
    00432     return;
    00433   }
    00434
    00435   done( 1 );
    00436 }
    00437
    00438 QString RenameDlg::suggestName(const KURL& baseURL, const QString& oldName)
    00439 {
    00440   QString dotSuffix, suggestedName;
    00441   QString basename = oldName;
    00442
    00443   int index = basename.find( '.' );
    00444   if ( index != -1 ) {
    00445     dotSuffix = basename.mid( index );
    00446     basename.truncate( index );
    00447   }
    00448
    00449   int pos = basename.findRev( '_' );
    00450   if(pos != -1 ){
    00451     QString tmp = basename.mid( pos+1 );
    00452     bool ok;
    00453     int number = tmp.toInt( &ok );
    00454     if ( !ok ) {// ok there is no number
    00455       suggestedName = basename + "1" + dotSuffix;
    00456     }
    00457     else {
    00458      // yes there's already a number behind the _ so increment it by one
    00459       basename.replace( pos+1, tmp.length(), QString::number(number+1) );
    00460       suggestedName = basename + dotSuffix;
    00461     }
    00462   }
    00463   else // no underscore yet
    00464     suggestedName = basename + "_1" + dotSuffix ;
    00465
    00466   // Check if suggested name already exists
    00467   bool exists = false;
    00468   // TODO: network transparency. However, using NetAccess from a modal dialog
    00469   // could be a problem, no? (given that it uses a modal widget itself....)
    00470   if ( baseURL.isLocalFile() )
    00471      exists = QFileInfo( baseURL.path(+1) + suggestedName ).exists();
    00472
    00473   if ( !exists )
    00474     return suggestedName;
    00475   else // already exists -> recurse
    00476     return suggestName( baseURL, suggestedName );
    00477 }
    00478
    00479 // Propose button clicked
    00480 void RenameDlg::b8Pressed()
    00481 {
    00482   /* no name to play with */
    00483   if ( d->m_pLineEdit->text().isEmpty() )
    00484     return;
    00485
    00486   KURL destDirectory( d->dest );
    00487   destDirectory.setPath( destDirectory.directory() );
    00488   d->m_pLineEdit->setText( suggestName( destDirectory, d->m_pLineEdit->text() ) );
    00489   return;
    00490 }
    00491
    00492 void RenameDlg::b2Pressed()
    00493 {
    00494   done( 2 );
    00495 }
    00496
    00497 void RenameDlg::b3Pressed()
    00498 {
    00499   done( 3 );
    00500 }
    00501
    00502 void RenameDlg::b4Pressed()
    00503 {
    00504   done( 4 );
    00505 }
    00506
    00507 void RenameDlg::b5Pressed()
    00508 {
    00509   done( 5 );
    00510 }
    00511
    00512 void RenameDlg::b6Pressed()
    00513 {
    00514   done( 6 );
    00515 }
    00516
    00517 void RenameDlg::b7Pressed()
    00518 {
    00519   done( 7 );
    00520 }
    00521
    00522 static QString mime( const KURL& src )
    00523 {
    00524   KMimeType::Ptr type = KMimeType::findByURL( src );
    00525   //if( type->name() == KMimeType::defaultMimeType() ){ // ok no mimetype
    00526     //    QString ty = KIO::NetAccess::mimetype(d->src );
    00527     // return ty;
    00528     return type->name();
    00529 }
    00530
    00537 void RenameDlg::pluginHandling()
    00538 {
    00539   d->mimeSrc = mime( d->src );
    00540   d->mimeDest = mime(d->dest );
    00541
    00542   kdDebug(7024) << "Source Mimetype: "<< d->mimeSrc << endl;
    00543   kdDebug(7024) << "Dest Mimetype: "<< d->mimeDest << endl;
    00544 }
    00545
    00546
    00547 RenameDlg_Result KIO::open_RenameDlg( const QString & _caption,
    00548                                       const QString & _src, const QString & _dest,
    00549                                       RenameDlg_Mode _mode,
    00550                                       QString& _new,
    00551                                       KIO::filesize_t sizeSrc,
    00552                                       KIO::filesize_t sizeDest,
    00553                                       time_t ctimeSrc,
    00554                                       time_t ctimeDest,
    00555                                       time_t mtimeSrc,
    00556                                       time_t mtimeDest)
    00557 {
    00558   Q_ASSERT(kapp);
    00559
    00560   RenameDlg dlg( 0L, _caption, _src, _dest, _mode,
    00561                  sizeSrc, sizeDest, ctimeSrc, ctimeDest, mtimeSrc, mtimeDest,
    00562                  true /*modal*/ );
    00563   int i = dlg.exec();
    00564   _new = dlg.newDestURL().path();
    00565
    00566   return (RenameDlg_Result)i;
    00567 }
    00568
    00569 #include "renamedlg.moc"
    00570
    00571
    00572
    00573
    00574

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:07 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003