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.
430 lines
11 KiB
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"
|