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.
krusader/krusader/DiskUsage/diskusage.cpp

1148 lines
30 KiB

/***************************************************************************
diskusage.cpp - description
-------------------
copyright : (C) 2004 + by Csaba Karai
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 <time.h>
#include <tqlayout.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <kmimetype.h>
#include <tdemessagebox.h>
#include <tdeglobalsettings.h>
#include <tdeio/job.h>
#include <tqpushbutton.h>
#include <tqhbox.h>
#include <tqapplication.h>
#include <tqcursor.h>
#include <tqpixmapcache.h>
#include <tqgroupbox.h>
#include <tqguardedptr.h>
#include "diskusage.h"
#include "../VFS/krpermhandler.h"
#include "../VFS/krvfshandler.h"
#include "../kicons.h"
#include "../defaults.h"
#include "../krusader.h"
#include "../krusaderview.h"
#include "../Panel/listpanel.h"
#include "../Panel/panelfunc.h"
#include "filelightParts/Config.h"
#include "dulines.h"
#include "dulistview.h"
#include "dufilelight.h"
// these are the values that will exist in the menu
#define DELETE_ID 90
#define EXCLUDE_ID 91
#define PARENT_DIR_ID 92
#define NEW_SEARCH_ID 93
#define REFRESH_ID 94
#define STEP_INTO_ID 95
#define INCLUDE_ALL_ID 96
#define VIEW_POPUP_ID 97
#define LINES_VIEW_ID 98
#define DETAILED_VIEW_ID 99
#define FILELIGHT_VIEW_ID 100
#define NEXT_VIEW_ID 101
#define PREVIOUS_VIEW_ID 102
#define ADDITIONAL_POPUP_ID 103
#define MAX_FILENUM 100
LoaderWidget::LoaderWidget( TQWidget *parent, const char *name ) : TQScrollView( parent, name ), cancelled( false )
{
viewport()->setEraseColor( TQt::white );
widget = new TQWidget( parent );
TQGridLayout *loaderLayout = new TQGridLayout( widget );
loaderLayout->setSpacing( 0 );
loaderLayout->setMargin( 0 );
TQGroupBox *loaderBox = new TQGroupBox( widget, "loaderGroupBox" );
loaderBox->setFrameShape( TQGroupBox::Box );
loaderBox->setFrameShadow( TQGroupBox::Sunken );
loaderBox->setColumnLayout(0, TQt::Vertical );
loaderBox->layout()->setSpacing( 0 );
loaderBox->layout()->setMargin( 0 );
loaderBox->setSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
loaderBox->setFrameStyle( TQFrame::Panel + TQFrame::Raised );
loaderBox->setLineWidth( 2 );
TQGridLayout *synchGrid = new TQGridLayout( loaderBox->layout() );
synchGrid->setSpacing( 6 );
synchGrid->setMargin( 11 );
TQLabel *titleLabel = new TQLabel( i18n( "Loading Usage Information" ), loaderBox, "titleLabel" );
titleLabel->setAlignment( TQt::AlignHCenter );
synchGrid->addMultiCellWidget( titleLabel, 0, 0, 0, 1 );
TQLabel *filesLabel = new TQLabel( i18n( "Files:" ), loaderBox, "filesLabel" );
filesLabel->setFrameShape( TQLabel::StyledPanel );
filesLabel->setFrameShadow( TQLabel::Sunken );
synchGrid->addWidget( filesLabel, 1, 0 );
TQLabel *directoriesLabel = new TQLabel( i18n( "Directories:" ), loaderBox, "directoriesLabel" );
directoriesLabel->setFrameShape( TQLabel::StyledPanel );
directoriesLabel->setFrameShadow( TQLabel::Sunken );
synchGrid->addWidget( directoriesLabel, 2, 0 );
TQLabel *totalSizeLabel = new TQLabel( i18n( "Total Size:" ), loaderBox, "totalSizeLabel" );
totalSizeLabel->setFrameShape( TQLabel::StyledPanel );
totalSizeLabel->setFrameShadow( TQLabel::Sunken );
synchGrid->addWidget( totalSizeLabel, 3, 0 );
files = new TQLabel( loaderBox, "files" );
files->setFrameShape( TQLabel::StyledPanel );
files->setFrameShadow( TQLabel::Sunken );
files->setAlignment( TQt::AlignRight );
synchGrid->addWidget( files, 1, 1 );
directories = new TQLabel( loaderBox, "directories" );
directories->setFrameShape( TQLabel::StyledPanel );
directories->setFrameShadow( TQLabel::Sunken );
directories->setAlignment( TQt::AlignRight );
synchGrid->addWidget( directories, 2, 1 );
totalSize = new TQLabel( loaderBox, "totalSize" );
totalSize->setFrameShape( TQLabel::StyledPanel );
totalSize->setFrameShadow( TQLabel::Sunken );
totalSize->setAlignment( TQt::AlignRight );
synchGrid->addWidget( totalSize, 3, 1 );
int width;
searchedDirectory = new KSqueezedTextLabel( loaderBox, "searchedDirectory" );
searchedDirectory->setFrameShape( TQLabel::StyledPanel );
searchedDirectory->setFrameShadow( TQLabel::Sunken );
searchedDirectory->setMinimumWidth( width = TQFontMetrics(searchedDirectory->font()).width("W") * 30 );
searchedDirectory->setMaximumWidth( width );
synchGrid->addMultiCellWidget( searchedDirectory, 4, 4, 0, 1 );
TQFrame *line = new TQFrame( loaderBox, "duLine" );
line->setFrameStyle( TQFrame::HLine | TQFrame::Sunken );
synchGrid->addMultiCellWidget( line, 5, 5, 0, 1 );
TQHBox *hbox = new TQHBox( loaderBox, "hbox" );
TQSpacerItem* spacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding );
hbox->layout()->addItem( spacer );
TQPushButton *cancelButton = new TQPushButton( hbox, "cancelButton" );
cancelButton->setText( i18n( "Cancel" ) );
synchGrid->addWidget( hbox, 6, 1 );
loaderLayout->addWidget( loaderBox, 0, 0 );
addChild( widget );
connect( cancelButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotCancelled() ) );
}
void LoaderWidget::resizeEvent ( TQResizeEvent *e )
{
TQScrollView::resizeEvent( e );
int x = ( viewport()->width() - widget->width() ) / 2;
int y = ( viewport()->height() - widget->height() ) / 2;
if( x < 0 ) x=0;
if( y < 0 ) y=0;
moveChild( widget, x, y );
}
void LoaderWidget::init()
{
cancelled = false;
}
void LoaderWidget::setCurrentURL( KURL url )
{
searchedDirectory->setText( vfs::pathOrURL( url, 1) );
}
void LoaderWidget::setValues( int fileNum, int dirNum, TDEIO::filesize_t total )
{
files->setText( TQString("%1").arg( fileNum ) );
directories->setText( TQString("%1").arg( dirNum ) );
totalSize->setText( TQString("%1").arg( KRpermHandler::parseSize( total ).stripWhiteSpace() ) );
}
void LoaderWidget::slotCancelled()
{
cancelled = true;
}
DiskUsage::DiskUsage( TQString confGroup, TQWidget *parent, char *name ) : TQWidgetStack( parent, name ),
currentDirectory( 0 ), root( 0 ), configGroup( confGroup ), loading( false ),
abortLoading( false ), clearAfterAbort( false ), deleting( false ), searchVfs( 0 )
{
listView = new DUListView( this, "DU ListView" );
lineView = new DULines( this, "DU LineView" );
filelightView = new DUFilelight( this, "Filelight canvas" );
loaderView = new LoaderWidget( this, "Loading view" );
addWidget( listView );
addWidget( lineView );
addWidget( filelightView );
addWidget( loaderView );
setView( VIEW_LINES );
Filelight::Config::read();
propertyMap.setAutoDelete( true );
connect( &loadingTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotLoadDirectory() ) );
}
DiskUsage::~DiskUsage()
{
if( root )
delete root;
if( listView ) // don't remove these lines. The module will crash at exit if removed
delete listView;
if( lineView )
delete lineView;
if( filelightView )
delete filelightView;
}
void DiskUsage::load( KURL baseDir )
{
if( searchVfs && !searchVfs->vfs_canDelete() ) {
return;
}
fileNum = dirNum = 0;
currentSize = 0;
emit status( i18n( "Loading the disk usage information..." ) );
clear();
baseURL = baseDir;
baseURL.setPath( baseDir.path( -1 ) );
root = new Directory( baseURL.fileName(), vfs::pathOrURL( baseDir ) );
directoryStack.clear();
parentStack.clear();
directoryStack.push( "" );
parentStack.push( root );
if( searchVfs )
{
delete searchVfs;
searchVfs = 0;
}
searchVfs = KrVfsHandler::getVfs( baseDir );
if( searchVfs == 0 )
{
loading = abortLoading = clearAfterAbort = false;
emit loadFinished( false );
return;
}
searchVfs->vfs_setQuiet( true );
currentVfile = 0;
if( !loading )
{
viewBeforeLoad = activeView;
setView( VIEW_LOADER );
}
loading = true;
loaderView->init();
loaderView->setCurrentURL( baseURL );
loaderView->setValues( fileNum, dirNum, currentSize );
loadingTimer.start( 0, true );
}
void DiskUsage::slotLoadDirectory()
{
if( searchVfs && !searchVfs->vfs_canDelete() ) { // recursive call from slotLoadDirectory?
loadingTimer.start( 100, true ); // as it can cause crash, ignore it and wait while
return; // the recursion finishes
}
if( ( currentVfile == 0 && directoryStack.isEmpty() ) || loaderView->wasCancelled() || abortLoading )
{
if( searchVfs )
delete searchVfs;
searchVfs = 0;
currentVfile = 0;
setView( viewBeforeLoad );
if( clearAfterAbort )
clear();
else {
calculateSizes();
changeDirectory( root );
}
emit loadFinished( !( loaderView->wasCancelled() || abortLoading ) );
loading = abortLoading = clearAfterAbort = false;
}
else if( loading )
{
for( int counter = 0; counter != MAX_FILENUM; counter ++ )
{
if( currentVfile == 0 )
{
if( directoryStack.isEmpty() )
break;
dirToCheck = directoryStack.pop();
currentParent = parentStack.pop();
contentMap.insert( dirToCheck, currentParent );
KURL url = baseURL;
if( !dirToCheck.isEmpty() )
url.addPath( dirToCheck );
#if defined(BSD)
if ( url.isLocalFile() && url.path().left( 7 ) == "/procfs" )
break;
#else
if ( url.isLocalFile() && url.path().left( 5 ) == "/proc" )
break;
#endif
loaderView->setCurrentURL( url );
if( !searchVfs->vfs_refresh( url ) )
break;
dirNum++;
currentVfile = searchVfs->vfs_getFirstFile();
}
else
{
fileNum++;
File *newItem = 0;
TQString mime = currentVfile->vfile_getMime(true); // fast == not using mimetype magic
if( currentVfile->vfile_isDir() && !currentVfile->vfile_isSymLink() )
{
newItem = new Directory( currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(),
currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(),
currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(),
mime );
directoryStack.push( (dirToCheck.isEmpty() ? "" : dirToCheck + "/" )+ currentVfile->vfile_getName() );
parentStack.push( dynamic_cast<Directory *>( newItem ) );
}
else
{
newItem = new File( currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(),
currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(),
currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(),
mime );
currentSize += currentVfile->vfile_getSize();
}
currentParent->append( newItem );
currentVfile = searchVfs->vfs_getNextFile();
}
}
loaderView->setValues( fileNum, dirNum, currentSize );
loadingTimer.start( 0, true );
}
}
void DiskUsage::stopLoad()
{
abortLoading = true;
}
void DiskUsage::close()
{
if( loading )
{
abortLoading = true;
clearAfterAbort = true;
}
}
void DiskUsage::dirUp()
{
if( currentDirectory != 0 )
{
if ( currentDirectory->parent() != 0 )
changeDirectory( (Directory *)(currentDirectory->parent()) );
else
{
KURL up = baseURL.upURL();
if( KMessageBox::questionYesNo( this, i18n( "Stepping into the parent directory requires "
"loading the content of the \"%1\" URL. Do you wish "
"to continue?" )
.arg( vfs::pathOrURL( up ) ),
i18n( "Krusader::DiskUsage" ), KStdGuiItem::yes(),
KStdGuiItem::no(), "DiskUsageLoadParentDir"
) == KMessageBox::Yes )
load( up );
}
}
}
Directory * DiskUsage::getDirectory( TQString dir )
{
while( dir.endsWith( "/" ) )
dir.truncate( dir.length() - 1 );
if( dir.isEmpty() )
return root;
return contentMap.find( dir );
}
File * DiskUsage::getFile( TQString path )
{
if( path == "" )
return root;
TQString dir = path;
int ndx = path.findRev( '/' );
TQString file = path.mid( ndx + 1 );
if( ndx == -1 )
dir = "";
else
dir.truncate( ndx );
Directory *dirEntry = getDirectory( dir );
if( dirEntry == 0 )
return 0;
for( Iterator<File> it = dirEntry->iterator(); it != dirEntry->end(); ++it )
if( (*it)->name() == file )
return *it;
return 0;
}
void DiskUsage::clear()
{
baseURL = KURL();
emit clearing();
propertyMap.clear();
contentMap.clear();
if( root )
delete root;
root = currentDirectory = 0;
}
int DiskUsage::calculateSizes( Directory *dirEntry, bool emitSig, int depth )
{
int changeNr = 0;
if( dirEntry == 0 )
dirEntry = root;
TDEIO::filesize_t own = 0, total = 0;
for( Iterator<File> it = dirEntry->iterator(); it != dirEntry->end(); ++it )
{
File * item = *it;
if( !item->isExcluded() )
{
if( item->isDir() )
changeNr += calculateSizes( dynamic_cast<Directory *>( item ), emitSig, depth + 1 );
else
own += item->size();
total += item->size();
}
}
TDEIO::filesize_t oldOwn = dirEntry->ownSize(), oldTotal = dirEntry->size();
dirEntry->setSizes( total, own );
if( dirEntry == currentDirectory )
currentSize = total;
if( emitSig && ( own != oldOwn || total != oldTotal ) ) {
emit changed( dirEntry );
changeNr++;
}
if( depth == 0 && changeNr != 0 )
emit changeFinished();
return changeNr;
}
int DiskUsage::exclude( File *file, bool calcPercents, int depth )
{
int changeNr = 0;
if( !file->isExcluded() )
{
file->exclude( true );
emit changed( file );
changeNr++;
if( file->isDir() )
{
Directory *dir = dynamic_cast<Directory *>( file );
for( Iterator<File> it = dir->iterator(); it != dir->end(); ++it )
changeNr += exclude( *it, false, depth + 1 );
}
}
if( calcPercents )
{
calculateSizes( root, true );
calculatePercents( true );
createStatus();
}
if( depth == 0 && changeNr != 0 )
emit changeFinished();
return changeNr;
}
int DiskUsage::include( Directory *dir, int depth )
{
int changeNr = 0;
if( dir == 0 )
return 0;
for( Iterator<File> it = dir->iterator(); it != dir->end(); ++it )
{
File *item = *it;
if( item->isDir() )
changeNr += include( dynamic_cast<Directory *>( item ), depth + 1 );
if( item->isExcluded() )
{
item->exclude( false );
emit changed( item );
changeNr++;
}
}
if( depth == 0 && changeNr != 0 )
emit changeFinished();
return changeNr;
}
void DiskUsage::includeAll()
{
include( root );
calculateSizes( root, true );
calculatePercents( true );
createStatus();
}
int DiskUsage::del( File *file, bool calcPercents, int depth )
{
int deleteNr = 0;
if( file == root )
return 0;
krConfig->setGroup( "General" );
bool trash = krConfig->readBoolEntry( "Move To Trash", _MoveToTrash );
KURL url = vfs::fromPathOrURL( file->fullPath() );
if( calcPercents )
{
// now ask the user if he want to delete:
krConfig->setGroup( "Advanced" );
if ( krConfig->readBoolEntry( "Confirm Delete", _ConfirmDelete ) ) {
TQString s, b;
if ( trash && url.isLocalFile() ) {
s = i18n( "Do you really want to move this item to the trash?" );
b = i18n( "&Trash" );
} else {
s = i18n( "Do you really want to delete this item?" );
b = i18n( "&Delete" );
}
TQStringList name;
name.append( file->fullPath() );
// show message
// note: i'm using continue and not yes/no because the yes/no has cancel as default button
if ( KMessageBox::warningContinueCancelList( krApp, s, name, i18n( "Warning" ), b ) != KMessageBox::Continue )
return 0;
}
emit status( i18n( "Deleting %1..." ).arg( file->name() ) );
}
if( file == currentDirectory )
dirUp();
if( file->isDir() )
{
Directory *dir = dynamic_cast<Directory *>( file );
Iterator<File> it;
while( ( it = dir->iterator() ) != dir->end() )
deleteNr += del( *it, false, depth + 1 );
TQString path;
for( const Directory *d = (Directory*)file; d != root && d && d->parent() != 0; d = d->parent() )
{
if( !path.isEmpty() )
path = "/" + path;
path = d->name() + path;
}
contentMap.remove( path );
}
emit deleted( file );
deleteNr++;
TQGuardedPtr<TDEIO::Job> job;
if( trash )
{
#if KDE_IS_VERSION(3,4,0)
job = TDEIO::trash( url, true );
#else
job = new TDEIO::CopyJob( url,TDEGlobalSettings::trashPath(),TDEIO::CopyJob::Move,false,true );
#endif
connect(job,TQ_SIGNAL(result(TDEIO::Job*)),krApp,TQ_SLOT(changeTrashIcon()));
}
else
{
job = new TDEIO::DeleteJob( vfs::fromPathOrURL( file->fullPath() ), false, false);
}
deleting = true; // during tqApp->processEvent strange things can occur
grabMouse(); // that's why we disable the mouse and keyboard events
grabKeyboard();
while( !job.isNull() )
tqApp->processEvents();
releaseMouse();
releaseKeyboard();
deleting = false;
((Directory *)(file->parent()))->remove( file );
delete file;
if( depth == 0 )
createStatus();
if( calcPercents )
{
calculateSizes( root, true );
calculatePercents( true );
createStatus();
emit enteringDirectory( currentDirectory );
}
if( depth == 0 && deleteNr != 0 )
emit deleteFinished();
return deleteNr;
}
void * DiskUsage::getProperty( File *item, TQString key )
{
Properties * props = propertyMap.find( item );
if( props == 0 )
return 0;
return props->find( key );
}
void DiskUsage::addProperty( File *item, TQString key, void * prop )
{
Properties * props = propertyMap.find( item );
if( props == 0 )
{
props = new Properties();
propertyMap.insert( item, props );
}
props->insert( key, prop );
}
void DiskUsage::removeProperty( File *item, TQString key )
{
Properties * props = propertyMap.find( item );
if( props == 0 )
return;
props->remove( key );
if( props->count() == 0 )
propertyMap.remove( item );
}
void DiskUsage::createStatus()
{
Directory *dirEntry = currentDirectory;
if( dirEntry == 0 )
return;
KURL url = baseURL;
if( dirEntry != root )
url.addPath( dirEntry->directory() );
emit status( i18n( "Current directory:%1, Total size:%2, Own size:%3" )
.arg( vfs::pathOrURL( url, -1 ) )
.arg( " "+KRpermHandler::parseSize( dirEntry->size() ) )
.arg( " "+KRpermHandler::parseSize( dirEntry->ownSize() ) ) );
}
void DiskUsage::changeDirectory( Directory *dir )
{
currentDirectory = dir;
currentSize = dir->size();
calculatePercents( true, dir );
createStatus();
emit enteringDirectory( dir );
}
Directory* DiskUsage::getCurrentDir()
{
return currentDirectory;
}
void DiskUsage::rightClickMenu( File *fileItem, TDEPopupMenu *addPopup, TQString addPopupName )
{
TDEPopupMenu popup( this );
popup.insertTitle( i18n("Disk Usage"));
if( fileItem != 0 )
{
popup.insertItem( i18n("Delete"), DELETE_ID);
popup.setAccel( Key_Delete, DELETE_ID );
popup.insertItem( i18n("Exclude"), EXCLUDE_ID);
popup.setAccel( CTRL + Key_E, EXCLUDE_ID );
popup.insertSeparator();
}
popup.insertItem( i18n("Up one directory"), PARENT_DIR_ID);
popup.setAccel( SHIFT + Key_Up, PARENT_DIR_ID );
popup.insertItem( i18n("New search"), NEW_SEARCH_ID);
popup.setAccel( CTRL + Key_N, NEW_SEARCH_ID );
popup.insertItem( i18n("Refresh"), REFRESH_ID);
popup.setAccel( CTRL + Key_R, REFRESH_ID );
popup.insertItem( i18n("Include all"), INCLUDE_ALL_ID);
popup.setAccel( CTRL + Key_I, INCLUDE_ALL_ID );
popup.insertItem( i18n("Step into"), STEP_INTO_ID);
popup.setAccel( SHIFT + Key_Down, STEP_INTO_ID );
popup.insertSeparator();
if( addPopup != 0 )
{
popup.insertItem( TQPixmap(), addPopup, ADDITIONAL_POPUP_ID );
popup.changeItem( ADDITIONAL_POPUP_ID, addPopupName );
}
TDEPopupMenu viewPopup;
viewPopup.insertItem(i18n("Lines"), LINES_VIEW_ID);
viewPopup.setAccel( CTRL + Key_L, LINES_VIEW_ID );
viewPopup.insertItem(i18n("Detailed"), DETAILED_VIEW_ID);
viewPopup.setAccel( CTRL + Key_D, DETAILED_VIEW_ID );
viewPopup.insertItem(i18n("Filelight"), FILELIGHT_VIEW_ID);
viewPopup.setAccel( CTRL + Key_F, FILELIGHT_VIEW_ID );
viewPopup.insertSeparator();
viewPopup.insertItem(i18n("Next"), NEXT_VIEW_ID);
viewPopup.setAccel( SHIFT + Key_Right, NEXT_VIEW_ID );
viewPopup.insertItem(i18n("Previous"), PREVIOUS_VIEW_ID);
viewPopup.setAccel( SHIFT + Key_Left, PREVIOUS_VIEW_ID );
popup.insertItem( TQPixmap(), &viewPopup, VIEW_POPUP_ID );
popup.changeItem( VIEW_POPUP_ID, i18n( "View" ) );
int result=popup.exec(TQCursor::pos());
executeAction( result, fileItem );
}
void DiskUsage::executeAction( int action, File * fileItem )
{
// check out the user's option
switch ( action )
{
case DELETE_ID:
if( fileItem )
del( fileItem );
break;
case EXCLUDE_ID:
if( fileItem )
exclude( fileItem );
break;
case PARENT_DIR_ID:
dirUp();
break;
case NEW_SEARCH_ID:
emit newSearch();
break;
case REFRESH_ID:
load( baseURL );
break;
case INCLUDE_ALL_ID:
includeAll();
break;
case STEP_INTO_ID:
{
TQString uri;
if( fileItem && fileItem->isDir() )
uri = fileItem->fullPath();
else
uri = currentDirectory->fullPath();
ACTIVE_FUNC->openUrl(vfs::fromPathOrURL( uri ));
}
break;
case LINES_VIEW_ID:
setView( VIEW_LINES );
break;
case DETAILED_VIEW_ID:
setView( VIEW_DETAILED );
break;
case FILELIGHT_VIEW_ID:
setView( VIEW_FILELIGHT );
break;
case NEXT_VIEW_ID:
setView( ( activeView + 1 ) % 3 );
break;
case PREVIOUS_VIEW_ID:
setView( ( activeView + 2 ) % 3 );
break;
}
visibleWidget()->setFocus();
}
void DiskUsage::keyPressEvent( TQKeyEvent *e )
{
if( activeView != VIEW_LOADER )
{
switch ( e->key() )
{
case Key_E:
if( e->state() == ControlButton )
{
executeAction( EXCLUDE_ID, getCurrentFile() );
return;
}
case Key_D:
if( e->state() == ControlButton )
{
executeAction( DETAILED_VIEW_ID );
return;
}
case Key_F:
if( e->state() == ControlButton )
{
executeAction( FILELIGHT_VIEW_ID );
return;
}
case Key_I:
if( e->state() == ControlButton )
{
executeAction( INCLUDE_ALL_ID );
return;
}
break;
case Key_L:
if( e->state() == ControlButton )
{
executeAction( LINES_VIEW_ID );
return;
}
case Key_N:
if( e->state() == ControlButton )
{
executeAction( NEW_SEARCH_ID );
return;
}
break;
case Key_R:
if( e->state() == ControlButton )
{
executeAction( REFRESH_ID );
return;
}
break;
case Key_Up:
if( e->state() == ShiftButton )
{
executeAction( PARENT_DIR_ID );
return;
}
break;
case Key_Down:
if( e->state() == ShiftButton )
{
executeAction( STEP_INTO_ID );
return;
}
break;
case Key_Left:
if( e->state() == ShiftButton )
{
executeAction( PREVIOUS_VIEW_ID );
return;
}
break;
case Key_Right:
if( e->state() == ShiftButton )
{
executeAction( NEXT_VIEW_ID );
return;
}
break;
case Key_Delete:
if( !e->state() )
{
executeAction( DELETE_ID, getCurrentFile() );
return;
}
case Key_Plus:
if( activeView == VIEW_FILELIGHT )
{
filelightView->zoomIn();
return;
}
break;
case Key_Minus:
if( activeView == VIEW_FILELIGHT )
{
filelightView->zoomOut();
return;
}
break;
}
}
TQWidgetStack::keyPressEvent( e );
}
TQPixmap DiskUsage::getIcon( TQString mime )
{
TQPixmap icon;
if ( !TQPixmapCache::find( mime, icon ) )
{
// get the icon.
if ( mime == "Broken Link !" )
icon = FL_LOADICON( "file_broken" );
else
icon = FL_LOADICON( KMimeType::mimeType( mime ) ->icon( TQString(), true ) );
// insert it into the cache
TQPixmapCache::insert( mime, icon );
}
return icon;
}
int DiskUsage::calculatePercents( bool emitSig, Directory *dirEntry, int depth )
{
int changeNr = 0;
if( dirEntry == 0 )
dirEntry = root;
for( Iterator<File> it = dirEntry->iterator(); it != dirEntry->end(); ++it )
{
File *item = *it;
if( !item->isExcluded() )
{
int newPerc;
if( dirEntry->size() == 0 && item->size() == 0 )
newPerc = 0;
else if( dirEntry->size() == 0 )
newPerc = -1;
else
newPerc = (int)((double)item->size() / (double)currentSize * 10000. + 0.5);
int oldPerc = item->intPercent();
item->setPercent( newPerc );
if( emitSig && newPerc != oldPerc ) {
emit changed( item );
changeNr++;
}
if( item->isDir() )
changeNr += calculatePercents( emitSig, dynamic_cast<Directory *>( item ), depth + 1 );
}
}
if( depth == 0 && changeNr != 0 )
emit changeFinished();
return changeNr;
}
TQString DiskUsage::getToolTip( File *item )
{
KMimeType::Ptr mimePtr = KMimeType::mimeType( item->mime() );
TQString mime = mimePtr->comment();
time_t tma = item->time();
struct tm* t=localtime((time_t *)&tma);
TQDateTime tmp(TQDate(t->tm_year+1900, t->tm_mon+1, t->tm_mday), TQTime(t->tm_hour, t->tm_min));
TQString date = TDEGlobal::locale()->formatDateTime(tmp);
TQString str = "<qt><h5><table><tr><td>" + i18n( "Name:" ) + "</td><td>" + item->name() + "</td></tr>"+
"<tr><td>" + i18n( "Type:" ) + "</td><td>" + mime + "</td></tr>"+
"<tr><td>" + i18n( "Size:" ) + "</td><td>" + KRpermHandler::parseSize( item->size() ) + "</td></tr>";
if( item->isDir() )
str += "<tr><td>" + i18n( "Own size:" ) + "</td><td>" + KRpermHandler::parseSize( item->ownSize() ) + "</td></tr>";
str += "<tr><td>" + i18n( "Last modified:" ) + "</td><td>" + date + "</td></tr>"+
"<tr><td>" + i18n( "Permissions:" ) + "</td><td>" + item->perm() + "</td></tr>"+
"<tr><td>" + i18n( "Owner:" ) + "</td><td>" + item->owner() + " - " + item->group() + "</td></tr>"+
"</table></h5></qt>";
str.replace( " ", "&nbsp;" );
return str;
}
void DiskUsage::setView( int view )
{
switch( view )
{
case VIEW_LINES:
raiseWidget( lineView );
break;
case VIEW_DETAILED:
raiseWidget( listView );
break;
case VIEW_FILELIGHT:
raiseWidget( filelightView );
break;
case VIEW_LOADER:
raiseWidget( loaderView );
break;
}
visibleWidget()->setFocus();
emit viewChanged( activeView = view );
}
File * DiskUsage::getCurrentFile()
{
File * file = 0;
switch( activeView )
{
case VIEW_LINES:
file = lineView->getCurrentFile();
break;
case VIEW_DETAILED:
file = listView->getCurrentFile();
break;
case VIEW_FILELIGHT:
file = filelightView->getCurrentFile();
break;
}
return file;
}
bool DiskUsage::event( TQEvent * e )
{
if( deleting ) { // if we are deleting, disable the mouse and
switch( e->type() ) { // keyboard events
case TQEvent::MouseButtonPress:
case TQEvent::MouseButtonRelease:
case TQEvent::MouseButtonDblClick:
case TQEvent::MouseMove:
case TQEvent::KeyPress:
case TQEvent::KeyRelease:
return true;
default:
break;
}
}
if ( e->type() == TQEvent::AccelOverride )
{
TQKeyEvent* ke = (TQKeyEvent*) e;
if ( ke->state() == TQt::NoButton || ke->state() == Keypad )
{
switch ( ke->key() )
{
case Key_Delete:
case Key_Plus:
case Key_Minus:
ke->accept();
break;
}
}else if( ke->state() == ShiftButton )
{
switch ( ke->key() )
{
case Key_Left:
case Key_Right:
case Key_Up:
case Key_Down:
ke->accept();
break;
}
}else if ( ke->state() & ControlButton )
{
switch ( ke->key() )
{
case Key_D:
case Key_E:
case Key_F:
case Key_I:
case Key_L:
case Key_N:
case Key_R:
ke->accept();
break;
}
}
}
return TQWidgetStack::event( e );
}
#include "diskusage.moc"