diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-22 18:35:24 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-22 18:35:24 +0000 |
commit | aec5a842670a66ff24572847d35375a31c0b379e (patch) | |
tree | 465d7790602658d86ab031788852bf3dbdc96691 /krename | |
download | krename-aec5a842670a66ff24572847d35375a31c0b379e.tar.gz krename-aec5a842670a66ff24572847d35375a31c0b379e.zip |
Added KDE3 version of krename
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/krename@1094420 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krename')
81 files changed, 12078 insertions, 0 deletions
diff --git a/krename/Makefile.am b/krename/Makefile.am new file mode 100644 index 0000000..5d1503f --- /dev/null +++ b/krename/Makefile.am @@ -0,0 +1,49 @@ +## Makefile.am for KRename + +# set the include path for X, qt and KDE +INCLUDES = -I$(top_srcdir)/src $(all_includes) + +# these are the headers for your project + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO +KDE_ICON = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kdedcoptest.pot + +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = krename + +# the application source, library search path, and link libraries + +krename_LDFLAGS = $(KDE_RPATH) $(all_libraries) +krename_LDADD =$(LIB_KPARTS) $(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET) + +noinst_HEADERS = ProgressDialog.h dateplugin.h fileplugin.h kmylistbox.h krenameimpl.h \ + pictureplugin.h tabs.h batchrenamer.h datetime.h firststartdlg.h \ + kmylistview.h mydirplugin.h plugin.h threadedlister.h commandplugin.h \ + dsdirselectdialog.h guimodeselector.h krecursivelister.h myinputdialog.h \ + pluginloader.h translitplugin.h confdialog.h encodingplugin.h helpdialog.h \ + krename.h numberdialog.h profiledlg.h undodialog.h coorddialog.h \ + fileoperation.h kmyhistorycombo.h krenamedcop.h permission.h replacedialog.h \ + wizard.h + +krename_SOURCES = guimodeselector.cpp firststartdlg.cpp tabs.cpp \ + krenameimpl.cpp numberdialog.cpp coorddialog.cpp commandplugin.cpp helpdialog.cpp \ + pictureplugin.cpp mydirplugin.cpp datetime.cpp permission.cpp fileplugin.cpp \ + undodialog.cpp myinputdialog.cpp kmylistview.cpp wizard.cpp replacedialog.cpp \ + pluginloader.cpp plugin.cpp kmylistbox.cpp kmyhistorycombo.cpp fileoperation.cpp \ + confdialog.cpp batchrenamer.cpp ProgressDialog.cpp main.cpp krecursivelister.cpp \ + dsdirselectdialog.cpp krenamedcop.skel dateplugin.cpp encodingplugin.cpp profiledlg.cpp \ + threadedlister.cpp translitplugin.cpp + + +xdg_apps_DATA = krename.desktop + +krenameservice_DATA = krenameservicemenu.desktop krename_dir.desktop +krenameservicedir = $(kde_datadir)/konqueror/servicemenus + +datafiles_DATA = logo.png krename_system_default_tabbed.xml krename_system_default_wizard.xml +datafilesdir = $(kde_datadir)/krename diff --git a/krename/ProgressDialog.cpp b/krename/ProgressDialog.cpp new file mode 100644 index 0000000..81723b5 --- /dev/null +++ b/krename/ProgressDialog.cpp @@ -0,0 +1,360 @@ +/*************************************************************************** + ProgressDialog.cpp - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// QT Includes +#include <qlayout.h> +#include <qprogressbar.h> +#include <qtimer.h> +#include <qtooltip.h> + +#if QT_VERSION < 0x030100 + #include <qregexp.h> +#endif + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <klistview.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kpushbutton.h> +#include <krun.h> + +#include <qfile.h> + +// Own includes +#include "ProgressDialog.h" +#include "krenameimpl.h" +#include "undodialog.h" +#include "fileoperation.h" + +#define MNU_ERROR_ID 33999 +#define MNU_DONE_ID 33998 + +// update user interface every 1/2 second +#define TIMER_INTERVAL 500 + +ProgressDialog::ProgressDialog( QWidget* parent, const char* name, WFlags fl ) + : QWidget( parent, name, fl ) +{ + renamedFiles = NULL; + + resize( 400, 380 ); + setCaption( i18n("Progress") ); + setIcon( BarIcon( "krename" ) ); + + ProgressDialogLayout = new QVBoxLayout( this, 11, 6 ); + Layout1 = new QHBoxLayout( 0, 0, 6 ); + QHBoxLayout* Layout2 = new QHBoxLayout( 0, 6, 6 ); + + bar = new QProgressBar( this ); + bar->setProgress( 0 ); + + buttonCancel = new KPushButton( i18n("&Cancel"), this ); + + display = new KListView( this ); + display->addColumn( i18n("Messages") ); + display->addColumn( "sort" ); + display->setColumnWidthMode( 0, QListView::Maximum ); + display->setColumnWidthMode( 1, QListView::Manual ); + display->setColumnWidth( 1, 0 ); + display->setSorting( -1 ); + display->setUpdatesEnabled( false ); + + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Minimum ); + + buttonUndo = new KPushButton( this ); + buttonUndo->setText( i18n("&Undo") ); + buttonUndo->setEnabled( false ); + + mnuButton = new KPopupMenu( this ); + mnuButton->insertItem( i18n("Restart KRename..."), this, SLOT( restart() )); + mnuButton->insertSeparator(); + mnuButton->insertItem( i18n("Rename Processed Files &Again..."), this, SLOT( again() ), 0, MNU_DONE_ID ); + mnuButton->insertItem( i18n("Rename Unprocessed Files &Again..."), this, SLOT( unAgain() ), 0, MNU_ERROR_ID ); + mnuButton->insertItem( i18n("Rename All Files &Again..."), this, SLOT( allAgain() )); + buttonRestart = new KPushButton( this ); + buttonRestart->setText( i18n( "&Rename More..." ) ); + buttonRestart->setPopup( mnuButton ); + buttonRestart->setEnabled( false ); + + buttonOpenDest = new KPushButton( this ); + buttonOpenDest->setText( i18n("&Open Destination...") ); + + buttonClose = new KPushButton( this ); + buttonClose->setText( i18n( "&Close" ) ); + buttonClose->setEnabled( false ); + + Layout1->addItem( spacer ); + Layout1->addWidget( buttonUndo ); + Layout1->addWidget( buttonRestart ); + Layout1->addWidget( buttonOpenDest ); + Layout1->addWidget( buttonClose ); + Layout1->addItem( spacer ); + + Layout2->addWidget( bar ); + Layout2->addWidget( buttonCancel ); + Layout2->setStretchFactor( bar, 2 ); + + ProgressDialogLayout->addLayout( Layout2 ); + ProgressDialogLayout->addWidget( display ); + ProgressDialogLayout->addLayout( Layout1 ); + + connect( buttonClose, SIGNAL(clicked()), this, SLOT(quitAll())); + connect( buttonOpenDest, SIGNAL(clicked()), this, SLOT(openDest())); + connect( buttonCancel, SIGNAL( clicked()), this, SLOT(canceled() )); + connect( buttonUndo, SIGNAL( clicked() ), this, SLOT( undo() ) ); + + m_count = 0; + m_canceled = false; + m_timer = new QTimer( this, "m_timer" ); + connect( m_timer, SIGNAL( timeout() ), this, SLOT( slotTimer() ) ); + + hide(); +} + +ProgressDialog::~ProgressDialog() +{ + delete m_timer; + + if( renamedFiles ) + delete [] renamedFiles; +} + +void ProgressDialog::print( QString text, QString pixmap ) +{ + if( !m_timer->isActive() ) + { + KApplication::setOverrideCursor( Qt::waitCursor ); + m_timer->start( TIMER_INTERVAL ); + } + + // set an icon if we have none yet + if( pixmap.isNull() ) + pixmap = "ok"; + + KListViewItem* item = new KListViewItem( display, text, count() ); + item->setPixmap( 0, SmallIcon(pixmap) ); + display->insertItem( item ); +} + +void ProgressDialog::error( QString text ) +{ + if( !m_timer->isActive() ) + { + KApplication::setOverrideCursor( Qt::waitCursor ); + m_timer->start( TIMER_INTERVAL ); + } + + //TODO: simplify this (breaks i18n) + KListViewItem* item = new KListViewItem( display, QString( i18n("Error: %1") ).arg( QString::null ) + simplify( text ), count() ); + item->setPixmap( 0, SmallIcon("cancel") ); + display->insertItem( item ); +} + +void ProgressDialog::warning( QString text ) +{ + if( !m_timer->isActive() ) + { + KApplication::setOverrideCursor( Qt::waitCursor ); + m_timer->start( TIMER_INTERVAL ); + } + + KListViewItem* item = new KListViewItem( display, QString( i18n("Warning: %1") ).arg( QString::null ) + simplify( text ), count() ); + item->setPixmap( 0, SmallIcon("idea") ); + display->insertItem( item ); +} + +void ProgressDialog::quitAll() +{ + KApplication::exit(0); +} + +void ProgressDialog::done( int errors, int successfull, bool allowundo ) +{ + m_timer->stop(); + KApplication::restoreOverrideCursor(); + + display->setUpdatesEnabled( true ); + display->setSorting( 1, true ); + display->sort(); + display->setSorting( -1 ); + display->triggerUpdate(); + display->ensureItemVisible( display->lastItem() ); + + bar->setProgress( bar->totalSteps() ); + mnuButton->setItemEnabled( MNU_ERROR_ID, errors ); + mnuButton->setItemEnabled( MNU_DONE_ID, successfull ); + + buttonClose->setEnabled( true ); + buttonRestart->setEnabled( true ); + if( allowundo ) + buttonUndo->setEnabled( true ); + buttonCancel->setEnabled( false ); + + kapp->processEvents( 0 ); +} + +void ProgressDialog::show() +{ + QWidget::show(); + + int w = kapp->desktop()->width(); + int h = kapp->desktop()->height(); + move( (w-width())/2,(h-height())/2 ); +} + +void ProgressDialog::restart() +{ + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), KURL::List() ); + krename->show(); + close(); +} + +void ProgressDialog::again() +{ + KURL::List list; + for( unsigned int i = 0; i < m_size; i++ ) + if( !renamedFiles[i].error ) + list.append( renamedFiles[i].dst ); + + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), list ); + krename->show(); + close(); +} + +void ProgressDialog::unAgain() +{ + KURL::List list; + for( unsigned int i = 0; i < m_size; i++ ) + if( renamedFiles[i].error ) + list.append( renamedFiles[i].src ); + + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), list ); + krename->show(); + close(); +} + +void ProgressDialog::allAgain() +{ + KURL::List list; + for( unsigned int i = 0; i < m_size; i++ ) + list.append( renamedFiles[i].error ? renamedFiles[i].src : renamedFiles[i].dst ); + + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), list ); + krename->show(); + close(); +} + +void ProgressDialog::openDest() +{ + new KRun( m_dest ); +} + +QString ProgressDialog::count() +{ + QString s; + return s.sprintf( "%0*i", 7, ++m_count ); +} + +void ProgressDialog::setProgressTotalSteps( int t ) +{ + bar->setTotalSteps( t ); +} + +void ProgressDialog::setProgress( int p ) +{ + m_timer->start( TIMER_INTERVAL ); + + bar->setProgress( p ); +} + +void ProgressDialog::canceled() +{ + warning( i18n("User pressed cancel!") ); + warning( i18n("Aborting...") ); + m_canceled = true; +} + +const QString ProgressDialog::simplify( const QString & text ) +{ + // make error messages fit in one line! + QString t( text ); +#if QT_VERSION >= 0x030100 + t.remove( '\n' ); +#else + t.replace( QRegExp("\n"), "" ); +#endif + + return t; +} + +void ProgressDialog::undo() +{ + KURL::List list; + FileOperation fop; + + m_timer->start( TIMER_INTERVAL ); + KApplication::setOverrideCursor( Qt::waitCursor ); + for( unsigned int i = 0; i < m_size; i++ ) + { + setProgress( i ); + list.append( renamedFiles[i].src ); + if( !renamedFiles[i].error ) + { + if( renamedFiles[i].dir ) { + /** handle renamed directories and their contents + */ + QString ddir = renamedFiles[i].dst.path(); + QString sdir = renamedFiles[i].src.path(); + for( unsigned int c = i+1; c < m_size; c++ ) { + QString dpath = renamedFiles[c].dst.path(); + QString spath = renamedFiles[c].src.path(); + + if( spath.startsWith( ddir ) ) + { + spath = sdir + spath.right( spath.length() - ddir.length() ); + renamedFiles[c].src.setPath( spath ); + } + + + if( dpath.startsWith( ddir ) ) + { + dpath = sdir + dpath.right( dpath.length() - ddir.length() ); + renamedFiles[c].dst.setPath( dpath ); + } + } + } + + if(!fop.start( renamedFiles[i].dst, renamedFiles[i].src, MOVE, false )) + error( i18n("Undo: ") + fop.error() ); + } + } + + print( i18n("Undoing the renaming operation has been completed."), "undo" ); + m_timer->stop(); + KApplication::restoreOverrideCursor(); + + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), list ); + krename->show(); + close(); +} + +void ProgressDialog::slotTimer() +{ + kapp->processEvents( 0 ); +} diff --git a/krename/ProgressDialog.h b/krename/ProgressDialog.h new file mode 100644 index 0000000..0bbab51 --- /dev/null +++ b/krename/ProgressDialog.h @@ -0,0 +1,129 @@ +/*************************************************************************** + ProgressDialog.h - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PROGRESSDIALOG_H +#define PROGRESSDIALOG_H + +#include <qwidget.h> +#include <kurl.h> + +typedef struct RenamedList +{ + KURL src; + KURL dst; + + bool dir; + bool error; +}; + +class KRenameImpl; +class KListView; +class KPopupMenu; +class KPushButton; +class QProgressBar; +class QStringList; +class QStrList; +class QString; +class QTimer; +class QHBoxLayout; +class QVBoxLayout; +class ProgressDialog : public QWidget +{ + Q_OBJECT + public: + ProgressDialog( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~ProgressDialog(); + + void setProgressTotalSteps( int t ); + void setProgress( int p ); + + inline bool wasCancelled() const; + inline void setDestination( const KURL & dir ); + inline void setRenamedFiles( RenamedList* list, unsigned int size ) ; + inline void setCreatedDirectories( const KURL::List & list ); + + void done( int errors, int successfull, bool allowundo ); + void print( QString text, QString pixmap = 0 ); + void error( QString text ); + void warning( QString text ); + + public slots: + void show(); + + private slots: + void quitAll(); + void restart(); + void again(); + void unAgain(); + void allAgain(); + void openDest(); + void canceled(); + void undo(); + void slotTimer(); + + private: + QString count(); + const QString simplify( const QString & text ); + + protected: + RenamedList* renamedFiles; + unsigned int m_size; + + KURL m_dest; + int m_count; + bool m_canceled; + KURL::List m_created; + + QTimer* m_timer; + + KListView* display; + KPushButton* buttonClose; + KPushButton* buttonRestart; + KPushButton* buttonOpenDest; + KPushButton* buttonUndo; + KPushButton* buttonCancel; + KPopupMenu* mnuButton; + + QProgressBar* bar; + + QVBoxLayout* ProgressDialogLayout; + QHBoxLayout* Layout1; +}; + + +bool ProgressDialog::wasCancelled() const +{ + return m_canceled; +} + +void ProgressDialog::setDestination( const KURL & dir ) +{ + m_dest = dir; +} + +void ProgressDialog::setRenamedFiles( RenamedList* list, unsigned int size ) +{ + renamedFiles = list; + m_size = size; +} + +void ProgressDialog::setCreatedDirectories( const KURL::List & list ) +{ + m_created = list; +} + +#endif // PROGRESSDIALOG_H diff --git a/krename/batchrenamer.cpp b/krename/batchrenamer.cpp new file mode 100644 index 0000000..89721e0 --- /dev/null +++ b/krename/batchrenamer.cpp @@ -0,0 +1,950 @@ +/*************************************************************************** + batchrenamer.cpp - description + ------------------- + begin : Sat Aug 18 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef VERSION + #define VERSION "unknown" +#endif + +// OS includes +#include <stdio.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +// chmod: +#include <sys/types.h> +#include <sys/stat.h> + +// QT includes +#include <qdir.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kio/job.h> +#include <kio/netaccess.h> +#include <klocale.h> + +// Own includes +#include "ProgressDialog.h" +#include "batchrenamer.h" +#include "fileoperation.h" +#include "pluginloader.h" +#include "kmylistview.h" + +using namespace KIO; + +BatchRenamer::BatchRenamer() + : m_index( 0 ) +{ + plug = PluginLoader::instance(); + m_counter_index = 0; +} + +BatchRenamer::~BatchRenamer() +{ +} + +void BatchRenamer::processFiles( ProgressDialog* p, QObject* object ) +{ + delete object; + t.start(); + + m_counters.clear(); + + for( unsigned int i = 0; i < m_files.count(); i++) + { + m_counter_index = 0; + + if( m_mode == RENAME ) {// final Path = source Path + m_files[i].dst.directory = m_files[i].src.directory; + m_files[i].dst.url = m_files[i].src.url; + m_files[i].dst.url.setFileName( QString::null ); + } else { + m_files[i].dst.directory = dirname.path(); + m_files[i].dst.url = dirname; + } + + if( i == 0 ) + p->setDestination( m_files[i].dst.url ); + else + { + if( m_reset ) + findCounterReset( i ); + } + + m_files[i].dst.name = processString( text, m_files[i].src.name, i ); + if( !extext.isEmpty() ) + m_files[i].dst.extension = processString( extext, m_files[i].src.extension, i ); + + (void)applyManualChanges( i ); + + // Assemble filenames + parseSubdirs( &m_files[i] ); + // TODO: DOM + // ESCAPE HERE + + m_files[i].src.name = BatchRenamer::buildFilename( &m_files[i].src, true ); + + // Let's run the plugins that change the final filename, + // i.e the encodingsplugin + m_files[i].dst.name = parsePlugins( i, m_files[i].dst.name, TYPE_FINAL_FILENAME ); + + m_files[i].dst.name = BatchRenamer::buildFilename( &m_files[i].dst, true ); + + /* + * take care of renamed directories and + * correct the paths of their contents + */ + if( m_files[i].dir && (m_mode == RENAME || m_mode == MOVE) ) { + for( unsigned int c = i; c < m_files.count(); c++ ) { + if( m_files[c].src.directory.left( m_files[i].src.name.length() + 1 ) + == ( m_files[i].src.name + "/" ) ) { + + m_files[c].src.directory.replace( 0, m_files[i].src.name.length(), m_files[i].dst.name ); + m_files[c].src.url.setPath( BatchRenamer::buildFilename( &m_files[c].src, true ) ); + } + } + } + } + + p->print( QString( i18n("Filenames Processed after %1 seconds.")).arg(t.elapsed()/1000) ); + + work( p ); +} + +QString BatchRenamer::processString( QString text, QString oldname, int i ) +{ + /* + * Come on! Grep for this text and help me! + * + * note about krename escape sequences + * for certain characters: + * + * Krename will have problems with files + * which contain one of the following + * unicode characters: 60000, 60001, 60002 + * 60003, 60004, 60005, 60006. + * + * This is not a good solution, if you have a + * better one please tell me about it! + */ + + doEscape( oldname ); + /* + * Call here all functions that handle + * arguments that are single tokens (&,%,...). + * or in [brackets] + */ + text = findBrackets( oldname, text, i ); + text = findAndProcess( "$", text, oldname ); + text = findAndProcess( "%", text, oldname.lower() ); + text = findAndProcess( "&", text, oldname.upper() ); + text = findAndProcess( "\\", text, oldname.stripWhiteSpace() ); + text = findStar( oldname, text ); + text = findNumbers( text, m_files.count(), i ); + /* + * text is used as argument token for plugins! + */ + text = parsePlugins( i, text, TYPE_TOKEN ); + /* + * Replace after Plugins ! + * Replace shoud be the last the + * before re-escaping tokens ! + */ + text = findReplace( text ); + + // convert special chars back (e.g. &,$) + // TODO: this is to early, because + // parseSubdirs creates subdirectories + // for "/" returned by plugins!!!! + // text = unEscape( text ); + + return text; +} + +QString BatchRenamer::parsePlugins( int i, const QString& text, int type ) +{ + QPtrListIterator<PluginLoader::PluginLibrary> it( plug->libs ); + QString ret = text; + + if( type == TYPE_FINAL_FILE ) + ret = ""; + + for( ; it.current(); ++it ) + if( (*it)->usePlugin && (*it)->plugin->type() == type ) + { + ret = (*it)->plugin->processFile( this, i, text, type ); + doEscape( ret ); + } + + return ret; +} + +void BatchRenamer::createPreview( QListView* list ) +{ + KMyListViewItem* item1 = NULL; + QString tmp; + + m_counters.clear(); + for( unsigned int i = 0; i < m_files.count(); i++) + { + m_counter_index = 0; + + if( i && m_reset ) + findCounterReset( i ); + + m_files[i].dst.name = processString( text, m_files[i].src.name, i ); + if( !extext.isEmpty() ) + m_files[i].dst.extension = processString( extext, m_files[i].src.extension, i ); + + bool modified = applyManualChanges( i ); + + + QString sname = BatchRenamer::buildFilename( &m_files[i].src, false ); + + // Let's run the plugins that change the final filename, + // i.e the encodingsplugin + m_files[i].dst.name = parsePlugins( i, m_files[i].dst.name, TYPE_FINAL_FILENAME ); + QString dname = BatchRenamer::buildFilename( &m_files[i].dst, false ); + + item1 = new KMyListViewItem( modified, list, item1, sname, dname ); + } +} + +void BatchRenamer::work( ProgressDialog* p ) +{ + // TODO: use CopyJob here + + FileOperation fop; + QFile* fundo ( NULL ); + QTextStream* tundo ( NULL ); + + if( undo ) { + // Create header for undo script + fundo = new QFile( m_undoScript ); + if( fundo->open( IO_WriteOnly ) ) { + tundo = new QTextStream( fundo ); + writeUndoScript( tundo ); + } else { + undo = false; + p->error( i18n("Can't create undo script :") + fundo->name() ); + delete fundo; + } + } + + int error = 0; + RenamedList* renamedFiles = new RenamedList[m_files.count()]; + p->setProgressTotalSteps( m_files.count() + 1 ); + + /* + * Give the user some information... + */ + if( m_mode == COPY) + p->print( QString( i18n("Files will be copied to: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == MOVE ) + p->print( QString( i18n("Files will be moved to: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == LINK ) + p->print( QString( i18n("Symbolic links will be created in: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == RENAME ) + p->print( i18n("Input files will be renamed.") ); + + unsigned int i; + for( i = 0; i < m_files.count(); i++) { + p->setProgress( i+1 ); + + if( p->wasCancelled() ) + break; + + KURL src = m_files[i].src.url; + KURL dst = m_files[i].dst.url; + dst.setPath( m_files[i].dst.name ); + + renamedFiles[i].src = src; + renamedFiles[i].dst = dst; + renamedFiles[i].dir = m_files[i].dir; + + FileOperation fop; + if( !fop.start( src, dst, m_mode, overwrite ) ) { + p->error( fop.error() ); + renamedFiles[i].error = true; + error++; + continue; + } else { + renamedFiles[i].error = false; + } + + // TODO: overwriting of files! + /* + * The renamed file should be on its correct location now, + * so that we can call the last plugins (e.g. for changing permissions) + * + * Remember, the token argument is the filename for this type of plugins! + * + * If the return value is not empty an error has occured! + * The plugin should return an error message in this case! + */ + + QString eplug = parsePlugins( i, QString::null, TYPE_FINAL_FILE ); + if( !eplug.isEmpty() ) { + p->error( eplug ); + error++; + } + + /* Create the undo script now */ + if( undo ) + if( dst.isLocalFile() && src.isLocalFile() ) { + // Plugins ??? + (*tundo) << "echo \"" << src.fileName() + << " -> " << dst.fileName() << "\"" << endl; + (*tundo) << "mv --force -b --suffix=.krename_ \"" << m_files[i].dst.name + << "\" \"" << m_files[i].src.name << "\"" << endl; + } else + p->warning( QString( i18n("Undo is not possible for remote file: %1") ).arg( dst.prettyURL() ) ); + + } + + if( !p->wasCancelled() ) { + QPtrListIterator<PluginLoader::PluginLibrary> it( plug->libs ); + for( ; it.current(); ++it ) { + if( (*it)->usePlugin ) + (*it)->plugin->finished(); + } + } + + const QString m = QString( i18n("Renamed %1 files successfully.") ).arg(i-error); + ( i - error ) ? p->print( m ) : p->warning( m ); + + if( error > 0 ) + p->warning( QString( i18n("%2 errors occurred!") ).arg(error)); + + p->print( QString( i18n("Elapsed time: %1 seconds") ).arg( t.elapsed()/1000 ), "kalarm" ); + p->print( i18n("KRename finished the renaming process."), "krename" ); + p->print( i18n("Press close to quit!") ); + p->setRenamedFiles( renamedFiles, m_files.count() ); + + if( undo ) { + (*tundo) << endl << "echo \"Finished undoing " << m_files.count() << " actions.\"" << endl; + delete tundo; + fundo->close(); + + // Make fundo exuteable + if( chmod( (const char*)m_undoScript, (unsigned int) S_IRUSR | S_IWUSR | S_IXUSR ) ) + p->error( i18n("Can't set executable bit on undo script.") ); + delete fundo; + } + + p->done( error, i-error, m_mode == MOVE || m_mode == RENAME ); + m_files.clear(); + delete this; +} + +void BatchRenamer::escape( QString & text, const QString & token, const QString & sequence ) +{ + /* + * NEVER, ABSOLUTELY NEVER change pos = 0 + * to pos = -1, it won't work ! + * This bug took hours to find and was + * a serious bug in 1.7. + */ +#if QT_VERSION >= 0x030100 + text.replace( token, sequence ); +#else + int pos = 0; + do { + pos = text.find( token, pos ); + if( pos >= 0 ) + text.replace( pos, token.length(), sequence ); + } while ( pos >= 0 ); +#endif +} + +QString & BatchRenamer::doEscape( QString & text, bool filename ) +{ + if( filename ) { + BatchRenamer::escape( text, "&", QChar( 60000 ) ); + BatchRenamer::escape( text, "$", QChar( 60001 ) ); + BatchRenamer::escape( text, "%", QChar( 60002 ) ); + BatchRenamer::escape( text, "#", QChar( 60004 ) ); + BatchRenamer::escape( text, "[", QChar( 60005 ) ); + BatchRenamer::escape( text, "]", QChar( 60006 ) ); + BatchRenamer::escape( text, "\\", QChar( 60007 ) ); + BatchRenamer::escape( text, "/", QChar( 60008 ) ); + BatchRenamer::escape( text, "{", QChar( 60009 ) ); + BatchRenamer::escape( text, "}", QChar( 60010 ) ); + BatchRenamer::escape( text, "*", QChar( 60011 ) ); + } else { + BatchRenamer::escape( text, "\\&", QChar( 60000 ) ); + BatchRenamer::escape( text, "\\$", QChar( 60001 ) ); + BatchRenamer::escape( text, "\\%", QChar( 60002 ) ); + BatchRenamer::escape( text, "\\#", QChar( 60004 ) ); + BatchRenamer::escape( text, "\\[", QChar( 60005 ) ); + BatchRenamer::escape( text, "\\]", QChar( 60006 ) ); + BatchRenamer::escape( text, "\\\\", QChar( 60007 ) ); + BatchRenamer::escape( text, "\\/", QChar( 60008 ) ); + BatchRenamer::escape( text, "\\{", QChar( 60009 ) ); + BatchRenamer::escape( text, "\\}", QChar( 60010 ) ); + BatchRenamer::escape( text, "\\*", QChar( 60011 ) ); + } + + return text; +} + +QString & BatchRenamer::unEscape( QString & text ) +{ + BatchRenamer::escape( text, QChar( 60000 ), "&" ); + BatchRenamer::escape( text, QChar( 60001 ), "$" ); + BatchRenamer::escape( text, QChar( 60002 ), "%" ); + BatchRenamer::escape( text, QChar( 60004 ), "#" ); + BatchRenamer::escape( text, QChar( 60005 ), "[" ); + BatchRenamer::escape( text, QChar( 60006 ), "]" ); + BatchRenamer::escape( text, QChar( 60007 ), "\\" ); + // %252f == /, it seems that filenames on unix cannot contain + // a /. So I use %252f, at least konqui displays it correctly + // this was needed, so that plugins that return a slash do not cause errors + BatchRenamer::escape( text, QChar( 60008 ), "%2f" ); + BatchRenamer::escape( text, QChar( 60009 ), "{" ); + BatchRenamer::escape( text, QChar( 60010 ), "}" ); + BatchRenamer::escape( text, QChar( 60011 ), "*" ); + + return text; +} + +int BatchRenamer::getCharacters( int n ) +{ + QString s; + s.sprintf( "%i", n ); + return s.length(); +} + +QString BatchRenamer::findAndProcess( const QString & token, QString text, const QString & replace ) +{ + /* + * pos can here be -1 because + * findRev is called with it as a + * value ! + */ +#if QT_VERSION >= 0x030100 + text.replace( token, replace ); +#else + int pos = -1; + do { + pos = text.findRev( token, pos ); + if( pos >= 0 ) + text.replace( pos, token.length(), replace ); + } while( pos >= 0 ); +#endif + return text; +} + +QString BatchRenamer::findNumbers( QString text, int count, int i ) +{ + // Rewritten in Version 0.8 + // Added numbers skipping in 1.3 + // Changed again in Version 1.8 to optimize it and fix a bug with skipping numbers + int pos = 0, counter = 1; + tCounterValues countervalues; + countervalues.start = m_index; + countervalues.step = m_step; + + if( text.contains( "#", FALSE ) <= 0 ) + return text; + + pos = text.find("#", pos); + pos++; + while( text[pos] == '#' ) { + text.remove(pos, 1); + counter++; + } + + findNumberAppendix( text, pos, &countervalues.start, &countervalues.step ); + + pos = text.find("#", 0); + + if( (signed int)m_counters.count() <= m_counter_index ) + { + countervalues.value = countervalues.start - countervalues.step; + // other wise the counter would start at: + // start + step instead of start + m_counters.append( countervalues ); + } + + do { + m_counters[m_counter_index].value += m_counters[m_counter_index].step; + } while( m_skip.contains( m_counters[m_counter_index].value ) ); + + /* + int v = start + (i*step) + m_skip_add[m_counter_index]; + for( unsigned int z = 0; z < m_skip.count(); z++ ) { + if( m_skip[z] == v ) { + m_skip_add[m_counter_index] += step; + v += step; + } + } + */ + + QString temp; + temp.sprintf("%0*i", counter, m_counters[m_counter_index].value ); + text.replace( pos, 1, temp); + + ++m_counter_index; + return findNumbers( text, count, i ); +} + +void BatchRenamer::findNumberAppendix( QString & text, int pos, int* start, int* step ) +{ + QString appendix = QString::null; + int tmp = 0; + int end = 0; + bool ok = false; + + if( text[pos] == '{' && (end = text.find( "}", pos )) > -1) + { + //qDebug("Found an appendix:" + appendix ); + appendix = text.mid( pos + 1, end - pos - 1); + text.remove( pos, end - pos + 1 ); + + tmp = appendix.section( ';', 0, 0 ).toInt( &ok ); // first section = start index + if( ok ) + *start = tmp; + + tmp = appendix.section( ';', 1, 1 ).toInt( &ok ); // second section = stepping + if( ok ) + *step = tmp; + } +} + +QString BatchRenamer::findStar( const QString & oldname, QString text ) +{ + int pos = -1; + do { + pos = text.findRev("*", pos); + if( pos >= 0 ) { + QString tmp = oldname.lower(); + if( tmp[0].isLetter() ) + tmp[0] = tmp[0].upper(); + + for( unsigned int i = 0; i < tmp.length(); i++ ) + if( tmp[i+1].isLetter() && !tmp[i].isLetter() && + tmp[i] != '\'' && tmp[i] != '?' && tmp[i] != '`' ) + tmp[i+1] = tmp[i+1].upper(); + + text.replace( pos, 1, tmp); + } + } while( pos >= 0 ); + return text; +} + +QString BatchRenamer::findBrackets( QString oldname, QString text, int i ) +{ + /* + * looks for a statement in brackets [ ] + * and calls findToken() with this statement. + */ + + int num, pos = -1, a; + QString token; + + if( text.contains("]", FALSE) <= 0 || text.isEmpty() ) + return text; + + num = text.contains("[", FALSE); + if(num <= 0 ) + return text; + + pos = text.findRev("[", pos); + a = text.find("]", pos ); + if( a < 0 && pos >= 0 ) + return text; + + if( pos < 0 && a >= 0 ) + return text; + + if( pos >= 0 && a >= 0 ) { + token = text.mid( pos+1, (a-pos)-1 ); + + // support [4-[length]] + token = findBrackets( oldname, token, i ); + + text.remove( pos, (a-pos)+1 ); + text.insert( pos, findToken( oldname, token, i )); + } + return findBrackets( oldname, text, i ); +} + +QString BatchRenamer::processToken( QString token, QString oldname, int i ) +{ + QString tmp; + + /* + * Call here all functions that handle + * arguments in brackets. + */ + tmp = findPartStrings( oldname, token ); + if( !tmp.isEmpty() ) + return tmp; + + tmp = findDirName( token, m_files[i].src.directory ); + if( !tmp.isEmpty() ) + return tmp; + + tmp = findLength( token, m_files[i].src.name ); + if( !tmp.isEmpty() ) + return tmp; + + Plugin* p = plug->findPlugin( token ); + if( p ) + { + tmp = p->processFile( this, i, token, TYPE_BRACKET ); + if( !tmp.isNull() ) + { + doEscape( tmp ); + return tmp; + } + } + + /* + * Maybe I should remove this! + * Krename simply ignores unknown tokens! + * Usefull for the MP3 Plugin! + */ + return QString::null; +} + +QString BatchRenamer::findToken( QString oldname, QString token, int i ) +{ + enum conversion { LOWER, UPPER, MIXED, STAR, STRIP, NONE, EMPTY, NUMBER }; + unsigned int numwidth = 0; + + conversion c = EMPTY; + if( !token.left(1).compare("$") ) + c = NONE; + else if( !token.left(1).compare("%") ) + c = LOWER; + else if( !token.left(1).compare("&") ) + c = UPPER; + else if( !token.left(1).compare("") ) + c = MIXED; + else if( !token.left(1).compare("*") ) + c = STAR; + else if( !token.left(1).compare("\\") ) + c = STRIP; + else if( !token.left(1).compare("#") ) { + while( !token.left(1).compare("#") ) { + token.remove( 0, 1 ); + ++numwidth; + } + + c = NUMBER; + } + + if( c != EMPTY && c != NUMBER ) + token.remove( 0, 1 ); + + QString save = token; + token = processToken( token, oldname, i ); + + switch( c ) { + case LOWER: + token = token.lower(); + break; + case UPPER: + token = token.upper(); + break; + case MIXED: + token = token.lower(); + token.replace( 0, 1, token[0].upper()); + break; + case STAR: + token = findStar( token, "*" ); + break; + case STRIP: + token = token.stripWhiteSpace(); + break; + case NUMBER: + { + bool b = false; + int n = token.toInt( &b ); + if( b ) + token = token.sprintf("%0*i", numwidth, n ); + } + break; + default: + break; + } + + doEscape( token ); + return token; +} + +QString BatchRenamer::findPartStrings( QString oldname, QString token ) +{ + QString first, second; + int pos = -1; + + // parse things like [2;4{[dirname]}] + if( token.contains( "{" ) >= 1 && token.contains( "}" ) >= 1 ) { + int pos = token.find( "{" ); + oldname = token.mid( pos + 1, token.findRev( "}" ) - pos - 1 ); + token = token.left( pos ); + } + + if( token.contains("-") ) { + pos = token.find( "-", 0 ); + first = token.left( pos ); + // ------- Code OK ^ ! + + second = token.mid( pos+1, token.length() ); + + // version < 1.7 + // return oldname.mid( first.toInt()-1, second.toInt()-first.toInt() +1 ); + // version > 1.7 + //return oldname.mid( first.toInt()-1, second.toInt()-first.toInt() ); + // version > 1.8 + + bool ok; + int sec = second.toInt( &ok ); + if( !ok || sec == 0 ) + sec = oldname.length(); + + /* + * x should not be larger than the old name + * and not smaller than zero. + */ + int x = sec-first.toInt(); + if( x > (signed int)oldname.length() || x < 0 ) + x = oldname.length()-first.toInt(); + + /* + * if I would comment my code I would understand this line :) + * without this line, there is sometimes the last letter + * of a filename missing. + */ + if( x != -1 ) + x++; + + return oldname.mid( first.toInt()-1, x ); + } else if( token.contains(";") ) { + pos = token.find( ";", 0 ); + + first = token.left( pos ); + second = token.mid( pos+1, token.length() ); + + return oldname.mid( first.toInt()-1, second.toInt() ); + } else { + bool ok = false; + int number = token.toInt( &ok ); + + if( ok && (number <= (signed int)oldname.length() && number > 0 ) ) + return QString(oldname[ number -1 ]); + else + return QString::null; + } +} + +QString BatchRenamer::findDirName( QString token, QString path ) +{ + if( token.left( 7 ).lower() == "dirname" ) { + if( path.right( 1 ) == "/" ) + path = path.left( path.length() - 1); + + int recursion = 1; + if( token.length() > 7 ) { + token = token.right( token.length() - 7 ); + recursion = token.contains( "." ); + if( recursion != (signed int)token.length() ) + return QString::null; + + recursion++; + } + + return path.section( "/", recursion * -1, recursion * -1); + } + + return QString::null; +} + +QString BatchRenamer::findLength( const QString & token, const QString & name ) +{ + if( token.lower().startsWith( "length" ) ) { + int minus = 0; + if( token[6] == '-' ) { + bool n = false; + minus = token.mid( 7, token.length() - 7 ).toInt( &n ); + if( !n ) + minus = 0; + } + + return QString::number( name.length() - minus ); + } + + return QString::null; +} + +QString BatchRenamer::findReplace( QString text ) +{ + // Call for each element in replace strings doReplace with correct values + for( unsigned int i = 0; i < m_replace.count(); i++ ) { + replacestrings s = m_replace[i]; + text = doReplace( text, unEscape( s.find ), s.replace, s.reg ); + } + + return text; +} + +QString BatchRenamer::doReplace( QString text, QString find, QString replace, bool reg ) +{ + if( !reg ) + { +#if QT_VERSION >= 0x030100 + // we use the escaped text here because the user might want + // to find a "&" and replace it + text.replace( doEscape( find ), replace ); +#else + int pos = 0; + QString f = doEscape( find ); + do { + + pos = text.find( f, pos ); + if( pos >= 0 ) { + text.replace( pos, f.length(), replace ); + pos += replace.length(); + } + } while( pos >= 0 ); +#endif + } + else + { +#if QT_VERSION >= 0x030100 + // no doEscape() here for the regexp, because it would destroy our regular expression + // other wise we will not find stuff like $, [ in the text + text = doEscape( unEscape( text ).replace( QRegExp( find ), replace ) ); +#else + // Test this code more! + pos = 0; + do { + QRegExp exp( find ); + pos = exp.search( text, pos ); + if( pos >= 0 ) { + text = doEscape( unEscape( text ).replace( pos, exp.matchedLength(), replace ) ); + pos += replace.length(); + } + } while( pos >= 0 ); +#endif + } + return text; +} + +void BatchRenamer::writeUndoScript( QTextStream* t ) +{ + // write header comments + (*t) << "#!/bin/bash" << endl + << "# KRename Undo Script" << endl << "#" << endl + << "# KRename was written by:" << endl + << "# Dominik Seichter <domseichter@web.de>" << endl + << "# http://krename.sourceforge.net" << endl << "#" << endl + << "# Script generated by KRename Version: " << VERSION << endl << endl + << "# This script must be started with the option --krename to work!" << endl; + + // write functions: + (*t) << "echo \"KRename Undo Script\"" << endl + << "echo \"http://krename.sourceforge.net\"" << endl + << "echo \"\"" << endl; + + (*t) << "if test --krename = $1 ; then" << endl + << " echo \"\"" << endl + << "else" << endl + << " echo \"You have to start this script\"" << endl + << " echo \"with the command line option\"" << endl + << " echo \"--krename\"" << endl + << " echo \"to undo a rename operation.\"" << endl + << " exit" << endl + << "fi" << endl; +} + +void BatchRenamer::parseSubdirs( data* f ) +{ + int pos = 0; + if( (pos = f->dst.name.findRev( "/", -1 ) ) > 0 ) { + QString dirs = f->dst.name.left( pos ); + f->dst.name = f->dst.name.right( f->dst.name.length() - pos - 1 ); + f->dst.directory += ( f->dst.directory.right( 1 ) == "/" ) ? "" : "/"; + + // create the missing subdir now + int i = 0; + QString d = ""; + while( (d = dirs.section( "/", i, i, QString::SectionSkipEmpty )) && ! d.isEmpty() ) { // asignment here! + KURL url = f->dst.url; + // it is important to unescape here + // to support dirnames containing "&" or + // similar tokens + url.addPath( unEscape( d ) ); + if( !NetAccess::exists( url ) && !NetAccess::mkdir( url ) ) + // TODO: GUI bug report + qDebug("Can't create %s", url.prettyURL().latin1() ); + + f->dst.url.addPath( d ); + f->dst.directory.append( d + "/" ); + i++; + } + } +} + +QString BatchRenamer::buildFilename( fileentry* entry, bool dir ) +{ + QString filename = ( dir ? entry->directory : QString::null ) + entry->name + ( entry->extension.isEmpty() ? QString::null : QString(".") ) + entry->extension; + // unescape here as filename is still escaped + unEscape( filename ); + return filename; +} + +bool BatchRenamer::applyManualChanges( int i ) +{ + /* + * The last step: make changes of + * the user visible + */ + + if( !m_changes.isEmpty() ) + for( unsigned int z = 0; z < m_changes.count(); z++ ) { + KURL file = m_changes[z].url; + if( file == m_files[i].src.url ) { + m_files[i].dst.name = m_changes[z].user; + // the file extension is already included + // in the users name + m_files[i].dst.extension = QString::null; + return true; + } + } + + return false; +} + +void BatchRenamer::findCounterReset( int i ) +{ + int z; + if( m_files[i-1].src.directory != m_files[i].src.directory ) + for( z=0;z<(int)m_counters.count();z++ ) + { + m_counters[z].value = m_counters[z].start - m_counters[z].step; + } +} + + diff --git a/krename/batchrenamer.h b/krename/batchrenamer.h new file mode 100644 index 0000000..1eae7c6 --- /dev/null +++ b/krename/batchrenamer.h @@ -0,0 +1,188 @@ +/*************************************************************************** + batchrenamer.h - description + ------------------- + begin : Sat Aug 18 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef BATCHRENAMER_H +#define BATCHRENAMER_H + +#include <qdatetime.h> +#include <qvaluelist.h> +#include <kurl.h> + +class QFile; +class QProgressDialog; +class QString; + +/* How many diferrent users and groups + * KRename supports. Values over 1000 + * make KRename slow, but it may be + * necessary on bigger systems to + * increase this value. + * MAXENTRIES must be < sizeof(int) + */ +#define MAXENTRIES 1000 + +/* May Value for SpinBoxes + * + */ +#define SPINMAX 100000 + +enum { + COPY, MOVE, RENAME, PREVIEW, LINK +}; + +typedef struct fileentry { + QString name; // filename + QString directory; // directory + QString extension; // extension + + KURL url; +}; + +typedef struct data { + fileentry src; + fileentry dst; + + bool dir; +}; + +/* + * Changes made by hand by the user + * in the preview list view are + * stored here. + */ +typedef struct manualchanges { + KURL url; // input filename + QString user; // name the user wants +}; + +typedef struct replacestrings { + QString find; // Text to replace + QString replace; // Replace with + bool reg; // is it a reg expression ? +}; + +typedef struct tCounterValues { + int value; // current value of this counter + int start; // start value of this counter (for findResetCounter) + int step; // stepping value of this counter; +}; + +/** + *@author Dominik Seichter + */ + +class QObject; +class QListView; +class ProgressDialog; +class PluginLoader; +class BatchRenamer { + public: + BatchRenamer(); + ~BatchRenamer(); + void processFiles( ProgressDialog* p, QObject* object ); + void createPreview( QListView* list ); + + inline void setText( const QString & t ) { text = t; doEscape( text, false ); } + inline void setExText( const QString & t ) { extext = t; } + inline void setDirname( const KURL & url ) { dirname = url; } + inline void setUndoScript( const QString & t ) { m_undoScript = t; } + inline void setUndo( bool b ) { undo = b; } + inline void setOverwrite( bool b ) { overwrite = b; } + inline void setIndex( int i ) { m_index = i; } + inline void setStep( int s ) { m_step = s; } + inline void setResetCounter( bool r ) { m_reset = r; } + inline void setSkipList( const QValueList<int> & s ) { m_skip = s; } + inline void setReplaceList( const QValueList<replacestrings> & r ) { m_replace = r; } + + inline void setFiles( const QValueList<data> & f ) { m_files = f; } //TODO: use a pointer for more speed + inline QValueList<data> files() const { return m_files; } + inline void setChanges( const QValueList<manualchanges> & m ) { m_changes = m; } + + inline void setMode( int m) { m_mode = m; } + inline int mode() const { return m_mode; } + + // Since 2.1 public, because plugins may want to access them to: + QString findAndProcess( const QString & token, QString text, const QString & replace ); + + QString findNumbers( QString text, int count, int i ); + QString findStar( const QString & oldname, QString text ); + QString findBrackets( QString oldname, QString text, int i ); + QString findToken( QString oldname, QString token, int i ); + QString processToken( QString token, QString oldname, int i ); + QString findPartStrings( QString oldname, QString token ); + static QString findDirName( QString token, QString path ); + QString findLength( const QString & token, const QString & name ); + QString findReplace( QString text ); // text is here already the new filename ! + QString doReplace( QString text, QString find, QString replace, bool reg ); // text is here already the new filename ! + + QString processString( QString text, QString oldname, int i ); + + static QString & doEscape( QString & text, bool filename = true ); + static QString & unEscape( QString & text ); + static void escape( QString & text, const QString & token, const QString & sequence ); + + static QString buildFilename( fileentry* entry, bool dir = true ); + + private: + /** + * Returns the length of the string when int n is converted to + * a string. + * @param n a number whose length as string is needed + * @returns stringlength of n converted to a string + */ + int getCharacters( int n ) ; + + void work( ProgressDialog* p ); + void writeUndoScript( QTextStream* t ); + void parseSubdirs( data* f ); + void findNumberAppendix( QString & text, int pos, int* start, int* step ); + /** resets all counters to there start value if the directory name at @p i + * in m_files changes. + * The caller has to check m_reset before calling this function. + */ + void findCounterReset( int i ); + QString parsePlugins( int i, const QString & text, int type ); + bool applyManualChanges( int i ); + + QString text; // template + KURL dirname; // destination dir + QString extext; // Extension template + QString m_undoScript; // Filename of undoscript + bool undo; // create an undo script + int m_index; // index for numbers + int m_step; // step for numbers + bool m_reset; // reset counter on new directories + bool overwrite; // overwrite existing files + int m_mode; // renaming mode + QValueList<int> m_skip; // Numbers to skip + QValueList<replacestrings> m_replace; // Replace strings + QValueList<data> m_files; + QValueList<manualchanges> m_changes; // User made changes + PluginLoader* plug; + + // a is used in find number and + // required for skipping. + int m_counter_index; + QValueList<tCounterValues> m_counters; + + protected: + QFile* f; + QTime t; + QProgressDialog* progress; +}; + +#endif diff --git a/krename/commandplugin.cpp b/krename/commandplugin.cpp new file mode 100644 index 0000000..d413cec --- /dev/null +++ b/krename/commandplugin.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** + commandplugin.cpp - description + ------------------- + begin : Son Jan 5 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "commandplugin.h" + +// QT includes +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> + +// KDE includes +#include <kapplication.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <klocale.h> +#include <klineedit.h> +#include <klistbox.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kprocess.h> + +const QString CommandPlugin::getName() const +{ + return i18n("Command Plugin"); +} + +const QString CommandPlugin::getAccelName() const +{ + return i18n("&Command Plugin"); +} + +const int CommandPlugin::type() const +{ + return TYPE_FINAL_FILE; +} + +bool CommandPlugin::checkError() +{ + if( commandline->text().isEmpty() ) { + KMessageBox::error( 0, i18n("You did not specify a command to execute.") ); + return false; + } + + return true; +} + +void CommandPlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + m_widget = w; + + QHBoxLayout* hb = new QHBoxLayout( 0, 0, 6 ); + QVBoxLayout* vb = new QVBoxLayout( 0, 0, 6 ); + + QLabel* la = new QLabel( w ); + la->setText( i18n("<b>Command Plugin</b>") ); + l->addWidget( la ); + + la = new QLabel( w ); + la->setText( i18n( "<qt>Executes a shell command on every file after it has been renamed. " + "Add %1 to the command line arguments to get the filename of the renamed file.</qt>") ); + l->addWidget( la ); + l->addWidget( new QLabel( i18n("Command:"), w ) ); + + commandline = new KLineEdit( w ); + l->addWidget( commandline ); + + checkNoBlock = new QCheckBox( i18n("&Execute without blocking (not recommended)"), w ); + l->addWidget( checkNoBlock ); + + buttonAdd = new KPushButton( i18n("&Add"), w ); + buttonRemove = new KPushButton( i18n("&Remove"), w ); + hb->addWidget( buttonAdd ); + hb->addWidget( buttonRemove ); + + vb->addLayout( hb ); + + list = new KListBox( w ); + vb->addWidget( list ); + vb->setStretchFactor( list, 2 ); + l->addLayout( vb ); + + connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( add() ) ); + connect( buttonRemove, SIGNAL( clicked() ), this, SLOT( remove() ) ); + connect( list, SIGNAL( executed( QListBoxItem* ) ), this, SLOT( exec() ) ); + + KConfig* conf = kapp->config(); + conf->setGroup("CommandPlugin"); + list->insertStringList( conf->readListEntry("commandlines" ) ); + + QStringList examples; + examples.append( "chmod 0444 %1" ); + examples.append( "convert %1 %1.png" ); + examples.append( "echo %1 >> $HOME/file.list" ); +// examples.append( ") + for( unsigned int i = 0; i < examples.count(); i++ ) + if( !list->findItem( examples[i] ) ) + list->insertItem( examples[i] ); +} + +void CommandPlugin::fillStructure() +{ + command = commandline->text(); + noblock = checkNoBlock->isChecked(); +} + +QString CommandPlugin::processFile( BatchRenamer* b, int i, QString, int ) +{ + QString filename = b->files()[i].dst.name; + + + QString c = command; + + KShellProcess proc; +#if QT_VERSION >= 0x030100 + c = c.replace( "%1", KShellProcess::quote( filename ) ); +#else + int pos = 0; + do { + pos = c.find( "%1", pos ); + if( pos >= 0 ) + c.replace( pos, 2, KShellProcess::quote( filename ) ); + } while ( pos >= 0 ); +#endif + + proc << c; + + if( noblock ) + proc.start( KProcess::DontCare, KProcess::NoCommunication ); + else + proc.start( KProcess::Block, KProcess::NoCommunication ); + + proc.resume(); + + if( !noblock && proc.exitStatus() ) + return command.arg( filename ) + QString( i18n(" exited with error: %1") ).arg( proc.exitStatus() ); + + return QString::null; +} + +void CommandPlugin::finished() +{ + KConfig* conf = kapp->config(); + conf->setGroup("CommandPlugin"); + QStringList slist; + for( unsigned int i = 0; i < list->count(); i++ ) + slist.append( list->text( i ) ); + + conf->writeEntry("commandlines", slist ); + conf->sync(); + return; +} + +void CommandPlugin::add() +{ + if( !commandline->text().isEmpty() ) { + for( unsigned int i = 0; i < list->count(); i++ ) + if( list->text( i ) == commandline->text() ) + return; + + list->insertItem( commandline->text() ); + } +} + +void CommandPlugin::remove() +{ + unsigned int i = 0; + do { + if(list->isSelected( i )) + list->removeItem( i ); + else + i++; + } while( i < list->count() ); +} + +void CommandPlugin::exec() +{ + for( unsigned int i = 0; i < list->count(); i++ ) + if( list->isSelected( i ) ) + commandline->setText( list->text( i ) ); +} + +const QPixmap CommandPlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "konsole", KIcon::Small ); +} + diff --git a/krename/commandplugin.h b/krename/commandplugin.h new file mode 100644 index 0000000..61edaee --- /dev/null +++ b/krename/commandplugin.h @@ -0,0 +1,62 @@ +/*************************************************************************** + commandplugin.h - description + ------------------- + begin : Son Jan 5 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef COMMANDPLUGIN_H +#define COMMANDPLUGIN_H + +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" + +class QCheckBox; +class KLineEdit; +class KListBox; +class KPushButton; +class CommandPlugin : public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + + bool checkError(); + void drawInterface( QWidget* w, QVBoxLayout* l ); + void fillStructure(); + QString processFile( BatchRenamer*, int, QString token, int ); + void finished(); + + bool alwaysUsed() const { return false; } + const QPixmap getIcon() const; + + private slots: + void add(); + void remove(); + void exec(); + + private: + KLineEdit* commandline; + QCheckBox* checkNoBlock; + KListBox* list; + KPushButton* buttonAdd; + KPushButton* buttonRemove; + + QString command; + bool noblock; +}; + +#endif diff --git a/krename/confdialog.cpp b/krename/confdialog.cpp new file mode 100644 index 0000000..eb03c3d --- /dev/null +++ b/krename/confdialog.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + confdialog.cpp - description + ------------------- + begin : Sun Jan 27 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// Own includes +#include "confdialog.h" + +// QT includes +#include <qbuttongroup.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qtooltip.h> + +// KDE includes +#include <kiconloader.h> +#include <klocale.h> + +ConfDialog::ConfDialog( QWidget* parent, const char* name ) + : KDialogBase( KDialogBase::IconList, "KRename", + KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Default, KDialogBase::Ok, parent, name, true, true ), + GUIModeSelector() +{ + setupTab1(); + setupTab2(); + + connect( this, SIGNAL( defaultClicked() ), this, SLOT( defaults() ) ); +} + +ConfDialog::~ConfDialog() +{ +} + +void ConfDialog::setupTab1() +{ + const QString caption = i18n("Look and Feel"); + QFrame* box = addPage( caption, caption, BarIcon("looknfeel") ); + QVBoxLayout* layout = new QVBoxLayout( box ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + QButtonGroup* group = new QButtonGroup( box ); + group->setColumnLayout(0, Qt::Vertical ); + QVBoxLayout* lgroup = new QVBoxLayout( group->layout() ); + + optionWizard = new QRadioButton( group ); + optionWizard->setText( i18n("Use &wizard style GUI (beginners)") ); + optionTabs = new QRadioButton( group ); + optionTabs->setText( i18n("Use &tabbed GUI (advanced users)") ); + + lgroup->addWidget( new QLabel( i18n("Configure the look and feel of the KRename GUI:<br>"), group ) ); + lgroup->addWidget( optionWizard ); + lgroup->addWidget( optionTabs ); + lgroup->addItem( spacer ); + + layout->addWidget( group ); + layout->addItem( spacer ); +} + +void ConfDialog::setupTab2() +{ + const QString caption = i18n("KRename"); + QFrame* box = addPage( caption, caption, BarIcon("krename") ); + QVBoxLayout* layout = new QVBoxLayout( box ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + checkPlugins = new QCheckBox( i18n("&Load file plugins on start"), box ); + checkAutosize = new QCheckBox( i18n("Auto &resize columns in preview"), box ); + + spinSize = new KIntNumInput( box ); + spinSize->setRange( 20, 500, 1, false ); + spinSize->setLabel( i18n( "&Thumbnail size:" ), AlignLeft | AlignVCenter ); + + spinHistory = new KIntNumInput( box ); + spinHistory->setRange( 2, 500, 1, false ); + spinHistory->setLabel( i18n( "&Number of template history items:" ), AlignLeft | AlignVCenter ); + + layout->addWidget( checkPlugins ); + layout->addWidget( checkAutosize ); + layout->addItem( spacer ); + layout->addWidget( spinSize ); + layout->addWidget( spinHistory ); + layout->addItem( spacer ); + + QToolTip::add( checkPlugins, i18n("Disabling this option decreases KRename's startup time, because no KFilePlugins are loaded.") ); +} + +void ConfDialog::defaults() +{ + checkPlugins->setChecked( true ); + checkAutosize->setChecked( false ); + + optionWizard->setChecked( true ); + + spinSize->setValue( 80 ); +} + diff --git a/krename/confdialog.h b/krename/confdialog.h new file mode 100644 index 0000000..06c7425 --- /dev/null +++ b/krename/confdialog.h @@ -0,0 +1,66 @@ +/*************************************************************************** + confdialog.h - description + ------------------- + begin : Sun Jan 27 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef CONFDIALOG_H +#define CONFDIALOG_H + +// QT includes +#include <qcheckbox.h> + +// KDE includes +#include <kdialogbase.h> +#include <knuminput.h> + +#include "guimodeselector.h" + +class QHBoxLayout; +class QVBoxLayout; +class QWidget; +class KIntNumInput; +class ConfDialog : public KDialogBase, public GUIModeSelector { + Q_OBJECT + public: + ConfDialog( QWidget* parent = 0, const char* name = 0 ); + ~ConfDialog(); + + inline bool loadplugins() const { return checkPlugins->isChecked(); } + inline int thumbSize() const { return spinSize->value(); } + inline bool autosize() const { return checkAutosize->isChecked(); } + inline int historyItems() const { return spinHistory->value(); } + + inline void setLoadPlugins( bool b ) { checkPlugins->setChecked( b ); } + inline void setThumbSize( int b ) { spinSize->setValue( b ); } + inline void setAutosize( bool b ) { checkAutosize->setChecked( b ); } + inline void setHistoryItems( int b ) { spinHistory->setValue( b ); } + + private slots: + void defaults(); + + private: + void setupTab1(); + void setupTab2(); + + protected: + QCheckBox* checkAsk; + QCheckBox* checkPlugins; + QCheckBox* checkAutosize; + + KIntNumInput* spinSize; + KIntNumInput* spinHistory; +}; + +#endif diff --git a/krename/coorddialog.cpp b/krename/coorddialog.cpp new file mode 100644 index 0000000..f67062d --- /dev/null +++ b/krename/coorddialog.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + coorddialog.cpp - description + ------------------- + begin : Die Feb 4 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "coorddialog.h" + +// Qt includes +#include <qcheckbox.h> +#include <qfontmetrics.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qvalidator.h> + +// KDE includes +#include <kapplication.h> +#include <klocale.h> + +DSLineEdit::DSLineEdit( QWidget* parent, const char* name ) + : KLineEdit( parent, name ) +{ +} + +void DSLineEdit::keyPressEvent( QKeyEvent* e ) +{ + KLineEdit::keyPressEvent( e ); + emit changed(); +} + +void DSLineEdit::mousePressEvent( QMouseEvent* e ) +{ + KLineEdit::mousePressEvent( e ); + emit changed(); +} + +bool CoordDialog::m_inversion = false; + +CoordDialog::CoordDialog( const QString & file, QWidget *_parent, const char *name ) + : KDialogBase( KDialogBase::Plain, "KRename", + KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, _parent, name, true, true ), m_file( file ) +{ + QFrame* parent = plainPage(); + QVBoxLayout* layout = new QVBoxLayout( parent ); + + filename = new DSLineEdit( parent ); + filename->setText( file ); + filename->setValidator( new QRegExpValidator( QRegExp( file ), this ) ); + + preview = new QLabel( parent ); + + checkInvert = new QCheckBox( i18n("&Invert selection"), plainPage() ); + checkInvert->setChecked( m_inversion ); + + layout->addWidget( new QLabel( i18n("Please select the text you want to insert:"), plainPage() ) ); + layout->addWidget( filename ); + layout->addWidget( checkInvert ); + layout->addWidget( preview ); + + updateCommand(); + connect( filename, SIGNAL( selectionChanged() ), this, SLOT( updateCommand() ) ); + connect( checkInvert, SIGNAL( clicked() ), this, SLOT( updateCommand() ) ); + connect( filename, SIGNAL( textChanged( const QString & ) ), this, SLOT( resetText() ) ); + connect( filename, SIGNAL( changed() ), this, SLOT( updateCommand() ) ); + + show(); + + QFontMetrics fm( filename->font() ); + int w = fm.width( file ); + if( w > width() ) + resize( + ( w < KApplication::desktop()->width() - 40 ? w + 40 : KApplication::desktop()->width() ), height() ); +} + +CoordDialog::~CoordDialog() +{ +} + +void CoordDialog::updateCommand() +{ + int start = 0; + int end = 0; + m_command = ""; + + (void)filename->getSelection( &start, &end ); + + if( !filename->text().isEmpty() ) { + if( checkInvert->isChecked() && filename->hasSelectedText() ) { + // inverted + if( end ) { + start++; + end++; + if( start > 1 ) + m_command = QString("[$1;%1]").arg(start-1); + + if( end <= (signed int)filename->text().length() ) + m_command.append( QString("[$%1-[length]]").arg(end) ); + } + } else if( checkInvert->isChecked() && !filename->hasSelectedText() ) { + int p = filename->cursorPosition(); + m_command = QString("[$1;%1][$%2-[length]]").arg(p).arg(p+1); + } else if( !checkInvert->isChecked() && filename->hasSelectedText() ){ + if( end ) { + start++; + end++; + if( end <= (signed int)filename->text().length() ) + m_command = QString("[$%1;%2]").arg(start).arg(end-start); + else + m_command = QString("[$%1-[length]]").arg(start); + } + } else if( !checkInvert->isChecked() && !filename->hasSelectedText() ) { + int p = filename->cursorPosition(); + m_command = QString("[$%1-[length]]").arg( p ); + } + + } + + preview->setText( i18n("Preview: ") + m_command ); +} + +void CoordDialog::resetText() +{ + filename->setText( m_file ); + updateCommand(); +} + +QString CoordDialog::coords() +{ + m_inversion = checkInvert->isChecked(); + return m_command; +} diff --git a/krename/coorddialog.h b/krename/coorddialog.h new file mode 100644 index 0000000..e8e5be3 --- /dev/null +++ b/krename/coorddialog.h @@ -0,0 +1,70 @@ +/*************************************************************************** + coorddialog.h - description + ------------------- + begin : Die Feb 4 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef COORDDIALOG_H +#define COORDDIALOG_H + +#include <kdialogbase.h> +#include <klineedit.h> + +class QKeyEvent; +class DSLineEdit : public KLineEdit { + Q_OBJECT + public: + DSLineEdit( QWidget* parent = 0, const char* name = 0 ); + + signals: + void changed(); + + protected: + void keyPressEvent( QKeyEvent* e ); + void mousePressEvent( QMouseEvent* e ); +}; + +class QCheckBox; +class QLabel; +class QString; + +/* The name of this class was a very bad choice. + * CoordDialog is an abreviation vor Coordinate Dialog, + * because this dialog is ought to be for selecting + * the coordinates of a filename using an [x;y] token. + */ +class CoordDialog : public KDialogBase { + Q_OBJECT + public: + CoordDialog( const QString & file, QWidget *_parent=0, const char *name=0); + ~CoordDialog(); + + QString coords(); + + static bool m_inversion; + + private slots: + void updateCommand(); + void resetText(); + + private: + QString m_file; + QString m_command; + + DSLineEdit* filename; + QCheckBox* checkInvert; + QLabel* preview; +}; + +#endif diff --git a/krename/dateplugin.cpp b/krename/dateplugin.cpp new file mode 100644 index 0000000..0021c94 --- /dev/null +++ b/krename/dateplugin.cpp @@ -0,0 +1,153 @@ +/*************************************************************************** + dateplugin.cpp - description + ------------------- + begin : Mon Feb 02 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "dateplugin.h" + +// Qt includes +#include <qdatetime.h> + +// KDE includes +#include <kfileitem.h> +#include <kio/netaccess.h> +#include <klocale.h> + +DatePlugin::DatePlugin() + : FilePlugin(0) +{ + keys.append("date"); + keys.append("date;.*"); + keys.append("year"); + keys.append("month"); + keys.append("day"); + keys.append("time"); + keys.append("hour"); + keys.append("minute"); + keys.append("second"); + keys.append("user"); + keys.append("group"); + keys.append("creationdate"); + keys.append("creationdate;.*"); + keys.append("modificationdate"); + keys.append("modificationdate;.*"); + keys.append("accessdate"); + keys.append("accessdate;.*"); + setupKeys(); + + m_icon = "clock"; +} + + +QString DatePlugin::processFile(BatchRenamer* b, int i, QString token, int ) +{ + if( !supports( token ) ) + return QString::null; + + if( token.lower().startsWith( getPattern() ) ) + token = token.mid( getPattern().length(), token.length() - getPattern().length() ); + + + QDate d = QDate::currentDate(); + QTime t = QTime::currentTime(); + QString tmp, text; + QString format = "dd-MM-yyyy"; + if( token.contains( ";" ) ) + { + format = token.section( ';', 1, 1 ); + token = token.section( ';', 0, 0 ).lower(); + } else + token = token.lower(); + + if( token == "date" ) { + return QDateTime::currentDateTime().toString( format ); + } else if( token == "year" ) + return QString( "%1" ).arg( d.year() ); + else if( token == "month" ) + return tmp.sprintf("%0*i", 2, d.month() ); + else if( token == "day" ) + return tmp.sprintf("%0*i", 2, d.day() ); + else if( token == "time" ) + return QString( "%1-%2-%3" ).arg( t.hour() ).arg( QString().sprintf("%0*i", 2, t.minute() ) ).arg( QString().sprintf("%0*i", 2, t.second() ) ); + else if( token == "hour" ) + return tmp.sprintf("%0*i", 2, t.hour() ); + else if( token == "minute" ) + return tmp.sprintf("%0*i", 2, t.minute() ); + else if( token == "second" ) + return tmp.sprintf("%0*i", 2, t.second() ); + else { + KIO::UDSEntry entry; + KIO::NetAccess::stat( b->files()[i].src.url, entry ); + KFileItem item( entry, b->files()[i].src.url ); + if( token == "user" ) + return item.user(); + else if( token == "group" ) + return item.group(); + else if( token == "creationdate" ) + return time( item.time( KIO::UDS_CREATION_TIME ), format ); + else if( token == "modificationdate" ) + return time( item.time( KIO::UDS_MODIFICATION_TIME ), format ); + else if( token == "accessdate" ) + return time( item.time( KIO::UDS_ACCESS_TIME ), format ); + + } + + return QString::null; +} + +const QString DatePlugin::getAccelName() const +{ + return i18n("&System Functions"); +} + +const QString DatePlugin::getName() const +{ + return i18n("System Functions"); +} + +const QString DatePlugin::getPattern() const +{ + return QString::null; +} + +const QString DatePlugin::time( time_t time, const QString & format ) +{ + QDateTime dt; + dt.setTime_t( time ); + return dt.toString( format ); +} + +void DatePlugin::addHelp( HelpDialogData* data ) +{ + QStringList list; + list.append( "[date];;" + i18n("Insert the current date") ); + list.append( "[date;yyyy-MM-dd];;" + i18n("Insert the current date using the formatting string yyyy-MM-dd") ); + list.append( "[year];;" + i18n("Insert the current year") ); + list.append( "[month];;" + i18n("Insert the current month as number") ); + list.append( "[day];;" + i18n("Insert the current day as number") ); + list.append( "[time];;" + i18n("Insert the current time") ); + list.append( "[hour];;" + i18n("Insert the current hour as number") ); + list.append( "[minute];;" + i18n("Insert the current minute as number") ); + list.append( "[second];;" + i18n("Insert the current second as number") ); + list.append( "[user];;" + i18n("Owner of the file") ); + list.append( "[group];;" + i18n("Owning group of the file") ); + list.append( "[creationdate];;" + i18n("Insert the files creation date")); + list.append( "[creationdate;yyyy-MM-dd];;" + i18n("Insert the formatted file creation date") ); + list.append( "[modificationdate];;" + i18n("Insert the files modification date")); + list.append( "[modificationdate;yyyy-MM-dd];;" + i18n("Insert the formatted modification date") ); + list.append( "[accessdate];;" + i18n("Insert the date of the last file access") ); + list.append( "[accessdate;yyyy-MM-dd];;" + i18n("Insert the formatted date of the last file access") ); + + data->add( getName(), &list, getIcon() ); +} diff --git a/krename/dateplugin.h b/krename/dateplugin.h new file mode 100644 index 0000000..06eee70 --- /dev/null +++ b/krename/dateplugin.h @@ -0,0 +1,44 @@ +/*************************************************************************** + dateplugin.h - description + ------------------- + begin : Mon Feb 02 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DATEPLUGIN_H +#define DATEPLUGIN_H + +#include <fileplugin.h> +// time_t support... +#include <time.h> +/** +@author Dominik Seichter +*/ +class DatePlugin : public FilePlugin +{ + public: + DatePlugin(); + + QString processFile(BatchRenamer* b, int i, QString token, int mode); + const QString getAccelName() const; + const QString getName() const; + const QString getPattern() const; + + void addHelp( HelpDialogData* data ); + + private: + const QString time( time_t time, const QString & format ); + +}; + +#endif diff --git a/krename/datetime.cpp b/krename/datetime.cpp new file mode 100644 index 0000000..f06fedb --- /dev/null +++ b/krename/datetime.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + datetime.cpp - description + ------------------- + begin : Mon Jan 7 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "datetime.h" + +// QT includes +#include <qcheckbox.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <kdatepik.h> +#include <knuminput.h> +#include <klocale.h> + +// OS includes +#include <stdio.h> +#include <time.h> +#include <utime.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +const QString MyDatePlugin::getName() const +{ + return i18n("Date & Time"); +} + +const QString MyDatePlugin::getAccelName() const +{ + return i18n("Date && &Time"); +} + +const int MyDatePlugin::type() const +{ + return TYPE_FINAL_FILE; +} + +bool MyDatePlugin::checkError() +{ + return true; +} + +const QPixmap MyDatePlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "kalarm", KIcon::Small ); +} + +void MyDatePlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + m_widget = w; + +#ifdef BENNY + l->addWidget( new QLabel("Setze Modifiaction Time um eine Stunde zurück", w) ); +#else + Layout0 = new QHBoxLayout( 0, 0, 6, "Layout0"); + Layout1 = new QVBoxLayout( 0, 0, 6, "Layout1"); + Layout2 = new QHBoxLayout( 0, 0, 6, "Layout2"); + + kDate = new KDatePicker( w ); + + checkAccess = new QCheckBox( w, "checkAccess" ); + checkAccess->setText( i18n( "Change &access date && time" ) ); + + checkModification = new QCheckBox( w, "checkModification" ); + checkModification->setText( i18n( "Change &modification date && time" ) ); + + labelTime = new QLabel( w, "labelTime" ); + labelTime->setText( i18n( "Time:" ) ); + + spinHour = new KIntSpinBox( w, "spinHour" ); + spinHour->setSuffix( i18n( "h" ) ); + spinHour->setMaxValue( 23 ); + + spinMinute = new KIntSpinBox( w, "spinMinute" ); + spinMinute->setSuffix( i18n( "min" ) ); + spinMinute->setMaxValue( 59 ); + + spinSecond = new KIntSpinBox( w, "spinSecond" ); + spinSecond->setSuffix( i18n( "s" ) ); + spinSecond->setMaxValue( 59 ); + + buttonCurrentDT = new QPushButton( w, "buttonCurrentDT" ); + buttonCurrentDT->setText( i18n( "&Get Current Date && Time" ) ); + + Layout2->addWidget( labelTime ); + Layout2->addWidget( spinHour ); + Layout2->addWidget( spinMinute ); + Layout2->addWidget( spinSecond ); + + Layout1->addWidget( kDate ); + Layout1->addWidget( checkAccess ); + Layout1->addWidget( checkModification ); + Layout1->addLayout( Layout2 ); + Layout1->addWidget( buttonCurrentDT ); + + + Layout0->addLayout( Layout1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + Layout0->addItem( spacer ); + + l->addLayout( Layout0 ); + + connect( buttonCurrentDT, SIGNAL(clicked()), this, SLOT(changeDT())); +#endif +} + +void MyDatePlugin::fillStructure() +{ +#ifndef BENNY + dvals.date = kDate->getDate(); + dvals.changeModification = checkModification->isChecked(); + dvals.changeAccess = checkAccess->isChecked(); + dvals.hour = spinHour->value(); + dvals.minute = spinMinute->value(); + dvals.second = spinSecond->value(); +#endif +} + +QString MyDatePlugin::processFile( BatchRenamer* b, int i, QString, int ) +{ +#ifdef BENNY + QString filename = b->files()[i].dst.name; + + FILE * f; + struct utimbuf * t = new utimbuf(); + struct tm tmp; + struct stat st; + + time_t ti; + + f = fopen((const char *)filename, "r"); + if( f == NULL ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + fclose( f ); + + QFileInfo info( filename ); + tmp.tm_mday = info.lastModified().date().day(); + tmp.tm_mon = info.lastModified().date().month() - 1; + tmp.tm_year = info.lastModified().date().year() - 1900; + + tmp.tm_hour = info.lastModified().time().hour() - 1; + tmp.tm_min = info.lastModified().time().minute(); + tmp.tm_sec = info.lastModified().time().second(); + tmp.tm_isdst = -1; + + ti = mktime( &tmp ); + if( ti == -1 ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + if( stat( (const char *)filename, &st ) == -1 ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + t->actime = st.st_atime; + t->modtime = ti; + + if(utime( (const char *)filename, t ) != 0) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + return QString::null; +#else + QString filename = b->files()[i].dst.name; + + FILE * f; + struct utimbuf * t = new utimbuf(); + struct tm tmp; + struct stat st; + + time_t ti; + + f = fopen((const char *)filename, "r"); + if( f == NULL ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + fclose( f ); + + tmp.tm_mday = dvals.date.day(); + tmp.tm_mon = dvals.date.month() - 1; + tmp.tm_year = dvals.date.year() - 1900; + + tmp.tm_hour = dvals.hour; + tmp.tm_min = dvals.minute; + tmp.tm_sec = dvals.second; + tmp.tm_isdst = -1; + + ti = mktime( &tmp ); + if( ti == -1 ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + if( stat( (const char *)filename, &st ) == -1 ) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + if(dvals.changeAccess) + t->actime = ti; + else + t->actime = st.st_atime; + + if(dvals.changeModification) + t->modtime = ti; + else + t->modtime = st.st_mtime; + + if(utime( (const char *)filename, t ) != 0) + return QString( i18n("Can't change date of file %1.") ).arg(filename); + + return QString::null; +#endif +} + +void MyDatePlugin::changeDT() +{ + spinHour->setValue( QTime::currentTime().hour()); + spinMinute->setValue( QTime::currentTime().minute()); + spinSecond->setValue( QTime::currentTime().second()); + kDate->setDate( QDate::currentDate() ); +} + + + diff --git a/krename/datetime.h b/krename/datetime.h new file mode 100644 index 0000000..769e4c7 --- /dev/null +++ b/krename/datetime.h @@ -0,0 +1,90 @@ +/*************************************************************************** + datetime.h - description + ------------------- + begin : Mon Jan 7 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DATETIME_H +#define DATETIME_H + +/* + * This two includes are required, because you have to use + * KRenames internal structures and enums. + */ +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" + +#include <stdio.h> + +class KDatePicker; +class KIntSpinBox; +class QCheckBox; +class QButtonGroup; +class QGroupBox; +class QLabel; +class QVBoxLayout; +class QHBoxLayout; +class QPushButton; +class QString; +class QWidget; + +class MyDatePlugin: public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + + bool checkError(); + void drawInterface( QWidget* w, QVBoxLayout* l ); + void fillStructure(); + QString processFile( BatchRenamer*, int, QString token, int ); + + const QPixmap getIcon() const; + + private slots: + void changeDT(); + + protected: + QCheckBox* checkAccess; + QCheckBox* checkModification; + KDatePicker* kDate; + QLabel* labelTime; + KIntSpinBox* spinHour; + KIntSpinBox* spinMinute; + KIntSpinBox* spinSecond; + QPushButton* buttonCurrentDT; + + QHBoxLayout* Layout0; + QVBoxLayout* Layout1; + QHBoxLayout* Layout2; + + struct datevals { + QDate date; // Date + + bool changeModification; // Change modification date + bool changeAccess; // Change access date + + int hour; + int minute; + int second; + } dvals; +}; + + +#endif + + diff --git a/krename/dsdirselectdialog.cpp b/krename/dsdirselectdialog.cpp new file mode 100644 index 0000000..c37c88a --- /dev/null +++ b/krename/dsdirselectdialog.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + dsdirselectdialog.cpp - description + ------------------- + begin : Sat Jan 03 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "dsdirselectdialog.h" + +// Qt includes +#include <qcheckbox.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qvbox.h> + +// KDE includes +#include <kdiroperator.h> +#include <klocale.h> +#include <kurlcombobox.h> + +DSDirSelectDialog::DSDirSelectDialog( QWidget* parent ) + : KFileDialog( ":KRename", "*", parent, 0, false ) +{ + setOperationMode( KFileDialog::Opening ); + setMode( KFile::Files | KFile::ExistingOnly ); + + QVBox* vbox = new QVBox( this ); + + if( layout() ) + layout()->add( vbox ); + else + qDebug("KFileDialog does not have a layout!!!"); + + checkDir = new QCheckBox( i18n("Add directory names &with filenames"), vbox ); + check = new QCheckBox( i18n("Add subdirectories &recursively"), vbox ); + QHBox* hbox = new QHBox( vbox ); + QWidget* spacer = new QWidget( hbox ); + spacer->setMinimumWidth( 20 ); + checkHidden = new QCheckBox( i18n("Add &hidden directories"), hbox ); + hbox->setStretchFactor( checkHidden, 4 ); + checkOnlyDir = new QCheckBox( i18n("Add directory names only"), vbox ); + connect( check, SIGNAL( clicked() ), this, SLOT( enableControls() )); + + QToolTip::add( check, i18n("Walk recursively through the directory tree and add also the content of all subdirectories to the list of files to rename.") ); + QToolTip::add( checkHidden, i18n("If not checked, KRename will ignore directories starting with a dot during recursive adding.") ); + QToolTip::add( checkOnlyDir, i18n("Add only the directory names and not the names of the files in the directory to KRename.") ); + QToolTip::add( checkDir, i18n("This option causes KRename to add also the name of the base directory of the selected files to its list.") ); + + enableControls(); +} + +bool DSDirSelectDialog::recursively() const +{ + return check->isChecked(); +} + +bool DSDirSelectDialog::hidden() const +{ + return checkHidden->isChecked(); +} + +bool DSDirSelectDialog::dirs() const +{ + return checkDir->isChecked(); +} + +bool DSDirSelectDialog::onlyDirs() const +{ + return checkOnlyDir->isChecked(); +} + +void DSDirSelectDialog::setRecursively( bool b ) +{ + check->setChecked( b ); +} + +void DSDirSelectDialog::enableControls() +{ + checkHidden->setEnabled( check->isChecked() ); +} + +void DSDirSelectDialog::slotOk() +{ + const KFileItemList *items = ops->selectedItems(); + if ( !items || items->isEmpty() ) + { + KDialogBase::accept(); + } else + KFileDialog::slotOk(); +} + +KURL::List DSDirSelectDialog::selectedURLs() +{ + KURL::List list = KFileDialog::selectedURLs(); + if( list.isEmpty() ) + list.append( baseURL() ); + + return list; +} +#include "dsdirselectdialog.moc" diff --git a/krename/dsdirselectdialog.h b/krename/dsdirselectdialog.h new file mode 100644 index 0000000..55dc573 --- /dev/null +++ b/krename/dsdirselectdialog.h @@ -0,0 +1,54 @@ +/*************************************************************************** + dsdirselectdialog.h - description + ------------------- + begin : Sat Jan 03 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DSDIRSELECTDIALOG_H +#define DSDIRSELECTDIALOG_H + +#include <kfiledialog.h> + +class QCheckBox; +class QLabel; +class KComboBox; + +/* A small helper class to allow layout changes in KDirSelectDialog */ +class DSDirSelectDialog : public KFileDialog { + Q_OBJECT + + public: + DSDirSelectDialog( QWidget* parent ); + + bool recursively() const; + bool hidden() const; + bool dirs() const; + bool onlyDirs() const; + void setRecursively( bool b ); + + KURL::List selectedURLs(); + + private slots: + void enableControls(); + void slotOk(); + + private: + QCheckBox* check; + QCheckBox* checkHidden; + QCheckBox* checkDir; + QCheckBox* checkOnlyDir; + QLabel* label; +}; + +#endif diff --git a/krename/encodingplugin.cpp b/krename/encodingplugin.cpp new file mode 100644 index 0000000..1bbabce --- /dev/null +++ b/krename/encodingplugin.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + encodingplugin.cpp - description + ------------------- + begin : Tue Jul 06 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "encodingplugin.h" + +// QT includes +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtextcodec.h> +#include <qvgroupbox.h> + + +// KDE includes +#include <kapplication.h> +#include <kcombobox.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> + +const QString EncodingPlugin::getName() const +{ + return i18n("Encoding Conversion Plugin"); +} + +const QString EncodingPlugin::getAccelName() const +{ + return i18n("&Encoding Conversion Plugin"); +} + +const int EncodingPlugin::type() const +{ + return TYPE_FINAL_FILENAME; +} + +void EncodingPlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + // build a list of all available TextCodecs + QStringList codecs; + QTextCodec *codec; + for( int i=0; (codec = QTextCodec::codecForIndex(i));i++) + codecs.append( codec->name() ); + + m_widget = w; + + codec = QTextCodec::codecForLocale(); + m_locale_codec = codec->name(); + + QLabel* label = new QLabel( + i18n("<qt>This plugin is able to convert filenames between different " + "encodings. For example you can convert filenames from KOI8-R " + "to UTF-8 encoding.</qt>"), w ); + l->addWidget( label ); + + QVGroupBox* groupInput = new QVGroupBox( i18n("Encoding of Input Files:"), w ); + checkInput = new QCheckBox( i18n("&Use local encoding: %1").arg( m_locale_codec), groupInput ); + comboInput = new KComboBox( false, groupInput ); + comboInput->insertStringList( codecs ); + + QVGroupBox* groupOutput = new QVGroupBox( i18n("Encoding of Output Files:"), w ); + checkOutput = new QCheckBox( i18n("&Use local encoding: %1").arg( m_locale_codec), groupOutput ); + checkOutput->setChecked( true ); + comboOutput = new KComboBox( false, groupOutput ); + comboOutput->insertStringList( codecs ); + + l->addWidget( groupInput ); + l->addWidget( groupOutput ); + + connect( checkInput, SIGNAL( clicked() ), this, SLOT( enableControls() ) ); + connect( checkOutput, SIGNAL( clicked() ), this, SLOT( enableControls() ) ); + + connect( comboOutput, SIGNAL( activated(int) ),this, SLOT( updatePreview() ) ); + connect( comboInput, SIGNAL( activated(int) ),this, SLOT( updatePreview() ) ); + + setLocale( comboInput ); + setLocale( comboOutput ); + + enableControls(); +} + +void EncodingPlugin::fillStructure() +{ + m_input_codec = (checkInput->isChecked() ? m_locale_codec : comboInput->currentText() ); + m_output_codec = (checkOutput->isChecked() ? m_locale_codec : comboOutput->currentText() ); +} + +bool EncodingPlugin::checkError() +{ + return true; +} + +QString EncodingPlugin::processFile( BatchRenamer*, int, QString token, int ) +{ + QString input = token; + QString unicode = QString::null; + + QTextCodec* toUnicode = QTextCodec::codecForName(m_input_codec); // get the codec for KOI8-R + QTextCodec* fromUnicode = QTextCodec::codecForName(m_output_codec); + + unicode = toUnicode->toUnicode( input ); + return fromUnicode->fromUnicode( unicode ); +} + +void EncodingPlugin::finished() +{ +} + + +const QPixmap EncodingPlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "fonts", KIcon::Small ); +} + +void EncodingPlugin::enableControls() +{ + comboInput->setEnabled( !checkInput->isChecked() ); + comboOutput->setEnabled( !checkOutput->isChecked() ); + + //updatePreview(); +} + +void EncodingPlugin::setLocale( KComboBox* combo ) +{ + for(int i=0;i<combo->count();i++) + if( combo->text(i) == m_locale_codec ) + { + combo->setCurrentItem( i ); + break; + } +} diff --git a/krename/encodingplugin.h b/krename/encodingplugin.h new file mode 100644 index 0000000..801dd3f --- /dev/null +++ b/krename/encodingplugin.h @@ -0,0 +1,68 @@ +/*************************************************************************** + encodingplugin.h - description + ------------------- + begin : Tue Jul 06 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _ENCODINGPLUGIN_H_ +#define _ENCODINGPLUGIN_H_ + +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" +#include "fileoperation.h" + +class KComboBox; +class QCheckBox; + +class EncodingPlugin : public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + + bool checkError(); + void drawInterface( QWidget* w, QVBoxLayout* l ); + void fillStructure(); + QString processFile( BatchRenamer*, int, QString token, int ); + void finished(); + + const QPixmap getIcon() const; + + private slots: + void enableControls(); + + private: + void setLocale( KComboBox* combo ); + + FileOperation fop; + + QString m_input_codec; + QString m_output_codec; + QString m_locale_codec; + + int mib_input; + int mib_output; + + QCheckBox* checkInput; + QCheckBox* checkOutput; + + KComboBox* comboInput; + KComboBox* comboOutput; +}; + + +#endif // _ENCODINGPLUGIN_H_ diff --git a/krename/fileoperation.cpp b/krename/fileoperation.cpp new file mode 100644 index 0000000..23fa405 --- /dev/null +++ b/krename/fileoperation.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** + fileoperation.cpp - description + ------------------- + begin : Sun Nov 11 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// KDE includes +#include <kapplication.h> +#include <klocale.h> +#include <kio/netaccess.h> +#include <kio/job.h> + +// QT includes +#if QT_VERSION >= 0x030100 + #include <qeventloop.h> +#else + #include <qapplication.h> +#endif + +#include <qfileinfo.h> + +// OS includes +#include <stdio.h> +#include <unistd.h> + +// Own includes +#include "fileoperation.h" +#include "ProgressDialog.h" +#include "batchrenamer.h" + +using namespace KIO; + +FileOperation::FileOperation() +{ + canceled = false; +} + +FileOperation::~FileOperation() { } + +bool FileOperation::start( const KURL & src, const KURL & dest, int mode, bool overwrite ) +{ + locked = true; + result = 0; + + if( src == dest && !overwrite ) { + m_error = QString( i18n( "File %1 exists already!") ).arg( dest.prettyURL() ); + return false; + } + + Job* job = 0; + switch( mode ) { + case RENAME: + case MOVE: + default: + job = file_move( src, dest, -1, overwrite, false, false ); + break; + case COPY: + job = file_copy( src, dest, -1, overwrite, false, false ); + break; + case LINK: + // Does only work if both files are on the same host + if( src.protocol() == dest.protocol() && src.host() == dest.host() ) + { + job = symlink( src.path(), dest, overwrite, false ); + } + else + { + m_error = i18n("Can't create symlinks on different hosts for file %1.").arg( src.prettyURL() ); + result = true; + return !result; + } + break; + }; + + if( !job ) + return false; + + job->setAutoErrorHandlingEnabled( false, 0 ); + connect( job, SIGNAL( result (KIO::Job *) ), + this, SLOT( slotResult (KIO::Job *) ) ); + +#if QT_VERSION >= 0x030100 + kapp->eventLoop()->enterLoop(); +#else + kapp->enter_loop(); +#endif + return !result; +} + +bool FileOperation::fcopy( const QString & src, const QString & dest ) +{ + return start( KURL( src ), KURL( dest ), KIO::CopyJob::Copy, false ); +} + +QString FileOperation::getName( const QString & file ) +{ + QFileInfo info( file ); + return info.fileName(); +} + +void FileOperation::slotResult( KIO::Job * job ) +{ + result = job->error(); + if( result ) + m_error = job->errorString(); + +#if QT_VERSION >= 0x030100 + kapp->eventLoop()->exitLoop(); +#else + kapp->exit_loop(); +#endif +} + diff --git a/krename/fileoperation.h b/krename/fileoperation.h new file mode 100644 index 0000000..32a2552 --- /dev/null +++ b/krename/fileoperation.h @@ -0,0 +1,54 @@ +/*************************************************************************** + fileoperation.h - description + ------------------- + begin : Sun Nov 11 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FILEOPERATION_H +#define FILEOPERATION_H + +#include <qobject.h> +#include <kio/jobclasses.h> +#include <kurl.h> + +class QString; +class FileOperation: public QObject { + Q_OBJECT + public: + FileOperation(); + ~FileOperation(); + + bool start( const KURL & src, const KURL & dest, int mode, bool overwrite ); + bool fcopy( const QString & src, const QString & dest ); + + inline const QString & error() const; + static QString getName( const QString & file ); + + private slots: + void slotResult( KIO::Job * job ); + + private: + bool locked; + bool canceled; + int result; + + QString m_error; +}; + +inline const QString & FileOperation::error() const +{ + return m_error; +} + +#endif diff --git a/krename/fileplugin.cpp b/krename/fileplugin.cpp new file mode 100644 index 0000000..535b8bb --- /dev/null +++ b/krename/fileplugin.cpp @@ -0,0 +1,213 @@ +/*************************************************************************** + fileplugin.cpp - description + ------------------- + begin : Mon Jul 1 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "fileplugin.h" + +// Qt includes +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kfilemetainfo.h> +#include <klineedit.h> +#include <klistbox.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kpushbutton.h> + +FilePlugin::FilePlugin( KService* service ) +{ + if(!service) { + setupKeys(); + return; + } + + KFileMetaInfoProvider* mip = KFileMetaInfoProvider::self(); + m_name = service->name(); + m_comment = service->comment(); + QStringList options = service->serviceTypes(); + for( unsigned int i = 0; i < options.count(); i++ ) { + if( options[i] != "KFilePlugin" ) { + m_mimetype = options[i]; + const KFileMimeTypeInfo* info = mip->mimeTypeInfo( m_mimetype ); + if( info ) + keys = info->supportedKeys(); + + fileplugin = mip->plugin( m_mimetype ); + + KMimeType::Ptr mime = KMimeType::mimeType( m_mimetype ); + m_icon = mime->icon( QString::null, true ); // arguments are unused + + setPattern( mime ); + } + } +} + +FilePlugin::~FilePlugin() +{ } + +void FilePlugin::setPattern( KMimeType::Ptr mime ) +{ + QStringList pattern = mime->patterns(); + if( pattern.count() ) { + m_pattern = pattern[0]; + if( m_pattern.startsWith( "*." ) ) + m_pattern = m_pattern.right( m_pattern.length() - 2 ); + } + + // TODO: REFACTOR + // We need a pattern + if( m_pattern.isEmpty() ) { + int a = 0; + a = m_name.find( "-" ); + if( a > -1 ) + m_pattern = m_name.left( a ).lower(); + else { + a = m_pattern.find( " " ); + if( a > -1 ) + m_pattern = m_name.left( a ).lower(); + else + m_pattern = m_name; + } + } + + setupKeys(); +} + +void FilePlugin::setupKeys() +{ + for( unsigned int i = 0; i < keys.count(); i++ ) + keys[i] = getPattern() + keys[i]; +} + +const QString FilePlugin::getName() const +{ + return m_name; +} + +const QString FilePlugin::getAccelName() const +{ + return "&" + getName(); +} + +const QString FilePlugin::getPattern() const +{ + return m_pattern; +} + +const int FilePlugin::type() const +{ + return TYPE_BRACKET; +} + +bool FilePlugin::checkError() +{ + return true; +} + +void FilePlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding ); + + QHBoxLayout* hbox = new QHBoxLayout( 0, 6, 6 ); + + QLabel* pix = new QLabel( w ); + pix->setPixmap( kapp->iconLoader()->loadIcon( m_icon, KIcon::Desktop ) ); + + hbox->addWidget( pix ); + hbox->addWidget( new QLabel( "<qt><b>"+getName()+"</b></qt>", w ) ); + hbox->addItem( spacer ); + + l->addLayout( hbox ); + l->addWidget( new QLabel( m_comment, w ) ); + l->addWidget( new QLabel( i18n("Supported tokens:"), w ) ); + + KListBox* list = new KListBox( w ); + list->setColumnMode( KListBox::FitToWidth ); + + for( unsigned int i = 0; i < keys.count(); i++ ) + list->insertItem( "[" + keys[i] + "]" ); + + l->addWidget( list ); + l->setStretchFactor( list, 2 ); +} + +QString FilePlugin::processFile( BatchRenamer* b, int i, QString token, int ) +{ + QString filename = BatchRenamer::buildFilename( &b->files()[i].src ); + + token = token.lower(); + + /* + * Check if we have something cached for this file + */ + if( cache.contains( filename + "::" + token ) ) + return cache[filename + "::" + token ]; + + for( unsigned int i = 0; i < keys.count(); i++ ) { + if( token.lower() == keys[i].lower() ) { + KFileMetaInfo meta( filename ); + if( meta.isValid() ) { + QString k = keys[i]; + if( k.startsWith( getPattern() ) ) + k = k.mid( getPattern().length(), k.length() - getPattern().length() ); + + QString ret = meta.item( k ).string( true ).stripWhiteSpace(); + + if( cache.count() >= CACHE_MAX ) + cache.remove( cache.begin() ); + + cache.insert( filename + "::" + token, ret ); + kapp->processEvents(); + return ret; + } + } + } + + return QString::null; +} + +void FilePlugin::addHelp( HelpDialogData* data ) +{ + QStringList list; + for( unsigned int i = 0; i < keys.count(); i++ ) + list.append( "[" + keys[i] + "]" + ";;" + keys[i] ); + + data->add( getName(), &list, getIcon() ); +} + +const QPixmap FilePlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( m_icon, KIcon::Small ); +} + +bool FilePlugin::supports( const QString & token ) +{ + for( unsigned int i = 0; i < keys.count(); i++ ) + if( QRegExp( keys[i].lower() ).exactMatch( token.lower() ) ) + return true; + + return false; +} + +void FilePlugin::clearCache() +{ + cache.clear(); +} diff --git a/krename/fileplugin.h b/krename/fileplugin.h new file mode 100644 index 0000000..8931936 --- /dev/null +++ b/krename/fileplugin.h @@ -0,0 +1,86 @@ +/*************************************************************************** + fileplugin.h - description + ------------------- + begin : Mon Jul 1 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FILEPLUGIN_H +#define FILEPLUGIN_H + +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" +#include <kmimetype.h> + +/* + * number of items we shall cache from file plugins + */ +#define CACHE_MAX 2000 + +class KFileMetaInfoProvider; +class KFileMimeTypeInfo; +class KPushButton; +class KService; +class QLabel; +class QWidget; +class QVBoxLayout; +class KFilePlugin; +class FilePlugin : public Plugin { + Q_OBJECT + public: + FilePlugin( KService* service ); + ~FilePlugin(); + + inline bool isValid() const; + + virtual const QString getName() const; + virtual const QString getAccelName() const; + virtual const QString getPattern() const; + virtual const int type() const; + + virtual bool checkError(); + virtual void drawInterface( QWidget* w, QVBoxLayout* l ); + virtual QString processFile( BatchRenamer* b, int i, QString token, int mode ); + + virtual void addHelp( HelpDialogData* data ); + virtual const QPixmap getIcon() const; + + virtual bool alwaysUsed() const { return true; } + + virtual const QStringList getKeys() const { return keys; } + + virtual void clearCache(); + + private: + void setPattern( KMimeType::Ptr mime ); + + protected: + bool supports( const QString & token ); + void setupKeys(); + + QMap<QString,QString> cache; + KFilePlugin* fileplugin; + + QString m_name, m_comment, m_icon, m_mimetype, m_pattern; + + QStringList keys; +}; + +bool FilePlugin::isValid() const +{ + return keys.count() > 0 && fileplugin ? true : false; +} + +#endif diff --git a/krename/firststartdlg.cpp b/krename/firststartdlg.cpp new file mode 100644 index 0000000..39b4941 --- /dev/null +++ b/krename/firststartdlg.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + firststartdlg.cpp - description + ------------------- + begin : Fre Jun 6 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "firststartdlg.h" + +FirstStartDlg::FirstStartDlg(QWidget *parent, const char *name ) + : KDialogBase( KDialogBase::Plain, "KRename", + KDialogBase::Ok, KDialogBase::Ok, parent, name, true, true ), + GUIModeSelector() +{ + setCaption( guiModeCaption() ); + createFrame( plainPage() ); + setUseWizard( true ); +} + +FirstStartDlg::~FirstStartDlg() +{ +} + diff --git a/krename/firststartdlg.h b/krename/firststartdlg.h new file mode 100644 index 0000000..998d617 --- /dev/null +++ b/krename/firststartdlg.h @@ -0,0 +1,32 @@ +/*************************************************************************** + firststartdlg.h - description + ------------------- + begin : Fre Jun 6 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FIRSTSTARTDLG_H +#define FIRSTSTARTDLG_H + +#include <qwidget.h> +#include <kdialogbase.h> +#include "guimodeselector.h" + +class FirstStartDlg : public KDialogBase, public GUIModeSelector { + Q_OBJECT + public: + FirstStartDlg(QWidget *parent=0, const char *name=0); + ~FirstStartDlg(); +}; + +#endif diff --git a/krename/guimodeselector.cpp b/krename/guimodeselector.cpp new file mode 100644 index 0000000..92b0e94 --- /dev/null +++ b/krename/guimodeselector.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + guimodeselector.cpp - description + ------------------- + begin : Fre Jun 6 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "guimodeselector.h" + +// Qt includes +#include <qbuttongroup.h> +#include <qframe.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> + +// KDE includes +#include <klocale.h> + +GUIModeSelector::GUIModeSelector() +{ + optionWizard = optionTabs = 0; +} + +GUIModeSelector::~GUIModeSelector() +{ +} + +bool GUIModeSelector::useWizard() const +{ + return optionWizard->isChecked(); +} + +void GUIModeSelector::setUseWizard( bool b ) +{ + optionWizard->setChecked( b ); + optionTabs->setChecked( !b ); +} + +const QString GUIModeSelector::guiModeCaption() const +{ + return i18n("Look and Feel"); +} + +void GUIModeSelector::createFrame( QFrame* frame ) +{ + QVBoxLayout* layout = new QVBoxLayout( frame ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + QButtonGroup* group = new QButtonGroup( frame ); + group->setColumnLayout(0, Qt::Vertical ); + QVBoxLayout* lgroup = new QVBoxLayout( group->layout() ); + + optionWizard = new QRadioButton( group ); + optionWizard->setText( i18n("Use &wizard style GUI (beginners)") ); + optionTabs = new QRadioButton( group ); + optionTabs->setText( i18n("Use &tabbed GUI (advanced users)") ); + + lgroup->addWidget( new QLabel( i18n("Configure the look and feel of the KRename GUI:<br>"), group ) ); + lgroup->addWidget( optionWizard ); + lgroup->addWidget( optionTabs ); + lgroup->addItem( spacer ); + + layout->addWidget( group ); + layout->addItem( spacer ); +} + + diff --git a/krename/guimodeselector.h b/krename/guimodeselector.h new file mode 100644 index 0000000..524319f --- /dev/null +++ b/krename/guimodeselector.h @@ -0,0 +1,41 @@ +/*************************************************************************** + guimodeselector.h - description + ------------------- + begin : Fre Jun 6 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GUIMODESELECTOR_H +#define GUIMODESELECTOR_H + +#include <qobject.h> + +class QFrame; +class QRadioButton; +class GUIModeSelector { + public: + GUIModeSelector(); + ~GUIModeSelector(); + + bool useWizard() const; + void setUseWizard( bool b ); + + protected: + const QString guiModeCaption() const; + void createFrame( QFrame* frame ); + + QRadioButton* optionWizard; + QRadioButton* optionTabs; +}; + +#endif diff --git a/krename/helpdialog.cpp b/krename/helpdialog.cpp new file mode 100644 index 0000000..2707f38 --- /dev/null +++ b/krename/helpdialog.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + helpdialog.cpp - description + ------------------- + begin : Fr Nov 15 13:44:19 CEST 2001 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "helpdialog.h" +#include "krenameimpl.h" + +// Qt includes +#include <qcombobox.h> +#include <qlayout.h> +#include <qlineedit.h> + +// KDE includes +#include <klocale.h> +#include <klistview.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +void HelpDialogData::remove( const QString & headline ) +{ + if( m_map.contains( headline ) ) { + m_map.remove( headline ); + m_icons.remove( headline ); + + emit updateHeadline(); + emit updateItems(); + } +} + +void HelpDialogData::add( const QString & headline, QStringList* commands, const QPixmap & icon, bool first ) +{ + m_map.insert( headline, *commands ); + m_icons.insert( headline, icon ); + if( first ) + m_first = headline; + + emit updateHeadline(); + emit updateItems(); +} + +QStringList HelpDialogData::tokens() const +{ + QStringList list; + +#if QT_VERSION >= 0x030005 + // map.keys() seems only to be avaible in Qt >= 3.0.5 + QStringList keys = m_map.keys(); +#else + QStringList keys; + QMap<QString, QStringList>::Iterator it; + for ( it = m_map.begin(); it != m_map.end(); ++it ) + keys.append( it.key() ); +#endif + + for( unsigned int i = 0; i < keys.count(); i++ ) + for( unsigned int z = 0; z < m_map[keys[i]].count(); z++ ) + list.append( m_map[keys[i]][z].section( ";;", 0, 0 ) ); + + return list; +} + + +HelpDialog::HelpDialog( HelpDialogData* data, QWidget* parent, + const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + text = NULL; + + resize( 500, 400 ); + setCaption( i18n( "Help" ) ); + HelpDialogLayout = new QVBoxLayout( this, 11, 6, "HelpDialogLayout"); + + comboHeadline = new QComboBox( FALSE, this, "comboHeadline" ); + HelpDialogLayout->addWidget( comboHeadline ); + + list = new KListView( this, "list" ); + list->addColumn( i18n( "Token" ) ); + list->addColumn( i18n( "Description" ) ); + HelpDialogLayout->addWidget( list ); + + Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1"); + QSpacerItem* spacer = new QSpacerItem( 91, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout1->addItem( spacer ); + + buttonAdd = new KPushButton( this, "buttonAdd" ); + buttonAdd->setText( i18n( "&Add" ) ); + Layout1->addWidget( buttonAdd ); + + buttonClose = createButton( KStdGuiItem::close(), this ); + Layout1->addWidget( buttonClose ); + HelpDialogLayout->addLayout( Layout1 ); + + // signals and slots connections + connect( buttonClose, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( execute() ) ); + connect( list, SIGNAL( executed(QListViewItem*) ), this, SLOT( execute() ) ); + connect( comboHeadline, SIGNAL( activated(int) ), this, SLOT(updateItems() ) ); + + m_data = data; + connect( m_data, SIGNAL( updateItems() ), this, SLOT( updateItems() ) ); + connect( m_data, SIGNAL( updateHeadline() ), this, SLOT( updateHeadline() ) ); +} + +HelpDialog::~HelpDialog() +{ + disconnect( m_data, SIGNAL( updateItems() ), this, SLOT( updateItems() ) ); + disconnect( m_data, SIGNAL( updateHeadline() ), this, SLOT( updateHeadline() ) ); +} + +void HelpDialog::execute() +{ + if(!list->currentItem()) + return; + + QString t = text->text(); + + t.insert( text->cursorPosition(), list->currentItem()->text( 0 ) ); + text->setText( t ); + + if( isModal() ) + accept(); +} + +void HelpDialog::updateItems() +{ + list->clear(); + QStringList items = m_data->map()[comboHeadline->currentText()]; + + for( unsigned int i = 0; i < items.count(); i++ ) { + QString tmp = items[i]; + new KListViewItem( list, tmp.section( ";;", 0, 0 ), tmp.section( ";;", 1, 1 ) ); + } +} + +void HelpDialog::updateHeadline() +{ + comboHeadline->clear(); + QMap<QString,QStringList> m = m_data->map(); + QMap<QString,QPixmap> ic = m_data->icons(); + + comboHeadline->insertItem( ic[m_data->first()], m_data->first() ); + QMap<QString, QStringList>::Iterator it; + for ( it = m.begin(); it != m.end(); ++it ) + if( it.key() != m_data->first() ) + comboHeadline->insertItem( ic[it.key()], it.key() ); +} + diff --git a/krename/helpdialog.h b/krename/helpdialog.h new file mode 100644 index 0000000..f15f541 --- /dev/null +++ b/krename/helpdialog.h @@ -0,0 +1,111 @@ +/*************************************************************************** + helpdialog.h - description + ------------------- + begin : Fr Nov 15 13:44:19 CEST 2001 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef HELPDIALOG_H +#define HELPDIALOG_H + +#include <qdialog.h> +#include <qstringlist.h> +#include <qpixmap.h> +#include <qmap.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QComboBox; +class QLineEdit; +class QPixmap; +class KListView; +class KPushButton; + +class HelpDialogData : public QObject { + Q_OBJECT + public: + HelpDialogData() {} + ~HelpDialogData() {} + + void add( const QString & headline, QStringList* commands, const QPixmap & icon, bool first = false ); + void remove( const QString & headline ); + + /** returns all available and supported tokens + */ + QStringList tokens() const; + + inline const QMap<QString,QStringList> & map() const + { + return m_map; + } + + inline const QMap<QString,QPixmap> & icons() const + { + return m_icons; + } + + inline const QString & first() const + { + return m_first; + } + + signals: + void updateHeadline(); + void updateItems(); + + private: + QMap<QString,QStringList> m_map; + QMap<QString,QPixmap> m_icons; + + QString m_first; +}; + +class HelpDialog : public QDialog +{ + Q_OBJECT + public: + HelpDialog( HelpDialogData* data, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~HelpDialog(); + + inline void setLineEdit( QLineEdit* lineedit ); + + public slots: + void updateItems(); + void updateHeadline(); + + private slots: + void execute(); + + private: + QComboBox* comboHeadline; + KListView* list; + KPushButton* buttonAdd; + KPushButton* buttonClose; + + protected: + HelpDialogData* m_data; + + QLineEdit* text; + + QVBoxLayout* HelpDialogLayout; + QHBoxLayout* Layout1; +}; + +void HelpDialog::setLineEdit( QLineEdit* lineedit ) +{ + text = lineedit; +} + +#endif // HELPDIALOG_H diff --git a/krename/hi32-app-krename.png b/krename/hi32-app-krename.png Binary files differnew file mode 100644 index 0000000..2a12806 --- /dev/null +++ b/krename/hi32-app-krename.png diff --git a/krename/hi48-app-krename.png b/krename/hi48-app-krename.png Binary files differnew file mode 100644 index 0000000..91762a8 --- /dev/null +++ b/krename/hi48-app-krename.png diff --git a/krename/kmyhistorycombo.cpp b/krename/kmyhistorycombo.cpp new file mode 100644 index 0000000..604d352 --- /dev/null +++ b/krename/kmyhistorycombo.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + kmyhistorycombo.cpp - description + ------------------- + begin : Tue Oct 16 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// QT includes +#include <qlistbox.h> + +// Own includes +#include "kmyhistorycombo.h" + +#include <kapplication.h> +#include <kconfig.h> +#include <klocale.h> + +#include <qpopupmenu.h> +#include <qtimer.h> + +#define TIMER_DELAY 500 + +#define KRENAME_FILENAME 5000 +#define KRENAME_FILENAME_LOWER 5001 +#define KRENAME_FILENAME_UPPER 5002 +#define KRENAME_NUMBER 5003 +#define KRENAME_DATE 5004 + +KMyHistoryCombo::KMyHistoryCombo( bool customPopup, QWidget* parent, const char* name) + : KHistoryCombo(parent, name) +{ + QStringList history; + QStringList completion; + KConfig* config = kapp->config(); + config->setGroup( name ); + this->setDuplicatesEnabled( false ); + + history = config->readListEntry("History"); + completion = config->readListEntry("CompletionItems"); + m_timer = new QTimer(); + + setHistoryItems( history ); + + completionObject()->setItems( ( completion.isEmpty() ? history : completion ) ); + setCompletionMode( (KGlobalSettings::Completion)config->readNumEntry( "CompletionMode", + KGlobalSettings::completionMode() ) ); + + connect( this, SIGNAL( textChanged( const QString & ) ), this, SLOT( textChangedGovernor() ) ); + connect( m_timer, SIGNAL( timeout() ), this, SIGNAL( delayedTextChanged() ) ); + + if( customPopup ) + connect( this, SIGNAL( aboutToShowContextMenu( QPopupMenu* ) ), this, SLOT( slotCustomContextMenu( QPopupMenu* ) ) ); +} + +KMyHistoryCombo::~KMyHistoryCombo() +{ + delete m_timer; +} + +void KMyHistoryCombo::saveSettings() +{ + addToHistory( text() ); + + KConfig* config = kapp->config(); + + config->setGroup( name() ? name() : "KMyHistoryCombo" ); + config->writeEntry( "History", historyItems() ); + config->writeEntry( "CompletionItems", completionObject()->items() ); + config->writeEntry( "CompletionMode", completionMode() ); + + config->sync(); +} + +QString KMyHistoryCombo::text( int index ) const +{ + return this->listBox()->text( index ); +} + +void KMyHistoryCombo::setText( const QString & text ) +{ + this->lineEdit()->setText( text ); +} + +void KMyHistoryCombo::add( const QString & text ) +{ + int i; + for ( i = 0; i < this->count(); i++ ) + if( this->text( i ) == text ) { + QString tmp = this->text( i ); + this->listBox()->removeItem( i ); + this->insertItem( tmp, 0 ); + return; + } + + if( this->count() == this->maxCount() ) + this->listBox()->removeItem( this->maxCount() ); + + this->insertItem( text, 0 ); +} + +bool KMyHistoryCombo::isEmpty() const +{ + return this->lineEdit()->text().isEmpty(); +} + +void KMyHistoryCombo::textChangedGovernor() +{ + m_timer->stop(); + m_timer->start( TIMER_DELAY, true ); +} + +void KMyHistoryCombo::slotCustomContextMenu( QPopupMenu* p ) +{ + QPopupMenu* krename = new QPopupMenu( p ); + krename->insertItem( i18n("&Filename"), KRENAME_FILENAME ); + krename->insertItem( i18n("Filename to &lowercase"), KRENAME_FILENAME_LOWER ); + krename->insertItem( i18n("Filename to &uppercase"), KRENAME_FILENAME_UPPER ); + krename->insertItem( i18n("&Number"), KRENAME_NUMBER ); + krename->insertItem( i18n("&Date"), KRENAME_DATE ); + + connect( krename, SIGNAL( activated( int ) ), this, SLOT( slotInsertKRenameCommand( int ) ) ); + + p->insertSeparator( 0 ); + p->insertItem( i18n("Insert &KRename token"), krename, 0, 0 ); +} + +void KMyHistoryCombo::slotInsertKRenameCommand( int id ) +{ + QString t; + + // TODO: + // also use constants for KRename tokens! + + switch( id ) + { + case KRENAME_FILENAME: + t = "$"; + break; + case KRENAME_FILENAME_LOWER: + t = "%"; + break; + case KRENAME_FILENAME_UPPER: + t = "&"; + break; + case KRENAME_NUMBER: + t = "#"; + break; + case KRENAME_DATE: + t = "[date]"; + break; + default: + break; + } + + if( !t.isEmpty() ) + this->lineEdit()->insert( t ); +} diff --git a/krename/kmyhistorycombo.h b/krename/kmyhistorycombo.h new file mode 100644 index 0000000..1f9f4d4 --- /dev/null +++ b/krename/kmyhistorycombo.h @@ -0,0 +1,74 @@ +/*************************************************************************** + kmyhistorycombo.h - description + ------------------- + begin : Tue Oct 16 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYHISTORYCOMBO_H +#define KMYHISTORYCOMBO_H + +// KDE includes +#include <kcombobox.h> +#include <kcompletion.h> + +class QPopupMenu; +class QTimer; + +class KMyHistoryCombo : public KHistoryCombo { + Q_OBJECT + public: + /** Create a new KMyHistoryCombo which has automatic KRename default history + * handling and a custom popup menu to insert tokens if customPopup is true + * + * \param customPopup insert custom menu items into context menu. + */ + KMyHistoryCombo(bool customPopup, QWidget* parent=0, const char* name=0); + ~KMyHistoryCombo(); + + /** + * Saves the settings of the HistoryCombo in the applications + * config file in a group named name() + * Saved settings include: + * - history items + * - completion items + * - completion mode + */ + void saveSettings(); + + inline QString text() const; + + QString text( int index ) const; + + void setText( const QString & text ); + void add( const QString & text ); + bool isEmpty() const; + + signals: + void delayedTextChanged(); + + private slots: + void textChangedGovernor(); + void slotCustomContextMenu( QPopupMenu* p ); + void slotInsertKRenameCommand( int id ); + + private: + QTimer* m_timer; +}; + +inline QString KMyHistoryCombo::text() const +{ + return currentText(); +} + +#endif diff --git a/krename/kmylistbox.cpp b/krename/kmylistbox.cpp new file mode 100644 index 0000000..c1b63ba --- /dev/null +++ b/krename/kmylistbox.cpp @@ -0,0 +1,839 @@ +/*************************************************************************** + kmylistbox.cpp - description + ------------------- + begin : Tue Oct 16 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// QT includes +#include <qcursor.h> +#include <qdir.h> +#include <qdragobject.h> +#include <qpainter.h> +#include <qpalette.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kdirlister.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kio/previewjob.h> +#include <kio/netaccess.h> +#include <qptrlist.h> +#include <kurldrag.h> +#include <kurllabel.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> + +// Own includes +#include "kmylistbox.h" +#include "krecursivelister.h" +#include "threadedlister.h" + +using namespace KIO; + +KMyListBox::KMyListBox(QWidget* parent, const char* name, WFlags fl) + :KListBox(parent, name, fl) +{ + m_running_lister_counter = 0; + + drag = ctrlPressed = shiftPressed = mousePressed = false; + moving = false; + m_sorting = UNSORTED; + + label = new KURLLabel( QString::null, "<br>" + i18n("Please add some files...") + "<br>", this ); + label->setFrameStyle( QFrame::GroupBoxPanel | QFrame::Sunken ); + + setAcceptDrops( true ); + setSelectionMode(Extended); // was extended before 2.9.0 + + connect( this, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(openFile(QListBoxItem*))); + connect( this, SIGNAL(returnPressed(QListBoxItem*)), this, SLOT(openFile(QListBoxItem*))); + connect( label, SIGNAL( leftClickedURL() ), this, SIGNAL( addFiles() ) ); + + positionLabel(); +} + +KMyListBox::~KMyListBox() +{ +} + +KURL KMyListBox::url( int index ) const +{ + return static_cast<KMyListBoxItem*>( item( index ) )->url(); +} + +bool KMyListBox::dir( int index ) const +{ + return static_cast<KMyListBoxItem*>( item( index ) )->dir(); +} + +void KMyListBox::setPreviewSize( int size ) +{ + previewSize = size; +} + +void KMyListBox::removeItem( int index ) +{ + KListBox::removeItem( index ); +} + +void KMyListBox::addFile( const KURL & filename, bool isfile ) +{ + // Check if the URL is a file and no dir + // Is the file already in our list ? + if( !isfile && !isFile( filename ) ) + return; + + if( isInList( filename ) ) + return; + + insertItem( new KMyListBoxItem( filename, false ), -1 ); + + positionLabel(); +} + +void KMyListBox::addDirName( const KURL & dirname ) +{ + if(!isInList( dirname ) ) + { + insertItem( new KMyListBoxItem( dirname, true ), -1 ); + positionLabel(); + } +} + +bool KMyListBox::isFile( const KURL & f, bool autoadd ) +{ + UDSEntry entry; + + NetAccess::stat( f, entry ); + KFileItem file( entry, f ); + if( !file.isReadable() ) + return false; + + if( file.isDir() ) { + if( autoadd ) + addDir( f, "*", false, true ); + return false; + } + + return true; +} + +void KMyListBox::addDir( const KURL & dirname, const QString & filter, bool hidden, bool recursively, bool dirnames ) +{ + ThreadedLister* thl = new ThreadedLister( &m_add_mutex, &m_running_lister_counter, this ); + thl->setDirname( dirname ); + thl->setDirnames( dirnames ); + thl->setFilter( filter ); + thl->setHidden( hidden ); + thl->setRecursive( recursively ); + + KApplication::setOverrideCursor( Qt::waitCursor ); + thl->start(); +} + +void KMyListBox::addDirName( const KURL & dirname, const QString & filter, bool hidden, bool recursive ) +{ + KApplication::setOverrideCursor( Qt::waitCursor ); + + if( recursive ) { + ThreadedLister* thl = new ThreadedLister( &m_add_mutex, &m_running_lister_counter, this ); + thl->setDirname( dirname ); + thl->setDirnames( true ); + thl->setFilter( filter ); + thl->setHidden( hidden ); + thl->setRecursive( recursive ); + thl->setRecursiveDirOnlyMode( true ); + + thl->start(); + } else { + // escape hiden directories + QString name = dirname.fileName(); + if( !hidden && name.right( 1 ) != QString::fromLatin1(".") ) + if( !isInList( dirname ) ) + addDirName( dirname ); + + listerDone( NULL ); + } +} + +void KMyListBox::dropEvent(QDropEvent* e) +{ + if( e->source() != this ) + e->accept(QTextDrag::canDecode(e)); + + KURL::List list; + if( KURLDrag::decode( e, list ) ) + { + + KApplication::setOverrideCursor( Qt::waitCursor ); + + setUpdatesEnabled( false ); + + for( unsigned int i = 0; i < list.count(); i++ ) + addFile( list[i], false ); + + setUpdatesEnabled( true ); + listerDone( NULL ); + } +} + +void KMyListBox::dragEnterEvent(QDragEnterEvent* e) +{ + if( e->source() != this ) + e->accept(QTextDrag::canDecode(e)); +} + +void KMyListBox::viewportMousePressEvent( QMouseEvent* e ) +{ + if( moving ) + move( index( itemAt( e->pos() ) ) ); + else { + KListBox::viewportMousePressEvent( e ); + QPoint p( e->pos() ); + QListBoxItem *i = itemAt( p ); + if ( i ) { + presspos = e->pos(); + mousePressed = TRUE; + } + } +} + +void KMyListBox::viewportMouseMoveEvent( QMouseEvent* e ) +{ + if ( mousePressed && ( presspos - e->pos() ).manhattanLength() > KApplication::startDragDistance() ) { + mousePressed = FALSE; + QListBoxItem *item = itemAt( presspos ); + if ( item ) { + QStringList source = text( index( item ) ); + for( int i = 0; i < (signed int)count(); i++ ) + if( isSelected(i) && (i != index(item) )) + source.append( text(i) ); + QUriDrag* ud = new QUriDrag(viewport()); + ud->setUnicodeUris( source ); + ud->drag(); + } + } else + KListBox::viewportMouseMoveEvent( e ); +} + +void KMyListBox::viewportMouseReleaseEvent( QMouseEvent* e ) +{ + mousePressed = FALSE; + KListBox::viewportMouseReleaseEvent( e ); +} + +void KMyListBox::keyPressEvent( QKeyEvent* e ) +{ + /* + * TODO: Document all this keyboard commands + */ + if( e->key() == Key_Control ) + ctrlPressed = true; + else if( e->key() == Key_Shift ) + shiftPressed = true; + else if( e->key() == Key_Up ) + setCurrentItem( currentItem()-1 ); + else if( e->key() == Key_Down ) + setCurrentItem( currentItem()+1 ); + else if( e->key() == Key_Space ) + select( item(currentItem()) ); + else if( e->key() == Key_Return ) + openFile( item(currentItem()) ); + else if( e->key() == Key_Delete ) + emit deletePressed(); + else if( e->key() == Key_A ) + for( unsigned int i = 0; i < count(); i++ ) + setSelected( i, true ); + else if( e->key() == Key_M ) { + moveMode(); + return; + } else if( e->key() == Key_N ) + for( unsigned int i = 0; i < count(); i++ ) + setSelected( i, false ); + else if( e->key() == Key_End ) + setCurrentItem( count()-1 ); + else if( e->key() == Key_Home ) + setCurrentItem( 0 ); + else + e->ignore(); + + emit updateCount(); + setPreview( KMyListBoxItem::preview() ); + emit updatePreview(); +} + +void KMyListBox::keyReleaseEvent( QKeyEvent* e ) +{ + if( e->key() == Key_Control ) + ctrlPressed = false; + else if( e->key() == Key_Shift ) + shiftPressed = false; +} + +void KMyListBox::openFile( QListBoxItem* item ) +{ + if( item ) { + KMyListBoxItem* it = static_cast<KMyListBoxItem*>(item); + KFileItem* fileItem = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, it->url() ); + fileItem->run(); + delete fileItem; + } +} + +void KMyListBox::moveMode() +{ + if ( !moving ) { + moving = true; + KApplication::setOverrideCursor( Qt::sizeAllCursor ); + } +} + +void KMyListBox::select( QListBoxItem* item ) +{ + if( !ctrlPressed && !shiftPressed ) + /* Single click on the list box, + * make all items but the clicked + * one not selected */ + for( int i = 0; i < (signed int)count(); i++ ) + if( i != index(item) ) + setSelected( i, false ); + + if( shiftPressed ) { + if( currentItem() == -1 ) { + setSelected( item, !isSelected( item )); + setCurrentItem( item ); + return; + } + if( currentItem() > index(item) ) { + for( int i = index(item); i <= currentItem(); i++ ) + setSelected( i, !isSelected( i )); + setCurrentItem( item ); + } else if( currentItem() < index(item) ) { /* Works !*/ + for( int i = currentItem()+1; i <= index(item); i++ ) + setSelected( i, !isSelected( i )); + } else /* c == index(item) */ /* Works !*/ + setSelected( item, !isSelected( item )); + } else { + setSelected( item, !isSelected( item )); + setCurrentItem( item ); + } +} + +void KMyListBox::preview( KURL::List list ) +{ + KIO::PreviewJob* job = KIO::filePreview( list, previewSize, previewSize, 0, 100, false, true, 0 ); + connect( job, SIGNAL( gotPreview( const KFileItem*, const QPixmap &) ), this, SLOT( previewDone( const KFileItem*, const QPixmap &) ) ); + connect( job, SIGNAL( failed( const KFileItem*)), this, SLOT( previewFailed( const KFileItem* ) )); + connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( previewFinished() ) ); + KApplication::setOverrideCursor( Qt::waitCursor ); +} + +void KMyListBox::previewDone( const KFileItem* item, const QPixmap &pixmap ) +{ + for( unsigned int i = 0; i < count(); i++ ) + if( url( i ) == item->url() ) { + KMyListBoxItem* it = static_cast<KMyListBoxItem*>(this->item( i )); + if( it && !pixmap.isNull() ) { + it->setPixmap( pixmap ); + //updateItem( i ); + } + break; + } +} + +void KMyListBox::previewFailed( const KFileItem* item ) +{ + for( unsigned int i = 0; i < count(); i++ ) + if( url( i ) == item->url() ) { + KMyListBoxItem* it = static_cast<KMyListBoxItem*>(this->item( i )); + if( it ) { + it->setPixmap( item->pixmap( getPreviewSize(), KIcon::DefaultState ) ); + } + break; + } +} + +void KMyListBox::previewFinished() +{ + triggerUpdate( true ); //maybe false is enough + KApplication::restoreOverrideCursor(); +} + +void KMyListBox::setPreview( bool prv ) +{ + KMyListBoxItem::setPreview( prv ); + + if( prv ) { + KURL::List list; + for( unsigned int i = 0; i < count(); i++ ) { + KMyListBoxItem* it = static_cast<KMyListBoxItem*>(item( i ) ); + if( !it->hasPreview() ) + list.append( it->url() ); + } + preview( list ); + } +} + +void KMyListBox::setName( bool name ) +{ + KMyListBoxItem::setName( name ); + setPreview( KMyListBoxItem::preview() ); + + if( name ) { + setColumnMode( FixedNumber ); + } else { + setColumnMode( FitToWidth ); + } +} + +void KMyListBox::move( int i ) +{ + KApplication::restoreOverrideCursor(); + moving = false; + + if( !count() ) + return; + + int nbSelectedBefore = 0; + for( unsigned int j = 0 ; j < count() ; j++ ) { + if( isSelected( j ) ) { + if( j < (unsigned int)i ) + nbSelectedBefore++; + + KMyListBoxItem* item = new KMyListBoxItem( static_cast<KMyListBoxItem*>(this->item( j )) ); + removeItem( j ); + j--; + insertItem( item, i - nbSelectedBefore ); + } + } +} + +void KMyListBox::moveUp() +{ + if( count() == 0 ) + return; + + unsigned int i = 0; + setUpdatesEnabled( false ); + do { + if( isSelected( i ) && i ) { + moveUp( i ); + + setSelected( i-1, true ); + setCurrentItem( i-1 ); + } + i++; + } while( i < count() ); + setUpdatesEnabled( true ); +} + +void KMyListBox::moveUp( int i ) +{ + if( count() == 0 ) + return; + + KMyListBoxItem* item = new KMyListBoxItem( static_cast<KMyListBoxItem*>(this->item( i )) ); + removeItem( i ); + insertItem( item, i - 1 ); +} + +void KMyListBox::moveDown() +{ + if( count() == 0 ) + return; + + unsigned int i = count(); + setUpdatesEnabled( false ); + do { + i--; + if( isSelected( i ) && (i < count()) ) { + moveDown( i ); + setSelected( i+1, true ); + setCurrentItem( i+1 ); + } + } while( i > 0 ); + setUpdatesEnabled( true ); +} + +void KMyListBox::moveDown( int i ) +{ + if( count() == 0 ) + return; + + KMyListBoxItem* item = new KMyListBoxItem( static_cast<KMyListBoxItem*>(this->item( i )) ); + removeItem( i ); + insertItem( item, i + 1 ); +} + +bool KMyListBox::isInList( KURL text ) +{ + // TODO: faster find algorithm + for( unsigned int i = 0; i < count(); i++ ) { + KMyListBoxItem* it = dynamic_cast<KMyListBoxItem*>(item( i ) ); + if( it && it->url() == text ) { + return true; + } + } + + return false; +} + +void KMyListBox::customEvent( QCustomEvent* e ) +{ + if( e->type() == ThreadedLister::TYPE() ) + { + listerDone( (ThreadedLister*)e->data() ); + } +} + +void KMyListBox::listerDone( ThreadedLister* lister ) +{ + m_add_mutex.lock(); + + if( lister ) + delete lister; + KApplication::restoreOverrideCursor(); + + setUpdatesEnabled( false ); + setPreview( KMyListBoxItem::preview() ); + sortList(); + setUpdatesEnabled( true ); + + emit updateCount(); + emit updatePreview(); + + m_add_mutex.unlock(); +} + +unsigned int KMyListBox::runningAddListeners() +{ + unsigned int u; + + m_add_mutex.lock(); + u = m_running_lister_counter; + m_add_mutex.unlock(); + + return u; +} + +void KMyListBox::sortAscending() +{ + m_sorting = ASCENDING; + + sortList(); +} + +void KMyListBox::sortDescending() +{ + m_sorting = DESCENDING; + + sortList(); +} + +void KMyListBox::sortRandom() +{ + m_sorting = RANDOM; + + sortList(); +} + +void KMyListBox::sortUnsorted() +{ + m_sorting = UNSORTED; + + sortList(); +} + +void KMyListBox::sortNummeric() +{ + m_sorting = NUMMERIC; + + sortList(); +} + +void KMyListBox::sortList() +{ + KApplication::setOverrideCursor( Qt::WaitCursor ); + + if( m_sorting == ASCENDING ) + sort( true ); + else if( m_sorting == DESCENDING ) + sort( false ); + else if( m_sorting == RANDOM ) + { + unsigned int p = 0; + for( unsigned int i = 0;i<count();i++) + { + p = KApplication::random() % count(); + if( p != i ) // This prevents the creation of a new ListBoxItem + // on the same position as before. It would not change + // the position of item, but cost a little bit of speed + { + KMyListBoxItem* item = new KMyListBoxItem( static_cast<KMyListBoxItem*>(this->item( i )) ); + removeItem( i ); + insertItem( item, p ); + } + } + } + else if( m_sorting == NUMMERIC ) + { + // a very simple bubble sort which sorts filenames by a number inside them. + // if no number is found a lexical comparison is performed + unsigned int z = count(); + while( z-- ) + for( unsigned int i=1;i<=z;i++) + { + KURL url1 = url( i - 1 ); + KURL url2 = url( i ); + if( url1.directory() != url2.directory() ) + { + // different directory, do a lexical comparison + if( text( i - 1 ).compare( text( i ) ) >= 0 ) + moveDown( i - 1 ); + } + else + { + if( compareNummeric( url1.filename(), url2.filename() ) >= 0 ) + moveDown( i - 1 ); + } + } + } + + KApplication::restoreOverrideCursor(); +} + +void KMyListBox::setSorting( int s ) +{ + switch( s ) + { + default: + case UNSORTED: + sortUnsorted(); + break; + case ASCENDING: + sortAscending(); + break; + case DESCENDING: + sortDescending(); + break; + case RANDOM: + sortRandom(); + break; + case NUMMERIC: + sortNummeric(); + break; + } + + emit updatePreview(); +} + +int KMyListBox::compareNummeric( const QString & s1, const QString & s2 ) +{ + unsigned int z = 0; + unsigned int max = ( s1.length() > s2.length() ? s1.length() : s2.length() ); + + QString num1; + QString num2; + for( z=0;z<max;z++) + { + //if( z >= s1.length() || z >= s2.length() ) + // break; + + if( s1[z] != s2[z] ) + { + if( z < s1.length() && s1[z].isDigit() ) + num1 = findNumInString( z, s1 ); + + if( z < s2.length() && s2[z].isDigit() ) + num2 = findNumInString( z, s2 ); + + if( num1.isNull() && num2.isNull() ) + break; + + int a = num1.toInt(); + int b = num2.toInt(); + if( a == b ) + return s1.compare( s2 ); + else + return ( a > b ) ? 1 : -1; + } + } + + return s1.compare( s2 ); +} + +const QString KMyListBox::findNumInString( unsigned int pos, const QString & s ) +{ + QString num; + + for( int i = (int)pos; i >= 0; i-- ) + if( s[i].isDigit() ) + num.prepend( s[i] ); + else + break; + + + for( unsigned int i = pos + 1; i < s.length(); i++ ) + if( s[i].isDigit() ) + num.append( s[i] ); + else + break; + + return num; +} + +void KMyListBox::resizeEvent( QResizeEvent* e ) +{ + KListBox::resizeEvent( e ); + positionLabel(); +} + +void KMyListBox::clear() +{ + KListBox::clear(); + positionLabel(); +} + +void KMyListBox::positionLabel() +{ + if( count() ) + { + label->hide(); + } + else + { + int x = (width() - label->minimumSizeHint().width()) / 2; + int y = (height() - label->minimumSizeHint().height()) / 2; + label->setGeometry( x, y, label->minimumSizeHint().width(), label->minimumSizeHint().height() ); + label->show(); + } +} + +void KMyListBox::paintEvent( QPaintEvent* e ) +{ + // qDebug("Updates=%i", (int)isUpdatesEnabled() ); + //if( isUpdatesEnabled() ) + KListBox::paintEvent( e ); +} + +KMyListBoxItem::KMyListBoxItem( const KMyListBoxItem* item ) + : QListBoxItem() +{ + m_url = item->url(); + m_dir = item->dir(); + m_has_preview = false; + pm = *item->pixmap(); +} + +KMyListBoxItem::KMyListBoxItem( const KURL & u, bool b ) + : QListBoxItem() +{ + m_url = u; + m_dir = b; + m_has_preview = false; +} + +void KMyListBoxItem::setPixmap( const QPixmap & pix ) +{ + KMyListBox* box = static_cast<KMyListBox*>(this->listBox()); + pm.resize( box->getPreviewSize(), box->getPreviewSize() ); + pm.fill( box->colorGroup().base() ); + QPainter painter( &pm ); + painter.drawPixmap( (pm.width()-pix.width())/2, (pm.height()-pix.height())/2, pix ); + m_has_preview = true; +} + +void KMyListBoxItem::setName( bool b ) +{ + KMyListBoxItem::m_name = b; +} + +void KMyListBoxItem::setPreview( bool b ) +{ + KMyListBoxItem::m_preview = b; +} + +void KMyListBoxItem::paint( QPainter *painter ) +{ + if( !KMyListBoxItem::m_preview ) { + int itemHeight = height( listBox() ); + QFontMetrics fm = painter->fontMetrics(); + int yPos = ( ( itemHeight - fm.height() ) / 2 ) + fm.ascent(); + painter->drawText( 3, yPos, text() ); + } else { + int itemHeight = height( listBox() ); + int yPos; + + if( pm.isNull() ) { + KFileItem item( KFileItem::Unknown, KFileItem::Unknown, m_url ); + KMyListBox* box = static_cast<KMyListBox*>(this->listBox()); + setPixmap( item.pixmap( box->getPreviewSize(), KIcon::DefaultState ) ); + } + + yPos = ( itemHeight - pm.height() ) / 2; + if( !isSelected() ) + painter->drawPixmap( 3, yPos, pm); + else + { + KPixmap pix = KPixmapEffect::selectedPixmap( pm, listBox()->colorGroup().highlight() ); + painter->drawPixmap( 3, yPos, pix ); + } + + if( KMyListBoxItem::m_name && !m_url.isEmpty() ) { + QFontMetrics fm = painter->fontMetrics(); + yPos = ( ( itemHeight - fm.height() ) / 2 ) + fm.ascent(); + painter->drawText( pm.width() + 5, yPos, text() ); + } + } +} + +int KMyListBoxItem::height( const QListBox* lb ) const +{ + if( !KMyListBoxItem::m_preview ) { + int h = listBox() ? listBox()->fontMetrics().lineSpacing() + 2 : 0; + return QMAX( h, QApplication::globalStrut().height() ); + } else { + int h; + if ( KMyListBoxItem::m_name && !m_url.prettyURL().isEmpty() ) + h = pm.height(); + else + h = QMAX( pm.height(), lb->fontMetrics().lineSpacing() + 2 ); + + return QMAX( h, QApplication::globalStrut().height() ); + } +} + +int KMyListBoxItem::width( const QListBox* ) const +{ + if( !KMyListBoxItem::m_preview ) { + int w = listBox() ? listBox()->fontMetrics().width( text() ) + 6 : 0; + return QMAX( w, QApplication::globalStrut().width() ); + } else { + if ( m_url.path().isEmpty() || !KMyListBoxItem::m_name) + return QMAX( pm.width() + 6, QApplication::globalStrut().width() ); + + return QMAX( pm.width() + listBox()->fontMetrics().width( text() ) + 6, QApplication::globalStrut().width() ); + } +} + +QString KMyListBoxItem::text() const +{ + return m_url.prettyURL( 0, m_url.isLocalFile() ? KURL::StripFileProtocol : KURL::NoAdjustements ); +} + +bool KMyListBoxItem::m_preview = false; +bool KMyListBoxItem::m_name = false; + diff --git a/krename/kmylistbox.h b/krename/kmylistbox.h new file mode 100644 index 0000000..b0c7a64 --- /dev/null +++ b/krename/kmylistbox.h @@ -0,0 +1,186 @@ +/*************************************************************************** + kmylistbox.h - description + ------------------- + begin : Tue Oct 16 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYLISTBOX_H +#define KMYLISTBOX_H + +// KDE includes +#include <klistbox.h> +#include <kurl.h> +#include <kfileitem.h> + +// Qt includes +#include <qmutex.h> +#include <qstringlist.h> + +class ThreadedLister; + +class KFileItem; +class KURLLabel; +class QDragObject; +class QPixmap; +class QPainter; +class QPoint; +class KMyListBox : public KListBox { + Q_OBJECT + public: + enum { ASCENDING = 1, DESCENDING = 2, RANDOM = 3, NUMMERIC = 4, UNSORTED = 0 }; + + KMyListBox(QWidget* parent=0, const char* name=0, WFlags fl=0); + ~KMyListBox(); + + void removeItem( int index ); + void addDir( const KURL & dirname, const QString & m_filter, bool m_hidden, bool recursively, bool dirnames = false ); + void addDirName( const KURL & dirname, const QString & m_filter, bool m_hidden, bool recursive = false ); + void setPreview( bool prv ); + + inline int sorting() const { return m_sorting; } + + void setName( bool name ); + + void move( int i ); + void setPreviewSize( int size ); + inline int getPreviewSize() const { return previewSize; } + + KURL url( int index ) const; + bool dir( int index ) const; + + bool isFile( const KURL & f, bool autoadd = true ); + void positionLabel(); + + void clear(); + + /** + * returns the number of currently running ThreadedListers for adding files + * or 0 if there is no file adding in progress right now. + */ + unsigned int runningAddListeners(); + + public slots: + void moveMode(); + void moveDown(); + void moveDown( int i ); + void moveUp(); + void moveUp( int i ); + void setSorting( int s ); + + void addFile( const KURL & filename, bool isfile = false ); + void addDirName( const KURL & dirname ); + + signals: + // emited when new item is drag'n'dropped into listobox + // or when files are removed or something similar + void updateCount(); + void updatePreview(); + void deletePressed(); + void addFiles(); + + void currentlyAddingFiles(); + + private: + void preview( KURL::List list ); + + void dropEvent( QDropEvent* e ); + void dragEnterEvent( QDragEnterEvent* e ); + void viewportMousePressEvent( QMouseEvent* e ); + void viewportMouseReleaseEvent( QMouseEvent* e ); + void viewportMouseMoveEvent( QMouseEvent* e ); + void keyPressEvent( QKeyEvent* e ); + void keyReleaseEvent( QKeyEvent* e ); + + bool isInList( KURL text ); + + void sortAscending(); + void sortDescending(); + void sortUnsorted(); + void sortRandom(); + void sortNummeric(); + void sortList(); + void setButtonText(); + + int compareNummeric( const QString & s1, const QString & s2 ); + const QString findNumInString( unsigned int pos, const QString & s ); + + private slots: + void openFile( QListBoxItem* item ); + void select( QListBoxItem* item ); + + void previewDone( const KFileItem* item, const QPixmap &pixmap ); + void previewFailed( const KFileItem* item ); + void previewFinished(); + + void listerDone( ThreadedLister* lister ); + + protected: + void resizeEvent( QResizeEvent* e ); + void customEvent( QCustomEvent* e ); + void paintEvent( QPaintEvent* e ); + + bool drag; + bool mousePressed; + bool ctrlPressed; + bool shiftPressed; + bool moving; + int previewSize; + int m_sorting; + + unsigned int m_running_lister_counter; + QMutex m_add_mutex; + + KURLLabel* label; + + QDragObject* drobj; + QPoint presspos; +}; + +class KMyListBoxItem : public QListBoxItem { + public: + KMyListBoxItem( const KMyListBoxItem* item ); + KMyListBoxItem( const KURL&, bool ); + + bool hasPreview() const { return m_has_preview; } + + static void setName( bool b ); + static void setPreview( bool b ); + void setPixmap( const QPixmap & pix ); + + static bool preview() { return m_preview; } + static bool name() { return m_name; } + + inline bool dir() const { return m_dir; } + inline KURL url() const { return m_url; } + inline const QPixmap* pixmap() const { return ± } + + private: + QString text() const; + + protected: + virtual void paint( QPainter *painter ); + virtual int width( const QListBox* ) const; + virtual int height( const QListBox* lb ) const; + + private: + KURL m_url; + bool m_dir; + bool m_has_preview; + QPixmap pm; + + static bool m_preview; + static bool m_name; +}; + +#endif diff --git a/krename/kmylistview.cpp b/krename/kmylistview.cpp new file mode 100644 index 0000000..6c6cdbc --- /dev/null +++ b/krename/kmylistview.cpp @@ -0,0 +1,177 @@ +/*************************************************************************** + kmylistview.cpp - description + ------------------- + begin : Mit M� 27 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmylistview.h" +#include "myinputdialog.h" + +// KDE includes +#include <kiconloader.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <krun.h> + +KMyListView::KMyListView( QValueList<manualchanges>* _changes, KMyListBox* _list, QWidget* parent, const char* name ) + :KListView(parent, name ) +{ + changes = _changes; + list = _list; + + connect( this, SIGNAL( doubleClicked(QListViewItem*, const QPoint&, int) ), + this, SLOT( changeItem(QListViewItem*, const QPoint&, int) ) ); + connect( this, SIGNAL( contextMenuRequested(QListViewItem*, const QPoint&, int) ), + this, SLOT( showContext(QListViewItem*, const QPoint&, int) ) ); + setAllColumnsShowFocus( true ); +} + +KMyListView::~KMyListView() +{ } + + +void KMyListView::changeItem( QListViewItem* item, const QPoint&, int ) +{ + if(!item) return; + + KURL url = list->url( itemIndex( item ) ); + + bool revertenable = false; + QValueList<manualchanges>::iterator it; + for ( it = changes->begin(); it != changes->end(); ++it ) + if( (*it).url == url ) { + changes->remove( it ); + revertenable = true; + break; + } + + + MyInputDialog i( item->text( 1 ), revertenable ); + i.setInputFilename( item->text( 0 ) ); + + int code = i.exec(); + if( code == MyInputDialog::OK ) { + manualchanges tmp = { + url, + i.filename() + }; + + changes->append( tmp ); + emit itemChanged(); + } else if( code == MyInputDialog::USE_KRENAME ) + emit itemChanged(); +} + +void KMyListView::showContext( QListViewItem* item, const QPoint& pos, int ) +{ + KPopupMenu* menu = new KPopupMenu( this ); + if(item) { + menu->insertTitle( list->text( itemIndex( item ) ), 0, 0 ); + menu->insertItem( i18n("&Change Filename Manually"), this, SLOT( changeCurrentItem() ), Key_F2 ); + menu->insertSeparator(); + menu->insertItem( BarIcon("exec"), i18n("Open"), this, SLOT( openCurrent() ) ); + menu->insertSeparator(); + } + menu->insertItem( BarIcon("fileopen"), i18n("&Add..."), this, SLOT( addFiles() ) ); + if(item) + menu->insertItem( BarIcon("editdelete"), i18n("&Remove"), this, SLOT( removeCurrentItem() ) ); + + menu->popup( pos ); +} + +void KMyListView::removeCurrentItem() +{ + int index = itemIndex( currentItem() ); + emit removeItem( index ); +} + +void KMyListView::addFiles() +{ + emit addFile(); +} + +void KMyListView::changeCurrentItem() +{ + changeItem( currentItem(), QPoint( 0, 0 ), 0 ); +} + +void KMyListView::openCurrent() +{ + if( currentItem() ) + new KRun( list->text( itemIndex( currentItem() ) ) ); +} + +///////////////////////////////////////////////////////////// + +KMyListViewItem::KMyListViewItem(QListView *parent) + : KListViewItem(parent) +{ } + +KMyListViewItem::KMyListViewItem(QListViewItem *parent) + : KListViewItem(parent) +{ } + +KMyListViewItem::KMyListViewItem(QListView *parent, QListViewItem *after) + : KListViewItem(parent, after) +{ } + +KMyListViewItem::KMyListViewItem(QListViewItem *parent, QListViewItem *after) + : KListViewItem(parent, after) +{ } + +KMyListViewItem::KMyListViewItem(bool m, QListView *parent, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : KListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) +{ + modified = m; +} + +KMyListViewItem::KMyListViewItem(bool m, QListViewItem *parent, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : KListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) +{ + modified = m; +} + +KMyListViewItem::KMyListViewItem(bool m, QListView *parent, QListViewItem *after, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : KListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) +{ + modified = m; +} + +KMyListViewItem::KMyListViewItem(QListViewItem *parent, QListViewItem *after, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : KListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) +{ } + +KMyListViewItem::~KMyListViewItem() +{ } + +void KMyListViewItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + QColorGroup _cg( cg ); + QColor c = _cg.text(); + if( modified ) + _cg.setColor( QColorGroup::Text, Qt::red ); + + KListViewItem::paintCell( p, _cg, column, width, alignment ); + _cg.setColor( QColorGroup::Text, c ); +} + diff --git a/krename/kmylistview.h b/krename/kmylistview.h new file mode 100644 index 0000000..da1dd29 --- /dev/null +++ b/krename/kmylistview.h @@ -0,0 +1,94 @@ +/*************************************************************************** + kmylistview.h - description + ------------------- + begin : Mit M� 27 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYLISTVIEW_H +#define KMYLISTVIEW_H + +#include "batchrenamer.h" +#include "kmylistbox.h" +#include <klistview.h> +#include <qvaluelist.h> + +class QMouseEvent; +class KMyListView : public KListView { + Q_OBJECT + public: + KMyListView( QValueList<manualchanges>* _changes, KMyListBox* _list, QWidget* parent=0, const char* name=0 ); + ~KMyListView(); + + signals: + void itemChanged(); + void removeItem(int); + void addFile(); + + private slots: + void changeItem( QListViewItem* item, const QPoint&, int ); + void showContext( QListViewItem* item, const QPoint& pos, int ); + void removeCurrentItem(); + void addFiles(); + void changeCurrentItem(); + void openCurrent(); + + private: + QValueList<manualchanges>* changes; + KMyListBox* list; +}; + +///////////////////////////////////////////////////////////// +class QColor; +class QString; +class KMyListViewItem : public KListViewItem { + public: + KMyListViewItem(QListView *parent); + KMyListViewItem(QListViewItem *parent); + KMyListViewItem(QListView *parent, QListViewItem *after); + KMyListViewItem(QListViewItem *parent, QListViewItem *after); + + KMyListViewItem(bool m, QListView *parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null); + + KMyListViewItem(bool m, QListViewItem *parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null); + + KMyListViewItem(bool m, QListView *parent, QListViewItem *after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null); + + KMyListViewItem(QListViewItem *parent, QListViewItem *after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null); + + virtual ~KMyListViewItem(); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment ); + + private: + bool modified; +}; + + +#endif diff --git a/krename/krecursivelister.cpp b/krename/krecursivelister.cpp new file mode 100644 index 0000000..94d96b4 --- /dev/null +++ b/krename/krecursivelister.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + krecursivelister.cpp - description + ------------------- + begin : Fri Aug 31 2001 + copyright : (C) 2001 by Jonathon Sim + email : jonathonsim@iname.com +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <qtimer.h> + +#include "krecursivelister.h" + +KRecursiveLister::KRecursiveLister(QObject *parent, const char *name ) : QObject(parent,name) { + lister = 0L; + filelist.clear(); + dirlist.clear(); + dirtree.clear(); + allItems.setAutoDelete( true ); // only there to delete all items + m_hidden = false; + m_dirs = false; + m_filter = QString::null; +} + +KRecursiveLister::~KRecursiveLister(){ + delete lister; +} + +void KRecursiveLister::cleanUp() +{ + filelist.clear(); + dirlist.clear(); +} +/** Starts listing the specified url */ +void KRecursiveLister::openURL(const KURL& url ){ + filelist.clear(); + dirlist.clear(); + startListing(url); +} + +/** Returns the list of fileitems found. */ +const KFileItemList & KRecursiveLister::items(){ + return filelist; +} + +/** handles completion of a listing. */ +void KRecursiveLister::slotListingComplete(){ + KFileItemList templist=lister->items(); + + KFileItem * item; + KFileItem * newitem; + for( item = templist.first(); item != 0; item=templist.next() ) + { + if (item->isDir()) { + newitem= new KFileItem(*item); + dirlist.append(newitem);//Used for recursing the directories + dirtree.append(newitem);//Returned to user on request. + allItems.append(newitem); + } + else { + newitem= new KFileItem(*item); + filelist.append(newitem); + allItems.append(newitem); + } + } + + QTimer::singleShot( 0, this, SLOT( listNextDirectory() )); +} + +/** Starts listing the specified url */ +void KRecursiveLister::startListing(const KURL& url){ + if (!lister) { + lister=new KDirLister(true); + lister->setShowingDotFiles( m_hidden ); + lister->setNameFilter( m_filter ); + lister->setDirOnlyMode( m_dirs ); + connect(lister,SIGNAL(completed()), this, SLOT(slotListingComplete()) ); + } + + lister->openURL( url, false, false ); +} + +void KRecursiveLister::listNextDirectory() +{ + if ( dirlist.isEmpty() ) + emit completed(); + else + { + KFileItem * nextdir=dirlist.last(); + KURL url = nextdir->url(); + dirlist.removeLast(); + startListing( url ); + } +} + +/** Stops the listing */ +void KRecursiveLister::stop(){ + lister->stop(); +} + +/** Returns the subdirectories found by the listing */ +const KFileItemList& KRecursiveLister::dirs(){ + return dirtree; +} +#include "krecursivelister.moc" diff --git a/krename/krecursivelister.h b/krename/krecursivelister.h new file mode 100644 index 0000000..b470772 --- /dev/null +++ b/krename/krecursivelister.h @@ -0,0 +1,107 @@ +/*************************************************************************** + krecursivelister.h - description + ------------------- + begin : Fri Aug 31 2001 + copyright : (C) 2001 by Jonathon Sim + email : jonathonsim@iname.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRECURSIVELISTER_H +#define KRECURSIVELISTER_H + +#include <qwidget.h> +#include <qobject.h> +#include <kdirlister.h> +#include <kfileitem.h> +#include <qguardedptr.h> + +/**A convienience class that recursively lists a directory + *@author Jonathon Sim + * + * Modified by Dominik Seichter to support a name filter, + * dir only mode, support for showing hidden files on demand + * and support for listing directories along with files. + */ + +class KRecursiveLister : public QObject { + Q_OBJECT + +public: + KRecursiveLister(QObject *parent=0, const char *name=0); + ~KRecursiveLister(); + + /** Returns the list of fileitems found. */ + const KFileItemList & items(); + + /** sets wether hidden files shall be listed */ + inline void setShowingDotFiles( bool dotfiles ); + + /** filter to be used */ + inline void setNameFilter( const QString & filter ); + + /** list only directories */ + inline void setDirOnlyMode( bool dirsOnly ); + + /** Starts listing the specified url */ + void openURL(const KURL& url); + + /** Stops the listing */ + void stop(); + + /** Returns the subdirectories found by the listing */ + const KFileItemList& dirs(); + + void cleanUp(); + + signals: // Signals + /** Listing is complete */ + void completed(); + +protected slots: // Protected slots + + /** handles completion of a listing. */ + void slotListingComplete(); + void listNextDirectory(); + +protected: // Protected methods + /** Starts listing the specified url */ + void startListing(const KURL& url); + + //Protected variables + KFileItemList filelist; //Files found at url + KFileItemList dirlist; //Dirs remaining to list + KFileItemList dirtree; + KFileItemList allItems; + QGuardedPtr<KDirLister> lister; //The current KDirLister + + bool m_hidden; + bool m_dirs; + QString m_filter; +}; + +void KRecursiveLister::setShowingDotFiles( bool dotfiles ) +{ + m_hidden = dotfiles; +} + +void KRecursiveLister::setNameFilter( const QString & filter ) +{ + m_filter = filter; +} + +void KRecursiveLister::setDirOnlyMode( bool dirsOnly ) +{ + m_dirs = dirsOnly; +} + + +#endif diff --git a/krename/krename.desktop b/krename/krename.desktop new file mode 100644 index 0000000..8504a0b --- /dev/null +++ b/krename/krename.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Exec=krename -caption "%c" %i %m %U +Icon=krename.png +MiniIcon=krename.png +DocPath=krename/index.html +Comment=A batch renamer +Comment[de]=Ein Batch Umbenenner +Terminal=false +Name=KRename +Categories=Qt;KDE;Utility; diff --git a/krename/krename.h b/krename/krename.h new file mode 100644 index 0000000..830975a --- /dev/null +++ b/krename/krename.h @@ -0,0 +1,30 @@ +/*************************************************************************** + krename.h - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRENAME_H +#define KRENAME_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// Why the hell am I still using this file ? ;) +// -- Just for config.h and we need a sourcefile +// with KRename in its name, since krename.cpp +// is missing since version 0.1 + +#endif // KRENAME_H diff --git a/krename/krename_dir.desktop b/krename/krename_dir.desktop new file mode 100644 index 0000000..f605f49 --- /dev/null +++ b/krename/krename_dir.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Actions=Rename +Encoding=UTF-8 +ServiceTypes=inode/directory + +[Desktop Action Rename] +Exec=krename -r %U +Name=Rename with KRename +Name[de]=Mit KRename umbenennen +Name[es]=Renombrar con KRename +Name[fr]=Renommer avec KRename +Icon=krename diff --git a/krename/krename_system_default_tabbed.xml b/krename/krename_system_default_tabbed.xml new file mode 100644 index 0000000..82b6d50 --- /dev/null +++ b/krename/krename_system_default_tabbed.xml @@ -0,0 +1,11 @@ +<!DOCTYPE KRenameProfile> +<krename> + <version version="3.0.3rc1" /> + <settings fileplugins="1" wizard="0" /> + <filename extension_start="1" extension_enabled="1" extension="$" filename="$" > + <replace/> + <numbering step="1" start="1" skip="" /> + </filename> + <destination undoscript="" mode="2" undo="0" overwrite="0" directory="" /> + <files names="1" sorting="0" preview="0" /> +</krename> diff --git a/krename/krename_system_default_wizard.xml b/krename/krename_system_default_wizard.xml new file mode 100644 index 0000000..f796b31 --- /dev/null +++ b/krename/krename_system_default_wizard.xml @@ -0,0 +1,11 @@ +<!DOCTYPE KRenameProfile> +<krename> + <version version="3.0.3rc1" /> + <settings fileplugins="1" wizard="1" /> + <filename extension_start="1" extension_enabled="1" extension="$" filename="$" > + <replace/> + <numbering step="1" start="1" skip="" /> + </filename> + <destination undoscript="" mode="2" undo="0" overwrite="0" directory="" /> + <files names="1" sorting="0" preview="0" /> +</krename> diff --git a/krename/krenamedcop.h b/krename/krenamedcop.h new file mode 100644 index 0000000..7e4f4ed --- /dev/null +++ b/krename/krenamedcop.h @@ -0,0 +1,55 @@ +/*************************************************************************** + krenamedcop.h - description + ------------------- + begin : Sat Dec 27 23:54:28 CET 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRENAMEDCOP_H +#define KRENAMEDCOP_H + +#include <dcopobject.h> +#include <qstringlist.h> +#include <kurl.h> + +class KRenameDCOP : virtual public DCOPObject +{ + K_DCOP + + public: + k_dcop: + virtual void addFileOrDir( const QString & name ) = 0; + virtual void addDir( const QString & name, const QString & filter, bool recursive, bool hidden, bool dirnames ) = 0; + virtual void updatePre() = 0; + + virtual void setFileNameTemplate( const QString & t ) = 0; + virtual const QString fileNameTemplate() const = 0; + + virtual void setExtensionTemplate( const QString & t ) = 0; + virtual const QString extensionTemplate() const = 0; + + virtual void setUseExtension( bool b ) = 0; + virtual bool useExtension() const = 0; + + virtual void setCounterStart( int index ) = 0; + virtual int counterStart() const = 0; + + virtual void start() = 0; + + virtual QStringList tokens() const = 0; + + virtual QString parseString( const QString & token, const QString & string ) = 0; +}; + +#endif /* KRENAMEDCOP_H */ + diff --git a/krename/krenameimpl.cpp b/krename/krenameimpl.cpp new file mode 100644 index 0000000..e321185 --- /dev/null +++ b/krename/krenameimpl.cpp @@ -0,0 +1,1836 @@ +/*************************************************************************** + krenameimpl.cpp - description + ------------------- + begin : Die Mai 20 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "krenameimpl.h" + +// Own includes +#include "ProgressDialog.h" +#include "confdialog.h" +#include "fileoperation.h" +#include "kmylistview.h" +#include "kmyhistorycombo.h" +#include "pluginloader.h" +#include "replacedialog.h" +#include "undodialog.h" +#include "helpdialog.h" +#include "coorddialog.h" +#include "numberdialog.h" +#include "firststartdlg.h" +#include "wizard.h" +#include "tabs.h" +#include "dsdirselectdialog.h" +#include "krenamedcop.h" +#include "profiledlg.h" + +// KDE includes +#include <dcopclient.h> +#include <kaboutapplication.h> +#include <kapplication.h> +#include <kaction.h> +#include <kcmdlineargs.h> +#include <kdirselectdialog.h> +#include <kfiledialog.h> +#include <kfileitem.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kmenubar.h> +#include <kpopupmenu.h> +#include <kurlrequester.h> +#include <ktempfile.h> +#include <klocale.h> +#include <kio/netaccess.h> + +// QT includes +#include <qbuttongroup.h> +#include <qcursor.h> +#include <qgrid.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qrect.h> +#include <qregexp.h> +#include <qtabwidget.h> +#include <qtimer.h> +#include <qtooltip.h> +#include <qvgroupbox.h> +#include <qvbox.h> +#include <qvbuttongroup.h> +#include <qwidget.h> +#include <qwidgetstack.h> + +#define ID_WIZARD 2905 +#define ID_TAB 2904 + +QString pageTitle[] = { + I18N_NOOP( "F&iles" ), + I18N_NOOP( "Des&tination" ), + I18N_NOOP( "P&lugins" ), + I18N_NOOP( "File&name" ) +}; + +KPushButton* createButton( KGuiItem item, QWidget* parent ) +{ + return new KPushButton( item.iconSet(), item.text(), parent ); +} + +KRenameImpl::KRenameImpl( QWidget* p, KMenuBar* m, QPushButton* finish ) + : DCOPObject( "KRename" ), QObject( (QObject*)p ), + parent( p ), menuBar( m ), finishButton( finish ) +{ + m_hasCommandlineProfile = false; + + // Load Plugins + plugin = PluginLoader::instance(); + helpDialogData = new HelpDialogData(); + // Maybe parent instead of 0 but might crash when switching from wizard to tab mode + helpDialog = new HelpDialog( helpDialogData, NULL, NULL, false ); + + m_switching = false; + + kapp->dcopClient()->registerAs( kapp->name() ); + +} + +KRenameImpl::~KRenameImpl() +{ + delete helpDialog; +} + +int KRenameImpl::numRealTimePreview = -1; + +void KRenameImpl::setup( bool wizardmode ) +{ + parent->setCaption( "KRename" ); // "KRename by Dominik Seichter + setupActions(); + setupPages(); + updateCount(); + + connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( addFile() )); + connect( buttonRemoveAll, SIGNAL( clicked()), this, SLOT( clearList() )); + connect( buttonRemove, SIGNAL( clicked()), this, SLOT( removeFile() )); + connect( buttonHelp, SIGNAL( clicked()), this, SLOT( showTokenHelp() )); + connect( finishButton, SIGNAL( clicked()), this, SLOT( start() )); + + connect( checkExtension, SIGNAL( clicked()), this, SLOT( enableControls() )); + connect( optionRename, SIGNAL( clicked()), this, SLOT( enableControls() )); + connect( optionMove, SIGNAL( clicked()), this, SLOT( enableControls() )); + connect( optionCopy, SIGNAL( clicked()), this, SLOT( enableControls() )); + connect( optionLink, SIGNAL( clicked()), this, SLOT( enableControls() )); + connect( checkUndoScript, SIGNAL( clicked()), this, SLOT( enableControls() )); + + connect( fileList, SIGNAL( updateCount()), this, SLOT( updateCount() )); + connect( fileList, SIGNAL( updatePreview()), this, SLOT( updatePreview() )); + connect( fileList, SIGNAL( deletePressed()), this, SLOT( removeFile() )); + connect( fileList, SIGNAL( addFiles()), this, SLOT( addFile() )); + connect( buttonUp, SIGNAL( clicked()), fileList, SLOT( moveUp() )); + connect( buttonDown, SIGNAL( clicked()), fileList, SLOT( moveDown() )); + connect( buttonUp, SIGNAL( clicked()), this, SLOT( updatePreview() )); + connect( buttonDown, SIGNAL( clicked()), this, SLOT( updatePreview() )); + connect( buttonUp2, SIGNAL( clicked()), this, SLOT( moveUp() )); + connect( buttonDown2, SIGNAL( clicked()), this, SLOT( moveDown() )); + connect( buttonReplace, SIGNAL( clicked()), this, SLOT( replace() )); + connect( buttonEasyReplace, SIGNAL( clicked()), this, SLOT( replace() )); + connect( buttonCoord, SIGNAL( clicked()), this, SLOT( getCoordinates() )); + connect( comboSort, SIGNAL( activated(int)), fileList, SLOT( setSorting(int) )); + + connect( filename, SIGNAL( delayedTextChanged() ), this, SLOT( updatePreview() )); + connect( extemplate, SIGNAL( delayedTextChanged() ), this, SLOT( updatePreview() )); + connect( checkExtension, SIGNAL( clicked()), this, SLOT( updatePreview() )); + connect( comboExtension, SIGNAL( activated(int) ), this, SLOT( updatePreview() )); + connect( checkPreview, SIGNAL( clicked()), this, SLOT( toggleImagePreview() )); + connect( preview, SIGNAL( itemChanged() ), this, SLOT( updatePreview() )); + connect( preview, SIGNAL( removeItem(int) ), this, SLOT( removeFile(int) )); + connect( preview, SIGNAL( addFile() ), this, SLOT( addFile() )); + connect( undorequester, SIGNAL( urlSelected(const QString &)), this, SLOT( changeUndoScriptName() )); + connect( kapp, SIGNAL( aboutToQuit() ), this, SLOT( saveConfig() ) ); + connect( buttonMove, SIGNAL( clicked()), fileList, SLOT( moveMode() )); + connect( checkName, SIGNAL( clicked()), this, SLOT( toggleName() )); + connect( buttonNumber, SIGNAL( clicked()), this, SLOT( changeNumbers() )); + + // Load Configuration + loadConfig(); + page_1->setEnabled( true ); + KApplication::restoreOverrideCursor(); + + filename->setText( "$" ); // no i18n() ! ;) + extemplate->setText( "$" ); + + // do it now so that it can be overwritten by commandline args + setWizardMode( wizardmode ); + + parseCommandline(); + enableControls(); +} + +const QString KRenameImpl::title( int index ) const +{ + return i18n( pageTitle[index] ); +} + +void KRenameImpl::parseCommandline() +{ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + QCStringList optlist = args->getOptionList ( "r" ); + for (QCStringList::ConstIterator it=optlist.begin(); it!=optlist.end(); ++it) + { + + KURL url; + url.setPath( *it ); + fileList->addDir( url, "*", false, true, false ); + } + + //fileList->setUpdatesEnabled( false ); + //fileList->viewport()->setUpdatesEnabled( false ); + for( int i = 0; i < args->count(); i++) + fileList->addFile( args->url( i ) ); + //fileList->viewport()->setUpdatesEnabled( true ); + //fileList->setUpdatesEnabled( true ); + + // load the profile first, so that we do not overwrite other + // commandline settings + QCString templ = args->getOption( "profile" ); + if( !templ.isEmpty() ) + { + m_hasCommandlineProfile = true; + ProfileManager::loadProfile( QString( templ ), this ); + } + + if( !args->isSet( "previewitems" ) ) + numRealTimePreview = -1; + else + numRealTimePreview = QString( args->getOption( "previewitems" ) ).toInt(); + + templ = args->getOption( "template" ); + if( !templ.isEmpty() ) + filename->setText( templ ); + + templ = args->getOption( "extension" ); + if( !templ.isEmpty() ) + { + extemplate->setText( templ ); + checkExtension->setChecked( false ); + } + + templ = args->getOption( "copy" ); + if( !templ.isEmpty() ) + { + urlrequester->setURL( templ ); + optionCopy->setChecked( true ); + } + + templ = args->getOption( "move" ); + if( !templ.isEmpty() ) + { + urlrequester->setURL( templ ); + optionMove->setChecked( true ); + } + + QCStringList uselist = args->getOptionList ( "use-plugin" ); + if( !uselist.isEmpty() ) + { + for(unsigned int i = 0; i < uselist.count(); i++ ) + uselist[i] = uselist[i].lower(); + + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); + while ( it.current() ) + { + if( uselist.contains( (*it)->plugin->getName().lower().utf8() ) ) + (*it)->check->setChecked( true ); + + ++it; + } + + pluginHelpChanged(); + } + + bool startnow = args->isSet( "start" ); + + // Free some memory + args->clear(); + + enableControls(); + updateCount(); + updatePreview(); + + if( fileList->count() ) + { + // we got already filenames over the commandline, so show directly the last + // page of the wizard + emit showPage( m_wizard ? 3 : 4 ); + } + + if( startnow ) + { + // As file adding runs in a another trhread, + // there might be adding in progress but not yet + // all files in the list. + // so let's wait for file adding to finish first + // before starting. + while( fileList->runningAddListeners() > 0 ) + kapp->processEvents(); + + if( fileList->count() ) + // start renaming + QTimer::singleShot( 200, this, SLOT( start() ) ); + } +} + +void KRenameImpl::setupActions() +{ + KActionCollection* actionCollection = new KActionCollection( this ); + + KPopupMenu* mnuExtra = new KPopupMenu( parent ); + KPopupMenu* mnuSettings = new KPopupMenu( parent ); + KHelpMenu* mnuHelp = new KHelpMenu( parent ); + + menuBar->insertItem( i18n("E&xtras"), mnuExtra ); + mnuExtra->insertItem( i18n("&Profiles..."), this, SLOT( manageProfiles() ) ); + mnuExtra->insertSeparator(); + mnuExtra->insertItem( SmallIcon("undo"), i18n("&Undo Old Renaming Action..."), this, SLOT( undo() ) ); + menuBar->insertItem( i18n("&Settings"), mnuSettings ); + menuBar->insertSeparator(); + menuBar->insertItem( i18n("&Help"), mnuHelp->menu() ); + + KAction* prefAct = KStdAction::preferences( this, SLOT(preferences()), actionCollection ); + loadPlugins = new KAction( i18n("&Load KDE file plugins"), 0, this, SLOT( loadFilePlugins() ), actionCollection ); + KAction* reloadAct = new KAction( i18n("&Reload Plugin Data"), 0, this, SLOT( reloadFilePluginData() ), actionCollection ); + + prefAct->plug( mnuSettings ); + mnuSettings->insertSeparator(); + loadPlugins->plug( mnuSettings ); + reloadAct->plug( mnuSettings ); + + connect( mnuHelp, SIGNAL(showAboutApplication()), this, SLOT(about())); +} + +void KRenameImpl::setupPages() +{ + setupPage1(); + setupPage2(); + setupPage3(); + setupPage4(); + + // Disable dirname ;) + enableControls(); +} + +void KRenameImpl::setupPage1() +{ + page_1 = new QWidget( parent ); + + pageLayout = new QHBoxLayout( page_1, 11, 6 ); + Layout3 = new QVBoxLayout( 0, 0, 6 ); + Layout4 = new QHBoxLayout( 0, 0, 6 ); + Layout5 = new QVBoxLayout( 0, 0, 6 ); + + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + QSpacerItem* spacer2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + + fileList = new KMyListBox( page_1 ); + + buttonAdd = new KPushButton( page_1 ); + buttonAdd->setText( i18n( "&Add..." ) ); + + buttonRemove = new KPushButton( page_1 ); + buttonRemove->setText( i18n( "Re&move" ) ); + + buttonRemoveAll = new KPushButton( page_1 ); + buttonRemoveAll->setText( i18n( "R&emove All" ) ); + + comboSort = new KComboBox( false, page_1 ); + comboSort->insertItem( i18n("Sort: Unsorted") ); + comboSort->insertItem( i18n("Sort: Ascending") ); + comboSort->insertItem( i18n("Sort: Descending") ); + comboSort->insertItem( i18n("Sort: Random") ); + comboSort->insertItem( i18n("Sort: Numeric") ); + + checkPreview = new QCheckBox( page_1 ); + checkPreview->setText( i18n("&Preview") ); + + labelCount = new QLabel( page_1 ); + + buttonUp = new KPushButton( page_1 ); + buttonUp->setPixmap( BarIcon( "1uparrow" ) ); + + buttonDown = new KPushButton( page_1 ); + buttonDown->setPixmap( BarIcon( "1downarrow" ) ); + + checkName = new QCheckBox( page_1 ); + checkName->setText( i18n("&Display name") ); + + buttonMove = new KPushButton( page_1 ); + buttonMove->setPixmap( BarIcon( "move" ) ); + + Layout5->addWidget( buttonUp ); + Layout5->addWidget( buttonMove ); + Layout5->addWidget( buttonDown ); + + Layout4->addLayout( Layout5 ); + Layout4->addItem( spacer2 ); + + Layout3->addWidget( buttonAdd ); + Layout3->addWidget( buttonRemove ); + Layout3->addWidget( buttonRemoveAll ); + Layout3->addWidget( comboSort ); + Layout3->addWidget( checkPreview ); + Layout3->addWidget( checkName ); + Layout3->addWidget( labelCount ); + Layout3->addItem( spacer ); + Layout3->addLayout( Layout4 ); + Layout3->addItem( spacer ); + + pageLayout->addWidget( fileList ); + pageLayout->setStretchFactor( fileList, 2 ); + pageLayout->addLayout( Layout3 ); + + emit pageDone( page_1, i18n( pageTitle[0] ) ); + + QToolTip::add( buttonAdd, i18n( "Add one or more files or directories" ) ); + QToolTip::add( buttonRemove, i18n( "Remove selected files" ) ); + QToolTip::add( buttonRemoveAll, i18n( "Remove all files" ) ); + QToolTip::add( checkPreview, i18n( "Enable/disable preview of pictures." ) ); + QToolTip::add( labelCount, i18n( "Displays the number of files in the list." ) ); + QToolTip::add( buttonUp, i18n( "Move selected items up" )); + QToolTip::add( buttonDown, i18n( "Move selected items down" )); + QToolTip::add( checkName, i18n( "Enable/disable display of file name." ) ); + QToolTip::add( buttonMove, i18n( "Move selected items (select the new location with the mouse)" )); +} + +void KRenameImpl::setupPage2() +{ + page_2 = new QWidget( parent ); + + pageLayout_2 = new QVBoxLayout( page_2, 6, 6 ); + + QSpacerItem* spacer_3 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + groupOptions = new QButtonGroup( page_2 ); + groupOptions->setTitle( i18n( "O&ptions" ) ); + groupOptions->setColumnLayout(0, Qt::Vertical ); + groupOptions->layout()->setSpacing( 6 ); + groupOptions->layout()->setMargin( 11 ); + groupOptionsLayout = new QVBoxLayout( groupOptions->layout() ); + groupOptionsLayout->setAlignment( Qt::AlignTop ); + + optionRename = new QRadioButton( groupOptions ); + optionRename->setText( i18n( "&Rename input files" ) ); + optionRename->setChecked( true ); + + optionCopy = new QRadioButton( groupOptions ); + optionCopy->setText( i18n( "Cop&y files to destination directory" ) ); + + optionMove = new QRadioButton( groupOptions ); + optionMove->setText( i18n( "&Move files to destination directory" ) ); + + optionLink = new QRadioButton( groupOptions ); + optionLink->setText( i18n("Create symbolic &links in destination directory") ); + + dirname = new KMyHistoryCombo( false, groupOptions, "Path" ); + urlrequester = new KURLRequester( dirname, groupOptions ); + urlrequester->setMode( KFile::Directory | KFile::ExistingOnly ); + + checkOverwrite = new QCheckBox( groupOptions ); + checkOverwrite->setText( i18n( "&Overwrite existing files" ) ); + + groupOptionsLayout->addWidget( optionRename ); + groupOptionsLayout->addWidget( optionCopy ); + groupOptionsLayout->addWidget( optionMove ); + groupOptionsLayout->addWidget( optionLink ); + groupOptionsLayout->addWidget( urlrequester ); + groupOptionsLayout->addItem( spacer_3 ); + groupOptionsLayout->addWidget( checkOverwrite ); + + groupUndo = new QVGroupBox( page_2 ); + groupUndo->setTitle( i18n("&Undo Renaming") ); + + checkUndoScript = new QCheckBox( i18n("&Create an undo script"), groupUndo ); + + undorequester = new KURLRequester( groupUndo ); + undorequester->setEnabled( false ); + undorequester->setMode( KFile::File | KFile::LocalOnly ); + undorequester->setFilter( i18n("*.krename|KRename undo scripts (*.krename)\n" + "*|All Files (*)") ); + undorequester->fileDialog()->setOperationMode( KFileDialog::Saving ); + + pageLayout_2->addWidget( groupOptions ); + pageLayout_2->addWidget( groupUndo ); + pageLayout_2->addItem( spacer_3 ); + + emit pageDone( page_2, i18n( pageTitle[1] ) ); + + QToolTip::add( optionRename, i18n( "Input files will be renamed." ) ); + QToolTip::add( optionCopy, i18n( "Copies all files to the destination directory and renames them." ) ); + QToolTip::add( optionMove, i18n( "Moves all files to the destination directory and renames them." ) ); +} + +void KRenameImpl::setupPage3() +{ + page_3 = new KJanusWidget( parent, "janus", KJanusWidget::TreeList ); + page_3->setShowIconsInTreeList( true ); + page_3->setTreeListAutoResize( true ); + + setupTab1(); + + emit pageDone( page_3, i18n( pageTitle[2] ) ); +} + +void KRenameImpl::setupPage4() +{ + page_4 = new QWidget( parent ); + pageLayout_4 = new QVBoxLayout( page_4, 11, 6 ); + + fileTab = new QWidgetStack( page_4 ); + setupFileTab1(); + setupFileTab2(); + + Layout22 = new QHBoxLayout( 0, 0, 6 ); + Layout23 = new QVBoxLayout( 0, 0, 6 ); + + preview = new KMyListView( &changes, fileList, page_4 ); + preview->setSorting( -1 ); + preview->addColumn( i18n( "Origin" ) ); + preview->addColumn( i18n( "Renamed" ) ); + + buttonUp2 = new KPushButton( page_4 ); + buttonUp2->setPixmap( BarIcon( "1uparrow" ) ); + + buttonDown2 = new KPushButton( page_4 ); + buttonDown2->setPixmap( BarIcon( "1downarrow" ) ); + + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding ); + + Layout23->addItem( spacer ); + Layout23->addWidget( buttonUp2 ); + Layout23->addWidget( buttonDown2 ); + Layout23->addItem( spacer ); + + Layout22->addWidget( preview ); + Layout22->addLayout( Layout23 ); + Layout22->setStretchFactor( preview, 2 ); + + pageLayout_4->addWidget( fileTab ); + pageLayout_4->addLayout( Layout22 ); + + emit pageDone( page_4, i18n( pageTitle[3] ) ); + + QToolTip::add( filename, i18n( "Add a template.<br>Example: <i>picture###</i>" ) ); + QToolTip::add( extemplate, i18n( "Add a template for the file extension.<br>It behaves like the filename template.") ); + QToolTip::add( checkExtension, i18n("Checking this checkbox is the same as setting the extension template to $")); + QToolTip::add( buttonUp2, i18n( "Move selected items up" )); + QToolTip::add( buttonDown2, i18n( "Move selected items down" )); + QToolTip::add( preview, i18n( "Double click on an item to modify it." )); + QToolTip::add( buttonHelp, i18n("Help Dialog with all tokens supported by KRename.")); + QToolTip::add( buttonReplace, i18n("<qt>Find and replace characters or part string of the source filename in the destination filename.</qt>") ); + QToolTip::add( buttonEasyReplace, i18n("<qt>Find and replace characters or part string of the source filename in the destination filename.</qt>") ); + QToolTip::add( comboExtension, i18n("<qt>You can use \".gz\" and \".tar.gz\" as file extension of the file backup.tar.gz depending on this setting.</qt>") ); +} + +void KRenameImpl::setupFileTab1() +{ + QWidget* tab = new QWidget( fileTab ); + + labelTemplate = new QLabel( tab ); + labelTemplate->setText( i18n( "&Template:" ) ); + + filename = new KMyHistoryCombo( true, tab, "Template" ); + labelTemplate->setBuddy( filename ); + + QLabel* labelDot = new QLabel( tab ); + labelDot->setText("<b>.</b>"); + + extemplate = new KMyHistoryCombo( true, tab, "ExTemplate" ); + extemplate->setEnabled( FALSE ); + + buttonHelp = new KPushButton( i18n("&Functions..."), tab ); + buttonHelp->setIconSet( SmallIcon("help") ); + + checkExtension = new QCheckBox( tab ); + checkExtension->setText( i18n( "&Use extension of the input file" ) ); + checkExtension->setChecked( TRUE ); + + comboExtension = new KComboBox( false, tab ); + + buttonReplace = new KPushButton( i18n("Find &and Replace..."), tab ); + buttonReplace->setIconSet( SmallIconSet("find") ); + + buttonNumber = new KPushButton( i18n("&Numbering..."), tab ); + buttonCoord = new KPushButton( i18n("&Insert Part of Filename..."), tab ); + + helpDialog->setLineEdit( filename->lineEdit() ); + + QStringList help; + help.append("$;;" + i18n("old filename") ); + help.append("%;;" + i18n("old filename converted to lower case") ); + help.append("&;;" + i18n("old filename converted to upper case") ); + help.append("*;;" + i18n("first letter of every word upper case") ); + help.append("[&1][%2-];;" + i18n("first letter of filename upper case") ); + help.append("#;;" + i18n("number (try also ##, ###, ... for leading zeros)") ); + help.append("#{0;1};;" + i18n("counter with custom start value 0 and custom stepping 1") ); + help.append("/;;" + i18n("create a subdirectory") ); + help.append("\\;;" + i18n("strip whitespaces leading and trailing") ); + help.append("[$x-y];;" + i18n("character x to y of old filename") ); + help.append("[$x;y];;" + i18n("y characters of old filename starting at x") ); + help.append("[$dirname];;" + i18n("insert name of directory") ); + help.append("[$dirname.];;" + i18n("insert name of parent directory") ); + help.append("[#length-0];;" + i18n("insert the length of the input filename") ); + helpDialogData->add( i18n("Built-in Functions:" ), &help, SmallIcon("krename"), true ); + + help.clear(); + help.append( "\\$;;" + i18n("Insert '$'") ); + help.append( "\\%;;" + i18n("Insert '%'") ); + help.append( "\\&;;" + i18n("Insert '&'") ); + help.append( "\\*;;" + i18n("Insert '*'") ); + help.append( "\\/;;" + i18n("Insert '/'") ); + help.append( "\\\\;;" + i18n("Insert '\\\\'") ); + help.append( "\\[;;" + i18n("Insert '['") ); + help.append( "\\];;" + i18n("Insert ']'") ); + help.append( "\\#;;" + i18n("Insert '#'") ); + helpDialogData->add( i18n("Special Characters:" ), &help, SmallIcon("krename") ); + + /* + //TODO: FIX this tooltip + QToolTip::add( buttonHelp, + i18n( + "<b>$</b> old filename<br><b>%</b> old filename" + " converted to lower case<br><b>&</b> old filename converted to upper case<br>" + "<b>*</b> first letter of every word uppercase<br>" + "<b>#</b> Adds a number to the filename (add more #'s for leading zeros)<br>" + "<b>/</b> creates a subdirectory<br>" + "<b>[$x-y]</b> Characters x to y of the old filename<br>" + "<b>[%x-y]</b> Characters x to y converted to lower case" + ) ); + */ + + QSpacerItem* spacer_9 = new QSpacerItem( 200, 20, QSizePolicy::Maximum, QSizePolicy::Maximum ); + + QVBoxLayout* layout = new QVBoxLayout( tab ); + QHBoxLayout* Layout1 = new QHBoxLayout( 0, 6, 6 ); + QHBoxLayout* Layout2 = new QHBoxLayout( 0, 6, 6 ); + QHBoxLayout* ExtensionLayout = new QHBoxLayout( 0, 6, 6 ); + + Layout1->addWidget( labelTemplate ); + Layout1->addWidget( filename ); + Layout1->setStretchFactor( filename, 4 ); + Layout1->addWidget( labelDot ); + Layout1->addWidget( extemplate ); + Layout1->addWidget( buttonHelp ); + + Layout2->addWidget( buttonReplace ); + Layout2->addWidget( buttonNumber ); + Layout2->addWidget( buttonCoord ); + Layout2->addItem( spacer_9 ); + + ExtensionLayout->addWidget( checkExtension ); + ExtensionLayout->addItem( spacer_9 ); + ExtensionLayout->addWidget( new QLabel( i18n("File extension starts at:"), tab ) ); + ExtensionLayout->addWidget( comboExtension ); + + layout->addLayout( Layout1 ); + layout->addLayout( ExtensionLayout ); + layout->addLayout( Layout2 ); + layout->addItem( spacer_9 ); + + fileTab->addWidget( tab, ID_TAB ); +} + +void KRenameImpl::setupFileTab2() +{ + QWidget* tab = new QWidget( page_4 ); + + QHBoxLayout* layout = new QHBoxLayout( tab, 6, 6 ); + + QVGroupBox* vgroup1 = new QVGroupBox( i18n("&Filename"), tab ); + QGrid* grid = new QGrid( 4, vgroup1 ); + + QLabel* l = new QLabel( i18n("&Prefix:"), grid ); + comboKRenamePrefix = new KComboBox( false, grid ); + comboPrefix = new KMyHistoryCombo( true, grid, "comboPrefix" ); + buttonEasy1 = new KPushButton( grid ); + l->setBuddy( comboPrefix ); + + l = new QLabel( i18n("&Suffix:"), grid ); + comboKRenameSuffix = new KComboBox( false, grid, "comboSuffix" ); + comboSuffix = new KMyHistoryCombo( true, grid ); + buttonEasy2 = new KPushButton( grid ); + l->setBuddy( comboSuffix ); + + QStringList comboItems; + comboItems.append( i18n("Convert to lower case ") ); + comboItems.append( i18n("Convert to upper case") ); + comboItems.append( i18n("Capitalize") ); + + l = new QLabel( i18n("&Name:"), grid ); + comboKRenameFilename = new KComboBox( false, grid ); + comboKRenameFilename->insertItem( i18n("Use original name") ); + comboKRenameFilename->insertStringList( comboItems ); + comboKRenameFilename->insertItem( i18n("Custom name") ); + l->setBuddy( comboKRenameFilename ); + + comboCustom = new KMyHistoryCombo( true, grid, "comboCustom" ); + buttonEasy3 = new KPushButton( grid ); + + l = new QLabel( i18n("&Extension:"), grid ); + comboKRenameExtension = new KComboBox( false, grid ); + comboKRenameExtension->insertItem( i18n("Use original extension") ); + comboKRenameExtension->insertStringList( comboItems ); + comboKRenameExtension->insertItem( i18n("Custom extension") ); + l->setBuddy( comboKRenameExtension ); + + comboCustomExtension = new KMyHistoryCombo( true, grid, "comboCustomExtension" ); + buttonEasy4 = new KPushButton( grid ); + + QVBox* rightBox = new QVBox( tab ); + QVGroupBox* group = new QVGroupBox( i18n("&Number" ), rightBox ); + + spinStart = new KIntNumInput( group ); + spinStart->setLabel( i18n( "Start &index:" ), AlignLeft | AlignVCenter ); + + spinNull = new KIntNumInput( spinStart, 1, group ); + spinNull->setLabel( i18n("&Number of digits:"), AlignLeft | AlignVCenter ); + spinNull->setRange( 1, 100, 1, false ); + + buttonEasyReplace = new KPushButton( i18n("&Find and Replace..."), rightBox ); + buttonEasyReplace->setIconSet( SmallIconSet("find") ); + + layout->addWidget( vgroup1 ); + layout->addWidget( rightBox ); + + comboKRenamePrefix->insertItem( "" ); + comboKRenamePrefix->insertItem( i18n("Number") ); + comboKRenamePrefix->insertItem( i18n("Date") ); + + comboKRenameSuffix->insertItem( "" ); + comboKRenameSuffix->insertItem( i18n("Number") ); + comboKRenameSuffix->insertItem( i18n("Date") ); + + enableControls(); + + connect( comboPrefix, SIGNAL( textChanged( const QString &)), this, SLOT( changed())); + connect( comboSuffix, SIGNAL( textChanged( const QString &)), this, SLOT( changed())); + connect( comboKRenameFilename, SIGNAL( activated(int)), this, SLOT( changed())); + connect( comboCustom, SIGNAL( textChanged( const QString & ) ), this, SLOT( changed() )); + connect( comboKRenamePrefix, SIGNAL(activated(int)), this, SLOT(changed())); + connect( comboKRenameExtension, SIGNAL( activated(int)), this, SLOT( changed())); + connect( comboCustomExtension, SIGNAL( textChanged( const QString & ) ), this, SLOT( changed() )); + connect( comboKRenameSuffix, SIGNAL(activated(int)), this, SLOT(changed())); + connect( spinNull, SIGNAL( valueChanged(int) ), this, SLOT( changed() )); + connect( spinStart, SIGNAL( valueChanged(int) ), this, SLOT( changed() )); + + buttonEasy1->setIconSet( SmallIcon("help") ); + buttonEasy2->setIconSet( SmallIcon("help") ); + buttonEasy3->setIconSet( SmallIcon("help") ); + buttonEasy4->setIconSet( SmallIcon("help") ); + + buttonEasy1->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + buttonEasy2->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + buttonEasy3->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + buttonEasy4->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + + const QString easy_text( i18n("<qt>Insert a special KRename command which inserts file information into the filename.</qt>") ); + + connect( buttonEasy1, SIGNAL( clicked() ), this, SLOT( slotEasy1() ) ); + connect( buttonEasy2, SIGNAL( clicked() ), this, SLOT( slotEasy2() ) ); + connect( buttonEasy3, SIGNAL( clicked() ), this, SLOT( slotEasy3() ) ); + connect( buttonEasy4, SIGNAL( clicked() ), this, SLOT( slotEasy4() ) ); + + QToolTip::add( buttonEasy1, easy_text ); + QToolTip::add( buttonEasy2, easy_text ); + QToolTip::add( buttonEasy3, easy_text ); + QToolTip::add( buttonEasy4, easy_text ); + + fileTab->addWidget( tab, ID_WIZARD ); +} + +QString KRenameImpl::easyOptions( KComboBox* combo, KMyHistoryCombo* custom ) +{ + QString t = QString::null; + if( combo->currentItem() == 0 ) + t = "$"; + else if( combo->currentItem() == 1 ) + t = "%"; + else if( combo->currentItem() == 2 ) + t = "&"; + else if( combo->currentItem() == 3 ) + t = "*"; + else if( combo->currentItem() == 4 ) + t = custom->text(); + + return t; +} + +void KRenameImpl::changed() +{ + QString t = easyOptions( comboKRenameFilename, comboCustom ); + t = comboPrefix->text() + t + comboSuffix->text(); + + for( int i=0; i<spinNull->value();i++) + { + if( comboKRenamePrefix->currentItem() == 1 ) + t.prepend("#"); + if( comboKRenameSuffix->currentItem() == 1 ) + t.append("#"); + } + + if( comboKRenamePrefix->currentItem() == 2 ) + t.prepend( "[date]" ); + + if( comboKRenameSuffix->currentItem() == 2 ) + t.append( "[date]" ); + + QString e = easyOptions( comboKRenameExtension, comboCustomExtension ); + + bool update = false; + update = ( counterStart() != spinStart->value() && t == fileNameTemplate() ); + setCounterStart( spinStart->value() ); + + filename->setText( t ); + extemplate->setText( e ); + checkExtension->setChecked( (comboKRenameExtension->currentItem() == 0) ); + + if( update ) + updatePre(); + + enableControls(); +} + +void KRenameImpl::parseWizardMode() +{ + /** This function is not very accrurate and + * guesses most cases. + * But it works pretty well and is IMHO enough for this + * simple dialog. + */ + QString t = filename->text(); + + spinNull->setValue( t.contains( "#" ) ); + + if( t.startsWith( "[date]") ) + { + t = t.right( t.length() - 6 ); + comboKRenamePrefix->setCurrentItem( 2 ); + } + else if( t.startsWith( "#") ) + { + while( t.startsWith( "#" ) ) + t = t.right( t.length() - 1 ); + comboKRenamePrefix->setCurrentItem( 1 ); + } + + if( t.endsWith( "[date]" ) ) + { + t = t.left( t.length() - 6 ); + comboKRenameSuffix->setCurrentItem( 2 ); + } + else if( t.endsWith( "#") ) + { + while( t.endsWith( "#" ) ) + t = t.left( t.length() - 1 ); + + comboKRenameSuffix->setCurrentItem( 1 ); + } + + int pos = -1; + if( (pos = t.find( "$" )) > -1 ) + comboKRenameFilename->setCurrentItem( 0 ); + else if( (pos = t.find( "%" )) > -1 ) + comboKRenameFilename->setCurrentItem( 1 ); + else if( (pos = t.find( "&" )) > -1 ) + comboKRenameFilename->setCurrentItem( 2 ); + else if( (pos = t.find( "*" )) > -1 ) + comboKRenameFilename->setCurrentItem( 3 ); + else + { + comboKRenameFilename->setCurrentItem( 4 ); + comboCustom->setText( t ); + } + + if( pos > 0 ) + { + comboPrefix->setText( t.left( pos ) ); + comboSuffix->setText( t.mid( pos + 1, t.length() - pos - 1) ); + } + + spinStart->setValue( m_index ); +} + +void KRenameImpl::setupTab1() +{ + /* + * Draw plugin user interfaces + */ + + QFrame* parent; + QVBoxLayout* Layout; + QVBoxLayout* gLayout; + QGroupBox* g; + QWidget* page; + + /* strangely I do not have to delete this stuff + * after plugins have been reloaded. + * could cause a memory leak though + */ + while( ( page = page_3->pageWidget( 0 ) ) ) + page_3->removePage( page ); + + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); // iterator for dict + while ( it.current() ) { + if( !(*it)->plugin->alwaysUsed() ) + { + parent = page_3->addPage( (*it)->plugin->getName(), QString::null, (*it)->plugin->getIcon() ); + + Layout = new QVBoxLayout( parent, 11, 6, "Layout"); + g = new QGroupBox( parent ); + gLayout = new QVBoxLayout( g, 11, 6, "gLayout" ); + + (*it)->check = new QCheckBox( i18n("&Use this plugin"), parent ); + connect( (*it)->check, SIGNAL( clicked() ), this, SLOT( pluginHelpChanged() ) ); + connect( (*it)->plugin, SIGNAL( previewChanged( Plugin* ) ), this, SLOT( updatePluginPreview( Plugin* ) ) ); + Layout->addWidget( (*it)->check ); + (*it)->plugin->drawInterface( g, gLayout ); + + Layout->addWidget( g ); + + } else + (*it)->plugin->addHelp( helpDialogData ); + + ++it; + } + + page_3->showPage( 1 ); +} + +void KRenameImpl::addFile() +{ + bool auto_up = false; + + DSDirSelectDialog* dsd = new DSDirSelectDialog( parent ); + if( dsd->exec() == QDialog::Accepted ) { + KURL::List slist = dsd->selectedURLs(); + KURL::List::Iterator it = slist.begin(); + + for ( ; it != slist.end(); ++it ) + { + if( !fileList->isFile( *it, false ) ) + { + if( dsd->onlyDirs() ) + fileList->addDirName( *it, dsd->currentFilter(), dsd->hidden(), dsd->recursively() ); + else + fileList->addDir( *it, dsd->currentFilter(), dsd->hidden(), dsd->recursively(), dsd->dirs() ); + } + else + { + fileList->addFile( *it, true ); + auto_up = true; + } + } + + if( auto_up ) + { + updatePreview(); + updateCount(); + } + } +} + +void KRenameImpl::clearList() +{ + fileList->clear(); + changes.clear(); + updateCount(); + updatePreview(); +} + +void KRenameImpl::removeFile() +{ + unsigned int i = 0; + do { + if(fileList->isSelected( i )) + removeFile( i ); + else + i++; + } while( i < fileList->count() ); + + updateCount(); + updatePreview(); +} + +void KRenameImpl::removeFile( int index ) +{ + KURL url = fileList->url( index ); + fileList->removeItem( index ); + // we have this to display the add files url label when count() == 0 + fileList->positionLabel(); + // remove this file from changes, too + for( unsigned int i = 0; i < changes.count(); i++ ) + if( changes[i].url == url ) + changes.remove( changes.at( i ) ); + + updateCount(); + updatePreview(); +} + +void KRenameImpl::help() +{ + kapp->invokeHelp(); +} + +void KRenameImpl::start() +{ + if(!checkErrors()) + return; + + // Let the plugins check for erorrs + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); + while ( it.current() ) { + if( (*it)->usePlugin && !(*it)->plugin->checkError() ) + return; + ++it; + } + + ProgressDialog* p = new ProgressDialog( 0, "p" ); + p->print(QString( i18n("Starting conversion of %1 files.") ).arg(fileList->count())); + + // Save History + dirname->saveSettings(); + filename->saveSettings(); + extemplate->saveSettings(); + + KConfig * config = kapp->config(); + config->setGroup("FileExtension"); + config->writeEntry("FileExtensionCombo", comboExtension->currentItem() ); + + // save the configuration + saveConfig(); + + b = new BatchRenamer(); + if( setupBatchRenamer( b, false ) ) + { + p->show(); + parent->hide(); + b->processFiles( p, this ); + } + + // Memory leak!!! : ?? + //delete parent; +} + +void KRenameImpl::enableControls() +{ + comboCustom->setEnabled( comboKRenameFilename->currentItem() == 4 ); + comboCustomExtension->setEnabled( comboKRenameExtension->currentItem() == 4 ); + buttonEasy3->setEnabled( comboKRenameFilename->currentItem() == 4 ); + buttonEasy4->setEnabled( comboKRenameExtension->currentItem() == 4 ); + urlrequester->setEnabled( !optionRename->isChecked() ); + checkUndoScript->setEnabled( !optionCopy->isChecked() && !optionLink->isChecked() ); + undorequester->setEnabled( checkUndoScript->isChecked() && checkUndoScript->isEnabled() ); + extemplate->setEnabled( !checkExtension->isChecked() ); + loadPlugins->setEnabled( !plugin->filePluginsLoaded() ); +} + +bool KRenameImpl::checkErrors() +{ + if( filename->text().isEmpty() ) { + KMessageBox::sorry( parent, i18n("Specify a template to use for renaming files.") ); + return false; + } + if( dirname->text().isEmpty() && !optionRename->isChecked()) { + KMessageBox::sorry( parent, i18n("Please give a destination directory !") ); + emit showPage( 2 ); + return false; + } + if( checkUndoScript->isChecked() && !optionCopy->isChecked() && undorequester->url().isEmpty() ) { + KMessageBox::sorry( parent, i18n("Please give the name of the undo script!") ); + showPage( 2 ); + return false; + } + + return true; +} + +void KRenameImpl::updateCount() +{ + labelCount->setText( QString( i18n("Files: <b>%1</b>") ).arg(fileList->count())); + + buttonCoord->setEnabled( (bool)fileList->count() ); + buttonReplace->setEnabled( (bool)fileList->count() ); + buttonEasyReplace->setEnabled( (bool)fileList->count() ); + emit enableFinish( (bool)fileList->count() ); + buttonRemove->setEnabled( (bool)fileList->count() ); + buttonRemoveAll->setEnabled( (bool)fileList->count() ); + buttonMove->setEnabled( (bool)fileList->count() ); + buttonUp->setEnabled( (bool)fileList->count() ); + buttonUp2->setEnabled( (bool)fileList->count() ); + buttonDown->setEnabled( (bool)fileList->count() ); + buttonDown2->setEnabled( (bool)fileList->count() ); + + updateDots(); +} + +void KRenameImpl::fillStructures( BatchRenamer* b, bool preview ) +{ + QValueList<data> f; + unsigned int max = (preview && KRenameImpl::numRealTimePreview > -1 ? KRenameImpl::numRealTimePreview : fileList->count()); + + for( unsigned int i = 0; i < max; i++) { + KURL url = fileList->url( i ); + QFileInfo fi( url.path() ); + + data fdata; + fdata.dir = fileList->dir( i ); + if( !fdata.dir ) { + splitFilename( &fi, &fdata.src.name, &fdata.src.extension ); + } else { + fdata.src.name = BatchRenamer::findDirName( "dirname", url.path() ); + fdata.src.extension = ""; + } + + fdata.src.url = url; + + /* Let's do some error checking for files + * called: file_xy. + */ + if( url.path().right(1) == "." ) + // File ends with a dot + fdata.src.name.append( "." ); + + fdata.src.directory = fi.dirPath( true ); + if( fdata.src.directory.right(1) != "/" ) + fdata.src.directory.append("/"); + + f.append( fdata ); + } + + /* + * Tell plugins that they should fill their structure, too. + * Check also which plugins should be used ! + */ + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); + for( int z = 0; it.current(); ++it, z++ ) { + if( (*it)->plugin->alwaysUsed() || ((*it)->check && (*it)->check->isChecked()) ) + (*it)->plugin->fillStructure(); + } + + b->setFiles( f ); +} + +void KRenameImpl::updatePre() +{ + updatePreview(); + updateCount(); + toggleImagePreview(); +} + +void KRenameImpl::addFileOrDir( const QString & name ) +{ + fileList->addFile( name, false ); +} + +void KRenameImpl::addFileOrDir( const KURL & name ) +{ + fileList->addFile( name, true ); +} + +bool KRenameImpl::setupBatchRenamer( BatchRenamer* b, bool preview ) +{ + b->setText( filename->text() ); + b->setExText( ( checkExtension->isChecked() ? QString("$") : extemplate->text() ) ); + b->setIndex( m_index ); + b->setResetCounter( m_reset ); + b->setStep( m_step ); + b->setSkipList( skip ); + b->setReplaceList( rep ); + b->setChanges( changes ); + + if( !preview ) { + QString url = urlrequester->url(); + if( url.right(1) != "/" ) + url.append( "/" ); + + if( !KIO::NetAccess::exists( KURL( url ) ) ) + { + int m = KMessageBox::warningContinueCancel( parent, i18n("The directory %1 does not exist. " + "KRename will create it for you.").arg( url ) ); + if( m == KMessageBox::Cancel ) + return false; + + int i = 0; + QString d = "/"; + while( (d += url.section( "/", i, i, QString::SectionSkipEmpty )) && ! d.isEmpty() ) { // asignment here! + if( !KIO::NetAccess::exists( d ) && !KIO::NetAccess::mkdir( d ) ) + { + qDebug( "Can't create %s", d.latin1() ); + break; + } + d.append( "/" ); + i++; + } + } + + b->setDirname( url ); + b->setOverwrite( checkOverwrite->isChecked() ); + b->setUndo( checkUndoScript->isChecked() && !optionCopy->isChecked() ); + if( checkUndoScript->isChecked() && !optionCopy->isChecked() ) + b->setUndoScript( undorequester->url() ); + + b->setMode( currentRenameMode() ); + } + + fillStructures( b, preview ); + return true; +} + +int KRenameImpl::currentRenameMode() +{ + if( optionCopy->isChecked() ) + return COPY; + else if( optionMove->isChecked() ) + return MOVE; + else if( optionRename->isChecked() ) + return RENAME; + else if( optionLink->isChecked() ) + return LINK; + // prevent a compiler warning + return RENAME; +} + +void KRenameImpl::updatePluginPreview( Plugin* p ) +{ + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); // iterator for dict + while ( it.current() ) { + if( (*it)->plugin == p && (*it)->usePlugin ) { + updatePreview(); + return; + } + + ++it; + } +} + +void KRenameImpl::updatePreview() +{ + // is there a number in the filename or extension + if( filename->text().contains( "#" ) || extemplate->text().contains( "#" ) ) + buttonNumber->setEnabled( true ); + else + buttonNumber->setEnabled( false ); + + if( filename->isEmpty() && extemplate->isEmpty() && !checkExtension->isChecked() ) + return; + + int h = preview->horizontalScrollBar()->value(); + int v = preview->verticalScrollBar()->value(); + + preview->clear(); + + if( fileList->count() <= 0 ) + return; + + BatchRenamer b; + if( setupBatchRenamer( &b, true ) ) + { + KApplication::setOverrideCursor( Qt::WaitCursor ); + b.createPreview( preview ); + KApplication::restoreOverrideCursor(); + } + preview->horizontalScrollBar()->setValue( h ); + preview->verticalScrollBar()->setValue( v ); +} + +void KRenameImpl::loadConfig() +{ + KConfig* config = kapp->config(); + + config->setGroup("HistSize"); + m_hist = config->readNumEntry("HistoryItems", 10 ); + updateHist(); + + config->setGroup("GUISettings"); + // Image Preview + checkPreview->setChecked(config->readBoolEntry("ImagePreview", false )); + fileList->setPreview( checkPreview->isChecked() ); + m_index = config->readNumEntry("StartIndex", 1); + m_step = 1; + m_reset = false; + m_loadplugins = config->readBoolEntry("LoadFilePlugins", true ); + m_autosize = config->readBoolEntry("ColumnAutosize", false ); + checkName->setChecked(config->readBoolEntry("Name", false )); + fileList->setPreviewSize( config->readNumEntry("PreviewSize", 80) ); + fileList->setName( checkName->isChecked() ); + fileList->setSorting( config->readNumEntry("FileListSorting", KMyListBox::UNSORTED ) ); + comboSort->setCurrentItem( fileList->sorting() ); + + CoordDialog::m_inversion = config->readBoolEntry("Inverse", false); + m_wizard = config->readBoolEntry( "GUIWizardMode", true ); + + int width = config->readNumEntry( "Width", parent->width() ); + int height = config->readNumEntry( "Height", parent->height() ); + if( config->readBoolEntry("Maximized", false ) ) { + parent->showMaximized(); + } else { + parent->resize( width, height ); + } + + refreshColumnMode(); + if( !m_autosize ) { + preview->setColumnWidth( 0, + config->readNumEntry("Column0", (width/2) - 40 ) ); + preview->setColumnWidth( 1, + config->readNumEntry("Column1", (width/2) - 40 ) ); + + if( preview->columnWidth( 0 ) > (width/2) ) + { + preview->setColumnWidth( 0, (width/2) - 40 ); + preview->setColumnWidth( 1, (width/2) - 40 ); + } + } + + if( !checkPreview->isChecked() ) { + checkName->setChecked( true ); + checkName->setEnabled( false ); + } + + //parent->show(); + page_1->setEnabled( false ); + KApplication::setOverrideCursor( Qt::WaitCursor ); + plugin->loadPlugins( m_loadplugins ); + setupTab1(); + config->setGroup("GUISettings"); + + // File Extension + config->setGroup("FileExtension"); + // default LAST DOT + comboExtension->setCurrentItem( config->readNumEntry("FileExtensionCombo", 1 ) ); +} + +void KRenameImpl::saveConfig() +{ + KConfig* config = kapp->config(); + + config->setGroup("HistSize"); + config->writeEntry("HistoryItems", m_hist ); + + config->setGroup("GUISettings"); + config->writeEntry("firststart", false ); + config->writeEntry("ImagePreview", checkPreview->isChecked() ); + config->writeEntry("StartIndex", m_index ); + config->writeEntry("Maximized", parent->isMaximized() ); + config->writeEntry("Width", parent->width() ); + config->writeEntry("Height", parent->height() ); + config->writeEntry("XPos", parent->x() ); + config->writeEntry("YPos", parent->y() ); + config->writeEntry("LoadFilePlugins", m_loadplugins ); + config->writeEntry("ColumnAutosize", m_autosize ); + config->writeEntry("Name", checkName->isChecked() ); + config->writeEntry("PreviewSize", fileList->getPreviewSize() ); + config->writeEntry("Inverse", CoordDialog::m_inversion ); + config->writeEntry("Column0", preview->columnWidth( 0 ) ); + config->writeEntry("Column1", preview->columnWidth( 1 ) ); + config->writeEntry("GUIWizardMode", m_wizard ); + config->writeEntry("FileListSorting", fileList->sorting() ); + + config->sync(); +} + +void KRenameImpl::replace() +{ + ReplaceDialog* r = new ReplaceDialog( rep, parent ); + if( r->exec() == QDialog::Accepted ) + { + rep = r->getList(); + updatePreview(); + } +} + +void KRenameImpl::toggleImagePreview() +{ + KApplication::setOverrideCursor( Qt::waitCursor ); + fileList->setPreview( checkPreview->isChecked() ); + checkName->setEnabled( checkPreview->isChecked() ); + if( !checkPreview->isChecked() ) + checkName->setChecked( true ); + fileList->setName( checkName->isChecked() ); + KApplication::restoreOverrideCursor(); +} + +void KRenameImpl::toggleName() +{ + KApplication::setOverrideCursor( Qt::waitCursor ); + fileList->setName( checkName->isChecked() ); + KApplication::restoreOverrideCursor(); +} + +void KRenameImpl::preferences() +{ + ConfDialog* cd = new ConfDialog( parent, "cd" ); + cd->setLoadPlugins( m_loadplugins ); + cd->setThumbSize( fileList->getPreviewSize() ); + cd->setAutosize( m_autosize ); + cd->setHistoryItems( m_hist ); + cd->setUseWizard( m_wizard ); + + if( cd->exec() == QDialog::Accepted ) { + bool oldwiz = m_wizard; + + m_loadplugins = cd->loadplugins(); + m_autosize = cd->autosize(); + m_hist = cd->historyItems(); + m_wizard = cd->useWizard(); + + refreshColumnMode(); + +// fileList->setHiddenDirs( cd->hiddendir() ); + + if( fileList->getPreviewSize() != cd->thumbSize() ) { + fileList->setPreviewSize( cd->thumbSize() ); + fileList->setPreview( checkPreview->isChecked() ); + } + + updatePreview(); + updateHist(); + + if( oldwiz != m_wizard ) + changeGUIMode(); + } +} + +void KRenameImpl::changeGUIMode() +{ + /* GUI Mode was changed by the user */ + saveConfig(); + + int x = parent->x(); + int y = parent->y(); + int w = parent->width(); + int h = parent->height(); + + QWidget* oldparent = parent; + QWidget* krename = KRenameImpl::launch( QRect( x, y, w, h ), QStringList(), this, false ); + + m_switching = true; + oldparent->removeChild( this ); + oldparent->hide(); + krename->insertChild( this ); + krename->show(); + + oldparent->close(); + m_switching = false; +} + +void KRenameImpl::moveUp() +{ + QListViewItem* item = preview->selectedItem(); + if(item) { + int i = preview->itemIndex( item ); + fileList->moveUp( i ); + updatePreview(); + if( (i-1) > 0 ) { + preview->setCurrentItem( preview->itemAtIndex( i-1 ) ); + preview->ensureItemVisible( preview->itemAtIndex( i-1 ) ); + } + } +} + +void KRenameImpl::moveDown() +{ + QListViewItem* item = preview->selectedItem(); + if(item) { + int i = preview->itemIndex( item ); + fileList->moveDown( i ); + updatePreview(); + preview->setCurrentItem( preview->itemAtIndex( i+1 ) ); + preview->ensureItemVisible( preview->itemAtIndex( i+1 ) ); + } +} + +void KRenameImpl::undo() +{ + UndoDialog* u = new UndoDialog( parent ); + u->exec(); + delete u; +} + +void KRenameImpl::changeUndoScriptName() +{ + const char* EXTENSION = ".krename"; + QString script = undorequester->url(); + if( script.right( 8 ) != EXTENSION ) { + script += EXTENSION; + undorequester->setURL( script ); + } +} + +void KRenameImpl::pluginHelpChanged() +{ + QPtrListIterator<PluginLoader::PluginLibrary> it( plugin->libs ); // iterator for dict + while ( it.current() ) { + if( !(*it)->plugin->alwaysUsed() ) { + (*it)->plugin->removeHelp( helpDialogData ); + + if( (*it)->check ) + { + (*it)->usePlugin = (*it)->check->isChecked(); + if( (*it)->check->isChecked() ) + (*it)->plugin->addHelp( helpDialogData ); + } + } + else + { + (*it)->plugin->removeHelp( helpDialogData ); + (*it)->plugin->addHelp( helpDialogData ); + } + + ++it; + } +} + +void KRenameImpl::showTokenHelp() +{ + helpDialog->show(); +} + +void KRenameImpl::getCoordinates() +{ + QString name; + QListViewItem* item = preview->selectedItem(); + if( item ) + name = item->text( 0 ); + else { + item = preview->itemAtIndex( 0 ); + if( item ) + name = item->text( 0 ); + } + + QFileInfo fi( name ); + QString extension; + splitFilename( &fi, &name, &extension ); + CoordDialog* cd = new CoordDialog( name, parent ); + if( cd->exec() == QDialog::Accepted ) { + QString t = filename->text(); + + if( filename->text() == "$" ) + filename->setText( cd->coords() ); + else { + t.insert( filename->cursorPosition(), cd->coords() ); + filename->setText( t ); + } + } + + delete cd; +} + +void KRenameImpl::splitFilename( QFileInfo* fi, QString* base, QString* extension ) +{ + // first dot + if( comboExtension->currentItem() == 0 ) { + *base = fi->baseName(); + *extension = fi->extension( true ); + // last dot + } else if( comboExtension->currentItem() == 1 ) { + *extension = fi->extension( false ); + if( !extension->isEmpty() ) + *base = fi->fileName().left( fi->fileName().length() - extension->length() - 1 ); + else + *base = fi->baseName(); + } else { + // custom value + int dot = comboExtension->currentText().toInt(); + + QString file = FileOperation::getName( fi->filePath() ); + int p = 0; + + if( !file.contains( "." ) || !dot || dot > file.contains( "." ) ) { + *base = file; + *extension = ""; + return; + } + + for( int i = 0; i < dot; i++ ) + p = file.find( ".", p + 1 ); + + *base = file.left( p ); + *extension = file.right( file.length() - p - 1 ); + } +} + +void KRenameImpl::refreshColumnMode() +{ + if( !m_autosize ) { + preview->setColumnWidthMode( 0, QListView::Manual ); + preview->setColumnWidthMode( 1, QListView::Manual ); + } else { + preview->setColumnWidthMode( 0, QListView::Maximum ); + preview->setColumnWidthMode( 1, QListView::Maximum ); + } +} + +void KRenameImpl::updateHist() +{ + dirname->setMaxCount( m_hist ); + filename->setMaxCount( m_hist ); + extemplate->setMaxCount( m_hist ); +} + +void KRenameImpl::changeNumbers() +{ + NumberDialog* nd = new NumberDialog( skip, parent ); + nd->spinIndex->setValue( m_index ); + nd->spinStep->setValue( m_step ); + nd->checkResetCounter->setChecked( m_reset ); + + if( nd->exec() ) { + m_index = nd->spinIndex->value(); + m_step = nd->spinStep->value(); + skip = nd->getList(); + m_reset = nd->checkResetCounter->isChecked(); + + updatePreview(); + } +} + + +void KRenameImpl::about() +{ + KAboutApplication * d = new KAboutApplication( kapp->aboutData(), parent ); + d->show(); +} + +void KRenameImpl::setWizardMode( bool mode ) +{ + fileTab->raiseWidget( mode ? ID_WIZARD : ID_TAB ); + // Maybe we should create a WidgetStack here, too + if( mode ) + { + optionLink->hide(); + if( optionLink->isChecked() ) + { + optionLink->setChecked( false ); + optionRename->setChecked( true ); + enableControls(); + } + } + else + optionLink->show(); + + if( mode ) + parseWizardMode(); +} + +void KRenameImpl::changeParent( QWidget* p, KMenuBar* m, QPushButton* finish, QRect r ) +{ + parent = p; + menuBar = m; + finishButton = finish; + + connect( finishButton, SIGNAL( clicked()), this, SLOT( start() )); + + if( !r.isNull() ) { + parent->resize( r.size() ); + parent->move( r.x(), r.y() ); + } + + setupActions(); + + page_1->reparent( parent, QPoint( 0, 0 ) ); + page_2->reparent( parent, QPoint( 0, 0 ) ); + page_3->reparent( parent, QPoint( 0, 0 ) ); + page_4->reparent( parent, QPoint( 0, 0 ) ); + + emit pageDone( page_1, i18n( pageTitle[0] ) ); + emit pageDone( page_2, i18n( pageTitle[1] ) ); + emit pageDone( page_3, i18n( pageTitle[2] ) ); + emit pageDone( page_4, i18n( pageTitle[3] ) ); +} + +QWidget* KRenameImpl::launch( QRect rect, const KURL::List & list, KRenameImpl* impl, bool loadprofile ) +{ + KConfig* config = kapp->config(); + config->setGroup("GUISettings"); + bool firststart = config->readBoolEntry( "firststart", true ); + bool wizardmode = config->readBoolEntry( "GUIWizardMode", false ); + + if( firststart ) { + /* start the GUI Mode selction dialog */ + FirstStartDlg* fsd = new FirstStartDlg(); + fsd->exec(); + wizardmode = fsd->useWizard(); + + config->setGroup("GUISettings"); + config->writeEntry( "firststart", false ); + config->writeEntry( "GUIWizardMode", wizardmode ); + config->sync(); + } + + QWidget* w = NULL; + KRenameImpl* k = NULL; + + if( wizardmode ) { + wizard* krename = new wizard( impl, rect ); + k = krename->getKRename(); + w = (QWidget*)krename; + } else { + tabs* krename = new tabs( impl, rect ); + k = krename->getKRename(); + w = (QWidget*)krename; + } + + kapp->setMainWidget( w ); + + for( unsigned int i = 0; i < list.count(); i++ ) + k->addFileOrDir( list[i] ); + + k->updatePre(); + + // it is time to load a default profile now (if the user has specified one) + if( loadprofile && !k->hasCommandlineProfile() && ProfileManager::hasDefaultProfile() ) + ProfileManager::loadDefaultProfile( k ); + else if ( !k->hasCommandlineProfile() ) + w->show(); + + return w; +} + +void KRenameImpl::updateDots() +{ + int index = comboExtension->currentItem(); + comboExtension->clear(); + + comboExtension->insertItem( i18n("First Dot") ); + comboExtension->insertItem( i18n("Last Dot") ); + + unsigned int max = 0; + for( unsigned int i = 0; i < fileList->count(); i++ ) { + QString name = fileList->url( i ).fileName(); + int c = name.contains( "." ); + max = ( c > (int)max ? c : (int)max); + } + + for( unsigned int i = 2; i <= max; i++ ) + comboExtension->insertItem( QString::number( i ) ); + + comboExtension->setCurrentItem( index ); +} + +/** DCOP functions implementation + */ + +void KRenameImpl::setFileNameTemplate( const QString & t ) +{ + filename->setText( t ); +} + +const QString KRenameImpl::fileNameTemplate() const +{ + return filename->text(); +} + +void KRenameImpl::setExtensionTemplate( const QString & t ) +{ + extemplate->setText( t ); +} + +const QString KRenameImpl::extensionTemplate() const +{ + return extemplate->text(); +} + +void KRenameImpl::setUseExtension( bool b ) +{ + checkExtension->setChecked( b ); + enableControls(); +} + +bool KRenameImpl::useExtension() const +{ + return checkExtension->isChecked(); +} + +QStringList KRenameImpl::tokens() const +{ + return helpDialogData->tokens(); +} + +QString KRenameImpl::parseString( const QString & token, const QString & string ) +{ + BatchRenamer b; + b.setIndex( 0 ); + b.setStep( 0 ); + + return b.processString( token, string, 0 ); +} + +void KRenameImpl::addDir( const QString & name, const QString & filter, bool recursive, bool hidden, bool dirnames ) +{ + fileList->addDir( name, filter, hidden, recursive, dirnames ); +} + +void KRenameImpl::setCounterStart( int index ) +{ + m_index = index; +} + +void KRenameImpl::loadFilePlugins() +{ + KApplication::setOverrideCursor( Qt::WaitCursor ); + plugin->loadPlugins( true ); + KApplication::restoreOverrideCursor(); + pluginHelpChanged(); + + enableControls(); +} + +void KRenameImpl::reloadFilePluginData() +{ + plugin->clearCache(); + updatePreview(); +} + +void KRenameImpl::manageProfiles() +{ + ProfileDlg dlg( this, parent, "dlg" ); + dlg.exec(); +} + +void KRenameImpl::getHelpDialogString( QLineEdit* edit ) +{ + HelpDialog hdlg( helpDialogData, parent, "hdlg", true ); + hdlg.setLineEdit( edit ); + hdlg.updateHeadline(); + hdlg.updateItems(); + hdlg.exec(); +} + +void KRenameImpl::slotEasy1() +{ + getHelpDialogString( comboPrefix->lineEdit() ); +} + +void KRenameImpl::slotEasy2() +{ + getHelpDialogString( comboSuffix->lineEdit() ); +} + +void KRenameImpl::slotEasy3() +{ + getHelpDialogString( comboCustom->lineEdit() ); +} + +void KRenameImpl::slotEasy4() +{ + getHelpDialogString( comboCustomExtension->lineEdit() ); +} diff --git a/krename/krenameimpl.h b/krename/krenameimpl.h new file mode 100644 index 0000000..ae62b7b --- /dev/null +++ b/krename/krenameimpl.h @@ -0,0 +1,353 @@ +/*************************************************************************** + krenameimpl.h - description + ------------------- + begin : Die Mai 20 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRENAMEIMPL_H +#define KRENAMEIMPL_H + +// Own includes +#include "batchrenamer.h" +#include "krenamedcop.h" + +class HelpDialog; +class HelpDialogData; +class KAction; +class KComboBox; +class KJanusWidget; +class KMyHistoryCombo; +class KMyListBox; +class KMyListView; +class KMenuBar; +class KPopupMenu; +class KPushButton; +class KToggleAction; +class KURL; +class KURLRequester; +class KIntNumInput; +class MyHelpCombo; +class MyLabel; +class Plugin; +class PluginLoader; +class QButtonGroup; +class QCheckBox; +class QGroupBox; +class QFileInfo; +class QFrame; +class QHBoxLayout; +class QLabel; +class QLineEdit; +class QListView; +class QPushButton; +class QRect; +class QWidgetStack; +class QRadioButton; +class QVBoxLayout; +class QVGroupBox; +class QWidget; + +#include <kguiitem.h> +KPushButton* createButton( KGuiItem item, QWidget* parent ); + +class KRenameImpl : public QObject, public KRenameDCOP { + Q_OBJECT + + friend class ProfileManager; + friend class ProfileDlg; + friend class tabs; + + public: + KRenameImpl( QWidget* p, KMenuBar* m, QPushButton* finish ); + ~KRenameImpl(); + + void setWizardMode( bool mode ); + + /* + * public because both get called from KRenameImpl::launch() + */ + void updatePre(); + void addFileOrDir( const KURL & name ); + + void setup( bool wizardmode ); + void changeParent( QWidget* p, KMenuBar* m, QPushButton* finish, QRect r ); + static QWidget* launch( QRect rect, const KURL::List & list, KRenameImpl* impl = 0, bool loadprofile = true ); + + /** DCOP functions we have to implement + */ + void addFileOrDir( const QString & name ); + const QString fileNameTemplate() const; + inline int counterStart() const; + + void setExtensionTemplate( const QString & t ); + const QString extensionTemplate() const; + + void setUseExtension( bool b ); + bool useExtension() const; + + QStringList tokens() const; + + QString parseString( const QString & token, const QString & string ); + void addDir( const QString & name, const QString & filter, bool recursive, bool hidden, bool dirnames ); + + const QString title( int index ) const; + + /** @returns true if the user has specified a profile on the commandline + * other wise false is returned + */ + inline bool hasCommandlineProfile() const; + + public slots: + void setFileNameTemplate( const QString & t ); + void setCounterStart( int index ); + + signals: + void pageDone( QWidget* page, const QString & title ); + void showPage( int page ); + void enableFinish( bool b ); + + private slots: + void about(); + void addFile(); + bool checkErrors(); + void clearList(); + void enableControls(); + void toggleImagePreview(); + void moveUp(); + void moveDown(); + void help(); + void removeFile(); + void removeFile( int index ); + void preferences(); + void replace(); + void saveConfig(); + void start(); + void updateCount(); + void undo(); + void changeUndoScriptName(); + void pluginHelpChanged(); + void getCoordinates(); + void changeNumbers(); + void updateDots(); + void updatePreview(); + void showTokenHelp(); + void toggleName(); + void changed(); + void loadFilePlugins(); + void reloadFilePluginData(); + void manageProfiles(); + QString easyOptions( KComboBox* combo, KMyHistoryCombo* custom ); + void slotEasy1(); + void slotEasy2(); + void slotEasy3(); + void slotEasy4(); + + /** Update the preview only if the passed + * plugin is enabled for use. + */ + void updatePluginPreview( Plugin* p ); + + private: + static int numRealTimePreview; + + /** Change the GUI mode according to the current setting of m_wizard + */ + void changeGUIMode(); + + /** Returns COPY if optionCopy is checked, RENAME if optionRename is checked + * ... + */ + int currentRenameMode(); + + void loadConfig(); + void fillStructures( BatchRenamer* b, bool preview ); + bool setupBatchRenamer( BatchRenamer* b, bool preview ); + void splitFilename( QFileInfo* fi, QString* base, QString* extension ); + + void setupActions(); + void setupPage1(); + void setupPage2(); + void setupPage3(); + void setupPage4(); + void setupTab1(); + void setupFileTab1(); + void setupFileTab2(); + void setupPages(); + void updateHist(); + void parseCommandline(); + void addTitle( QWidget* p, QVBoxLayout* layout, QString title ); + + QValueList<manualchanges> changes; + void refreshColumnMode(); + void parseWizardMode(); + void getHelpDialogString( QLineEdit* edit ); + + protected: + QWidget* parent; + KMenuBar* menuBar; + KPopupMenu* mnuSort; + KAction* loadPlugins; + + QPushButton* finishButton; + + PluginLoader* plugin; + + QWidgetStack* fileTab; + + QWidget* page_1; + QWidget* page_2; + KJanusWidget* page_3; + QWidget* page_4; + + bool m_wizard; + bool m_loadplugins; + bool m_switching; + bool m_autosize; + int m_hist; + int m_index; + int m_step; + bool m_reset; + + bool m_hasCommandlineProfile; + + KPushButton* buttonUp; + KPushButton* buttonDown; + KPushButton* buttonUp2; + KPushButton* buttonDown2; + KPushButton* buttonAdd; + KPushButton* buttonRemove; + KPushButton* buttonRemoveAll; + KPushButton* buttonReplace; + KPushButton* buttonEasyReplace; + KPushButton* buttonHelp; + KPushButton* buttonMove; + KPushButton* buttonCoord; + KPushButton* buttonNumber; + + KPushButton* buttonEasy1; + KPushButton* buttonEasy2; + KPushButton* buttonEasy3; + KPushButton* buttonEasy4; + KComboBox* comboSort; + + QLabel* description; + QLabel* description2; + QLabel* description3; + QLabel* description4; + + QLabel* labelTemplate; + QLabel* labelHelp; + QLabel* labelCount; + QLabel* labelPoint; + + KMyListBox* fileList; + KMyListView* preview; + QButtonGroup* groupOptions; + + QRadioButton* optionCopy; + QRadioButton* optionMove; + QRadioButton* optionRename; + QRadioButton* optionLink; + + QGroupBox* groupExtension; + QVGroupBox* groupUndo; + + KMyHistoryCombo* dirname; + KURLRequester* urlrequester; + KURLRequester* undorequester; + KMyHistoryCombo* filename; + KMyHistoryCombo* extemplate; + + QCheckBox* checkName; + QCheckBox* checkExtension; + QCheckBox* checkOverwrite; + QCheckBox* checkPreview; + QCheckBox* checkUndoScript; + + KComboBox* comboExtension; + + MyHelpCombo* comboHelp; + HelpDialog* helpDialog; + HelpDialogData* helpDialogData; + + BatchRenamer* b; + QValueList<int> skip; + QValueList<replacestrings> rep; + + // ========== + // Easy mode: + // ========== + + KComboBox* comboKRenamePrefix; + KComboBox* comboKRenameSuffix; + KComboBox* comboKRenameFilename; + KComboBox* comboKRenameExtension; + + KMyHistoryCombo* comboPrefix; + KMyHistoryCombo* comboSuffix; + KMyHistoryCombo* comboCustom; + KMyHistoryCombo* comboCustomExtension; + + KIntNumInput* spinStart; + KIntNumInput* spinNull; + + // =========== + // Layout: + // =========== + + QHBoxLayout* pageLayout; + QVBoxLayout* pageLayout_2; + QVBoxLayout* pageLayout_3; + QVBoxLayout* pageLayout_4; + + QHBoxLayout* tabLayout_0; + QHBoxLayout* tabLayout_1; + QHBoxLayout* tabLayout_2; + QVBoxLayout* tabLayout_3; + QVBoxLayout* groupAdvancedExtensionLayout; + QVBoxLayout* groupOptionsLayout; + QHBoxLayout* groupDirLayout; + QVBoxLayout* groupNumberLayout; + QHBoxLayout* groupExtensionLayout; + + // page1 + QHBoxLayout* Layout2; + QVBoxLayout* Layout3; + QHBoxLayout* Layout4; + QVBoxLayout* Layout5; + + // page4 + QVBoxLayout* Layout10; + QHBoxLayout* Layout15; + QVBoxLayout* Layout16; + QHBoxLayout* Layout22; + QVBoxLayout* Layout23; + + // tab + QHBoxLayout* Layout100; + QHBoxLayout* Layout101; +}; + + +int KRenameImpl::counterStart() const +{ + return m_index; +} + +bool KRenameImpl::hasCommandlineProfile() const +{ + return m_hasCommandlineProfile; +} + +#endif diff --git a/krename/krenameservicemenu.desktop b/krename/krenameservicemenu.desktop new file mode 100644 index 0000000..608f1a4 --- /dev/null +++ b/krename/krenameservicemenu.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=all/allfiles +Actions=Rename + +ExcludeServiceTypes=kdedevice/* + +[Desktop Action Rename] +Name=Rename with KRename +Name[de]=Mit KRename umbenennen +Name[es]=Renombrar con KRename +Name[fr]=Renommer avec KRename +Name[pt_BR]=Renomear com KRename +Exec=krename %F +Icon=krename + diff --git a/krename/lo16-app-krename.png b/krename/lo16-app-krename.png Binary files differnew file mode 100644 index 0000000..841ee79 --- /dev/null +++ b/krename/lo16-app-krename.png diff --git a/krename/lo32-app-krename.png b/krename/lo32-app-krename.png Binary files differnew file mode 100644 index 0000000..a2d4071 --- /dev/null +++ b/krename/lo32-app-krename.png diff --git a/krename/logo.png b/krename/logo.png Binary files differnew file mode 100644 index 0000000..b80036d --- /dev/null +++ b/krename/logo.png diff --git a/krename/main.cpp b/krename/main.cpp new file mode 100644 index 0000000..f8df37a --- /dev/null +++ b/krename/main.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your2192 option) any later version. * + * * + ***************************************************************************/ + +// Qt includes +#include <qrect.h> +#include <qwidget.h> + +// KDE includes +#include <kapplication.h> +#include <kaboutapplication.h> +#include <kcmdlineargs.h> +#include <kconfig.h> +#include <kimageio.h> +#include <klocale.h> +#include <kmessagebox.h> + +// Own includes +#include "wizard.h" +#include "tabs.h" +#include "krenameimpl.h" +#include "firststartdlg.h" + +#ifdef HAVE_CONFIG_H + #include <config.h> +#endif + +// OS includes +#include <unistd.h> +#include <sys/types.h> + +#ifndef VERSION + #define VERSION "unknown" +#endif + +KAboutData aboutData( "krename", I18N_NOOP("KRename"), VERSION, I18N_NOOP( + "KRename is a batch file renamer which can rename a\n" + "list of files based on a set of expressions.\n\n" + "If you like KRename you may want to support it.\n" + "Testing, bug fixes and feature request are as welcome\n" + "as financial support (everybody needs money ;)\nSee help files for details.\n" ), + KAboutData::License_GPL, "KRename Build:" __DATE__ " " __TIME__ + , "(c) 2001-2007, Dominik Seichter\n", + "http://www.krename.net", "domseichter@web.de" ); + + +static KCmdLineOptions options[] = +{ + { "+[file]", I18N_NOOP("file will be added to the list of files for renaming"), 0}, + { "r +[dir]", I18N_NOOP("add directory recursively"), 0 }, + { "template +", I18N_NOOP("set a template"), 0 }, + { "extension +", I18N_NOOP("set a template for the file extension"), 0 }, + { "use-plugin +", I18N_NOOP("enable a plugin for use"), 0 }, + { "copy +[dir]", I18N_NOOP("copy files to directory"), 0 }, + { "move +[dir]", I18N_NOOP("move files to directory"), 0 }, + { "profile +[profile]", I18N_NOOP("load the profile named [profile] on startup"), 0 }, + { "start", I18N_NOOP("start renaming immediately"), 0 }, + { "previewitems <num>", I18N_NOOP("only show <num> preview items"), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char *argv[]) +{ + aboutData.addAuthor("Dominik Seichter", 0, "domseichter@web.de", + "http://www.krename.net" ); + aboutData.addAuthor("Stefan \"Stonki\" Onken", + I18N_NOOP("Website, testing, very good ideas and keeping me coding!"), + "support@stonki.de", "http://www.stonki.de" ); + + aboutData.addCredit("Trevor Semeniuk", I18N_NOOP("Thanks to him for creating RedHat 7.x packages and some other help."), + "semeniuk@ee.ualberta.ca", "http://www.semeniuk.net" ); + aboutData.addCredit("Groult Richard", I18N_NOOP("Fixed a bug with startIndex and added the BatchRenamer class\n" + "to his excellent image viewer showimg."), + "rgroult@jalix.org", "http://ric.jalix.org/" ); + aboutData.addCredit("Michael Elvers", I18N_NOOP("Fixed a bug that caused krename not closing open files."), + "m_elvers@yahoo.com", "http://come.to/melvers" ); + aboutData.addCredit("Andreas Pour", I18N_NOOP("Thanks for his great job at apps.kde.com and help with contributing krename to apps.kde.com."), + "pour@mieterra.com", "http://apps.kde.com" ); + aboutData.addCredit("Charles Samuels", I18N_NOOP("Thanks for noatun and the ID3/Ogg Tag code is based on his noatun modules."), + "charles@kde.org", "http://noatun.kde.org/" ); + aboutData.addCredit("Franz Schmid", I18N_NOOP("Gave me a good start into writing plugins with his application scribus."), + "Franz.Schmid@altmuehlnet.de", "http://web2.altmuehlnet.de/fschmid/index.html" ); + aboutData.addCredit("Rolf Magnus", I18N_NOOP("Parts of the PNG support are copied from his KFile plugin for png support."), + "ramagnus@kde.org" ); + aboutData.addCredit("Michael v.Ostheim", I18N_NOOP("Created the Gentoo Ebuild scripts for Krename."), + "MvOstheim@web.de", "http://www.vonostheim.de" ); + aboutData.addCredit("Brandon Low", I18N_NOOP("Some GCC 3.1 fixes for Gentoo."), + "lostlogic@gentoo.org", "http://www.gentoo.org" ); + aboutData.addCredit("Per �vind Karlsen", I18N_NOOP("Thanks for creating the Mandrake RPM"), + "peroyvind@delonic.no" ); + aboutData.addCredit("Daniele Medri", I18N_NOOP("Italian translation"), "madrid@linuxmeeting.net" ); + aboutData.addCredit("Stephan Johach", I18N_NOOP("Provided a gcc3.x namespace patch"), "lucardus@onlinehome.de" ); + aboutData.addCredit("Micha� Zugaro", I18N_NOOP("Provided the new preview and move features") , "michael.zugaro@college-de-france.fr" ); + aboutData.addCredit("Rene Gass", I18N_NOOP("Fixed problems with the spec file and contributed rpms for every SuSE version you can imagine and is also the new Gentoo maintainer for KRename"), "kde-package@gmx.de" ); + aboutData.addCredit("Mark Volkert", I18N_NOOP("Provided SuSE RPMs and very good suggestions"), "mark.volkert@rakekniven.de" ); + aboutData.addCredit("Jose Rodriguez", I18N_NOOP("Contributed a Spanish translation"), "chmpmi@eresmas.net" ); + aboutData.addCredit("Steven P. Ulrick", I18N_NOOP("Provided a RedHat RPM and was big help in improving KRename"), "steve@afolkey2.net" ); + aboutData.addCredit("UTUMI Hirosi", I18N_NOOP("Translated KRename to Japanese"), "utuhiro@mx12.freecom.ne.jp" ); + aboutData.addCredit("Nicolas Benoit", I18N_NOOP("Translated KRename into French"), "nbenoit@tuxfamily.org" ); + aboutData.addCredit("Krzysztof Pawlak", I18N_NOOP("Translated KRename into Polish"), "jmnemonic@gazeta.pl" ); + aboutData.addCredit("Ilya Ivkov", I18N_NOOP("Translated KRename into Russian"), "ilya-ivkov@yandex.ru" ); + aboutData.addCredit("Asim Husanovic", I18N_NOOP("Translated KRename into Bosnian"), "asim.h@megatel.ba" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication a; + a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + + KImageIO::registerFormats(); + + QWidget* krename = KRenameImpl::launch( QRect( 0, 0, 0, 0 ), QStringList() ); + + /* Check if Krename + * was started from root! + */ + unsigned int uid = geteuid(); + if( uid == 0 ) + KMessageBox::information( krename, i18n( + "<b>Krename was started from root!</b><br>" + "When started from root, Krename may damage your " + "system if you do not know exactly what you are " + "doing!" + ), i18n("Error"), "KrenameRootWarning" ); + +/* + * Activate this warning message for unstable development releases. + */ +/* KMessageBox::sorry( krename, i18n( + "<b>Warning !</b> This is a development release which may cause damage to your files!" + "<br>Make backups before using KRename." )); +*/ + return a.exec(); +} + diff --git a/krename/mydirplugin.cpp b/krename/mydirplugin.cpp new file mode 100644 index 0000000..202079f --- /dev/null +++ b/krename/mydirplugin.cpp @@ -0,0 +1,169 @@ +/*************************************************************************** + mydirplugin.cpp - description + ------------------- + begin : Tue Jan 29 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// Own includes +#include "mydirplugin.h" + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <kfiledialog.h> +#include <klocale.h> + +// QT includes +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qspinbox.h> + +const QString MyDirPlugin::getName() const +{ + return i18n("Dir Plugin"); +} + +const QString MyDirPlugin::getAccelName() const +{ + return i18n("&Dir Plugin"); +} + +const int MyDirPlugin::type() const +{ + return TYPE_FINAL_FILE; +} + +bool MyDirPlugin::checkError() +{ + return true; +} + +const QPixmap MyDirPlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "folder", KIcon::Small ); +} + +void MyDirPlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + QSpacerItem* spacer2 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + QVBoxLayout* LayoutA = new QVBoxLayout( 0, 6, 6 ); + QVBoxLayout* LayoutB = new QVBoxLayout( 0, 6, 6 ); + + m_widget = w; + + QLabel* la = new QLabel( w ); + la->setText( i18n("<qt>This plugin sorts files after renaming in subdirectories.</qt>") ); + l->addWidget( la ); + + groupNumber = new QGroupBox( w ); + groupNumber->setTitle( i18n( "&Options" ) ); + groupNumber->setColumnLayout(0, Qt::Vertical ); + groupNumber->layout()->setSpacing( 6 ); + groupNumber->layout()->setMargin( 11 ); + groupNumberLayout = new QHBoxLayout( groupNumber->layout() ); + groupNumberLayout->setAlignment( Qt::AlignTop ); + + QLabel* la2 = new QLabel( groupNumber ); + la2->setText( i18n( "Files per directory:" ) ); + + spinFiles = new QSpinBox( groupNumber ); + spinFiles->setRange( 1, 60000 ); + spinFiles->setValue( 10 ); + + QLabel* la3 = new QLabel( groupNumber ); + la3->setText( i18n( "Start index:" ) ); + + spinStart = new QSpinBox( groupNumber ); + spinFiles->setRange( 0, 60000 ); + + LayoutA->addWidget( la2 ); + LayoutA->addWidget( la3 ); + LayoutB->addWidget( spinFiles ); + LayoutB->addWidget( spinStart ); + + groupNumberLayout->addLayout( LayoutA ); + groupNumberLayout->addLayout( LayoutB ); + groupNumberLayout->addItem( spacer ); + + groupOutput = new QGroupBox( w ); + groupOutput->setTitle( i18n( "Output &Directory" ) ); + groupOutput->setColumnLayout(0, Qt::Vertical ); + groupOutput->layout()->setSpacing( 6 ); + groupOutput->layout()->setMargin( 11 ); + groupOutputLayout = new QHBoxLayout( groupOutput->layout() ); + groupOutputLayout->setAlignment( Qt::AlignTop ); + + outputdir = new QLineEdit( groupOutput ); + buttonDir = new QPushButton( groupOutput ); + buttonDir->setText( "..." ); + + groupOutputLayout->addWidget( outputdir ); + groupOutputLayout->addWidget( buttonDir ); + + l->addWidget( groupNumber ); + l->addWidget( groupOutput ); + l->addItem( spacer2 ); + + connect( buttonDir, SIGNAL(clicked()), this, SLOT(chooseDir())); +} + +void MyDirPlugin::fillStructure() +{ + fpd = spinFiles->value(); + fpd--; + dir = outputdir->text(); + + filecounter = 0; + dircounter = spinStart->value(); + curdir = dir + QString("/%1/").arg( dircounter ); + + d = new QDir( dir ); + d->mkdir( curdir ); +} + +QString MyDirPlugin::processFile( BatchRenamer*, int, QString token, int ) +{ + QString newname; + // token = filename + if( filecounter == fpd ) { + filecounter = 0; + dircounter++; + curdir = dir + QString("/%1/").arg( dircounter ); + d->mkdir( curdir ); + } + + QFileInfo f( token ); + newname = curdir + f.fileName(); + d->rename( token, newname ); + filecounter++; + return QString::null; +} + +void MyDirPlugin::finished() +{ + filecounter = dircounter = 0; +} + +void MyDirPlugin::chooseDir() +{ + QString s (KFileDialog::getExistingDirectory ( QString::null )); + if(!s.isEmpty()) + outputdir->setText( s ); +} + diff --git a/krename/mydirplugin.h b/krename/mydirplugin.h new file mode 100644 index 0000000..1c27dc7 --- /dev/null +++ b/krename/mydirplugin.h @@ -0,0 +1,72 @@ +/*************************************************************************** + mydirplugin.h - description + ------------------- + begin : Tue Jan 29 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MYDIRPLUGIN_H +#define MYDIRPLUGIN_H + +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" + +class QDir; +class QHBoxLayout; +class QGroupBox; +class QLineEdit; +class QPushButton; +class QSpinBox; +class QString; +class QVBoxLayout; +class QWidget; +class MyDirPlugin : public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + bool checkError(); + void drawInterface( QWidget* w, QVBoxLayout* l ); + void fillStructure(); + QString processFile( BatchRenamer*, int, QString token, int ); + void finished(); + + const QPixmap getIcon() const; + + private slots: + void chooseDir(); + + protected: + int fpd; // files per dir + int filecounter; + int dircounter; + QString dir; + QString curdir; + QDir* d; + + QLineEdit* outputdir; + QPushButton* buttonDir; + QSpinBox* spinFiles; + QSpinBox* spinStart; + + QGroupBox* groupOutput; + QHBoxLayout* groupOutputLayout; + + QGroupBox* groupNumber; + QHBoxLayout* groupNumberLayout; +}; + +#endif diff --git a/krename/myinputdialog.cpp b/krename/myinputdialog.cpp new file mode 100644 index 0000000..10428d2 --- /dev/null +++ b/krename/myinputdialog.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + myinputdialog.cpp - description + ------------------- + begin : Mit Apr 01 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "myinputdialog.h" + +#include <klineedit.h> +#include <kpushbutton.h> +#include <klocale.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> + +MyInputDialog::MyInputDialog( QString filename, bool revertEnabled, QWidget* parent ) + : QDialog( parent, 0, true, 0 ) +{ + // I do not think this has to be translated + setCaption( "KRename" ); + + MyInputDialogLayout = new QVBoxLayout( this, 11, 6, "MyInputDialogLayout"); + Layout = new QHBoxLayout( 0, 0, 6, "Layout"); + + TextLabel1 = new QLabel( this, "TextLabel1" ); + TextLabel1->setText( i18n( "Please input a new filename:" ) ); + + text = new KLineEdit( this, "text" ); + text->setText( filename ); + + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + + buttonKrename = new KPushButton( this, "buttonKrename" ); + buttonKrename->setText( i18n( "&Revert Changes" ) ); + buttonKrename->setEnabled( revertEnabled ); + + buttonFilename = new KPushButton( this, "buttonFilename" ); + buttonFilename->setText( i18n("Use &Input Filename") ); + + buttonOk = new KPushButton( this, "buttonOk" ); + buttonOk->setText( i18n( "&Ok" ) ); + buttonOk->setDefault( true ); + + buttonCancel = new KPushButton( this, "buttonCancel" ); + buttonCancel->setText( i18n( "&Cancel" ) ); + + text->setFocus(); + + Layout->addWidget( buttonKrename ); + Layout->addWidget( buttonFilename ); + Layout->addItem( spacer ); + Layout->addWidget( buttonOk ); + Layout->addWidget( buttonCancel ); + + MyInputDialogLayout->addWidget( TextLabel1 ); + MyInputDialogLayout->addWidget( text ); + MyInputDialogLayout->addLayout( Layout ); + + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( buttonKrename, SIGNAL( clicked() ), this, SLOT( krename() ) ); + connect( buttonFilename, SIGNAL( clicked() ), this, SLOT( slotFilename() ) ); + + QToolTip::add( buttonKrename, i18n("Use the filename that is generated by " + "KRename instead of your changes." ) ); +} + +MyInputDialog::~MyInputDialog() +{ } + + QString MyInputDialog::filename() const +{ + return text->text(); +} + +void MyInputDialog::accept() +{ + if( text->text().isEmpty() ) + reject(); + else + done( OK ); +} + +void MyInputDialog::reject() +{ + done( CANCEL ); +} + +void MyInputDialog::krename() +{ + done( USE_KRENAME ); +} + +void MyInputDialog::slotFilename() +{ + text->setText( m_oldfilename ); +} + diff --git a/krename/myinputdialog.h b/krename/myinputdialog.h new file mode 100644 index 0000000..689cead --- /dev/null +++ b/krename/myinputdialog.h @@ -0,0 +1,74 @@ +/*************************************************************************** + myinputdialog.h - description + ------------------- + begin : Mit Apr 01 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MYINPUTDIALOG_H +#define MYINPUTDIALOG_H + +#include <qdialog.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class KLineEdit; +class KPushButton; +class QLabel; +class QString; +class MyInputDialog : public QDialog +{ + Q_OBJECT + public: + MyInputDialog( QString filename, bool revertEnabled = true, QWidget* parent = 0 ); + ~MyInputDialog(); + + QString filename() const; + inline void setInputFilename( const QString s ); + + enum returnCodes { + OK, + CANCEL, + USE_KRENAME + }; + + private slots: + /** Use the file name generated by KRename.... + */ + void krename(); // ????? :-) + void slotFilename(); + void accept(); + void reject(); + + private: + QLabel* TextLabel1; + KLineEdit* text; + KPushButton* buttonKrename; + KPushButton* buttonFilename; + KPushButton* buttonOk; + KPushButton* buttonCancel; + + QString m_oldfilename; + + protected: + QVBoxLayout* MyInputDialogLayout; + QHBoxLayout* Layout; +}; + +void MyInputDialog::setInputFilename( const QString s ) +{ + m_oldfilename = s; +} + +#endif // MYINPUTDIALOG_H diff --git a/krename/numberdialog.cpp b/krename/numberdialog.cpp new file mode 100644 index 0000000..d7264c9 --- /dev/null +++ b/krename/numberdialog.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + numberdialog.cpp - description + ------------------- + begin : Don Apr 24 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "numberdialog.h" +#include "batchrenamer.h" + +// Qt includes +#include <qgroupbox.h> +#include <qlayout.h> +#include <qtooltip.h> + +// KDE includes +#include <kapplication.h> +#include <kconfig.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <qcheckbox.h> + +void KMyIntSpinBox::keyPressEvent( QKeyEvent* e ) +{ + if( e->key() == Key_Return ) + emit returnPressed(); +} + +NumberDialog::NumberDialog(QValueList<int> & n,QWidget *parent ) + : KDialogBase( KDialogBase::Plain, "KRename", + KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, parent, 0, true, true ) +{ + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + QVBoxLayout* layout = new QVBoxLayout( plainPage(), 6, 6 ); + + QGroupBox* group1 = new QGroupBox( plainPage() ); + group1->setTitle( i18n("&Numbering") ); + group1->setColumnLayout(0, Qt::Vertical ); + group1->layout()->setSpacing( 6 ); + group1->layout()->setMargin( 11 ); + QVBoxLayout* group1Layout = new QVBoxLayout( group1->layout() ); + group1Layout->setAlignment( Qt::AlignTop ); + + spinIndex = new KIntNumInput( group1 ); + spinIndex->setMaxValue( SPINMAX ); + spinIndex->setLabel( i18n( "Start &index:" ), AlignLeft | AlignVCenter ); + + spinStep = new KIntNumInput( spinIndex, 1, group1 ); + spinStep->setRange( -SPINMAX, SPINMAX, 1, false ); + spinStep->setValue( 1 ); + spinStep->setLabel( i18n( "Step &by:" ), AlignLeft | AlignVCenter ); + + checkResetCounter = new QCheckBox( i18n("&Reset counter for every directory"), group1 ); + + QGroupBox* group2 = new QGroupBox( plainPage() ); + group2->setTitle( i18n("S&kip Numbers") ); + group2->setColumnLayout(0, Qt::Horizontal ); + group2->layout()->setSpacing( 6 ); + group2->layout()->setMargin( 11 ); + QHBoxLayout* group2Layout = new QHBoxLayout( group2->layout() ); + group2Layout->setAlignment( Qt::AlignTop ); + + listNumbers = new KListBox( group2 ); + + buttonAdd = new KPushButton( group2 ); + buttonAdd->setText( i18n( "&Add Number" ) ); + + buttonRemove = new KPushButton( group2 ); + buttonRemove->setText( i18n( "&Remove Number" ) ); + + spinNumber = new KMyIntSpinBox( group2 ); + spinNumber->setMaxValue( SPINMAX ); + spinNumber->setMinValue( -SPINMAX ); + spinNumber->setValue( 0 ); + spinNumber->setFocus(); + + QVBoxLayout* layout2 = new QVBoxLayout( 0, 6, 6 ); + layout2->addWidget( buttonAdd ); + layout2->addWidget( buttonRemove ); + layout2->addWidget( spinNumber ); + layout2->addItem( spacer ); + + group1Layout->addWidget( spinIndex ); + group1Layout->addWidget( spinStep ); + group1Layout->addWidget( checkResetCounter ); + + group2Layout->addWidget( listNumbers ); + group2Layout->addLayout( layout2 ); + + layout->addWidget( group1 ); + layout->addWidget( group2 ); + + QToolTip::add( spinIndex, i18n( "Number of the first file." ) ); + QToolTip::add( spinStep, i18n( "The counter is increased/decreased by this value." ) ); + QToolTip::add( listNumbers, i18n("Add all numbers that should be skipped by krename during the rename process.<br>" + "E.g.: If 2 is skipped files will be numbered: file0, file1, file3, ...") ); + QToolTip::add( checkResetCounter, i18n("<qt>The counter is set to the start index in every directory. " + "This setting applies to all used counters.</qt>" ) ); + + connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( addNumber() ) ); + connect( buttonRemove,SIGNAL( clicked() ), this, SLOT( removeNumber() ) ); + connect( spinNumber, SIGNAL( returnPressed()), this, SLOT( addNumber() ) ); + + for( unsigned int i = 0; i < n.count(); i++ ) + listNumbers->insertItem( QString("%1").arg(n[i]), -1 ); + + update(); +} + +NumberDialog::~NumberDialog() +{ +} + +void NumberDialog::addNumber() +{ + QString tmp = QString("%1").arg(spinNumber->value()); + for( unsigned int i = 0; i < listNumbers->count(); i++ ) + if( listNumbers->text(i) == tmp ) + return; + listNumbers->insertItem( tmp, -1 ); + sort(); +} + +void NumberDialog::removeNumber() +{ + unsigned int i = 0; + do { + if(listNumbers->isSelected( i )) { + listNumbers->removeItem( i ); + listNumbers->setSelected( i-1, true ); + return; + } else + i++; + } while( i < listNumbers->count() ); +} + +QValueList<int> NumberDialog::getList() +{ + QValueList<int> skip; + for( unsigned int i = 0; i < listNumbers->count(); i++ ) + skip.append( listNumbers->text(i).toInt() ); + + return skip; +} + +void NumberDialog::sort() +{ + // Not very fast, but I hope it won't be used on ot big lists ;) + if( listNumbers->count() < 1 ) + return; + + for( unsigned int i = 0; i < listNumbers->count()-1; i++) { + if( listNumbers->text(i).toInt() > listNumbers->text(i+1).toInt() ) { + QString tmp = listNumbers->text(i); + listNumbers->removeItem(i); + listNumbers->insertItem( tmp, i+1 ); + i = 0; + } + } +} diff --git a/krename/numberdialog.h b/krename/numberdialog.h new file mode 100644 index 0000000..9de464c --- /dev/null +++ b/krename/numberdialog.h @@ -0,0 +1,74 @@ +/*************************************************************************** + numberdialog.h - description + ------------------- + begin : Don Apr 24 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef NUMBERDIALOG_H +#define NUMBERDIALOG_H + +#include <qwidget.h> +#include <kdialogbase.h> +#include <qvaluelist.h> + +// KDE includes +#include <knuminput.h> + +class KMyIntSpinBox : public KIntSpinBox +{ + Q_OBJECT + public: + KMyIntSpinBox( QWidget* parent ) + : KIntSpinBox( parent ) + { }; + ~KMyIntSpinBox() { }; + private: + void keyPressEvent( QKeyEvent* e ); + signals: + void returnPressed(); +}; + +class QCheckBox; +class KIntNumInput; +class KListBox; +class KPushButton; +class NumberDialog : public KDialogBase { + Q_OBJECT + public: + NumberDialog(QValueList<int> & n,QWidget *parent=0); + ~NumberDialog(); + + // TODO: bad object oriented design!!! + // make them accessible by members + KIntNumInput* spinIndex; + KIntNumInput* spinStep; + + QCheckBox* checkResetCounter; + + QValueList<int> getList(); + + private slots: + void addNumber(); + void removeNumber(); + + private: + void sort(); + + KListBox* listNumbers; + KPushButton* buttonAdd; + KPushButton* buttonRemove; + KMyIntSpinBox* spinNumber; +}; + +#endif diff --git a/krename/permission.cpp b/krename/permission.cpp new file mode 100644 index 0000000..918052e --- /dev/null +++ b/krename/permission.cpp @@ -0,0 +1,329 @@ +/*************************************************************************** + permission.cpp - description + ------------------- + begin : Sun Jan 13 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "permission.h" + +// QT includes +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlayout.h> + +// KDE includes +#include <kapplication.h> +#include <kcombobox.h> +#include <kiconloader.h> +#include <klocale.h> + +// OS includes +#include <stdio.h> +#include <pwd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <grp.h> +#include <unistd.h> + +const QString MyPermPlugin::getName() const +{ + return i18n("Permissions"); +} + +const QString MyPermPlugin::getAccelName() const +{ + return i18n("&Permissions"); +} + +const int MyPermPlugin::type() const +{ + return TYPE_FINAL_FILE; +} + +bool MyPermPlugin::checkError() +{ + return true; +} + +void MyPermPlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + int i; + unsigned int uid; // Maybe this must be signed int ? + struct passwd *user; + struct group *ge; + QLabel *la, *cl[3]; + QGridLayout *gl; + + QString strOwner; + + m_widget = w; + + l->setResizeMode( QLayout::FreeResize ); + w->setMinimumSize( QSize( 100, 100 ) ); + + Layout0 = new QVBoxLayout( 0, 0, 6 ); + + groupPermission = new QGroupBox ( i18n("Access permissions"), w ); + groupPermission->setEnabled( FALSE ); + + gl = new QGridLayout (groupPermission, 6, 6, 15); + gl->addRowSpacing(0, 10); + + checkPermissions = new QCheckBox( i18n("Change &Permissions"), w ); + + la = new QLabel(i18n("Class"), groupPermission); + gl->addWidget(la, 1, 0); + + la = new QLabel( i18n("Read"), groupPermission ); + gl->addWidget (la, 1, 1); + + la = new QLabel( i18n("Write"), groupPermission ); + gl->addWidget (la, 1, 2); + + la = new QLabel( i18n("Exec"), groupPermission ); + QSize size = la->sizeHint(); + size.setWidth(size.width() + 15); + la->setFixedSize(size); + gl->addWidget (la, 1, 3); + + la = new QLabel( i18n("Special"), groupPermission ); + gl->addMultiCellWidget(la, 1, 1, 4, 5); + + cl[0] = new QLabel( i18n("User"), groupPermission ); + gl->addWidget (cl[0], 2, 0); + + cl[1] = new QLabel( i18n("Group"), groupPermission ); + gl->addWidget (cl[1], 3, 0); + + cl[2] = new QLabel( i18n("Others"), groupPermission ); + gl->addWidget (cl[2], 4, 0); + + la = new QLabel(i18n("UID"), groupPermission); + gl->addWidget(la, 2, 5); + + la = new QLabel(i18n("GID"), groupPermission); + gl->addWidget(la, 3, 5); + + la = new QLabel(i18n("Sticky"), groupPermission); + gl->addWidget(la, 4, 5); + + for (int row = 0; row < 3 ; ++row) { + for (int col = 0; col < 4; ++col) { + QCheckBox *cb = new QCheckBox(groupPermission); + permBox[row][col] = cb; + gl->addWidget (permBox[row][col], row+2, col+1); + + permBox[row][0]->setChecked( TRUE ); + } + } + permBox[0][1]->setChecked( TRUE ); + + gl->setColStretch(6, 10); + + checkOwner = new QCheckBox( i18n("Change &Owner"), w ); + + groupOwner = new QGroupBox ( i18n("Ownership"), w ); + groupOwner->setEnabled( FALSE ); + groupOwner->setColumnLayout(0, Qt::Vertical ); + groupOwner->layout()->setSpacing( 6 ); + groupOwner->layout()->setMargin( 11 ); + groupOwnerLayout = new QVBoxLayout( groupOwner->layout() ); + groupOwnerLayout->setAlignment( Qt::AlignTop ); + + Layout2 = new QHBoxLayout( 0, 0, 6 ); + Layout3 = new QHBoxLayout( 0, 0, 6 ); + Layout4 = new QHBoxLayout( 0, 0, 6 ); + + la = new QLabel( i18n("User:"), groupOwner ); + Layout2->addWidget( la ); + la = new QLabel( i18n("Group:"), groupOwner ); + Layout3->addWidget( la ); + + username = new KComboBox( groupOwner ); + uid = geteuid(); + + setpwent(); + for (i=0; ((user = getpwent()) != 0L) && (i < MAXENTRIES); i++) { + if( uid == 0 ) + username->insertItem(QString::fromLatin1(user->pw_name)); + else + if( user->pw_uid == uid ) + username->insertItem(QString::fromLatin1(user->pw_name)); + } + endpwent(); + + groupname = new KComboBox( groupOwner ); + user = getpwuid(geteuid()); + QString strUser = user->pw_name; + + setgrent(); + for (i=0; ((ge = getgrent()) != 0L) && (i < MAXENTRIES); i++) { + if( uid == 0 ) { + groupname->insertItem(QString::fromLatin1(ge->gr_name)); + } else { + char ** members = ge->gr_mem; + char * member; + + while ((member = *members) != 0L) { + if (strUser == member) { + groupname->insertItem(QString::fromLatin1(ge->gr_name)); + break; + } + + ++members; + } + } + } + endgrent(); + + /* add the users group */ + ge = getgrgid (getegid()); + if (ge) { + QString name = QString::fromLatin1(ge->gr_name); + if (name.isEmpty()) + name.setNum(ge->gr_gid); + + groupname->insertItem( name ); + } + + // make the users group visible + groupname->setCurrentItem( groupname->count() ); + + QSpacerItem* spacer8 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + QSpacerItem* spacer9 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + Layout2->addWidget( username ); + Layout2->addItem( spacer8 ); + Layout3->addWidget( groupname ); + Layout3->addItem( spacer9 ); + + groupOwnerLayout->addLayout( Layout2 ); + groupOwnerLayout->addLayout( Layout3 ); + + QSpacerItem* spacer10 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + Layout4->addWidget( checkPermissions ); + Layout4->addWidget( checkOwner ); + + l->addLayout( Layout4 ); + l->addWidget( groupPermission ); + l->addWidget( groupOwner ); + l->addItem( spacer10 ); + + connect( checkOwner, SIGNAL(clicked()), this, SLOT(enableControls()) ); + connect( checkPermissions, SIGNAL(clicked()), this, SLOT(enableControls()) ); +} + +void MyPermPlugin::fillStructure() +{ + perm.changeOwner = checkOwner->isChecked(); + perm.changePermissions = checkPermissions->isChecked(); + if( perm.changeOwner ) { + perm.group = groupname->currentText(); + perm.owner = username->currentText(); + } + + if( perm.changePermissions ) + perm.newPermission = getPermissions(); + +} + +QString MyPermPlugin::processFile( BatchRenamer* b, int i, QString, int ) +{ + QString filename = b->files()[i].dst.name; + if( perm.changePermissions ) + if( chmod( (const char *)filename, (mode_t)perm.newPermission ) == -1 ) + return QString( i18n("Can't chmod %1.") ).arg(filename); + + if( perm.changeOwner ) + if( chown( (const char*)filename, getUid( perm.owner), getGid( perm.group ))) + return QString( i18n("Can't chown %1.") ).arg(filename); + + return QString::null; +} + +void MyPermPlugin::finished() +{ + // We don't care about this event! + return; +} + +int MyPermPlugin::getPermissions() +{ + int fperm[3][4] = { + {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID}, + {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID}, + {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX} + }; + + int permissions = 0, mask = 0; + + for (int row = 0;row < 3; ++row) + for (int col = 0; col < 4; ++col) + { + switch (permBox[row][col]->state()) + { + case QCheckBox::On: + permissions |= fperm[row][col]; + //fall through + case QCheckBox::Off: + mask |= fperm[row][col]; + break; + default: + break; + } + } + + return permissions; +} + +int MyPermPlugin::getGid( QString group ) +{ + int i, r; + struct group *ge; + setgrent(); + for (i=0; ((ge = getgrent()) != 0L) && (i < MAXENTRIES); i++) + if( !strcmp( ge->gr_name, (const char *)group ) ) + break; + r = ge->gr_gid; + endgrent(); + return r; +} + +int MyPermPlugin::getUid( QString owner ) +{ + int i, r; + struct passwd *user; + setpwent(); + for (i=0; ((user = getpwent()) != 0L) && (i < MAXENTRIES); i++) + if( !strcmp(user->pw_name, (const char *)owner) ) + break; + r = user->pw_uid; + endpwent(); + return r; +} + +void MyPermPlugin::enableControls() +{ + groupOwner->setEnabled( checkOwner->isChecked() ); + groupPermission->setEnabled( checkPermissions->isChecked() ); +} + +const QPixmap MyPermPlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "clanbomber", KIcon::Small ); +} + + diff --git a/krename/permission.h b/krename/permission.h new file mode 100644 index 0000000..5bbf66b --- /dev/null +++ b/krename/permission.h @@ -0,0 +1,90 @@ +/*************************************************************************** + permission.h - description + ------------------- + begin : Sun Jan 13 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PERMISSION_H +#define PERMISSION_H + +/* + * This two includes are required, because you have to use + * krenames internal structures and enums. + */ +#include "batchrenamer.h" +#include "pluginloader.h" +#include "plugin.h" +#include "helpdialog.h" + +#include <stdio.h> + +class KComboBox; +class QCheckBox; +class QGroupBox; +class QVBoxLayout; +class QHBoxLayout; +class QString; +class QWidget; + + +// Plugin class starts here +class MyPermPlugin: public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + + bool checkError(); + void drawInterface( QWidget* w, QVBoxLayout* l ); + void fillStructure(); + QString processFile( BatchRenamer* b, int, QString token, int ); + void finished(); + const QPixmap getIcon() const; + + private: + int getPermissions(); + int getGid( QString group ); + int getUid( QString owner ); + + struct pervals { + bool changePermissions; + bool changeOwner; + + QString owner; // name of owner + QString group; // name of group + + int newPermission; // Permissions + }perm; + + private slots: + void enableControls(); + + protected: + QGroupBox* groupPermission; + QGroupBox* groupOwner; + QCheckBox* checkPermissions; + QCheckBox* checkOwner; + QCheckBox* permBox[3][4]; + KComboBox* username; + KComboBox* groupname; + + QVBoxLayout* groupOwnerLayout; + QVBoxLayout* Layout0; + QHBoxLayout* Layout2; + QHBoxLayout* Layout3; + QHBoxLayout* Layout4; +}; + +#endif diff --git a/krename/pictureplugin.cpp b/krename/pictureplugin.cpp new file mode 100644 index 0000000..d0a0bc3 --- /dev/null +++ b/krename/pictureplugin.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + pictureplugin.cpp - description + ------------------- + begin : Son Apr 14 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "pictureplugin.h" + +// QT includes +#include <qimage.h> + +// KDE includes +#include <kapplication.h> +#include <klocale.h> + +PicturePlugin::PicturePlugin() + : FilePlugin( 0 ) +{ + keys.append( "resolution" ); + keys.append( "xres" ); + keys.append( "yres" ); + keys.append( "bitdepth" ); + setupKeys(); + + m_icon = "image"; +} + +const QString PicturePlugin::getName() const +{ + return i18n("Picture Plugin"); +} + +const QString PicturePlugin::getAccelName() const +{ + return i18n("P&icture Plugin"); +} + +const QString PicturePlugin::getPattern() const +{ + return "pic"; +} + +QString PicturePlugin::processFile( BatchRenamer* b, int i, QString token, int ) +{ + QString resolution; + QString xres; + QString yres; + QString bitdepth; + + QString filename = BatchRenamer::buildFilename( &b->files()[i].src ); + + token = token.lower(); + + /* + * Check if we have something cached for this file + */ + if( cache.contains( filename + "::" + token ) ) + return cache[filename + "::" + token ]; + + QImage img( filename ); + if( img.isNull() ) + return QString::null; + + resolution = QString( "%1x%2" ).arg(img.width()).arg(img.height()); + xres = QString::number( img.width() ); + yres = QString::number( img.height() ); + bitdepth = QString::number( img.depth() ); + + if( cache.count() >= CACHE_MAX ) + cache.remove( cache.begin() ); + + QString ret = QString::null; + + if( token == getPattern() + "resolution" ) + ret = resolution; + else if( token == getPattern() + "xres" ) + ret = xres; + else if( token == getPattern() + "yres" ) + ret = yres; + else if( token == getPattern() + "bitdepth" ) + ret = bitdepth; + + cache.insert( filename + "::" + token, ret ); + return ret; +} + + diff --git a/krename/pictureplugin.h b/krename/pictureplugin.h new file mode 100644 index 0000000..1fcc28f --- /dev/null +++ b/krename/pictureplugin.h @@ -0,0 +1,40 @@ +/*************************************************************************** + pictureplugin.h - description + ------------------- + begin : Son Apr 14 2002 + copyright : (C) 2002 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PICTUREPLUGIN_H +#define PICTUREPLUGIN_H + +#include "batchrenamer.h" +#include "pluginloader.h" +#include "fileplugin.h" + +class QVBoxLayout; +class QHBoxLayout; +class QString; +class QWidget; +class PicturePlugin : public FilePlugin { + Q_OBJECT + public: + PicturePlugin(); + + const QString getName() const; + const QString getAccelName() const; + const QString getPattern() const; + QString processFile( BatchRenamer* b, int i, QString token, int ); +}; + +#endif diff --git a/krename/plugin.cpp b/krename/plugin.cpp new file mode 100644 index 0000000..92460d9 --- /dev/null +++ b/krename/plugin.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + plugin.cpp - description + ------------------- + begin : Sun Dec 30 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "plugin.h" +#include "helpdialog.h" + +#include <qpixmap.h> + +Plugin::Plugin() +{ + m_widget = NULL; +} + +Plugin::~Plugin() +{ + delete m_widget; +} + +void Plugin::addHelp( HelpDialogData* ) { } +void Plugin::removeHelp( HelpDialogData* data ) +{ + data->remove( getName() ); +} + +bool Plugin::alwaysUsed() const +{ + return false; +} + +const QStringList Plugin::getKeys() const +{ + return QStringList(); +} + +const QString Plugin::getPattern() const +{ + return QString::null; +}; + +const QPixmap Plugin::getIcon() const +{ + return QPixmap(); +} + +void Plugin::clearCache() +{ + // do nothing... +} diff --git a/krename/plugin.h b/krename/plugin.h new file mode 100644 index 0000000..0b987d3 --- /dev/null +++ b/krename/plugin.h @@ -0,0 +1,72 @@ +/*************************************************************************** + plugin.h - description + ------------------- + begin : Sun Dec 30 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include "batchrenamer.h" + +#include <qobject.h> + +class HelpDialogData; + +class QString; +class QStringList; +class QWidget; +class QVBoxLayout; +class Plugin : public QObject { + Q_OBJECT + public: + Plugin(); + virtual ~Plugin(); + + virtual const QString getName() const = 0; + virtual const QString getAccelName() const = 0; + virtual const QString getPattern() const; + virtual const int type() const = 0; + virtual bool alwaysUsed() const; + + virtual bool checkError() = 0; + virtual void drawInterface( QWidget* w, QVBoxLayout* l ) = 0; + virtual void fillStructure() { } + virtual QString processFile( BatchRenamer* b, int i, QString token, int mode ) = 0; + virtual void finished() { } + + virtual void addHelp( HelpDialogData* data ); + virtual void removeHelp( HelpDialogData* data ); + + virtual void clearCache(); + + virtual const QPixmap getIcon() const; + virtual const QStringList getKeys() const; + + signals: + void previewChanged( Plugin* plugin ); + + protected slots: + // call this method when your plugin settings changed + // in a way, that KRename should update its preview + void updatePreview() + { + emit previewChanged( this ); + } + + protected: + QWidget* m_widget; +}; + +#endif diff --git a/krename/pluginloader.cpp b/krename/pluginloader.cpp new file mode 100644 index 0000000..4e5c300 --- /dev/null +++ b/krename/pluginloader.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** + pluginloader.cpp - description + ------------------- + begin : Sun Dec 30 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* + * Parts of this code are copied from + * Franz Schmid's <Franz.Schmid@altmuehlnet.de> + * Scribus. + */ + +// Own includes +#include "pluginloader.h" +#include "fileplugin.h" +#include "datetime.h" +#include "mydirplugin.h" +#include "permission.h" +#include "pictureplugin.h" +#include "commandplugin.h" +#include "dateplugin.h" +#include "encodingplugin.h" +#include "translitplugin.h" + +// QT includes +#include <qregexp.h> +#include <qstringlist.h> + +// KDE includes +#include <kapplication.h> +#include <kservice.h> + +/* use a prime number here */ +#define DICT_SIZE 43 +#define BRACKET_CACHE_COUNT 19 + +PluginLoader::PluginLoader() +{ + libs.setAutoDelete( true ); + m_loaded = false; + m_file = false; +} + +PluginLoader::~PluginLoader() +{ } + +PluginLoader* PluginLoader::instance() +{ + if( !m_plugin ) + m_plugin = new PluginLoader(); + + return m_plugin; +} + +PluginLoader* PluginLoader::m_plugin = NULL; + +void PluginLoader::loadPlugins( bool fileplugins ) +{ + int i; + + // make sure all plugins with display + // get deleted and the GUI is rebuild + if( m_loaded ) + { + for( i=0;i<NUM_INTERNAL_PLUGINS;i++ ) + { + for( unsigned int z=0;z<libs.count();z++ ) + if( libs.at(z)->plugin == m_internal_plugins[i] ) + { + libs.remove( z ); + break; + } + } + } + + m_loaded = true; + m_internal_plugins[0] = new CommandPlugin(); + m_internal_plugins[1] = new MyPermPlugin(); + m_internal_plugins[2] = new MyDatePlugin(); + m_internal_plugins[3] = new MyDirPlugin(); + m_internal_plugins[4] = new PicturePlugin(); + m_internal_plugins[5] = new EncodingPlugin(); + m_internal_plugins[6] = new DatePlugin(); + m_internal_plugins[7] = new TranslitPlugin(); + + for( i=0;i<NUM_INTERNAL_PLUGINS;i++ ) + addPlugin( m_internal_plugins[i] ); + + if( fileplugins && !m_file ) + loadFilePlugins(); + + m_bracket_map.clear(); + QPtrListIterator<PluginLoader::PluginLibrary> it( libs ); + for( ; it.current(); ++it ) { + if( (*it)->plugin->type() == TYPE_BRACKET ) { + const QStringList list = (*it)->plugin->getKeys(); + for( unsigned int i = 0; i < list.count(); i++ ) + m_bracket_map.insert( list[i].lower(), (*it)->plugin ); + } + } + +} + +void PluginLoader::clearCache() +{ + QPtrListIterator<PluginLoader::PluginLibrary> it( libs ); + for( ; it.current(); ++it ) + (*it)->plugin->clearCache(); +} + +Plugin* PluginLoader::findPlugin( const QString & token ) +{ + // Optimize a little bit for speed and convert only once to lower() + QString lower = token.lower(); + + if( m_bracket_cache.contains( lower ) ) + return m_bracket_cache[lower]; + + /* The new version is slower than the old one :-( + */ + QMap<QString,Plugin*>::Iterator it; + for ( it = m_bracket_map.begin(); it != m_bracket_map.end(); ++it ) + { + if( QRegExp( it.key() ).exactMatch( lower ) ) + { + m_bracket_cache.insert( lower, it.data(), true ); + if( m_bracket_cache.count() > BRACKET_CACHE_COUNT ) + m_bracket_cache.remove( m_bracket_cache.begin() ); + + return it.data(); + } + } + + // add typos to the cache, too: + // So that we find immediately that this key is not supported. + m_bracket_cache.insert( lower, NULL, true ); + if( m_bracket_cache.count() > BRACKET_CACHE_COUNT ) + m_bracket_cache.remove( m_bracket_cache.begin() ); + + return NULL; +} + +void PluginLoader::addPlugin( Plugin* plugin ) +{ + PluginLibrary* listitem=new PluginLibrary; + listitem->plugin = plugin; + listitem->check = NULL; + listitem->usePlugin = plugin->alwaysUsed(); + libs.append( listitem ); +} + +void PluginLoader::loadFilePlugins() +{ + KService::List list = KService::allServices(); + for( unsigned int i = 0; i < list.count(); i++ ) { + KService* s = (KService*)list[i]; + if( !s->terminal() && s->type() == "Service" && s->hasServiceType( "KFilePlugin" ) ) { + FilePlugin* kfileplugin = new FilePlugin( s ); + if( kfileplugin->isValid() ) { + addPlugin( kfileplugin ); + kapp->processEvents(); + } else + delete kfileplugin; + } + } + + m_file = true; +} diff --git a/krename/pluginloader.h b/krename/pluginloader.h new file mode 100644 index 0000000..234a35c --- /dev/null +++ b/krename/pluginloader.h @@ -0,0 +1,92 @@ +/*************************************************************************** + pluginloader.h - description + ------------------- + begin : Sun Dec 30 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PLUGINLOADER_H +#define PLUGINLOADER_H + +// Own includes +#include "batchrenamer.h" +#include "plugin.h" + +#include <qmap.h> +#include <qptrlist.h> + +class QCheckBox; +class QVBoxLayout; +class QString; +class QWidget; + +#define NUM_INTERNAL_PLUGINS 8 + +enum pluginType { + TYPE_BRACKET = 2, // Plugin argument is in brackets like [artist] or [1-2] + TYPE_TOKEN = 4, // Plugin has its own reserved token like ,& or / + TYPE_FINAL_FILE = 8, // Plugin does something with the final file + // i.e. that is not changing its name but its permission or similar! + TYPE_FINAL_FILENAME = 16 // Plugin changes the final filename before renaming +}; + +class PluginLoader { + public: + // For RedHat :) + struct PluginLibrary { + Plugin *plugin; + bool usePlugin; + + /* access this member only + * from within KRenameImpl + * when the GUI is already constructed! + */ + QCheckBox* check; + }; + + static PluginLoader* instance(); + + void loadPlugins( bool fileplugins ); + QPtrList<PluginLoader::PluginLibrary> libs; + + Plugin* findPlugin( const QString & token ); + + inline bool filePluginsLoaded() const; + + void clearCache(); + + private: + PluginLoader(); + ~PluginLoader(); + + void addPlugin( Plugin* plugin ); + void loadFilePlugins(); + + private: + + Plugin* m_internal_plugins[NUM_INTERNAL_PLUGINS]; + static PluginLoader* m_plugin; + + QMap<QString,Plugin*> m_bracket_map; + QMap<QString,Plugin*> m_bracket_cache; + + bool m_loaded; + bool m_file; +}; + +bool PluginLoader::filePluginsLoaded() const +{ + return m_file; +} + +#endif diff --git a/krename/profiledlg.cpp b/krename/profiledlg.cpp new file mode 100644 index 0000000..621d51f --- /dev/null +++ b/krename/profiledlg.cpp @@ -0,0 +1,602 @@ +/*************************************************************************** + profiledlg.cpp - description + ------------------- + begin : Sat Nov 20 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "profiledlg.h" +#include "krenameimpl.h" +#include "kmyhistorycombo.h" +#include "pluginloader.h" +#include "kmylistbox.h" + +#include <kapplication.h> +#include <kcombobox.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <kinputdialog.h> +#include <klistbox.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kstandarddirs.h> +#include <kurlrequester.h> + +#include <qcheckbox.h> +#include <qdom.h> +#include <qfile.h> +#include <qlayout.h> +#include <qpainter.h> +#include <qradiobutton.h> +#include <qtooltip.h> + +#ifdef HAVE_CONFIG_H + #include <config.h> +#endif + +#ifndef VERSION + #define VERSION "unknown" +#endif + +#define PROFILE_WIZARD_INDEX 0 +#define PROFILE_TABBED_INDEX 1 + +#define PROFILE_WIZARD_NAME i18n("KRename: Wizard default profile") +#define PROFILE_TABBED_NAME i18n("KRename: Tabbed default profile") + +class ProfileListBoxText : public QListBoxText { + +public: + ProfileListBoxText( const QString & text = QString::null ) + : QListBoxText( text ) + { + m_default = false; + } + + inline bool isDefault() const { + return m_default; + } + + inline void setDefault( const bool b ) { + m_default = b; + } + +protected: + void paint( QPainter* painter ) + { + QFont f = painter->font(); + f.setBold( m_default ); + painter->setFont( f ); + + QListBoxText::paint( painter ); + } + +private: + bool m_default; + +}; + +ProfileManager::ProfileManager( KRenameImpl* krename ) + : m_krename( krename ) +{ + +} + +const QString ProfileManager::readProfilePath( const QString & name ) +{ + QString path; + KConfig* conf = kapp->config(); + + conf->setGroup( "Profiles" ); + path = conf->readEntry( name, QString::null ); + + return path; +} + +const QString ProfileManager::getProfilePath( const QString & name ) +{ + QStringList list; + + if( name == PROFILE_WIZARD_NAME ) + return locate( "data", "krename/krename_system_default_wizard.xml" ); + else if( name == PROFILE_TABBED_NAME ) + return locate( "data", "krename/krename_system_default_tabbed.xml" ); + + QString path = locateLocal( "data", QString( "krename/%1.xml" ).arg( name ) ); + + KConfig* conf = kapp->config(); + + conf->setGroup( "ProfilesHeader" ); + list = conf->readListEntry( "list" ); + if( !list.contains( name ) ) + list.append( name ); + conf->writeEntry( "list", list ); + + conf->setGroup( "Profiles" ); + conf->writeEntry( name, path ); + conf->sync(); + + return path; +} + +void ProfileManager::writeXML( const QString & name ) +{ + QString path = getProfilePath( name ); + QFile file( path ); + + if( !file.open( IO_WriteOnly ) ) + { + qDebug("Cannot write to: %s", path.latin1() ); + return; + } + + QDomDocument doc( "KRenameProfile" ); + QDomElement root = doc.createElement( "krename" ); + doc.appendChild( root ); + + QDomElement v = doc.createElement( "version" ); + v.setAttribute( "version", VERSION ); + root.appendChild( v ); + + // General settings of Krename + QDomElement settings = doc.createElement( "settings" ); + settings.setAttribute( "wizard", m_krename->m_wizard ); + settings.setAttribute( "fileplugins", m_krename->plugin->filePluginsLoaded() ); + root.appendChild( settings ); + + // Filename settings + QDomElement filename = doc.createElement( "filename" ); + filename.setAttribute( "filename", m_krename->filename->text() ); + filename.setAttribute( "extension", m_krename->extemplate->text() ); + filename.setAttribute( "extension_enabled", m_krename->checkExtension->isChecked() ); + filename.setAttribute( "extension_start", m_krename->comboExtension->currentItem() ); + + QDomElement numbering = doc.createElement( "numbering" ); + numbering.setAttribute( "start", m_krename->m_index ); + numbering.setAttribute( "step", m_krename->m_step ); + numbering.setAttribute( "skip", listToString( m_krename->skip ) ); + numbering.setAttribute( "reset", m_krename->m_reset ); + + QDomElement replace = doc.createElement( "replace" ); + for( unsigned int i=0;i<m_krename->rep.count();i++) + { + QDomElement r = doc.createElement( "item" ); + r.setAttribute( "find", m_krename->rep[i].find ); + r.setAttribute( "replace", m_krename->rep[i].replace ); + r.setAttribute( "reg", m_krename->rep[i].reg ); + + replace.appendChild( r ); + } + + // destination settings + QDomElement dest = doc.createElement( "destination" ); + dest.setAttribute( "mode", m_krename->currentRenameMode() ); + dest.setAttribute( "overwrite", QString::number( m_krename->checkOverwrite->isChecked() ) ); + dest.setAttribute( "directory", m_krename->dirname->text() ); + dest.setAttribute( "undo", QString::number( m_krename->checkUndoScript->isChecked() ) ); + dest.setAttribute( "undoscript", m_krename->undorequester->url() ); + + // file adding settings + QDomElement files = doc.createElement( "files" ); + files.setAttribute( "sorting", QString::number( m_krename->comboSort->currentItem() ) ); + files.setAttribute( "preview", QString::number( m_krename->checkPreview->isChecked() ) ); + files.setAttribute( "names", QString::number( m_krename->checkName->isChecked() ) ); + + filename.appendChild( replace ); + filename.appendChild( numbering ); + root.appendChild( settings ); + root.appendChild( filename ); + root.appendChild( dest ); + root.appendChild( files ); + + QCString xml = doc.toCString(); + file.writeBlock( xml, xml.length() ); + file.close(); +} + +bool ProfileManager::loadXML( const QString & path ) +{ + QFile file( path ); + + if( !file.open( IO_ReadOnly ) ) + { + qDebug("Cannot read from: %s", path.latin1() ); + return false; + } + + QDomDocument doc( "KRenameProfile" ); + if ( !doc.setContent( &file ) ) + { + file.close(); + return false; + } + + QDomNode n = doc.documentElement().firstChild(); + while( !n.isNull() ) + { + QDomElement e = n.toElement(); // try to convert the node to an element. + if( !e.isNull() ) + { + if( e.tagName() == "settings" ) + { + bool wiz, plug; + wiz = (bool)e.attribute( "wizard", + QString( "%1" ).arg( m_krename->m_wizard ) ).toInt(); + + m_krename->setWizardMode( wiz ); +// if( wiz != m_krename->m_wizard ) + { + m_krename->m_wizard = wiz; + m_krename->changeGUIMode(); + } + + plug = (bool)e.attribute( "fileplugins", + QString( "%1" ).arg( m_krename->plugin->filePluginsLoaded() ) ).toInt(); + if( plug && !m_krename->plugin->filePluginsLoaded() ) + m_krename->plugin->loadPlugins( true ); + } + else if( e.tagName() == "filename" ) + { + m_krename->filename->setText( e.attribute("filename", m_krename->filename->text() ) ); + m_krename->extemplate->setText( e.attribute("extension", m_krename->extemplate->text() ) ); + m_krename->checkExtension->setChecked( + (bool)e.attribute("extension_enabled", + QString("%1").arg(m_krename->checkExtension->isChecked() ) ).toInt() ); + m_krename->comboExtension->setCurrentItem( + e.attribute("extension_start", + QString::number( m_krename->comboExtension->currentItem() ) ).toInt() ); + + QDomNode n = e.firstChild(); + while( !n.isNull() ) + { + QDomElement e = n.toElement(); // try to convert the node to an element. + if( !e.isNull() ) + { + if( e.tagName() == "numbering" ) + { + m_krename->m_index = e.attribute( "start", QString::number( m_krename->m_index ) ).toInt(); + m_krename->m_step = e.attribute( "step", QString::number( m_krename->m_step ) ).toInt(); + m_krename->skip = stringToList( e.attribute("skip", listToString( m_krename->skip ) ) ); + m_krename->m_reset = (bool)e.attribute( "reset", QString::number( (int)m_krename->m_reset ) ).toInt(); + } + else if( e.tagName() == "replace" ) + { + m_krename->rep.clear(); + QDomNode n = e.firstChild(); + while( !n.isNull() ) + { + QDomElement e = n.toElement(); // try to convert the node to an element. + if( !e.isNull() && e.tagName() == "item" ) + { + replacestrings r; + r.find = e.attribute( "find", QString::null ); + r.replace = e.attribute( "replace", QString::null ); + r.reg = (bool)e.attribute( "reg", "0" ).toInt(); + m_krename->rep.append( r ); + } + n = n.nextSibling(); + } + } + } + n = n.nextSibling(); + } + } + else if( e.tagName() == "destination" ) + { + int mode = e.attribute( "mode", QString::number( m_krename->currentRenameMode() ) ).toInt(); + m_krename->optionRename->setChecked( false ); + m_krename->optionCopy->setChecked( false ); + m_krename->optionMove->setChecked( false ); + m_krename->optionLink->setChecked( false ); + + switch( mode ) + { + default: + case RENAME: + m_krename->optionRename->setChecked( true ); break; + case COPY: + m_krename->optionCopy->setChecked( true ); break; + case MOVE: + m_krename->optionMove->setChecked( true ); break; + case LINK: + m_krename->optionLink->setChecked( true ); break; + } + + m_krename->checkOverwrite->setChecked( e.attribute( "overwrite", + QString::number( m_krename->checkOverwrite->isChecked() ) ).toInt() ); + m_krename->dirname->setText( e.attribute( "directory", m_krename->dirname->text() ) ); + m_krename->checkUndoScript->setChecked( e.attribute( "undo", + QString::number( m_krename->checkUndoScript->isChecked() ) ).toInt() ); + m_krename->undorequester->setURL( e.attribute( "undoscript", m_krename->undorequester->url() ) ); + } + else if( e.tagName() == "files" ) + { + m_krename->comboSort->setCurrentItem( e.attribute( "sorting", + QString::number( m_krename->comboSort->currentItem() ) ).toInt() ); + m_krename->checkPreview->setChecked( e.attribute( "preview", + QString::number( m_krename->checkPreview->isChecked() ) ).toInt() ); + m_krename->checkName->setChecked( e.attribute( "names", + QString::number( m_krename->checkName->isChecked() ) ).toInt() ); + } + } + n = n.nextSibling(); + } + + if( m_krename->m_wizard ) + m_krename->parseWizardMode(); + + file.close(); + return true; +} + +const QString ProfileManager::listToString( QValueList<int> & list ) +{ + QString data; + for( unsigned int i = 0; i < list.count(); i++ ) + data += QString( "%1;" ).arg( list[i] ); + + return data; +} + +const QValueList<int> ProfileManager::stringToList( const QString & data ) +{ + QValueList<int> list; + int c = data.contains( ";" ); + if( c > 0 ) + { + for( int i = 0;i<c;i++) + list.append( data.section( ';', i, i ).toInt() ); + } + + return list; +} + +bool ProfileManager::hasDefaultProfile() +{ + KConfig* conf = kapp->config(); + conf->setGroup( "ProfilesHeader" ); + + QString def = conf->readEntry( "defprofile", QString::null ); + + return (!def.isEmpty()); +} + +void ProfileManager::loadDefaultProfile( KRenameImpl* krename ) +{ + KConfig* conf = kapp->config(); + conf->setGroup( "ProfilesHeader" ); + + QString def = conf->readEntry( "defprofile", QString::null ); + + if( !def.isEmpty() ) + ProfileManager::loadProfile( def, krename ); +} + +void ProfileManager::loadProfile( const QString & name, KRenameImpl* krename ) +{ + ProfileManager manager( krename ); + manager.loadXML( manager.getProfilePath( name ) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +ProfileDlg::ProfileDlg(KRenameImpl* krename, QWidget *parent, const char *name) + : KDialogBase( KDialogBase::Plain, i18n("Profiles"), + KDialogBase::Close, KDialogBase::Close, parent, name, true, true ), ProfileManager( krename ) +{ + int i; + + QHBoxLayout* layout = new QHBoxLayout( plainPage(), 6, 6 ); + QVBoxLayout* button = new QVBoxLayout( 0, 6, 6 ); + + profiles = new KListBox( plainPage() ); + profiles->insertItem( new ProfileListBoxText( PROFILE_WIZARD_NAME ), PROFILE_WIZARD_INDEX ); + profiles->insertItem( new ProfileListBoxText( PROFILE_TABBED_NAME ), PROFILE_TABBED_INDEX ); + + createProfile = new KPushButton( i18n("&Save As Profile..."), plainPage() ); + loadProfile = new KPushButton( i18n("&Load Profile"), plainPage() ); + deleteProfile = new KPushButton( i18n("&Delete Profile"), plainPage() ); + checkDefault = new QCheckBox( i18n("&Use as default profile on startup"), plainPage() ); + + createProfile->setIconSet( SmallIconSet( "filesaveas") ); + loadProfile->setIconSet( SmallIconSet( "fileopen" ) ); + deleteProfile->setIconSet( SmallIconSet( "edittrash" ) ); + + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding ); + button->addWidget( createProfile ); + button->addWidget( loadProfile ); + button->addWidget( deleteProfile ); + button->addItem( spacer ); + button->addWidget( checkDefault ); + + layout->addWidget( profiles ); + layout->addLayout( button ); + layout->setStretchFactor( profiles, 2 ); + + QToolTip::add( createProfile, i18n("<qt>Save KRename's current settings as a new profile. " + "The settings are saved and can be restored with Load Profile later.</qt>" ) ); + QToolTip::add( loadProfile, i18n("<qt>Load all settings stored in this profile.</qt>") ); + + enableControls(); + + connect( createProfile, SIGNAL( clicked() ), this, SLOT( slotCreateProfile() ) ); + connect( loadProfile, SIGNAL( clicked() ), this, SLOT( slotLoadProfile() ) ); + connect( deleteProfile, SIGNAL( clicked() ), this, SLOT( slotDeleteProfile() ) ); + connect( profiles, SIGNAL( selectionChanged () ), this, SLOT( enableControls() ) ); + connect( checkDefault, SIGNAL( clicked() ), this, SLOT( slotSetDefault() ) ); + connect( this, SIGNAL( hidden() ), this, SLOT( slotHidden() ) ); + + KConfig* conf = kapp->config(); + conf->setGroup( "ProfilesHeader" ); + ProfileListBoxText* item; + + QStringList list = conf->readListEntry( "list" ); + QString def = conf->readEntry( "defprofile", QString::null ); + for( i=0;i<(int)list.count();i++ ) + profiles->insertItem( new ProfileListBoxText( list[i] ) ); + + for( i=0;i<(int)profiles->count();i++ ) + { + item = static_cast<ProfileListBoxText*>(profiles->item(i)); + if( item->text() == def ) + { + item->setDefault( true); + break; + } + } + + profiles->repaintContents(); +} + + +ProfileDlg::~ProfileDlg() +{ +} + + +void ProfileDlg::enableControls() +{ + ProfileListBoxText* item; + + loadProfile->setEnabled( profiles->selectedItem() ); + // Do not allow to delete the two default profiles + deleteProfile->setEnabled( profiles->selectedItem() && + profiles->currentItem() != PROFILE_TABBED_INDEX && profiles->currentItem() != PROFILE_WIZARD_INDEX ); + checkDefault->setEnabled( profiles->selectedItem() ); + + item = static_cast<ProfileListBoxText*>(profiles->selectedItem()); + checkDefault->setChecked( item && item->isDefault() ); +} + +void ProfileDlg::slotSetDefault() +{ + int i; + ProfileListBoxText* item; + + for( i=0;i<(int)profiles->count();i++ ) + { + item = static_cast<ProfileListBoxText*>(profiles->item( i )); + item->setDefault( false ); + } + + item = static_cast<ProfileListBoxText*>(profiles->selectedItem()); + if( item ) + item->setDefault( checkDefault->isChecked() ); + + profiles->repaintContents(); +} + +void ProfileDlg::slotLoadProfile() +{ + QString profile = profiles->currentText(); + QString msg = QString( i18n("Do you really want to load the profile and overwrite the current settings: %1") ).arg( profile ); + + QString path = getProfilePath( profile ); + + if( path.isEmpty() ) + { + KMessageBox::error( this, i18n("The profile \"%1\" could not be found.").arg( profile ) ); + return; + } + + if( KMessageBox::questionYesNo( this, msg ) == KMessageBox::Yes ) + { + if( loadXML( path ) ) + this->close(); + + enableControls(); + + m_krename->enableControls(); + m_krename->updatePre(); + } +} + +void ProfileDlg::slotCreateProfile() +{ + bool ok = false; + const char* mask = "xXXXXXXXXXXXXXXXXXXX"; // allows for 20 characters + QString name = KInputDialog::getText( i18n("Profile Name"), i18n("Please enter a name for the new profile:"), + "KRename", &ok, this, 0, 0, mask ); + + if( !ok ) + return; + + if( profiles->findItem( name, Qt::ExactMatch ) ) + { + KMessageBox::error( this, i18n("This profile does already exist. Please choose another name.") ); + slotCreateProfile(); + return; + } + + profiles->insertItem( new ProfileListBoxText( name ) ); + writeXML( name ); + + enableControls(); +} + +void ProfileDlg::slotDeleteProfile() +{ + if( profiles->currentItem() == PROFILE_WIZARD_INDEX || profiles->currentItem() == PROFILE_TABBED_INDEX ) + { + KMessageBox::error( this, i18n("You cannot delete default profiles!") ); + return; + } + + QString profile = profiles->currentText(); + QString msg = QString( i18n("Do you really want to delete the profile: %1") ).arg( profile ); + + if( KMessageBox::questionYesNo( this, msg ) == KMessageBox::Yes ) + { + QString path = readProfilePath( profile ); + QFile::remove( path ); + + QListBoxItem* item = profiles->findItem( profile, Qt::ExactMatch ); + if( item ) + delete item; + + KConfig* conf = kapp->config(); + + conf->setGroup( "ProfilesHeader" ); + QStringList list = conf->readListEntry( "list" ); + list.remove( profile ); + conf->writeEntry( "list", list ); + conf->sync(); + + enableControls(); + } +} + +void ProfileDlg::slotHidden() +{ + int i; + KConfig* conf = kapp->config(); + QString def = QString::null; + ProfileListBoxText* item; + + for( i=0;i<(int)profiles->count();i++ ) + { + item = static_cast<ProfileListBoxText*>(profiles->item( i )); + if( item->isDefault() ) + { + def = profiles->text( i ); + break; + } + } + + conf->setGroup( "ProfilesHeader" ); + conf->writeEntry( "defprofile", def ); + conf->sync(); +} + +#include "profiledlg.moc" diff --git a/krename/profiledlg.h b/krename/profiledlg.h new file mode 100644 index 0000000..a9a29c3 --- /dev/null +++ b/krename/profiledlg.h @@ -0,0 +1,79 @@ +/*************************************************************************** + profiledlg.h - description + ------------------- + begin : Sat Nov 20 2004 + copyright : (C) 2004 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PROFILEDLG_H +#define PROFILEDLG_H + +#include <kdialogbase.h> + +class KListBox; +class KPushButton; +class KRenameImpl; +class QCheckBox; + +class ProfileManager { + public: + ProfileManager( KRenameImpl* krename ); + + static void loadDefaultProfile( KRenameImpl* krename ); + static void loadProfile( const QString & name, KRenameImpl* krename ); + static bool hasDefaultProfile(); + + protected: + const QString getProfilePath( const QString & name ); + const QString readProfilePath( const QString & name ); + + const QString listToString( QValueList<int> & list ); + const QValueList<int> stringToList( const QString & ); + + void writeXML( const QString & name ); + bool loadXML( const QString & path ); + + protected: + KRenameImpl* m_krename; +}; + + +/** +@author Dominik Seichter +*/ +class ProfileDlg : public KDialogBase, public ProfileManager +{ + Q_OBJECT + + public: + ProfileDlg(KRenameImpl* krename, QWidget *parent = 0, const char *name = 0); + ~ProfileDlg(); + + private slots: + void enableControls(); + void slotLoadProfile(); + void slotCreateProfile(); + void slotDeleteProfile(); + void slotSetDefault(); + void slotHidden(); + + private: + KListBox* profiles; + + QCheckBox* checkDefault; + KPushButton* createProfile; + KPushButton* loadProfile; + KPushButton* deleteProfile; +}; + +#endif diff --git a/krename/replacedialog.cpp b/krename/replacedialog.cpp new file mode 100644 index 0000000..342d4d1 --- /dev/null +++ b/krename/replacedialog.cpp @@ -0,0 +1,257 @@ +/*************************************************************************** + replacedialog.cpp - description + ------------------- + begin : Sat Aug 18 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// Own includes +#include "replacedialog.h" + +// QT includes +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qlayout.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> +#include <kpushbutton.h> +#include <kregexpeditorinterface.h> + +ReplaceDialog::ReplaceDialog( QValueList<replacestrings> & r, QWidget* parent ) + : KDialogBase( KDialogBase::Plain, i18n( "Find and Replace" ), + KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, parent, 0, true, true ) +{ + ReplaceDialogLayout = new QGridLayout( plainPage(), 11, 6); + + list = new KListView( plainPage() ); + list->addColumn( i18n("Find") ); + list->addColumn( i18n("Replace With") ); + list->addColumn( i18n("Regular Expression") ); + list->addColumn( "regexp" ); // no i18n, because not user visible +// list->setColumnWidthMode( 0, QListView::Manual ); +// list->setColumnWidthMode( 1, QListView::Manual ); +// list->setColumnWidthMode( 2, QListView::Manual ); + list->setColumnWidthMode( 3, QListView::Manual ); + list->setColumnWidth( 3, 0 ); + list->setSorting( -1 ); + list->setAllColumnsShowFocus( true ); + + TextLabel1 = new QLabel( plainPage() ); + TextLabel1->setText( i18n( "Find:" ) ); + TextLabel2 = new QLabel( plainPage() ); + TextLabel2->setText( i18n( "Replace with:" ) ); + + text1 = new QLineEdit( plainPage() ); + text2 = new QLineEdit( plainPage() ); + + checkReg = new QCheckBox( i18n("&Regular expression"), plainPage() ); + buttonRegEdit = new KPushButton( plainPage() ); + buttonRegEdit->setText( i18n( "&Edit..." ) ); + buttonRegEdit->setEnabled( false ); + + buttonAdd = new KPushButton( plainPage() ); + buttonAdd->setText( i18n( "&Add" ) ); + + buttonEdit = new KPushButton( plainPage() ); + buttonEdit->setText( i18n("&Edit") ); + + buttonRemove = new KPushButton( plainPage() ); + buttonRemove->setText( i18n( "&Remove" ) ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + + ReplaceDialogLayout->addWidget( TextLabel1, 0, 0 ); + ReplaceDialogLayout->addWidget( text1, 0, 1 ); + + ReplaceDialogLayout->addWidget( TextLabel2, 0, 3 ); + ReplaceDialogLayout->addWidget( text2, 0, 4 ); + + ReplaceDialogLayout->addWidget( checkReg, 1, 0 ); + ReplaceDialogLayout->addWidget( buttonRegEdit, 1, 1 ); + + ReplaceDialogLayout->addWidget( buttonAdd, 0, 6 ); + ReplaceDialogLayout->addWidget( buttonEdit, 1, 6 ); + ReplaceDialogLayout->addWidget( buttonRemove, 2, 6 ); + + ReplaceDialogLayout->addItem( spacer, 0, 5 ); + ReplaceDialogLayout->addItem( spacer, 0, 2 ); + ReplaceDialogLayout->addMultiCellWidget( list, 3, 3, 0, 4 ); + + text1->setFocus(); + + connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( add() ) ); + connect( buttonRemove, SIGNAL( clicked() ), this, SLOT( remove() ) ); + connect( list, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( enableControls() ) ); + connect( list, SIGNAL( doubleClicked( QListViewItem* ) ), this, SLOT( slotEdit() ) ); + connect( text2, SIGNAL( returnPressed() ), this, SLOT( add() ) ); + connect( text1, SIGNAL( returnPressed() ), this, SLOT( moveFocus() ) ); + connect( buttonRegEdit, SIGNAL( clicked() ), this, SLOT( invokeRegEdit() ) ); + connect( checkReg, SIGNAL( clicked() ), this, SLOT( enableControls() ) ); + connect( buttonEdit, SIGNAL( clicked() ), this, SLOT( slotEdit() ) ); + + for( unsigned int i = 0; i < r.count(); i++ ) { + replacestrings rs = r[i]; + + BatchRenamer::unEscape( rs.find ); + + KListViewItem* item = new KListViewItem( list ); + item->setText( 0, encode( rs.find ) ); + item->setText( 1, encode( rs.replace ) ); + item->setText( 2, rs.reg ? i18n("yes") : i18n("no") ); + item->setText( 3, QString::number( rs.reg ) ); + list->insertItem( item ); + } + + enableControls(); +} + +ReplaceDialog::~ReplaceDialog() +{ } + +void ReplaceDialog::add() +{ + if( text1->text().isEmpty() ) { + KMessageBox::sorry( this, i18n( "Add a text that should be replaced." ) ); + return; + } + + QListViewItem* it = list->firstChild(); + while( it ) { + if( it->text( 0 ) == text1->text() ) { + KMessageBox::sorry( this, i18n( "You can't replace the same text twice." ) ); + return; + } + it = it->nextSibling(); + } + + KListViewItem* item = new KListViewItem( list, i18n("Regular expression") ); + item->setText( 0, encode( text1->text() ) ); + item->setText( 1, encode( text2->text() ) ); + item->setText( 2, checkReg->isChecked() ? i18n("yes") : i18n("no") ); + item->setText( 3, QString::number( checkReg->isChecked() ) ); + list->insertItem( item ); + + reset(); + + enableControls(); +} + +void ReplaceDialog::remove() +{ + if( list->selectedItem() ) { + QListViewItem* item = list->selectedItem(); + list->takeItem( item ); + delete item; + } + + enableControls(); +} + +QValueList<replacestrings> ReplaceDialog::getList() +{ + QValueList<replacestrings> r; + QListViewItem* item = list->firstChild(); + while( item ) { + replacestrings n; + n.find = decode( item->text( 0 ) ); + n.replace = decode( item->text( 1 ) ); + n.reg = item->text( 3 ).toInt(); + + BatchRenamer::doEscape( n.find ); + + r.append( n ); + + item = item->nextSibling(); + } + return r; +} + +void ReplaceDialog::moveFocus() +{ + text2->setFocus(); +} + +void ReplaceDialog::invokeRegEdit() +{ + QDialog* regExpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this ); + + KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( regExpDialog->qt_cast( "KRegExpEditorInterface" ) ); + if ( !iface ) + return; + + iface->setRegExp( text1->text() ); + bool ok = regExpDialog->exec(); + if ( ok ) + text1->setText( iface->regExp() ); +} + +QString ReplaceDialog::encode( QString s ) +{ + s.append("\""); + s.prepend("\""); + return s; +} + +QString ReplaceDialog::decode( QString s ) +{ + if( s[0] == '"' ) + s.remove( 0, 1 ); + + if( s[s.length()-1] == '"' ) + s.remove( s.length()-1, 1 ); + return s; +} + +void ReplaceDialog::resizeEvent( QResizeEvent* e ) +{ + QDialog::resizeEvent( e ); +// list->setColumnWidth( 0, TextLabel1->width() + text1->width() ); +// list->setColumnWidth( 1, TextLabel2->width() + text2->width() ); +} + +void ReplaceDialog::reset() +{ + text1->clear(); + text2->clear(); + checkReg->setChecked( false ); + text1->setFocus(); +} + +void ReplaceDialog::enableControls() +{ + buttonRemove->setEnabled( list->selectedItem() ); + buttonRegEdit->setEnabled( checkReg->isChecked() && !KTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ); + buttonEdit->setEnabled( list->selectedItem() ); +} + +void ReplaceDialog::slotEdit() +{ + text1->setText( decode( list->selectedItem()->text( 0 ) ) ); + text2->setText( decode( list->selectedItem()->text( 1 ) ) ); + checkReg->setChecked( list->selectedItem()->text( 3 ).toInt() ); + + QListViewItem* item = list->selectedItem(); + list->takeItem( item ); + delete item; + + text1->setFocus(); + + enableControls(); +} diff --git a/krename/replacedialog.h b/krename/replacedialog.h new file mode 100644 index 0000000..0598fcc --- /dev/null +++ b/krename/replacedialog.h @@ -0,0 +1,78 @@ +/*************************************************************************** + replacedialog.h - description + ------------------- + begin : Sat Aug 18 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef REPLACEDIALOG_H +#define REPLACEDIALOG_H + +// QT includes +#include <kdialogbase.h> +#include <qvaluelist.h> + +// Own includes +#include "batchrenamer.h" + +class QCheckBox; +class QGridLayout; +class QGridLayout; +class QLabel; +class QLineEdit; +class KPushButton; +class QListViewItem; +class KListView; +class ReplaceDialog : public KDialogBase +{ + Q_OBJECT + + public: + ReplaceDialog( QValueList<replacestrings> & r, QWidget* parent = 0 ); + ~ReplaceDialog(); + + QValueList<replacestrings> getList(); + + private slots: + void add(); + void moveFocus(); + void remove(); + void invokeRegEdit(); + void enableControls(); + void slotEdit(); + + private: + void reset(); + + QLabel* TextLabel1; + QLineEdit* text2; + QLabel* TextLabel2; + QLineEdit* text1; + KListView* list; + QCheckBox* checkReg; + + KPushButton* buttonAdd; + KPushButton* buttonRemove; + KPushButton* buttonEdit; + KPushButton* buttonRegEdit; + + QString encode( QString s ); + QString decode( QString s ); + + protected: + void resizeEvent( QResizeEvent* e ); + + QGridLayout* ReplaceDialogLayout; +}; + +#endif // REPLACEDIALOG_H diff --git a/krename/semantic.cache b/krename/semantic.cache new file mode 100644 index 0000000..453579e --- /dev/null +++ b/krename/semantic.cache @@ -0,0 +1,15 @@ +;; Object krename/ +;; SEMANTICDB Tags save file +(semanticdb-project-database-file "krename/" + :tables (list + (semanticdb-table "kmylistbox.cpp" + :major-mode 'c++-mode + :tags '(("qcursor.h" include (:system-flag t) nil [1041 1061]) ("qdir.h" include (:system-flag t) nil [1062 1079]) ("qdragobject.h" include (:system-flag t) nil [1080 1104]) ("qpainter.h" include (:system-flag t) nil [1105 1126]) ("qpalette.h" include (:system-flag t) nil [1127 1148]) ("qregexp.h" include (:system-flag t) nil [1149 1169]) ("kapplication.h" include (:system-flag t) nil [1187 1212]) ("kdirlister.h" include (:system-flag t) nil [1213 1236]) ("kiconloader.h" include (:system-flag t) nil [1237 1261]) ("klocale.h" include (:system-flag t) nil [1262 1282]) ("kio/previewjob.h" include (:system-flag t) nil [1283 1310]) ("kio/netaccess.h" include (:system-flag t) nil [1311 1337]) ("qptrlist.h" include (:system-flag t) nil [1338 1359]) ("kurldrag.h" include (:system-flag t) nil [1360 1381]) ("kurllabel.h" include (:system-flag t) nil [1382 1404]) ("kpixmap.h" include (:system-flag t) nil [1405 1425]) ("kpixmapeffect.h" include (:system-flag t) nil [1426 1452]) ("kmylistbox.h" include nil nil [1471 1494]) ("krecursivelister.h" include nil nil [1495 1524]) ("threadedlister.h" include nil nil [1525 1552]) ("KMyListBox" function (:constructor-flag t :parent "KMyListBox" :arguments (("parent" variable (:pointer 1 :type ("QWidget" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1599 1615]) ("name" variable (:pointer 1 :constant-flag t :type "char") (reparse-symbol arg-sub-list) [1616 1633]) ("fl" variable (:type ("WFlags" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1634 1644])) :type ("KMyListBox" type "class")) nil [1576 2387]) ("KMyListBox" function (:destructor-flag t :parent "KMyListBox" :type "void") nil [2389 2418]) ("url" function (:parent "KMyListBox" :arguments (("index" variable (:type "int") (reparse-symbol arg-sub-list) [2442 2453])) :type ("KURL" type (:type "class") nil nil)) nil [2420 2528]) ("dir" function (:parent "KMyListBox" :arguments (("index" variable (:type "int") (reparse-symbol arg-sub-list) [2552 2563])) :type ("bool" type (:type "class") nil nil)) nil [2530 2638]) ("setPreviewSize" function (:parent "KMyListBox" :arguments (("size" variable (:type "int") (reparse-symbol arg-sub-list) [2673 2683])) :type "void") nil [2640 2711]) ("removeItem" function (:parent "KMyListBox" :arguments (("index" variable (:type "int") (reparse-symbol arg-sub-list) [2742 2753])) :type "void") nil [2713 2792]) ("addFile" function (:parent "KMyListBox" :arguments (("filename" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [2820 2842]) ("isfile" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [2843 2856])) :type "void") nil [2794 3135]) ("addDirName" function (:parent "KMyListBox" :arguments (("dirname" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3166 3188])) :type "void") nil [3137 3322]) ("isFile" function (:parent "KMyListBox" :arguments (("f" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3349 3364]) ("autoadd" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3365 3379])) :type ("bool" type (:type "class") nil nil)) nil [3324 3662]) ("addDir" function (:parent "KMyListBox" :arguments (("dirname" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3689 3710]) ("filter" variable (:constant-flag t :type ("QString" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3711 3734]) ("hidden" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3735 3747]) ("recursively" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3748 3765]) ("dirnames" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3766 3781])) :type "void") nil [3664 4122]) ("addDirName" function (:parent "KMyListBox" :arguments (("dirname" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [4153 4174]) ("filter" variable (:constant-flag t :type ("QString" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [4175 4198]) ("hidden" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [4199 4211]) ("recursive" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [4212 4228])) :type "void") nil [4124 4974]) ("dropEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QDropEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [5003 5017])) :type "void") nil [4976 5441]) ("dragEnterEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QDragEnterEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [5475 5494])) :type "void") nil [5443 5572]) ("viewportMousePressEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QMouseEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [5616 5632])) :type "void") nil [5574 5934]) ("viewportMouseMoveEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QMouseEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [5977 5993])) :type "void") nil [5936 6611]) ("viewportMouseReleaseEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QMouseEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [6657 6673])) :type "void") nil [6613 6749]) ("keyPressEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QKeyEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [6783 6797])) :type "void") nil [6751 7951]) ("keyReleaseEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QKeyEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [7987 8001])) :type "void") nil [7953 8135]) ("openFile" function (:parent "KMyListBox" :arguments (("item" variable (:pointer 1 :type ("QListBoxItem" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [8164 8184])) :type "void") nil [8137 8424]) ("moveMode" function (:parent "KMyListBox" :type "void") nil [8426 8569]) ("select" function (:parent "KMyListBox" :arguments (("item" variable (:pointer 1 :type ("QListBoxItem" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [8596 8616])) :type "void") nil [8571 9666]) ("preview" function (:parent "KMyListBox" :arguments (("list" variable (:type ("KURL::List" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [9694 9711])) :type "void") nil [9668 10203]) ("previewDone" function (:parent "KMyListBox" :arguments (("item" variable (:pointer 1 :constant-flag t :type ("KFileItem" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [10235 10257]) ("pixmap" variable (:constant-flag t :type ("QPixmap" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [10258 10281])) :type "void") nil [10205 10615]) ("previewFailed" function (:parent "KMyListBox" :arguments (("item" variable (:pointer 1 :constant-flag t :type ("KFileItem" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [10649 10672])) :type "void") nil [10617 10998]) ("previewFinished" function (:parent "KMyListBox" :type "void") nil [11000 11132]) ("setPreview" function (:parent "KMyListBox" :arguments (("prv" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [11163 11173])) :type "void") nil [11134 11506]) ("setName" function (:parent "KMyListBox" :arguments (("name" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [11534 11545])) :type "void") nil [11508 11743]) ("move" function (:parent "KMyListBox" :arguments (("i" variable (:type "int") (reparse-symbol arg-sub-list) [11768 11775])) :type "void") nil [11745 12288]) ("moveUp" function (:parent "KMyListBox" :type "void") nil [12290 12642]) ("moveUp" function (:parent "KMyListBox" :arguments (("i" variable (:type "int") (reparse-symbol arg-sub-list) [12669 12676])) :type "void") nil [12644 12868]) ("moveDown" function (:parent "KMyListBox" :type "void") nil [12870 13237]) ("moveDown" function (:parent "KMyListBox" :arguments (("i" variable (:type "int") (reparse-symbol arg-sub-list) [13266 13273])) :type "void") nil [13239 13465]) ("isInList" function (:parent "KMyListBox" :arguments (("text" variable (:type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [13494 13505])) :type ("bool" type (:type "class") nil nil)) nil [13467 13766]) ("customEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QCustomEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [13798 13815])) :type "void") nil [13768 13927]) ("listerDone" function (:parent "KMyListBox" :arguments (("lister" variable (:pointer 1 :type ("ThreadedLister" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [13958 13982])) :type "void") nil [13929 14306]) ("runningAddListeners" function (:parent "KMyListBox" :type "unsigned int") nil [14308 14480]) ("sortAscending" function (:parent "KMyListBox" :type "void") nil [14482 14566]) ("sortDescending" function (:parent "KMyListBox" :type "void") nil [14568 14654]) ("sortRandom" function (:parent "KMyListBox" :type "void") nil [14656 14734]) ("sortUnsorted" function (:parent "KMyListBox" :type "void") nil [14736 14818]) ("sortNummeric" function (:parent "KMyListBox" :type "void") nil [14820 14902]) ("sortList" function (:parent "KMyListBox" :type "void") nil [14904 16654]) ("setSorting" function (:parent "KMyListBox" :arguments (("s" variable (:type "int") (reparse-symbol arg-sub-list) [16685 16692])) :type "void") nil [16656 17125]) ("compareNummeric" function (:parent "KMyListBox" :arguments (("s1" variable (:constant-flag t :type ("QString" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [17160 17179]) ("s2" variable (:constant-flag t :type ("QString" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [17180 17200])) :type "int") nil [17127 18078]) ("findNumInString" function (:parent "KMyListBox" :constant-flag t :arguments (("pos" variable (:type "unsigned int") (reparse-symbol arg-sub-list) [18123 18140]) ("s" variable (:constant-flag t :type ("QString" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [18141 18160])) :type ("QString" type (:type "class") nil nil)) nil [18080 18506]) ("resizeEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QResizeEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [18538 18555])) :type "void") nil [18508 18612]) ("clear" function (:parent "KMyListBox" :type "void") nil [18614 18686]) ("positionLabel" function (:parent "KMyListBox" :type "void") nil [18688 19060]) ("paintEvent" function (:parent "KMyListBox" :arguments (("e" variable (:pointer 1 :type ("QPaintEvent" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19091 19107])) :type "void") nil [19062 19234]) ("KMyListBoxItem" function (:constructor-flag t :parent "KMyListBoxItem" :arguments (("item" variable (:pointer 1 :constant-flag t :type ("KMyListBoxItem" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19268 19296])) :type ("KMyListBoxItem" type "class")) nil [19236 19424]) ("KMyListBoxItem" function (:constructor-flag t :parent "KMyListBoxItem" :arguments (("u" variable (:constant-flag t :type ("KURL" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19458 19473]) ("b" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19474 19482])) :type ("KMyListBoxItem" type "class")) nil [19426 19564]) ("setPixmap" function (:parent "KMyListBoxItem" :arguments (("pix" variable (:constant-flag t :type ("QPixmap" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19598 19619])) :type "void") nil [19566 19940]) ("setName" function (:parent "KMyListBoxItem" :arguments (("b" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [19972 19980])) :type "void") nil [19942 20016]) ("setPreview" function (:parent "KMyListBoxItem" :arguments (("b" variable (:type ("bool" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [20051 20059])) :type "void") nil [20018 20098]) ("paint" function (:parent "KMyListBoxItem" :arguments (("painter" variable (:pointer 1 :type ("QPainter" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [20128 20147])) :type "void") nil [20100 21325]) ("height" function (:parent "KMyListBoxItem" :arguments (("lb" variable (:pointer 1 :constant-flag t :type ("QListBox" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [21355 21375])) :type "int") nil [21327 21849]) ("width" function (:parent "KMyListBoxItem" :arguments (("" variable (:pointer 1 :constant-flag t :type ("QListBox" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [21878 21895])) :type "int") nil [21851 22376]) ("text" function (:parent "KMyListBoxItem" :type ("QString" type (:type "class") nil nil)) nil [22378 22521]) ("KMyListBoxItem::m_preview" variable (:default-value "false;" :type ("bool" type (:type "class") nil nil)) nil [22523 22562]) ("KMyListBoxItem::m_name" variable (:default-value "false;" :type ("bool" type (:type "class") nil nil)) nil [22563 22599])) + :file "kmylistbox.cpp" + :pointmax 22601 + ) + ) + :file "semantic.cache" + :semantic-tag-version "2.0pre3" + :semanticdb-version "2.0pre3" + ) diff --git a/krename/tabs.cpp b/krename/tabs.cpp new file mode 100644 index 0000000..b6ed00e --- /dev/null +++ b/krename/tabs.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + tabs.cpp - description + ------------------- + begin : Die Mai 20 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "tabs.h" +#include "krenameimpl.h" +#include "kmyhistorycombo.h" + +// Qt includes +#include <qlayout.h> +#include <qsizepolicy.h> +#include <qtabwidget.h> + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmenubar.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kstartupinfo.h> + +tabs::tabs(KRenameImpl* impl, QRect r, QWidget *parent, const char *name ) + : QDialog(parent,name) +{ + setIcon( BarIcon( "krename" ) ); + + QVBoxLayout* layout = new QVBoxLayout( this, 6, 6 ); + QHBoxLayout* buttons = new QHBoxLayout( 0, 6, 6 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding ); + + tab = new QTabWidget( this ); + finishButton = new KPushButton( i18n("&Finish"), this ); + finishButton->setIconSet( SmallIconSet( "finish" ) ); + finishButton->setDefault( true ); + cancelButton = new KPushButton( i18n("&Cancel"), this ); + cancelButton->setIconSet( SmallIconSet( "button_cancel" ) ); + + buttons->addItem( spacer ); + buttons->addWidget( finishButton ); + buttons->addWidget( cancelButton ); + + layout->addWidget( tab ); + layout->addLayout( buttons ); + layout->setStretchFactor( tab, 2 ); + + menuBar = new KMenuBar( this ); + layout->setMenuBar( menuBar ); + + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( close() ) ); + + krename = impl ? impl : new KRenameImpl( this, menuBar, finishButton ); + + connect( krename, SIGNAL( pageDone( QWidget*, const QString & ) ), this, SLOT( slotAddPage( QWidget*, const QString & ) ) ); + connect( krename, SIGNAL( showPage( int ) ), this, SLOT( slotShowPage( int ) ) ); + connect( krename, SIGNAL( enableFinish( bool ) ), this, SLOT( slotEnableFinish( bool ) ) ); + connect( tab, SIGNAL( currentChanged( QWidget* ) ), this, SLOT( slotTabChanged() ) ); + + if( impl ) + { + krename->changeParent( this, menuBar, finishButton, r ); + krename->setWizardMode( false ); + } else + krename->setup( false ); + + // Tell KStartupInfo that KRename has been loaded completly + KStartupInfoId id; + id.initId( kapp->startupId() ); + KStartupInfo::sendFinish( id ); +} + +tabs::~tabs() +{ +} + +void tabs::slotAddPage( QWidget* page, const QString & title ) +{ + tab->addTab( page, title ); +} + +void tabs::slotShowPage( int page ) +{ + tab->setCurrentPage( page - 1 ); +} + +void tabs::slotEnableFinish( bool b ) +{ + finishButton->setEnabled( b ); +} + +void tabs::slotTabChanged() +{ + if( tab->currentPageIndex() == tab->count() - 1 ) + { + krename->filename->setFocus(); + krename->filename->lineEdit()->selectAll(); + } +} + +void tabs::keyPressEvent( QKeyEvent *e ) +{ + // ESC should not close KRename + if( e->key() == Qt::Key_Escape ) + e->accept(); + else + e->ignore(); +} diff --git a/krename/tabs.h b/krename/tabs.h new file mode 100644 index 0000000..9e52f5c --- /dev/null +++ b/krename/tabs.h @@ -0,0 +1,57 @@ +/*************************************************************************** + tabs.h - description + ------------------- + begin : Die Mai 20 2003 + copyright : (C) 2003 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TABS_H +#define TABS_H + +#include <qwidget.h> +#include <qdialog.h> + +class KMenuBar; +class KRenameImpl; +class KPushButton; +class QCloseEvent; +class QRect; +class QString; +class QTabWidget; +class tabs : public QDialog { + Q_OBJECT + public: + tabs(KRenameImpl* impl, QRect r, QWidget *parent=0, const char *name=0); + ~tabs(); + + inline KRenameImpl* getKRename() { return krename; } + + private slots: + void slotAddPage( QWidget* page, const QString & title ); + void slotShowPage( int page ); + void slotEnableFinish( bool b ); + void slotTabChanged(); + + protected: + virtual void keyPressEvent( QKeyEvent *e ); + + protected: + KRenameImpl* krename; + KPushButton* finishButton; + KPushButton* cancelButton; + + KMenuBar* menuBar; + QTabWidget* tab; +}; + +#endif diff --git a/krename/threadedlister.cpp b/krename/threadedlister.cpp new file mode 100644 index 0000000..9af929a --- /dev/null +++ b/krename/threadedlister.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + + threadedlister.cpp - description + ------------------- + begin : Tue Feb 01 2005 + copyright : (C) 2005 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "threadedlister.h" + +#include "kmylistbox.h" +#include "krecursivelister.h" + +#include <kapplication.h> +#include <qmutex.h> + +ThreadedLister::ThreadedLister( QMutex* mutex, unsigned int* counter, KMyListBox* list ) + : QObject(), QThread(), m_mutex( mutex ), m_counter( counter ), m_list( list ) +{ + m_mutex->lock(); + ++(*m_counter); + m_mutex->unlock(); + + m_reclister = NULL; + m_lister = NULL; + m_internal = NULL; + + m_hidden = false; + m_recursive = false; + m_dirnames = false; + m_dironly = false; +} + + +ThreadedLister::~ThreadedLister() +{ + if( m_reclister ) + delete m_reclister; + + if( m_lister ) + delete m_lister; + + if( m_internal ) + delete m_internal; +} + +void ThreadedLister::run() +{ + m_internal = new QMutex(); + m_internal->lock(); + + if( m_recursive ) + { + m_reclister = new KRecursiveLister(); + + m_reclister->setShowingDotFiles( m_hidden ); + m_reclister->setNameFilter( m_filter ); + m_reclister->setDirOnlyMode( m_dironly ); + + connect( m_reclister, SIGNAL( completed() ), this, SLOT( reclisterFinished() ) ); + + m_reclister->openURL( m_dirname ); + } else { + m_lister = new KDirLister(); + + m_lister->setAutoUpdate( false ); + m_lister->setShowingDotFiles( m_hidden ); + m_lister->setNameFilter( m_filter ); + + connect( m_lister, SIGNAL( completed() ), this, SLOT( listerFinished() ) ); + + m_lister->openURL( m_dirname, false, false ); + } + + // try to lock the mutex. + // This will block run as long as *listerFinished() + // does not unlock the mutex. + m_internal->lock(); + m_internal->unlock(); + + KApplication::postEvent( m_list, new QCustomEvent( (QEvent::Type)ThreadedLister::TYPE(), (void*)this ) ); +} + + +void ThreadedLister::reclisterFinished() +{ + KFileItemList l = m_reclister->items(); + FileList list = l; + + if( m_dirnames ) + { + FileList dirs = m_reclister->dirs(); + KFileItem* item; + for( item = dirs.first(); item; item = dirs.next() ) + list.append( item ); + } + + list.sort(); + + m_mutex->lock(); + m_list->setUpdatesEnabled( false ); + + if( m_dirnames ) + { + QString name = m_dirname.fileName(); + if( !m_hidden && name.right( 1 ) != QString::fromLatin1(".") ) + m_list->addDirName( m_dirname ); + } + + KFileItem* item; + for( item = list.first(); item; item = list.next() ) + if( item->isFile() ) + m_list->addFile( item->url(), true ); + else if( item->isDir() ) + m_list->addDirName( item->url() ); + + m_mutex->unlock(); + m_list->setUpdatesEnabled( true ); + + m_internal->unlock(); +} + +void ThreadedLister::listerFinished() +{ + if( m_lister->isFinished() ) { + FileList list = m_lister->items( KDirLister::FilteredItems ); + list.sort(); + + m_mutex->lock(); + m_list->setUpdatesEnabled( false ); + + if( m_dirnames ) + { + QString name = m_dirname.fileName(); + if( !m_hidden && name.right( 1 ) != QString::fromLatin1(".") ) + m_list->addDirName( m_dirname ); + } + + KFileItem* item; + for( item = list.first(); item; item = list.next() ) + if( item->isFile() ) + m_list->addFile( item->url(), true ); + + --(*m_counter); + m_mutex->unlock(); + m_list->setUpdatesEnabled( true ); + + m_internal->unlock(); + } +} + +#include "threadedlister.moc" diff --git a/krename/threadedlister.h b/krename/threadedlister.h new file mode 100644 index 0000000..8398e0d --- /dev/null +++ b/krename/threadedlister.h @@ -0,0 +1,158 @@ +/*************************************************************************** + + threadedlister.h - description + ------------------- + begin : Tue Feb 01 2005 + copyright : (C) 2005 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef THREADEDLISTER_H +#define THREADEDLISTER_H + +#include <qobject.h> +#include <qthread.h> + +#include <kfileitem.h> + +class KDirLister; +class KRecursiveLister; +class KMyListBox; +class QMutex; + +class FileList : public QPtrList<KFileItem> { + public: + FileList() : QPtrList<KFileItem>() {} + FileList( KFileItemList list ) + : QPtrList<KFileItem>() { + KFileItem* it; + for( it = list.first(); it; it = list.next() ) + this->append( it ); + } + + protected: + int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) { + return static_cast<KFileItem*>(item1)->url().url().compare( static_cast<KFileItem*>(item2)->url().url() ); + } + +}; + + +class ThreadedLister : public QObject, public QThread +{ + Q_OBJECT + public: + ThreadedLister( QMutex* mutex, unsigned int* counter, KMyListBox* list ); + ~ThreadedLister(); + + static int TYPE() { return 51984; } + + inline FileList* items(); + + inline const KURL & dirname(); + inline bool dirnames(); + inline const QString & filter(); + inline bool hidden(); + + inline void setDirname( const KURL & dirname ); + inline void setDirnames( bool names ); + inline void setFilter( const QString & filter ); + inline void setHidden( bool h ); + inline void setRecursive( bool r ); + inline void setRecursiveDirOnlyMode( bool m ); + + signals: + void listerDone( ThreadedLister* ); + + protected: + void run(); + + private slots: + void reclisterFinished(); + void listerFinished(); + + private: + QMutex* m_mutex; + QMutex* m_internal; + unsigned int* m_counter; + + FileList m_files; + + KURL m_dirname; + QString m_filter; + bool m_hidden; + bool m_recursive; + bool m_dirnames; + bool m_dironly; + + KDirLister* m_lister; + KRecursiveLister* m_reclister; + + KMyListBox* m_list; +}; + +void ThreadedLister::setDirname( const KURL & dirname ) +{ + m_dirname = dirname; +} + +void ThreadedLister::setDirnames( bool names ) +{ + m_dirnames = names; +} + +void ThreadedLister::setFilter( const QString & filter ) +{ + m_filter = filter; +} + +void ThreadedLister::setHidden( bool h ) +{ + m_hidden = h; +} + +void ThreadedLister::setRecursive( bool r ) +{ + m_recursive = r; +} + +void ThreadedLister::setRecursiveDirOnlyMode( bool m ) +{ + m_dironly = m; +} + +FileList* ThreadedLister::items() +{ + return &m_files; +} + +const KURL & ThreadedLister::dirname() +{ + return m_dirname; +} + +bool ThreadedLister::dirnames() +{ + return m_dirnames; +} + +const QString & ThreadedLister::filter() +{ + return m_filter; +} + +bool ThreadedLister::hidden() +{ + return m_hidden; +} + +#endif diff --git a/krename/translitplugin.cpp b/krename/translitplugin.cpp new file mode 100644 index 0000000..65031e0 --- /dev/null +++ b/krename/translitplugin.cpp @@ -0,0 +1,106 @@ +// +// C++ Implementation: translitplugin +// +// Description: +// +// +// Author: Dominik Seichter <domseichter@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "translitplugin.h" +#include "translitplugin.moc" + +const QString TranslitPlugin::m_strUtf8[] = {"а","б","в","г","д","е","ё","ж","з","и", + "й","к","л","м","н","о","п","р","с","т","у","ф","х","ц","ч","ш","щ","ъ","ы","ь", + "э","ю","я", + "А","Б","В","Г","Д","Е","Ё","Ж","З","И","Й","К","Л","М","Н","О","П", + "Р","С","Т","У","Ф","Х","Ц","Ч","Ш","Щ","Ъ","Ы","Ь","Э","Ю","Я", + "á","ä","č","ď","é","ě","í","ľ","ĺ","ň","ó","ô","ř","ŕ","š","ť","ú","ů","ý","ž", + "Á","Ä","Č","Ď","É","Ě","Í","Ľ","Ĺ","Ň","Ó","Ô","Ř","Ŕ","Š","Ť","Ú","Ů","Ý","Ž",QString::null}; + +const QString TranslitPlugin::m_strEngl[]= {"a","b","v","g","d","e","yo","zh","z","i", + "j","k","l","m","n","o","p","r","s","t","u","f","h","c","ch","sh","sh","","y","", + "e","yu","ya", + "A","B","V","G","D","E","Yo","Zh","Z","I","J","K","L","M","N","O","P", + "R","S","T","U","F","H","C","Ch","Sh","Sh","","Y","","E","Yu","Ya", + "a","a","c","d","e","e","i","l","l","n","o","o","r","r","s","t","u","u","y","z", + "A","A","C","D","E","E","I","L","L","N","O","O","R","R","S","T","U","U","Y","Z",QString::null}; + +const QString TranslitPlugin::getName() const +{ + return i18n("Transliteration Plugin"); +} + +const QString TranslitPlugin::getAccelName() const +{ + return i18n("&Transliteration Plugin"); +} + +const QPixmap TranslitPlugin::getIcon() const +{ + return kapp->iconLoader()->loadIcon( "fonts", KIcon::Small ); +} + +const int TranslitPlugin::type() const +{ + return TYPE_FINAL_FILENAME; +} + +void TranslitPlugin::drawInterface( QWidget* w, QVBoxLayout* l ) +{ + QLabel* label = new QLabel( + i18n("<qt>This plugin transliterates names written with non-english characters.</qt>"), w ); + l->addWidget( label ); + + label = new QLabel( "<qt><b>WARNING! THIS PLUGIN IS EXPERIMENTAL AND MIGHT CAUSE LOSS OF DATA!</b></qt>", w ); + l->addWidget( label ); +} + +void TranslitPlugin::finished() +{ +} + +void TranslitPlugin::fillStructure() +{ +} + +bool TranslitPlugin::checkError() +{ + return true; +} + +QString TranslitPlugin::processFile( BatchRenamer*, int, QString token, int ) +{ + QString output = translit( token ); + + return output; // no error +} + +QString TranslitPlugin::translit(const QString & unicoded) +{ + int i; + QString transed = ""; + + for (i=0; i<(int)unicoded.length(); i++) { + QString charIn = unicoded.mid(i, 1); + if (m_mapFromUTF8[charIn.utf8()]) { + QString charTrans = m_mapFromUTF8[charIn.utf8()]; + transed.append(charTrans); + } else { + transed.append(charIn); + } + } + return transed; +} + +TranslitPlugin::TranslitPlugin() { + // Initialize transliteration map + int i; + for (i=0; m_strUtf8[i]!=QString::null; i++) { + QString src = m_strUtf8[i]; + QString dst = m_strEngl[i]; + m_mapFromUTF8[src] = dst; + } +} diff --git a/krename/translitplugin.h b/krename/translitplugin.h new file mode 100644 index 0000000..c385b36 --- /dev/null +++ b/krename/translitplugin.h @@ -0,0 +1,59 @@ +// +// C++ Interface: translitplugin +// +// Description: +// +// +// Author: Dominik Seichter <domseichter@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TRANSLITPLUGIN_H +#define TRANSLITPLUGIN_H + +#include "plugin.h" +#include "pluginloader.h" +#include "batchrenamer.h" + +// QT includes +#include <qlabel.h> +#include <qlayout.h> +#include <qtextcodec.h> +#include <qvgroupbox.h> +#include <qcheckbox.h> + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kcombobox.h> +// #include <kdebug.h> + +/** +@author Dominik Seichter +*/ +class TranslitPlugin : public Plugin { + Q_OBJECT + public: + const QString getName() const; + const QString getAccelName() const; + const int type() const; + const QPixmap getIcon() const; + void drawInterface( QWidget* w, QVBoxLayout* l ); + void finished(); + bool checkError(); + void fillStructure(); + QString processFile( BatchRenamer*, int, QString token, int ); + TranslitPlugin(); + protected: + QString translit(const QString &); + + typedef QMap<QString, QString> TranslitMap; + TranslitMap m_mapFromUTF8; + + static const QString m_strUtf8[]; + static const QString m_strEngl[]; +}; + +#endif diff --git a/krename/undodialog.cpp b/krename/undodialog.cpp new file mode 100644 index 0000000..1dcd8b9 --- /dev/null +++ b/krename/undodialog.cpp @@ -0,0 +1,136 @@ + /*************************************************************************** + undodialog.cpp - description + ------------------- + begin : Mon Mai 27 20:08:19 CEST 2002 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "undodialog.h" + +// Qt includes +#include <qlabel.h> +#include <qlayout.h> + +// KDE includes +#include <kfiledialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <ktextbrowser.h> +#include <kurlrequester.h> + +UndoDialog::UndoDialog( QWidget* parent ) + : KDialogBase( KDialogBase::Plain, i18n("Undo Renaming"), + KDialogBase::User1 | KDialogBase::Close, KDialogBase::User1, parent, 0, false, true ) +{ + UndoDialogLayout = new QVBoxLayout( plainPage(), 11, 6, "UndoDialogLayout"); + + TextLabel1 = new QLabel( plainPage(), "TextLabel1" ); + TextLabel1->setText( i18n( "Undo script:" ) ); + UndoDialogLayout->addWidget( TextLabel1 ); + + scriptname = new KURLRequester( plainPage(), "KURLRequester1" ); + scriptname->setMode( KFile::File | KFile::LocalOnly ); + scriptname->fileDialog()->setOperationMode( KFileDialog::Opening ); + + scriptname->setFilter( i18n("*.krename|KRename undo scripts (*.krename)\n" + "*|All Files (*)") ); + UndoDialogLayout->addWidget( scriptname ); + + TextLabel2 = new QLabel( plainPage(), "TextLabel2" ); + TextLabel2->setText( i18n( "<qt>Undo Scripts are normal shell scripts which can also be executed manually from the command line.</qt>" ) ); + UndoDialogLayout->addWidget( TextLabel2 ); + + browser = new KTextBrowser( plainPage()); + browser->setWordWrap( QTextEdit::NoWrap ); + browser->setTextFormat( Qt::RichText ); + + UndoDialogLayout->addWidget( browser ); + + setButtonText( KDialogBase::User1, i18n( "&Start" ) ); + + connect( this, SIGNAL( user1Clicked() ), this, SLOT( start() ) ); + connect( scriptname, SIGNAL( textChanged( const QString & ) ), this, SLOT( enableControls() ) ); + + enableControls(); +} + +UndoDialog::~UndoDialog() +{ } + +void UndoDialog::start() +{ + if( scriptname->url().right( 8 ) != ".krename" ) // EXTENSION + if( KMessageBox::warningContinueCancel( this, i18n("This script does not seem " + "to be a Krename undo script. Execution of this " + "script can be dangerous. Continue ?") ) + == KMessageBox::Cancel ) + return; + + KProcess *proc = new KProcess; + *proc << scriptname->url() << "--krename"; + + enableButton( KDialogBase::User1, false ); + + if( !proc->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) { + KMessageBox::sorry( this, i18n("Unable to start the given undo script!") ); + enableButton( KDialogBase::User1, true ); + delete proc; + return; + } + proc->resume(); + connect( proc, SIGNAL( receivedStdout( KProcess*, char*, int) ), this, SLOT( receive( KProcess*, char*, int ) ) ); + connect( proc, SIGNAL( receivedStderr( KProcess*, char*, int) ), this, SLOT( receiveErr( KProcess*, char*, int ) ) ); + connect( proc, SIGNAL( processExited( KProcess* ) ), this, SLOT( finished( KProcess* ) ) ); +} + +void UndoDialog::receive( KProcess*, char* buffer, int len ) +{ + QString text; + for( int i = 0; i < len; i++ ) + text.append( buffer[i] ); + + browser->setText( browser->text() + text + "<br>"); +} + +void UndoDialog::receiveErr( KProcess*, char* buffer, int len ) +{ + QString text = "<b>"; + for( int i = 0; i < len; i++ ) + text.append( buffer[i] ); + + browser->setText( browser->text() + text + "</b><br>"); +} + +void UndoDialog::finished( KProcess* p ) +{ + delete p; + KMessageBox::information( this, i18n("Finished successfully") ); + enableControls(); +} + +void UndoDialog::enableControls() +{ + QFileInfo fi( scriptname->url() ); + bool b = !scriptname->url().isEmpty() && fi.exists() && fi.isExecutable(); + enableButton( KDialogBase::User1, b ); +} + +void UndoDialog::setUndoScript( const QString & filename ) +{ + scriptname->setURL( filename ); +} + + + + diff --git a/krename/undodialog.h b/krename/undodialog.h new file mode 100644 index 0000000..e6ad0c8 --- /dev/null +++ b/krename/undodialog.h @@ -0,0 +1,59 @@ +/************************************************************************** + undodialog.h - description + ------------------- + begin : Mon Mai 27 20:08:19 CEST 2002 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef UNDODIALOG_H +#define UNDODIALOG_H + +#include <kdialogbase.h> + +class KPushButton; +class KProcess; +class KTextBrowser; +class KURLRequester; +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QLabel; +class UndoDialog : public KDialogBase +{ + Q_OBJECT + public: + UndoDialog( QWidget* parent = 0 ); + ~UndoDialog(); + + void setUndoScript( const QString & filename ); + + public slots: + void start(); + + private slots: + void receive( KProcess*, char* buffer, int len ); + void receiveErr( KProcess*, char* buffer, int len ); + void finished( KProcess* p ); + void enableControls(); + + private: + QLabel* TextLabel1; + KURLRequester* scriptname; + QLabel* TextLabel2; + KTextBrowser* browser; + + protected: + QVBoxLayout* UndoDialogLayout; +}; + +#endif // UNDODIALOG_H diff --git a/krename/wizard.cpp b/krename/wizard.cpp new file mode 100644 index 0000000..31720c9 --- /dev/null +++ b/krename/wizard.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + wizard.cpp - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// Own includes +#include "wizard.h" +#include "krenameimpl.h" + +// KDE includes +#include <kapplication.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmenubar.h> +#include <kmessagebox.h> +#include <kstartupinfo.h> + +// Qt includes +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qsizepolicy.h> +#include <qvbox.h> + +wizard::wizard( KRenameImpl* impl, QRect r, QWidget* parent, const char* name ) + : KWizard( parent, name ) +{ + setIcon( BarIcon( "krename" ) ); + menuBar = new KMenuBar(this); + + krename = impl ? impl : new KRenameImpl( this, menuBar, this->finishButton() ); + + connect( krename, SIGNAL( pageDone( QWidget*, const QString & ) ), this, SLOT( slotAddPage( QWidget*, const QString & ) ) ); + connect( krename, SIGNAL( showPage( int ) ), this, SLOT( slotShowPage( int ) ) ); + connect( krename, SIGNAL( enableFinish( bool ) ), this, SLOT( slotEnableFinish( bool ) ) ); + + if( impl ) + { + krename->changeParent( this, menuBar, this->finishButton(), r ); + krename->setWizardMode( true ); + } else + krename->setup( true ); + + // Tell KStartupInfo that KRename has been loaded completly + KStartupInfoId id; + id.initId( kapp->startupId() ); + KStartupInfo::sendFinish( id ); + + // Disable ESC key + cancelButton()->setAccel( QKeySequence() ); +} + +wizard::~wizard() +{ +} + +void wizard::slotAddPage( QWidget* page, const QString & title ) +{ + // exclude page 3 from wizard + if( krename->title( 2 ) == title ) + { + page->hide(); + return; + } + + QString t = title + i18n(" - Step %1 of %2").arg( pageCount()+1 ).arg( 3 ); + + QVBox* layout = new QVBox( this ); + + new QLabel( QString( t ).remove( title.find( "&" ), 1 ), layout ); + + QFrame* hbar1 = new QFrame( layout, "<hr>", 0 ); + hbar1->setFrameStyle( QFrame::Sunken + QFrame::HLine ); + + page->reparent( layout, QPoint( 0, 0 ) ); + addPage( layout, t ); + setHelpEnabled( layout, false ); +} + +void wizard::slotShowPage( int page ) +{ + showPage( this->page( page - 1 ) ); +} + +void wizard::slotEnableFinish( bool b ) +{ + setFinishEnabled( page( pageCount() - 1), b ); +} + +void wizard::accept() +{ +/** do nothing */ +} + diff --git a/krename/wizard.h b/krename/wizard.h new file mode 100644 index 0000000..a415be0 --- /dev/null +++ b/krename/wizard.h @@ -0,0 +1,54 @@ +/*************************************************************************** + wizard.h - description + ------------------- + begin : Die Mai 15 15:34:19 CEST 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef WIZARD_H +#define WIZARD_H + +// KDE includes +#include <kwizard.h> +class QCloseEvent; +class KRenameImpl; +class KMenuBar; +class QCloseEvent; +class QHBoxLayout; +class QRect; +class QString; +class QVBoxLayout; +class QWidget; +class wizard : public KWizard +{ + Q_OBJECT + + public: + wizard( KRenameImpl* impl, QRect r, QWidget* parent = 0, const char* name = 0 ); + ~wizard(); + + inline KRenameImpl* getKRename() { return krename; } + + private slots: + void slotAddPage( QWidget* page, const QString & title ); + void slotShowPage( int page ); + void slotEnableFinish( bool b ); + + protected: + void accept(); + + KMenuBar* menuBar; + KRenameImpl* krename; +}; + +#endif // WIZARD_H |