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.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 22 14:24:13 2004 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2003