~ubuntu-branches/ubuntu/intrepid/gwenview/intrepid

« back to all changes in this revision

Viewing changes to src/gvfiledetailview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christopher Martin
  • Date: 2005-04-06 11:33:06 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050406113306-7zovl7z0io5bacpd
Tags: 1.2.0-1
* New upstream release.
  + Fixes crashes when using "Back" to navigate. (Closes: #301811)
* Enable KIPI support.
* Add a doc-base file for the handbook.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// vim: set tabstop=4 shiftwidth=4 noexpandtab
 
2
/* This file is based on kfiledetailview.cpp v1.43 from the KDE libs. Original
 
3
   copyright follows.
 
4
*/
 
5
/* This file is part of the KDE libraries
 
6
   Copyright (C) 1997 Stephan Kulow <coolo@kde.org>
 
7
                 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
 
8
 
 
9
   This library is free software; you can redistribute it and/or
 
10
   modify it under the terms of the GNU Library General Public
 
11
   License as published by the Free Software Foundation; either
 
12
   version 2 of the License, or (at your option) any later version.
 
13
 
 
14
   This library is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
   Library General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU Library General Public License
 
20
   along with this library; see the file COPYING.LIB.   If not, write to
 
21
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
22
   Boston, MA 02111-1307, USA.
 
23
*/
 
24
 
 
25
// Qt
 
26
#include <qevent.h>
 
27
#include <qheader.h>
 
28
#include <qkeycode.h>
 
29
#include <qpainter.h>
 
30
#include <qpixmap.h>
 
31
 
 
32
// KDE 
 
33
#include <kapplication.h>
 
34
#include <kdebug.h>
 
35
#include <kfileitem.h>
 
36
#include <kglobalsettings.h>
 
37
#include <kiconloader.h>
 
38
#include <klocale.h>
 
39
#include <kurldrag.h>
 
40
 
 
41
// Local
 
42
#include "gvarchive.h"
 
43
#include "gvfiledetailviewitem.h"
 
44
#include "gvfiledetailview.moc"
 
45
 
 
46
 
 
47
GVFileDetailView::GVFileDetailView(QWidget *parent, const char *name)
 
48
        : KListView(parent, name), GVFileViewBase()
 
49
{
 
50
        mSortingCol = COL_NAME;
 
51
        mBlockSortingSignal = false;
 
52
 
 
53
        addColumn( i18n( "Name" ) );
 
54
        addColumn( i18n( "Size" ) );
 
55
        addColumn( i18n( "Date" ) );
 
56
        addColumn( i18n( "Permissions" ) );
 
57
        addColumn( i18n( "Owner" ) );
 
58
        addColumn( i18n( "Group" ) );
 
59
        setShowSortIndicator( TRUE );
 
60
        setAllColumnsShowFocus( TRUE );
 
61
 
 
62
        connect( header(), SIGNAL( sectionClicked(int)),
 
63
                         SLOT(slotSortingChanged(int) ));
 
64
 
 
65
 
 
66
        connect( this, SIGNAL( returnPressed(QListViewItem *) ),
 
67
                         SLOT( slotActivate( QListViewItem *) ) );
 
68
 
 
69
        connect( this, SIGNAL( clicked(QListViewItem *, const QPoint&, int)),
 
70
                         SLOT( selected( QListViewItem *) ) );
 
71
        connect( this, SIGNAL( doubleClicked(QListViewItem *, const QPoint&, int)),
 
72
                         SLOT( slotActivate( QListViewItem *) ) );
 
73
 
 
74
        connect( this, SIGNAL(contextMenuRequested( QListViewItem *,
 
75
                                                                                                const QPoint &, int )),
 
76
                         this, SLOT( slotActivateMenu( QListViewItem *, const QPoint& )));
 
77
 
 
78
        QListView::setSelectionMode( QListView::Extended );
 
79
        connect( this, SIGNAL( selectionChanged() ),
 
80
                         SLOT( slotSelectionChanged() ));
 
81
 
 
82
        // GVFileViewStack need to be aware of sort changes, to update the sort menu
 
83
        connect( sig, SIGNAL(sortingChanged(QDir::SortSpec)),
 
84
                this, SIGNAL(sortingChanged(QDir::SortSpec)) );
 
85
        
 
86
        setSorting( sorting() );
 
87
 
 
88
 
 
89
        mResolver =
 
90
                new KMimeTypeResolver<GVFileDetailViewItem,GVFileDetailView>( this );
 
91
 
 
92
        setDragEnabled(true);
 
93
        
 
94
        setAcceptDrops(true);
 
95
        setDropVisualizer(false);
 
96
        setDropHighlighter(false);
 
97
}
 
98
 
 
99
 
 
100
GVFileDetailView::~GVFileDetailView()
 
101
{
 
102
        delete mResolver;
 
103
}
 
104
 
 
105
 
 
106
void GVFileDetailView::setSelected( const KFileItem *info, bool enable )
 
107
{
 
108
        if (!info) return;
 
109
        GVFileDetailViewItem *item = viewItem(info);
 
110
        if (item) KListView::setSelected(item, enable);
 
111
}
 
112
 
 
113
void GVFileDetailView::setCurrentItem( const KFileItem *item )
 
114
{
 
115
        if (!item) return;
 
116
        GVFileDetailViewItem *listItem = viewItem(item);
 
117
        if (listItem) KListView::setCurrentItem(listItem);
 
118
}
 
119
 
 
120
KFileItem * GVFileDetailView::currentFileItem() const
 
121
{
 
122
        GVFileDetailViewItem *current = static_cast<GVFileDetailViewItem*>( currentItem() );
 
123
        if ( current ) return current->fileInfo();
 
124
 
 
125
        return 0L;
 
126
}
 
127
 
 
128
void GVFileDetailView::clearSelection()
 
129
{
 
130
        KListView::clearSelection();
 
131
}
 
132
 
 
133
void GVFileDetailView::selectAll()
 
134
{
 
135
        KListView::selectAll( true );
 
136
}
 
137
 
 
138
void GVFileDetailView::invertSelection()
 
139
{
 
140
        KListView::invertSelection();
 
141
}
 
142
 
 
143
void GVFileDetailView::slotActivateMenu (QListViewItem *item,const QPoint& pos )
 
144
{
 
145
        if ( !item ) {
 
146
                sig->activateMenu( 0, pos );
 
147
                return;
 
148
        }
 
149
        GVFileDetailViewItem *i = (GVFileDetailViewItem*) item;
 
150
        sig->activateMenu( i->fileInfo(), pos );
 
151
}
 
152
 
 
153
void GVFileDetailView::clearView()
 
154
{
 
155
        mResolver->m_lstPendingMimeIconItems.clear();
 
156
        mShownFileItem=0L;
 
157
        KListView::clear();
 
158
}
 
159
 
 
160
void GVFileDetailView::insertItem( KFileItem *i )
 
161
{
 
162
        KFileView::insertItem( i );
 
163
 
 
164
        GVFileDetailViewItem *item = new GVFileDetailViewItem( (QListView*) this, i );
 
165
 
 
166
        setSortingKey( item, i );
 
167
 
 
168
        i->setExtraData( this, item );
 
169
 
 
170
        if ( !i->isMimeTypeKnown() )
 
171
                mResolver->m_lstPendingMimeIconItems.append( item );
 
172
}
 
173
 
 
174
void GVFileDetailView::slotActivate( QListViewItem *item )
 
175
{
 
176
        if ( !item ) return;
 
177
 
 
178
        const KFileItem *fi = ( (GVFileDetailViewItem*)item )->fileInfo();
 
179
        if ( fi ) sig->activate( fi );
 
180
}
 
181
 
 
182
void GVFileDetailView::selected( QListViewItem *item )
 
183
{
 
184
        if ( !item ) return;
 
185
 
 
186
        if ( KGlobalSettings::singleClick() ) {
 
187
                const KFileItem *fi = ( (GVFileDetailViewItem*)item )->fileInfo();
 
188
                if ( fi && (fi->isDir() || !onlyDoubleClickSelectsFiles()) )
 
189
                        sig->activate( fi );
 
190
        }
 
191
}
 
192
 
 
193
void GVFileDetailView::highlighted( QListViewItem *item )
 
194
{
 
195
        if ( !item ) return;
 
196
 
 
197
        const KFileItem *fi = ( (GVFileDetailViewItem*)item )->fileInfo();
 
198
        if ( fi ) sig->highlightFile( fi );
 
199
}
 
200
 
 
201
 
 
202
bool GVFileDetailView::isSelected(const KFileItem* fileItem) const
 
203
{
 
204
        if (!fileItem) return false;
 
205
 
 
206
        GVFileDetailViewItem *item = viewItem(fileItem);
 
207
        return item && item->isSelected();
 
208
}
 
209
 
 
210
 
 
211
void GVFileDetailView::updateView( bool b )
 
212
{
 
213
        if ( !b ) return;
 
214
 
 
215
        QListViewItemIterator it( (QListView*)this );
 
216
        for ( ; it.current(); ++it ) {
 
217
                GVFileDetailViewItem *item=static_cast<GVFileDetailViewItem *>(it.current());
 
218
                item->setPixmap( 0, item->fileInfo()->pixmap(KIcon::SizeSmall) );
 
219
        }
 
220
}
 
221
 
 
222
void GVFileDetailView::updateView( const KFileItem *i )
 
223
{
 
224
        if ( !i ) return;
 
225
 
 
226
        GVFileDetailViewItem *item = viewItem(i);
 
227
        if ( !item ) return;
 
228
 
 
229
        item->init();
 
230
        setSortingKey( item, i );
 
231
}
 
232
 
 
233
 
 
234
void GVFileDetailView::setSortingKey( GVFileDetailViewItem *item,
 
235
                                                                         const KFileItem *i )
 
236
{
 
237
        // see also setSorting()
 
238
        QDir::SortSpec spec = KFileView::sorting();
 
239
        bool isDirOrArchive=i->isDir() || GVArchive::fileItemIsArchive(i);
 
240
 
 
241
        QString key;
 
242
        if ( spec & QDir::Time )
 
243
                key=sortingKey( i->time( KIO::UDS_MODIFICATION_TIME ),
 
244
                                                                  isDirOrArchive, spec );
 
245
        else if ( spec & QDir::Size )
 
246
                key=sortingKey( i->size(), isDirOrArchive, spec );
 
247
 
 
248
        else // Name or Unsorted
 
249
                key=sortingKey( i->text(), isDirOrArchive, spec );
 
250
 
 
251
        item->setKey(key);
 
252
}
 
253
 
 
254
 
 
255
void GVFileDetailView::removeItem( const KFileItem *i )
 
256
{
 
257
        if ( !i ) return;
 
258
 
 
259
        GVFileDetailViewItem *item = viewItem(i);
 
260
        mResolver->m_lstPendingMimeIconItems.remove( item );
 
261
        if(mShownFileItem==i) mShownFileItem=0L;
 
262
        delete item;
 
263
 
 
264
        KFileView::removeItem( i );
 
265
}
 
266
 
 
267
void GVFileDetailView::slotSortingChanged( int col )
 
268
{
 
269
        QDir::SortSpec sort = sorting();
 
270
        int sortSpec = -1;
 
271
        bool reversed = col == mSortingCol && (sort & QDir::Reversed) == 0;
 
272
        mSortingCol = col;
 
273
 
 
274
        switch( col ) {
 
275
        case COL_NAME:
 
276
                sortSpec = (sort & ~QDir::SortByMask | QDir::Name);
 
277
                break;
 
278
        case COL_SIZE:
 
279
                sortSpec = (sort & ~QDir::SortByMask | QDir::Size);
 
280
                break;
 
281
        case COL_DATE:
 
282
                sortSpec = (sort & ~QDir::SortByMask | QDir::Time);
 
283
                break;
 
284
 
 
285
        // the following columns have no equivalent in QDir, so we set it
 
286
        // to QDir::Unsorted and remember the column (mSortingCol)
 
287
        case COL_OWNER:
 
288
        case COL_GROUP:
 
289
        case COL_PERM:
 
290
                // grmbl, QDir::Unsorted == SortByMask.
 
291
                sortSpec = (sort & ~QDir::SortByMask);// | QDir::Unsorted;
 
292
                break;
 
293
        default:
 
294
                break;
 
295
        }
 
296
 
 
297
        if ( reversed )
 
298
                sortSpec |= QDir::Reversed;
 
299
        else
 
300
                sortSpec &= ~QDir::Reversed;
 
301
 
 
302
        if ( sort & QDir::IgnoreCase )
 
303
                sortSpec |= QDir::IgnoreCase;
 
304
        else
 
305
                sortSpec &= ~QDir::IgnoreCase;
 
306
 
 
307
 
 
308
        KFileView::setSorting( static_cast<QDir::SortSpec>( sortSpec ) );
 
309
 
 
310
        KFileItem *item;
 
311
        KFileItemListIterator it( *items() );
 
312
 
 
313
        for ( ; (item = it.current() ); ++it ) {
 
314
                GVFileDetailViewItem* thumbItem=viewItem( item );
 
315
                if (thumbItem) setSortingKey(thumbItem,item);
 
316
        }
 
317
 
 
318
        KListView::setSorting( mSortingCol, !reversed );
 
319
        KListView::sort();
 
320
 
 
321
        if (!mBlockSortingSignal) sig->changeSorting( static_cast<QDir::SortSpec>( sortSpec ) );
 
322
}
 
323
 
 
324
 
 
325
void GVFileDetailView::setSorting( QDir::SortSpec spec )
 
326
{
 
327
        int col = 0;
 
328
        if ( spec & QDir::Time )
 
329
                col = COL_DATE;
 
330
        else if ( spec & QDir::Size )
 
331
                col = COL_SIZE;
 
332
        else if ( spec & QDir::Unsorted )
 
333
                col = mSortingCol;
 
334
        else
 
335
                col = COL_NAME;
 
336
 
 
337
        // inversed, because slotSortingChanged will reverse it
 
338
        if ( spec & QDir::Reversed )
 
339
                spec = (QDir::SortSpec) (spec & ~QDir::Reversed);
 
340
        else
 
341
                spec = (QDir::SortSpec) (spec | QDir::Reversed);
 
342
 
 
343
        mSortingCol = col;
 
344
        KFileView::setSorting( (QDir::SortSpec) spec );
 
345
 
 
346
 
 
347
        // don't emit sortingChanged() when called via setSorting()
 
348
        mBlockSortingSignal = true; // can't use blockSignals()
 
349
        slotSortingChanged( col );
 
350
        mBlockSortingSignal = false;
 
351
}
 
352
 
 
353
void GVFileDetailView::ensureItemVisible( const KFileItem *i )
 
354
{
 
355
        if ( !i ) return;
 
356
 
 
357
        GVFileDetailViewItem *item = viewItem(i);
 
358
                
 
359
        if ( item ) KListView::ensureItemVisible( item );
 
360
}
 
361
 
 
362
// we're in multiselection mode
 
363
void GVFileDetailView::slotSelectionChanged()
 
364
{
 
365
        sig->highlightFile( 0L );
 
366
}
 
367
 
 
368
KFileItem * GVFileDetailView::firstFileItem() const
 
369
{
 
370
        GVFileDetailViewItem *item = static_cast<GVFileDetailViewItem*>( firstChild() );
 
371
        if ( item ) return item->fileInfo();
 
372
        return 0L;
 
373
}
 
374
 
 
375
KFileItem * GVFileDetailView::nextItem( const KFileItem *fileItem ) const
 
376
{
 
377
        if ( fileItem ) {
 
378
                GVFileDetailViewItem *item = viewItem( fileItem );
 
379
                if ( item && item->itemBelow() )
 
380
                        return ((GVFileDetailViewItem*) item->itemBelow())->fileInfo();
 
381
                else
 
382
                        return 0L;
 
383
        }
 
384
        else
 
385
                return firstFileItem();
 
386
}
 
387
 
 
388
KFileItem * GVFileDetailView::prevItem( const KFileItem *fileItem ) const
 
389
{
 
390
        if ( fileItem ) {
 
391
                GVFileDetailViewItem *item = viewItem( fileItem );
 
392
                if ( item && item->itemAbove() )
 
393
                        return ((GVFileDetailViewItem*) item->itemAbove())->fileInfo();
 
394
                else
 
395
                        return 0L;
 
396
        }
 
397
        else
 
398
                return firstFileItem();
 
399
}
 
400
 
 
401
void GVFileDetailView::keyPressEvent( QKeyEvent *e )
 
402
{
 
403
        KListView::keyPressEvent( e );
 
404
 
 
405
        if ( e->key() == Key_Return || e->key() == Key_Enter ) {
 
406
                if ( e->state() & ControlButton )
 
407
                        e->ignore();
 
408
                else
 
409
                        e->accept();
 
410
        }
 
411
}
 
412
 
 
413
//
 
414
// mimetype determination on demand
 
415
//
 
416
void GVFileDetailView::mimeTypeDeterminationFinished()
 
417
{
 
418
        // anything to do?
 
419
}
 
420
 
 
421
void GVFileDetailView::determineIcon( GVFileDetailViewItem *item )
 
422
{
 
423
        (void) item->fileInfo()->determineMimeType();
 
424
        updateView( item->fileInfo() );
 
425
}
 
426
 
 
427
void GVFileDetailView::listingCompleted()
 
428
{
 
429
        mResolver->start();
 
430
}
 
431
 
 
432
void GVFileDetailView::startDrag()
 
433
{
 
434
        KURL::List urls;
 
435
        KFileItemListIterator it(*KFileView::selectedItems());
 
436
 
 
437
        for ( ; it.current(); ++it ) {
 
438
                urls.append(it.current()->url());
 
439
        }
 
440
 
 
441
        if (urls.isEmpty()) {
 
442
                kdWarning() << "No item to drag\n";
 
443
                return;
 
444
        }
 
445
 
 
446
        QDragObject* drag=new KURLDrag(urls, this, 0);
 
447
        QPixmap dragPixmap;
 
448
        if (urls.count()>1) {
 
449
                dragPixmap=SmallIcon("kmultiple");
 
450
        } else {
 
451
                dragPixmap=KFileView::selectedItems()->getFirst()->pixmap(16);
 
452
        }
 
453
        drag->setPixmap( dragPixmap, QPoint(dragPixmap.width()/2, dragPixmap.height()/2) );
 
454
 
 
455
        drag->dragCopy();
 
456
}
 
457
 
 
458
 
 
459
void GVFileDetailView::setShownFileItem(KFileItem* fileItem)
 
460
{
 
461
        if( fileItem == mShownFileItem ) return;
 
462
        GVFileDetailViewItem* oldShownItem=viewItem(mShownFileItem);
 
463
        GVFileDetailViewItem* newShownItem=viewItem(fileItem);
 
464
        
 
465
        GVFileViewBase::setShownFileItem(fileItem);
 
466
        if (oldShownItem) oldShownItem->repaint();
 
467
        if (newShownItem) newShownItem->repaint();
 
468
}
 
469
 
 
470
 
 
471
//----------------------------------------------------------------------
 
472
//
 
473
// Drop support
 
474
//
 
475
//----------------------------------------------------------------------
 
476
bool GVFileDetailView::acceptDrag(QDropEvent* event) const {
 
477
        return KURLDrag::canDecode(event);
 
478
}
 
479
 
 
480
void GVFileDetailView::contentsDropEvent(QDropEvent *event) {
 
481
        KFileItem* fileItem=0L;
 
482
        QListViewItem *item=itemAt(contentsToViewport(event->pos() ) );
 
483
        
 
484
        if (item) {
 
485
                fileItem=static_cast<GVFileDetailViewItem*>(item)->fileInfo();
 
486
        }
 
487
        emit dropped(event,fileItem);
 
488
}