You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kio/kfile/kfileview.cpp

430 lines
11 KiB

/* This file is part of the KDE libraries
Copyright (C) 1998 Stephan Kulow <coolo@kde.org>
1998 Daniel Grana <grana@ie.iwi.unibe.ch>
2001 Carsten Pfeiffer <pfeiffer@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <assert.h>
#include <stdlib.h>
#include <kaction.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include "config-kfile.h"
#include "kfileview.h"
#ifdef Unsorted // the "I hate X.h" modus
#undef Unsorted
#endif
QDir::SortSpec KFileView::defaultSortSpec = static_cast<QDir::SortSpec>(QDir::Name | QDir::IgnoreCase | QDir::DirsFirst);
class KFileView::KFileViewPrivate
{
public:
KFileViewPrivate()
{
actions = 0;
dropOptions = 0;
}
~KFileViewPrivate()
{
if( actions ) {
actions->clear(); // so that the removed() signal is emitted!
delete actions;
}
}
QGuardedPtr<KActionCollection> actions;
int dropOptions;
};
KFileView::KFileView()
{
d = new KFileViewPrivate();
m_sorting = KFileView::defaultSortSpec;
sig = new KFileViewSignaler();
sig->setName("view-signaller");
m_selectedList = 0L;
filesNumber = 0;
dirsNumber = 0;
view_mode = All;
selection_mode = KFile::Single;
m_viewName = i18n("Unknown View");
myOnlyDoubleClickSelectsFiles = false;
m_itemList.setAutoDelete( false ); // just references
}
KFileView::~KFileView()
{
delete d;
delete sig;
delete m_selectedList;
}
void KFileView::setParentView(KFileView *parent)
{
if ( parent ) { // pass all signals right to our parent
QObject::connect(sig, SIGNAL( activatedMenu(const KFileItem *,
const QPoint& ) ),
parent->sig, SIGNAL( activatedMenu(const KFileItem *,
const QPoint& )));
QObject::connect(sig, SIGNAL( dirActivated(const KFileItem *)),
parent->sig, SIGNAL( dirActivated(const KFileItem*)));
QObject::connect(sig, SIGNAL( fileSelected(const KFileItem *)),
parent->sig, SIGNAL( fileSelected(const KFileItem*)));
QObject::connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ),
parent->sig,SIGNAL(fileHighlighted(const KFileItem*)));
QObject::connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ),
parent->sig, SIGNAL(sortingChanged( QDir::SortSpec)));
QObject::connect(sig, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&) ),
parent->sig, SIGNAL(dropped(const KFileItem *, QDropEvent*, const KURL::List&)));
}
}
bool KFileView::updateNumbers(const KFileItem *i)
{
if (!( viewMode() & Files ) && i->isFile())
return false;
if (!( viewMode() & Directories ) && i->isDir())
return false;
if (i->isDir())
dirsNumber++;
else
filesNumber++;
return true;
}
void qt_qstring_stats();
// filter out files if we're in directory mode and count files/directories
// and insert into the view
void KFileView::addItemList(const KFileItemList& list)
{
KFileItem *tmp;
for (KFileItemListIterator it(list); (tmp = it.current()); ++it)
{
if (!updateNumbers(tmp))
continue;
insertItem( tmp );
}
#ifdef Q2HELPER
qt_qstring_stats();
#endif
}
void KFileView::insertItem( KFileItem * )
{
}
void KFileView::setSorting(QDir::SortSpec new_sort)
{
m_sorting = new_sort;
}
void KFileView::clear()
{
m_itemList.clear();
filesNumber = 0;
dirsNumber = 0;
clearView();
}
void KFileView::sortReversed()
{
int spec = sorting();
setSorting( static_cast<QDir::SortSpec>( spec ^ QDir::Reversed ) );
}
#if 0
int KFileView::compareItems(const KFileItem *fi1, const KFileItem *fi2) const
{
static const QString &dirup = KGlobal::staticQString("..");
bool bigger = true;
bool keepFirst = false;
bool dirsFirst = ((m_sorting & QDir::DirsFirst) == QDir::DirsFirst);
if (fi1 == fi2)
return 0;
// .. is always bigger, independent of the sort criteria
if ( fi1->name() == dirup ) {
bigger = false;
keepFirst = dirsFirst;
}
else if ( fi2->name() == dirup ) {
bigger = true;
keepFirst = dirsFirst;
}
else {
if ( fi1->isDir() != fi2->isDir() && dirsFirst ) {
bigger = fi2->isDir();
keepFirst = true;
}
else {
QDir::SortSpec sort = static_cast<QDir::SortSpec>(m_sorting & QDir::SortByMask);
//if (fi1->isDir() || fi2->isDir())
// sort = static_cast<QDir::SortSpec>(KFileView::defaultSortSpec & QDir::SortByMask);
switch (sort) {
case QDir::Name:
default:
sort_by_name:
if ( (m_sorting & QDir::IgnoreCase) == QDir::IgnoreCase )
bigger = (fi1->name( true ) > fi2->name( true ));
else
bigger = (fi1->name() > fi2->name());
break;
case QDir::Time:
{
time_t t1 = fi1->time( KIO::UDS_MODIFICATION_TIME );
time_t t2 = fi2->time( KIO::UDS_MODIFICATION_TIME );
if ( t1 != t2 ) {
bigger = (t1 > t2);
break;
}
// Sort by name if both items have the same timestamp.
// Don't honor the reverse flag tho.
else {
keepFirst = true;
goto sort_by_name;
}
}
case QDir::Size:
{
KIO::filesize_t s1 = fi1->size();
KIO::filesize_t s2 = fi2->size();
if ( s1 != s2 ) {
bigger = (s1 > s2);
break;
}
// Sort by name if both items have the same size.
// Don't honor the reverse flag tho.
else {
keepFirst = true;
goto sort_by_name;
}
}
case QDir::Unsorted:
bigger = true; // nothing
break;
}
}
}
if (reversed && !keepFirst ) // don't reverse dirs to the end!
bigger = !bigger;
return (bigger ? 1 : -1);
}
#endif
void KFileView::updateView(bool f)
{
widget()->repaint(f);
}
void KFileView::updateView(const KFileItem *)
{
}
void KFileView::setCurrentItem(const QString &filename )
{
if (!filename.isNull()) {
KFileItem *item;
for ( (item = firstFileItem()); item; item = nextItem( item ) ) {
if (item->name() == filename) {
setCurrentItem( item );
return;
}
}
}
kdDebug(kfile_area) << "setCurrentItem: no match found: " << filename << endl;
}
const KFileItemList * KFileView::items() const
{
KFileItem *item = 0L;
// only ever use m_itemList in this method!
m_itemList.clear();
for ( (item = firstFileItem()); item; item = nextItem( item ) )
m_itemList.append( item );
return &m_itemList;
}
const KFileItemList * KFileView::selectedItems() const
{
if ( !m_selectedList )
m_selectedList = new KFileItemList;
m_selectedList->clear();
KFileItem *item;
for ( (item = firstFileItem()); item; item = nextItem( item ) ) {
if ( isSelected( item ) )
m_selectedList->append( item );
}
return m_selectedList;
}
void KFileView::selectAll()
{
if (selection_mode == KFile::NoSelection || selection_mode== KFile::Single)
return;
KFileItem *item = 0L;
for ( (item = firstFileItem()); item; item = nextItem( item ) )
setSelected( item, true );
}
void KFileView::invertSelection()
{
KFileItem *item = 0L;
for ( (item = firstFileItem()); item; item = nextItem( item ) )
setSelected( item, !isSelected( item ) );
}
void KFileView::setSelectionMode( KFile::SelectionMode sm )
{
selection_mode = sm;
}
KFile::SelectionMode KFileView::selectionMode() const
{
return selection_mode;
}
void KFileView::setViewMode( ViewMode vm )
{
view_mode = vm;
}
void KFileView::removeItem( const KFileItem *item )
{
if ( !item )
return;
if ( item->isDir() )
dirsNumber--;
else
filesNumber--;
if ( m_selectedList )
m_selectedList->removeRef( item );
}
void KFileView::listingCompleted()
{
// empty default impl.
}
KActionCollection * KFileView::actionCollection() const
{
if ( !d->actions )
d->actions = new KActionCollection( widget(), "KFileView::d->actions" );
return d->actions;
}
void KFileView::readConfig( KConfig *, const QString& )
{
}
void KFileView::writeConfig( KConfig *, const QString& )
{
}
QString KFileView::sortingKey( const QString& value, bool isDir, int sortSpec )
{
bool reverse = sortSpec & QDir::Reversed;
bool dirsFirst = sortSpec & QDir::DirsFirst;
char start = (isDir && dirsFirst) ? (reverse ? '2' : '0') : '1';
QString result = (sortSpec & QDir::IgnoreCase) ? value.lower() : value;
return result.prepend( start );
}
QString KFileView::sortingKey( KIO::filesize_t value, bool isDir, int sortSpec)
{
bool reverse = sortSpec & QDir::Reversed;
bool dirsFirst = sortSpec & QDir::DirsFirst;
char start = (isDir && dirsFirst) ? (reverse ? '2' : '0') : '1';
return KIO::number( value ).rightJustify( 24, '0' ).prepend( start );
}
void KFileView::setDropOptions(int options)
{
virtual_hook(VIRTUAL_SET_DROP_OPTIONS, &options); // Virtual call
}
void KFileView::setDropOptions_impl(int options)
{
d->dropOptions = options;
}
int KFileView::dropOptions()
{
return d->dropOptions;
}
int KFileView::autoOpenDelay()
{
return (QApplication::startDragTime() * 3) / 2;
}
void KFileView::virtual_hook( int id, void* data)
{
switch(id) {
case VIRTUAL_SET_DROP_OPTIONS:
setDropOptions_impl(*(int *)data);
break;
default:
/*BASE::virtual_hook( id, data );*/
break;
}
}
#include "kfileview.moc"