|
|
|
/***************************************************************************
|
|
|
|
krview.cpp
|
|
|
|
-------------------
|
|
|
|
copyright : (C) 2000-2002 by Shie Erlich & Rafi Yanai
|
|
|
|
e-mail : krusader@users.sourceforge.net
|
|
|
|
web site : http://krusader.sourceforge.net
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
Description
|
|
|
|
***************************************************************************
|
|
|
|
|
|
|
|
A
|
|
|
|
|
|
|
|
db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b.
|
|
|
|
88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D
|
|
|
|
88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY'
|
|
|
|
88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b
|
|
|
|
88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88.
|
|
|
|
YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD
|
|
|
|
|
|
|
|
S o u r c e F i l e
|
|
|
|
|
|
|
|
***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
#include "krview.h"
|
|
|
|
#include "../kicons.h"
|
|
|
|
#include "../defaults.h"
|
|
|
|
#include "../VFS/krpermhandler.h"
|
|
|
|
#include "krviewitem.h"
|
|
|
|
#include <tqnamespace.h>
|
|
|
|
#include <tqpixmapcache.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqbitmap.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kinputdialog.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define VF getVfile()
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------- operator
|
|
|
|
KrViewOperator::KrViewOperator(KrView *view, TQWidget *widget): _view(view), _widget(widget) {
|
|
|
|
}
|
|
|
|
|
|
|
|
KrViewOperator::~KrViewOperator() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrViewOperator::startDrag() {
|
|
|
|
TQStringList items;
|
|
|
|
_view->getSelectedItems( &items );
|
|
|
|
if ( items.empty() )
|
|
|
|
return ; // don't drag an empty thing
|
|
|
|
TQPixmap px;
|
|
|
|
if ( items.count() > 1 )
|
|
|
|
px = FL_LOADICON( "queue" ); // how much are we dragging
|
|
|
|
else
|
|
|
|
px = _view->getCurrentKrViewItem() ->icon();
|
|
|
|
emit letsDrag( items, px );
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------- krview
|
|
|
|
|
|
|
|
KrView::KrView( KConfig *cfg ) : _config( cfg ), _widget(0), _nameToMakeCurrent( TQString() ), _nameToMakeCurrentIfAdded( TQString() ),
|
|
|
|
_numSelected( 0 ), _count( 0 ), _numDirs( 0 ), _countSize( 0 ), _selectedSize( 0 ), _properties(0), _focused( false ), _nameInKConfig(TQString()) {
|
|
|
|
}
|
|
|
|
|
|
|
|
KrView::~KrView() {
|
|
|
|
if (_properties)
|
|
|
|
qFatal("A class inheriting KrView didn't delete _properties!");
|
|
|
|
if (_operator)
|
|
|
|
qFatal("A class inheriting KrView didn't delete _operator!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::init() {
|
|
|
|
// sanity checks:
|
|
|
|
if (_nameInKConfig.isEmpty())
|
|
|
|
qFatal("_nameInKConfig must be set during construction of KrView inheritors");
|
|
|
|
if (!_widget)
|
|
|
|
qFatal("_widget must be set during construction of KrView inheritors");
|
|
|
|
// ok, continue
|
|
|
|
initProperties();
|
|
|
|
initOperator();
|
|
|
|
setup();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPixmap KrView::getIcon( vfile *vf /*, KRListItem::cmpColor color*/ ) {
|
|
|
|
//krConfig->setGroup("Advanced");
|
|
|
|
//////////////////////////////
|
|
|
|
TQPixmap icon;
|
|
|
|
TQString icon_name = vf->vfile_getIcon();
|
|
|
|
//TQPixmapCache::setCacheLimit( krConfig->readNumEntry("Icon Cache Size",_IconCacheSize) );
|
|
|
|
|
|
|
|
if( icon_name.isNull() )
|
|
|
|
icon_name="";
|
|
|
|
|
|
|
|
// first try the cache
|
|
|
|
if ( !TQPixmapCache::find( icon_name, icon ) ) {
|
|
|
|
icon = FL_LOADICON( icon_name );
|
|
|
|
// insert it into the cache
|
|
|
|
TQPixmapCache::insert( icon_name, icon );
|
|
|
|
}
|
|
|
|
// if it's a symlink - add an arrow overlay
|
|
|
|
if ( vf->vfile_isSymLink() ) {
|
|
|
|
TQPixmap link( link_xpm );
|
|
|
|
bitBlt ( TQT_TQPAINTDEVICE(&icon), 0, icon.height() - 11, TQT_TQPAINTDEVICE(&link), 0, 21, 10, 11, TQt::CopyROP, false );
|
|
|
|
icon.setMask( icon.createHeuristicMask( false ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this function ADDs a list of selected item names into 'names'.
|
|
|
|
* it assumes the list is ready and doesn't initialize it, or clears it
|
|
|
|
*/
|
|
|
|
void KrView::getItemsByMask( TQString mask, TQStringList* names, bool dirs, bool files ) {
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) ) {
|
|
|
|
if ( ( it->name() == ".." ) || !TQDir::match( mask, it->name() ) ) continue;
|
|
|
|
// if we got here, than the item fits the mask
|
|
|
|
if ( it->getVfile()->vfile_isDir() && !dirs ) continue; // do we need to skip folders?
|
|
|
|
if ( !it->getVfile()->vfile_isDir() && !files ) continue; // do we need to skip files
|
|
|
|
names->append( it->name() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this function ADDs a list of selected item names into 'names'.
|
|
|
|
* it assumes the list is ready and doesn't initialize it, or clears it
|
|
|
|
*/
|
|
|
|
void KrView::getSelectedItems( TQStringList *names ) {
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) )
|
|
|
|
if ( it->isSelected() && ( it->name() != ".." ) ) names->append( it->name() );
|
|
|
|
|
|
|
|
// if all else fails, take the current item
|
|
|
|
TQString item = getCurrentItem();
|
|
|
|
if ( names->empty() && item!=TQString() && item!=".." ) names->append( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::getSelectedKrViewItems( KrViewItemList *items ) {
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) )
|
|
|
|
if ( it->isSelected() && ( it->name() != ".." ) ) items->append( it );
|
|
|
|
|
|
|
|
// if all else fails, take the current item
|
|
|
|
TQString item = getCurrentItem();
|
|
|
|
if ( items->empty() && item!=TQString() && item!=".." ) items->append( getCurrentKrViewItem() );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KrView::statistics() {
|
|
|
|
_countSize = _numSelected = _selectedSize = 0;
|
|
|
|
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) ){
|
|
|
|
if ( it->isSelected() ) {
|
|
|
|
++_numSelected;
|
|
|
|
_selectedSize += it->getVfile()->vfile_getSize();
|
|
|
|
}
|
|
|
|
if (it->getVfile()->vfile_getSize() > 0)
|
|
|
|
_countSize += it->getVfile()->vfile_getSize();
|
|
|
|
}
|
|
|
|
TQString tmp = TQString(i18n("%1 out of %2, %3 (%4) out of %5 (%6)"))
|
|
|
|
.tqarg( _numSelected ).tqarg( _count ).tqarg( KIO::convertSize( _selectedSize ) )
|
|
|
|
.tqarg( KRpermHandler::parseSize(_selectedSize) )
|
|
|
|
.tqarg( KIO::convertSize( _countSize ) ).tqarg( KRpermHandler::parseSize(_countSize) );
|
|
|
|
// notify if we're running a filtered view
|
|
|
|
if (filter() != KrViewProperties::All)
|
|
|
|
tmp = ">> [ " + filterMask().nameFilter() + " ] "+tmp;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::changeSelection( const KRQuery& filter, bool select, bool includeDirs ) {
|
|
|
|
KConfigGroupSaver grpSvr( _config, "Look&Feel" );
|
|
|
|
bool markDirs = _config->readBoolEntry( "Mark Dirs", _MarkDirs ) || includeDirs;
|
|
|
|
|
|
|
|
KrViewItem *temp = getCurrentKrViewItem();
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) ) {
|
|
|
|
if ( it->name() == ".." ) continue;
|
|
|
|
if ( it->getVfile()->vfile_isDir() && !markDirs ) continue;
|
|
|
|
|
|
|
|
vfile * file = it->getMutableVfile(); // filter::match calls getMimetype which isn't const
|
|
|
|
if( file == 0 ) continue;
|
|
|
|
|
|
|
|
if( filter.match( file ) ) {
|
|
|
|
// we're increasing/decreasing the number of selected files
|
|
|
|
if ( select ) {
|
|
|
|
if ( !it->isSelected() ) {
|
|
|
|
++_numSelected;
|
|
|
|
_selectedSize += it->getVfile()->vfile_getSize();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( it->isSelected() ) {
|
|
|
|
--_numSelected;
|
|
|
|
_selectedSize -= it->getVfile()->vfile_getSize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
it->setSelected( select );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateView();
|
|
|
|
makeItemVisible( temp );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::invertSelection() {
|
|
|
|
KConfigGroupSaver grpSvr( _config, "Look&Feel" /*nameInKConfig()*/ );
|
|
|
|
bool markDirs = _config->readBoolEntry( "Mark Dirs", _MarkDirs );
|
|
|
|
|
|
|
|
KrViewItem *temp = getCurrentKrViewItem();
|
|
|
|
for ( KrViewItem * it = getFirst(); it != 0; it = getNext( it ) ) {
|
|
|
|
if ( it->name() == ".." ) continue;
|
|
|
|
if ( it->getVfile()->vfile_isDir() && !markDirs && !it->isSelected() ) continue;
|
|
|
|
if ( it->isSelected() ) {
|
|
|
|
--_numSelected;
|
|
|
|
_selectedSize -= it->getVfile()->vfile_getSize();
|
|
|
|
} else {
|
|
|
|
++_numSelected;
|
|
|
|
_selectedSize += it->getVfile()->vfile_getSize();
|
|
|
|
}
|
|
|
|
it->setSelected( !it->isSelected() );
|
|
|
|
}
|
|
|
|
updateView();
|
|
|
|
makeItemVisible( temp );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KrView::firstUnmarkedBelowCurrent() {
|
|
|
|
KrViewItem * iterator = getNext( getCurrentKrViewItem() );
|
|
|
|
while ( iterator && iterator->isSelected() )
|
|
|
|
iterator = getNext( iterator );
|
|
|
|
if ( !iterator ) {
|
|
|
|
iterator = getPrev( getCurrentKrViewItem() );
|
|
|
|
while ( iterator && iterator->isSelected() )
|
|
|
|
iterator = getPrev( iterator );
|
|
|
|
}
|
|
|
|
if ( !iterator ) return TQString();
|
|
|
|
return iterator->name();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::delItem(const TQString &name) {
|
|
|
|
KrViewItem * it = _dict[ name ];
|
|
|
|
if ( !it ) {
|
|
|
|
krOut << "got signal deletedVfile(" << name << ") but can't find KrViewItem" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!preDelItem(it)) return; // do not delete this after all
|
|
|
|
|
|
|
|
// remove from dict
|
|
|
|
if (it->VF->vfile_isDir()) {
|
|
|
|
--_numDirs;
|
|
|
|
} else {
|
|
|
|
_countSize -= it->VF->vfile_getSize();
|
|
|
|
}
|
|
|
|
--_count;
|
|
|
|
_dict.remove( name );
|
|
|
|
delete it;
|
|
|
|
op()->emitSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
KrViewItem *KrView::addItem( vfile *vf ) {
|
|
|
|
KrViewItem *item = preAddItem(vf);
|
|
|
|
if (!item) return 0; // don't add it after all
|
|
|
|
|
|
|
|
// add to dictionary
|
|
|
|
_dict.insert( vf->vfile_getName(), item );
|
|
|
|
if ( vf->vfile_isDir() )
|
|
|
|
++_numDirs;
|
|
|
|
else _countSize += vf->vfile_getSize();
|
|
|
|
++_count;
|
|
|
|
|
|
|
|
if (item->name() == nameToMakeCurrent() ) {
|
|
|
|
setCurrentItem(item->name()); // dictionary based - quick
|
|
|
|
makeItemVisible( item );
|
|
|
|
}
|
|
|
|
if (item->name() == nameToMakeCurrentIfAdded() ) {
|
|
|
|
setCurrentItem(item->name());
|
|
|
|
setNameToMakeCurrentIfAdded(TQString());
|
|
|
|
makeItemVisible( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
op()->emitSelectionChanged();
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::updateItem(vfile *vf) {
|
|
|
|
// since we're deleting the item, make sure we keep
|
|
|
|
// it's properties first and repair it later
|
|
|
|
KrViewItem * it = _dict[ vf->vfile_getName() ];
|
|
|
|
if ( !it ) {
|
|
|
|
krOut << "got signal updatedVfile(" << vf->vfile_getName() << ") but can't find KrViewItem" << endl;
|
|
|
|
} else {
|
|
|
|
bool selected = it->isSelected();
|
|
|
|
bool current = ( getCurrentKrViewItem() == it );
|
|
|
|
delItem( vf->vfile_getName() );
|
|
|
|
KrViewItem *updatedItem = addItem( vf );
|
|
|
|
// restore settings
|
|
|
|
( _dict[ vf->vfile_getName() ] ) ->setSelected( selected );
|
|
|
|
if ( current ) {
|
|
|
|
setCurrentItem( vf->vfile_getName() );
|
|
|
|
makeItemVisible( updatedItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
op()->emitSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrView::clear() {
|
|
|
|
_count = _numSelected = _numDirs = _selectedSize = _countSize = 0;
|
|
|
|
_dict.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// good old dialog box
|
|
|
|
void KrView::renameCurrentItem() {
|
|
|
|
TQString newName, fileName;
|
|
|
|
|
|
|
|
KrViewItem *it = getCurrentKrViewItem();
|
|
|
|
if ( it ) fileName = it->name();
|
|
|
|
else return ; // quit if no current item available
|
|
|
|
|
|
|
|
// don't allow anyone to rename ..
|
|
|
|
if ( fileName == ".." ) return ;
|
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
newName = KInputDialog::getText( i18n( "Rename" ), i18n( "Rename " ) + fileName + i18n( " to:" ),
|
|
|
|
fileName, &ok, krApp );
|
|
|
|
// if the user canceled - quit
|
|
|
|
if ( !ok || newName == fileName )
|
|
|
|
return ;
|
|
|
|
op()->emitRenameItem(it->name(), newName);
|
|
|
|
}
|
|
|
|
|