/*************************************************************************** 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 #include #include #include #include #include #include #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( TDEConfig *cfg ) : _config( cfg ), _widget(0), _nameToMakeCurrent( TQString() ), _nameToMakeCurrentIfAdded( TQString() ), _numSelected( 0 ), _count( 0 ), _numDirs( 0 ), _countSize( 0 ), _selectedSize( 0 ), _properties(0), _focused( false ), _nameInTDEConfig(TQString()) { } KrView::~KrView() { if (_properties) tqFatal("A class inheriting KrView didn't delete _properties!"); if (_operator) tqFatal("A class inheriting KrView didn't delete _operator!"); } void KrView::init() { // sanity checks: if (_nameInTDEConfig.isEmpty()) tqFatal("_nameInTDEConfig must be set during construction of KrView inheritors"); if (!_widget) tqFatal("_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 ( &icon, 0, icon.height() - 11, &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)")) .arg( _numSelected ).arg( _count ).arg( TDEIO::convertSize( _selectedSize ) ) .arg( KRpermHandler::parseSize(_selectedSize) ) .arg( TDEIO::convertSize( _countSize ) ).arg( 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 ) { TDEConfigGroupSaver 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() { TDEConfigGroupSaver grpSvr( _config, "Look&Feel" /*nameInTDEConfig()*/ ); 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); }