summaryrefslogtreecommitdiffstats
path: root/kdirstat/kcleanupcollection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdirstat/kcleanupcollection.cpp')
-rw-r--r--kdirstat/kcleanupcollection.cpp283
1 files changed, 283 insertions, 0 deletions
diff --git a/kdirstat/kcleanupcollection.cpp b/kdirstat/kcleanupcollection.cpp
new file mode 100644
index 0000000..fffa9b4
--- /dev/null
+++ b/kdirstat/kcleanupcollection.cpp
@@ -0,0 +1,283 @@
+/*
+ * File name: kcleanupcollection.cpp
+ * Summary: Support classes for KDirStat
+ * License: LGPL - See file COPYING.LIB for details.
+ * Author: Stefan Hundhammer <sh@suse.de>
+ *
+ * Updated: 2004-11-23
+ */
+
+
+#include <klocale.h>
+#include "kcleanup.h"
+#include "kstdcleanup.h"
+#include "kcleanupcollection.h"
+
+
+using namespace KDirStat;
+
+
+KCleanupCollection::KCleanupCollection( KActionCollection * actionCollection )
+ : QObject()
+ , _actionCollection( actionCollection )
+{
+ /**
+ * All cleanups beloningt to this collection are stored in two separate Qt
+ * collections, a QList and a QDict. Make _one_ of them manage the cleanup
+ * objects, i.e. have them clear the KCleanup objects upon deleting. The
+ * QList is the master collection, the QDict the slave.
+ **/
+
+ _cleanupList.setAutoDelete( true );
+ _cleanupDict.setAutoDelete( false );
+
+ _nextUserCleanupNo = 0;
+}
+
+
+KCleanupCollection::KCleanupCollection( const KCleanupCollection &src )
+ : QObject()
+{
+ deepCopy( src );
+
+ // Keep consistent with the KCleanup copy constructor: It explicitly uses a
+ // zero KActionCollecton to make sure no duplicates of cleanups get into
+ // the action collection.
+ _actionCollection = 0;
+}
+
+
+KCleanupCollection::~KCleanupCollection()
+{
+ // No need to delete the cleanups: _cleanupList takes care of that
+ // (autoDelete!).
+}
+
+
+KCleanupCollection &
+KCleanupCollection::operator= ( const KCleanupCollection &src )
+{
+ if ( size() != src.size() )
+ {
+ /**
+ * If the sizes are different, we really need to make a deep copy -
+ * i.e. discard all the existing cleanups in this collection and create
+ * new ones with the KCleanup copy constructor.
+ **/
+
+ // kdDebug() << k_funcinfo << "Sizes different - deep copy" << endl;
+
+ deepCopy( src );
+ }
+ else
+ {
+ /**
+ * If the sizes are the same, we'd rather just use the KCleanup
+ * assignment operator to individually assign each cleanup in the
+ * source collection to the corresponding one in this collection.
+ *
+ * The background of this seemingly awkward solution are (again) the
+ * limitations of the KCleanup copy constructor: It doesn't make a
+ * truly identical copy of the entire KCleanup object. Rather, it
+ * copies only the KCleanup members and leaves most of the KAction
+ * members (the parent class) untouched.
+ *
+ * The behaviour implemented here comes handy in the most common
+ * situation where this assignment operator is used:
+ *
+ * KCleanupCollection tmpCollection( origCollection );
+ * ...
+ * ... // let use change settings in settings dialog
+ * ...
+ * origCollection = tmpCollection;
+ *
+ * 'tmpCollection' here is an incomplete copy of 'origCollection' -
+ * which represents what the user really can see in the menus, i.e. all
+ * the KAction stuff in there really needs to work.
+ *
+ * During changing preferences in the 'settings' dialog, the user only
+ * changes 'tmpCollection' - if he chooses to abandon his changes
+ * (e.g., he clicks on the 'cancel' button), no harm is done -
+ * 'tmpCollection' is simply not copied back to
+ * 'origCollection'. Anyway, since 'tmpCollection' is merely a
+ * container for the true KCleanup members, the KAction members don't
+ * matter here: There is no representation of 'tmpCollection' in any
+ * menu or tool bar.
+ *
+ * As soon as the user clicks on 'apply' or 'ok' in the 'settings'
+ * dialog, however, 'tmpCollection' is copied back to 'origCollection'
+ * - that is, its KCleanup members. Most of the KAction members (other
+ * than 'text()' which is explicitly copied back) remain untouched,
+ * thus maintaining consistency with the user interface is guaranteed.
+ **/
+
+ // kdDebug() << k_funcinfo << "Same sizes - individual assignment" << endl;
+
+ KCleanupList srcList = src.cleanupList();
+ KCleanupListIterator srcIt( srcList );
+ KCleanupListIterator destIt( _cleanupList );
+
+ while ( *srcIt && *destIt )
+ {
+ // kdDebug() << "Assigning " << *srcIt << endl;
+ **destIt = **srcIt;
+ ++srcIt;
+ ++destIt;
+ }
+ }
+
+ // Intentionally leaving '_actionCollection' untouched!
+
+ return *this;
+}
+
+
+void
+KCleanupCollection::deepCopy( const KCleanupCollection &src )
+{
+ // Copy simple values
+ _nextUserCleanupNo = src.nextUserCleanupNo();
+
+ // Just to make sure - clear the internal collections
+ _cleanupList.clear();
+ _cleanupDict.clear();
+
+
+ // Make a deep copy of all the cleanups in the source collection
+
+ KCleanupList srcList = src.cleanupList();
+ KCleanupListIterator it( srcList );
+
+ while ( *it )
+ {
+ // kdDebug() << k_funcinfo << "Creating new " << *it << endl;
+
+ add( new KCleanup( **it ) );
+ ++it;
+ }
+}
+
+
+void
+KCleanupCollection::add( KCleanup *newCleanup )
+{
+ CHECK_PTR( newCleanup );
+
+ if ( _cleanupDict[ newCleanup->id() ] ) // Already there?
+ {
+ // Delete any old instance in the list.
+ //
+ // The instance in the dict will be deleted automatically by inserting
+ // the new one.
+
+ _cleanupList.first(); // Moves _cleanupList.current() to beginning
+
+ while ( _cleanupList.current() )
+ {
+ if ( _cleanupList.current()->id() == newCleanup->id() )
+ {
+ // Found a cleanup with the same ID -
+ // remove the current list item, delete it (autoDelete!) and
+ // move _cleanupList.current() to the next item.
+
+ _cleanupList.remove();
+ }
+ else
+ _cleanupList.next();
+ }
+ }
+
+ _cleanupList.append( newCleanup );
+ _cleanupDict.insert( newCleanup->id(), newCleanup );
+
+ connect( this, SIGNAL( selectionChanged( KFileInfo * ) ),
+ newCleanup, SLOT ( selectionChanged( KFileInfo * ) ) );
+
+ connect( this, SIGNAL( readConfig() ),
+ newCleanup, SLOT ( readConfig() ) );
+
+ connect( this, SIGNAL( saveConfig() ),
+ newCleanup, SLOT ( saveConfig() ) );
+
+ connect( newCleanup, SIGNAL( executed() ),
+ this, SLOT ( cleanupExecuted() ) );
+}
+
+
+void
+KCleanupCollection::addStdCleanups()
+{
+ add( KStdCleanup::openInKonqueror ( _actionCollection ) );
+ add( KStdCleanup::openInTerminal ( _actionCollection ) );
+ add( KStdCleanup::compressSubtree ( _actionCollection ) );
+ add( KStdCleanup::makeClean ( _actionCollection ) );
+ add( KStdCleanup::deleteTrash ( _actionCollection ) );
+ add( KStdCleanup::moveToTrashBin ( _actionCollection ) );
+ add( KStdCleanup::hardDelete ( _actionCollection ) );
+}
+
+
+void
+KCleanupCollection::addUserCleanups( int number )
+{
+ for ( int i=0; i < number; i++ )
+ {
+ QString id;
+ id.sprintf( "cleanup_user_defined_%d", _nextUserCleanupNo );
+ QString title;
+
+ if ( _nextUserCleanupNo <= 9 )
+ // Provide a keyboard shortcut for cleanup #0..#9
+ title=i18n( "User Defined Cleanup #&%1" ).arg(_nextUserCleanupNo);
+ else
+ // No keyboard shortcuts for cleanups #10.. - they would be duplicates
+ title=i18n( "User Defined Cleanup #%1" ).arg(_nextUserCleanupNo);
+
+ _nextUserCleanupNo++;
+
+ KCleanup *cleanup = new KCleanup( id, "", title, _actionCollection );
+ CHECK_PTR( cleanup );
+ cleanup->setEnabled( false );
+
+ if ( i <= 9 )
+ {
+ // Provide an application-wide keyboard accelerator for cleanup #0..#9
+ cleanup->setShortcut( Qt::CTRL + Qt::Key_0 + i );
+ }
+
+ add( cleanup );
+ }
+}
+
+
+KCleanup *
+KCleanupCollection::cleanup( const QString & id )
+{
+ return _cleanupDict[ id ];
+}
+
+
+void
+KCleanupCollection::clear()
+{
+ _cleanupList.clear();
+ _cleanupDict.clear();
+ _nextUserCleanupNo = 0;
+}
+
+
+void
+KCleanupCollection::slotReadConfig()
+{
+ emit readConfig();
+}
+
+
+void
+KCleanupCollection::cleanupExecuted()
+{
+ emit userActivity( 10 );
+}
+
+
+// EOF