summaryrefslogtreecommitdiffstats
path: root/kdirstat/kcleanupcollection.cpp
blob: d7c116ede60b82ec9b291fa32cad7623f5527edd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
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 <tdelocale.h>
#include "kcleanup.h"
#include "kstdcleanup.h"
#include "kcleanupcollection.h"


using namespace KDirStat;


KCleanupCollection::KCleanupCollection( TDEActionCollection * actionCollection )
    : TQObject()
    , _actionCollection( actionCollection )
{
    /**
     * All cleanups beloningt to this collection are stored in two separate TQt
     * collections, a TQPtrList and a TQDict. Make _one_ of them manage the cleanup
     * objects, i.e. have them clear the KCleanup objects upon deleting. The
     * TQPtrList is the master collection, the TQDict the slave.
     **/
    
    _cleanupList.setAutoDelete( true  );
    _cleanupDict.setAutoDelete( false );
    
    _nextUserCleanupNo	= 0;
}


KCleanupCollection::KCleanupCollection( const KCleanupCollection &src )
    : TQObject()
{
    deepCopy( src );
    
    // Keep consistent with the KCleanup copy constructor: It explicitly uses a
    // zero TDEActionCollecton 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 TDEAction
	 * 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 TDEAction 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 TDEAction 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 TDEAction 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 )
{
    TQ_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,       TQT_SIGNAL( selectionChanged( KFileInfo * ) ),
	     newCleanup, TQT_SLOT  ( selectionChanged( KFileInfo * ) ) );
    
    connect( this,       TQT_SIGNAL( readConfig() ),
	     newCleanup, TQT_SLOT  ( readConfig() ) );
    
    connect( this,       TQT_SIGNAL( saveConfig() ),
	     newCleanup, TQT_SLOT  ( saveConfig() ) );
    
    connect( newCleanup, TQT_SIGNAL( executed() ),
	     this, 	 TQT_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++ )
    {
	TQString id;
	id.sprintf( "cleanup_user_defined_%d", _nextUserCleanupNo );
	TQString 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 );
	TQ_CHECK_PTR( cleanup );
	cleanup->setEnabled( false );

	if ( i <= 9 )
	{
	    // Provide an application-wide keyboard accelerator for cleanup #0..#9
	    cleanup->setShortcut( TQt::CTRL + TQt::Key_0 + i );
	}
	
	add( cleanup );
    }
}


KCleanup *
KCleanupCollection::cleanup( const TQString & 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