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.
555 lines
17 KiB
555 lines
17 KiB
/***************************************************************************
|
|
directorylist.cpp
|
|
-------------------
|
|
begin : Tue Feb 4 2003
|
|
copyright : (C) 2003 Scott Wheeler <wheeler@kde.org>
|
|
: (C) 2004 Max Howell <max.howell@methylblue.com>
|
|
: (C) 2004 Mark Kretschmann <markey@web.de>
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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 <tqlabel.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqdir.h>
|
|
|
|
#include <tdeconfig.h>
|
|
#include <tdeglobal.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdefileitem.h>
|
|
#include <tdelocale.h>
|
|
#include <kdebug.h>
|
|
#include <tdeversion.h>
|
|
#include <tqregexp.h>
|
|
#include <kiconloader.h>
|
|
#include <tdeapplication.h>
|
|
#include <dcopref.h>
|
|
#include <dcopclient.h>
|
|
|
|
#include "directorylist.h"
|
|
|
|
using Collection::Item;
|
|
using Collection::DeviceItem;
|
|
|
|
CollectionSetup::CollectionSetup( TQWidget *parent, bool recursive, bool fullMode, TQStringList dirs )
|
|
: TQVBox( parent )
|
|
{
|
|
m_dirs = dirs;
|
|
|
|
// (new TQLabel( i18n(
|
|
// "Select the folder(s) to scan. "), this ))->setAlignment( TQt::WordBreak );
|
|
|
|
m_view = new TQListView( this );
|
|
/* m_recursive = new TQCheckBox( i18n("&Scan folders recursively"), this );*/
|
|
m_recursive = recursive;
|
|
// m_monitor = new TQCheckBox( i18n("&Watch folders for changes"), this );
|
|
// m_playlists = new TQCheckBox( i18n("&Import playlists"), this );
|
|
//
|
|
// TQToolTip::add( m_recursive, i18n( "If selected, amaroK reads all folders recursively." ) );
|
|
// TQToolTip::add( m_monitor, i18n( "If selected, folders will automatically get rescanned when the content is modified, e.g. when a new file was added." ) );
|
|
// TQToolTip::add( m_playlists, i18n( "If selected, playlist files (.m3u) will automatically be added to the Playlist-Browser." ) );
|
|
|
|
// Read config values
|
|
// m_dirs = AmarokConfig::collectionFolders();
|
|
// m_recursive->setChecked( false );
|
|
// m_monitor->setChecked( AmarokConfig::monitorChanges() );
|
|
// m_playlists->setChecked( AmarokConfig::importPlaylists() );
|
|
|
|
m_view->addColumn( TQString::null );
|
|
m_view->setRootIsDecorated( true );
|
|
reinterpret_cast<TQWidget*>(m_view->header())->hide();
|
|
new Item( m_view, this, i18n( "System Folder" ), "/", "folder_red" );
|
|
new Item( m_view, this, i18n( "Home Folder" ), TQDir::homeDirPath(), "folder_home" );
|
|
if( fullMode ) new DeviceItem( m_view, this);
|
|
|
|
setSpacing( 6 );
|
|
}
|
|
|
|
void CollectionSetup::slotRecursiveToggled(bool on)
|
|
{
|
|
m_recursive = on;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// CLASS Item
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
Item::Item( TQListView *parent, CollectionSetup *collection, const TQString &name, const TQString &path, const TQString &icon )
|
|
: TQCheckListItem( parent, name, TQCheckListItem::CheckBox )
|
|
, m_lister( true )
|
|
, m_url( "file:" + path )
|
|
, m_listed( false )
|
|
{
|
|
collectionSetup = collection;
|
|
m_lister.setDirOnlyMode( true );
|
|
m_lister.setShowingDotFiles( true );
|
|
connect( &m_lister, TQ_SIGNAL(newItems( const KFileItemList& )), TQ_SLOT(newItems( const KFileItemList& )) );
|
|
setText( 1, path );
|
|
setOpen( true );
|
|
if ( !icon.isNull() )
|
|
setPixmap( 0, SmallIcon( icon ) );
|
|
else
|
|
setPixmap( 0, SmallIcon( "folder" ) );
|
|
setVisible( true );
|
|
connect( collectionSetup, TQ_SIGNAL(resetDirs()), this, TQ_SLOT(reset()) );
|
|
}
|
|
|
|
|
|
Item::Item( TQListViewItem *parent, CollectionSetup *collection, const KURL &url )
|
|
: TQCheckListItem( parent, url.fileName(), TQCheckListItem::CheckBox )
|
|
, m_lister( true )
|
|
, m_url( url )
|
|
, m_listed( false )
|
|
{
|
|
collectionSetup = collection;
|
|
m_lister.setDirOnlyMode( true );
|
|
m_lister.setShowingDotFiles( true );
|
|
setText( 1, url.fileName() );
|
|
setExpandable( true );
|
|
connect( &m_lister, TQ_SIGNAL(newItems( const KFileItemList& )), TQ_SLOT(newItems( const KFileItemList& )) );
|
|
connect( &m_lister, TQ_SIGNAL(completed()), TQ_SLOT(completed()) );
|
|
connect( &m_lister, TQ_SIGNAL(canceled()), TQ_SLOT(completed()) );
|
|
connect( collectionSetup, TQ_SIGNAL(resetDirs()), this, TQ_SLOT(reset()) );
|
|
}
|
|
|
|
|
|
TQString
|
|
Item::fullPath() const
|
|
{
|
|
TQString path;
|
|
|
|
for ( const TQListViewItem *item = this; dynamic_cast<const TQListViewItem*>( item ); item = item->parent() )
|
|
{
|
|
path.prepend( '/' );
|
|
path.prepend( item->text( 1 ) );
|
|
}
|
|
return path;
|
|
}
|
|
|
|
|
|
void
|
|
Item::setOpen( bool b )
|
|
{
|
|
if ( !m_listed )
|
|
{
|
|
m_lister.openURL( m_url, true );
|
|
m_listed = true;
|
|
}
|
|
|
|
TQListViewItem::setOpen( b );
|
|
}
|
|
|
|
|
|
void
|
|
Item::stateChange( bool b )
|
|
{
|
|
if( collectionSetup->recursive() )
|
|
for( TQListViewItem *item = firstChild(); item; item = item->nextSibling() )
|
|
static_cast<TQCheckListItem*>(item)->TQCheckListItem::setOn( b );
|
|
|
|
// Update folder list
|
|
TQStringList::Iterator it = collectionSetup->m_dirs.find( m_url.path() );
|
|
if ( isOn() ) {
|
|
if ( it == collectionSetup->m_dirs.end() )
|
|
{
|
|
collectionSetup->m_dirs << m_url.path();
|
|
collectionSetup->m_refcount[ m_url.path() ] = 1;
|
|
}
|
|
else
|
|
collectionSetup->m_refcount[ m_url.path() ]++;
|
|
}
|
|
else if ( collectionSetup->m_refcount.find( m_url.path() ) != collectionSetup->m_refcount.end() )
|
|
{
|
|
if ( --collectionSetup->m_refcount[ m_url.path() ] == 0 )
|
|
{
|
|
collectionSetup->m_dirs.erase( it );
|
|
collectionSetup->m_refcount.remove( m_url.path() );
|
|
}
|
|
}
|
|
|
|
// Redraw parent items
|
|
listView()->triggerUpdate();
|
|
}
|
|
|
|
|
|
void
|
|
Item::activate()
|
|
{
|
|
if( !isDisabled() )
|
|
TQCheckListItem::activate();
|
|
}
|
|
|
|
|
|
void
|
|
Item::newItems( const KFileItemList &list ) //TQ_SLOT
|
|
{
|
|
for( KFileItemListIterator it( list ); *it; ++it )
|
|
{
|
|
Item *item = new Item( this, collectionSetup, (*it)->url() );
|
|
|
|
item->setOn( collectionSetup->recursive() && isOn() ||
|
|
collectionSetup->m_dirs.contains( item->fullPath() ) );
|
|
|
|
item->setPixmap( 0, (*it)->pixmap( TDEIcon::SizeSmall ) );
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
Item::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int align )
|
|
{
|
|
bool dirty = false;
|
|
|
|
// Figure out if a child folder is activated
|
|
for ( uint i = 0; i < collectionSetup->m_dirs.count(); i++ )
|
|
{
|
|
if ( collectionSetup->m_dirs[ i ] == m_url.path() )
|
|
{
|
|
dirty = true;
|
|
}
|
|
else if ( collectionSetup->m_dirs[ i ].startsWith( m_url.path() ) )
|
|
dirty = true;
|
|
}
|
|
|
|
// Use a different color if this folder has an activated child folder
|
|
TQColorGroup _cg = cg;
|
|
if ( dirty ) _cg.setColor( TQColorGroup::Text, TQt::blue );
|
|
|
|
TQCheckListItem::paintCell( p, isDisabled() ? listView()->palette().disabled() : _cg, column, width, align );
|
|
if (!dirty)
|
|
setOn(false);
|
|
}
|
|
|
|
void Item::reset() { this->setOn(false); }
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// CLASS DeviceItem
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DeviceItem::DeviceItem( TQListView *parent, CollectionSetup *collection )
|
|
: TQCheckListItem( parent, i18n("Devices"), TQCheckListItem::CheckBox )
|
|
, m_lister( true )
|
|
, m_listed( false )
|
|
{
|
|
collectionSetup = collection;
|
|
m_lister.setDirOnlyMode( true );
|
|
connect( &m_lister, TQ_SIGNAL(newItems( const KFileItemList& )), TQ_SLOT(newItems( const KFileItemList& )) );
|
|
connect( collectionSetup, TQ_SIGNAL(resetDirs()), this, TQ_SLOT(reset()) );
|
|
|
|
if ( KDE::versionMajor() == 3 && KDE::versionMinor() < 4 )
|
|
{
|
|
m_url = "devices:/";
|
|
}
|
|
else
|
|
m_url = "media:/";
|
|
|
|
setText(1, "devices");
|
|
setOpen( true );
|
|
setPixmap(0, SmallIcon("kfm") );
|
|
setVisible( true );
|
|
}
|
|
|
|
|
|
DeviceItem::DeviceItem( TQListViewItem *parent, CollectionSetup *collection, const TQString &name, const KURL &url )
|
|
: TQCheckListItem( parent, name, TQCheckListItem::CheckBox )
|
|
, m_lister( true )
|
|
, m_url( url )
|
|
, m_listed( false )
|
|
{
|
|
collectionSetup = collection;
|
|
|
|
if (!kapp->dcopClient()->isAttached())
|
|
kapp->dcopClient()->attach();
|
|
else
|
|
////kdDebug() << "attached" << endl;
|
|
|
|
TQByteArray data;
|
|
TQByteArray param;
|
|
TQCString retType;
|
|
TQStringList retVal;
|
|
TQDataStream streamout(param,IO_WriteOnly);
|
|
streamout<< url.fileName();
|
|
TQCString mediacall="mediamanager";
|
|
TQCString devicecall="properties";
|
|
if ( KDE::versionMajor() == 3 && KDE::versionMinor() < 4 )
|
|
{
|
|
mediacall="mountwatcher";
|
|
devicecall="basicDeviceInfo";
|
|
}
|
|
|
|
|
|
DCOPRef mediamanager("kded", mediacall);
|
|
DCOPReply reply = mediamanager.call( devicecall, url.fileName() );
|
|
|
|
if ( !reply.isValid() )
|
|
{
|
|
////kdDebug() << "not valid" << endl;
|
|
}
|
|
retVal = reply;
|
|
//KAutoMount* am = new KAutoMount( true, "", retVal[5], "","", false );
|
|
////kdDebug() << retVal[6] << endl;
|
|
|
|
setText(1, KURL(retVal[6]).path());
|
|
setText(2, url.fileName());
|
|
kdDebug() << "Device Item: " << name << " " << url.fileName() << " " << text(1) << endl;
|
|
m_lister.setDirOnlyMode( true );
|
|
setExpandable( false );
|
|
connect( &m_lister, TQ_SIGNAL(newItems( const KFileItemList& )), TQ_SLOT(newItems( const KFileItemList& )) );
|
|
connect( &m_lister, TQ_SIGNAL(completed()), TQ_SLOT(completed()) );
|
|
connect( &m_lister, TQ_SIGNAL(canceled()), TQ_SLOT(completed()) );
|
|
connect( collectionSetup, TQ_SIGNAL(resetDirs()), this, TQ_SLOT(reset()) );
|
|
}
|
|
|
|
|
|
TQString
|
|
DeviceItem::fullPath() const
|
|
{
|
|
TQString path = text(1);
|
|
if (path != "devices")
|
|
return path;
|
|
return "";
|
|
}
|
|
|
|
|
|
void
|
|
DeviceItem::setOpen( bool b )
|
|
{
|
|
if ( !m_listed && text(1) == "devices")
|
|
{
|
|
m_lister.openURL( m_url, true );
|
|
}
|
|
m_listed = true;
|
|
|
|
TQListViewItem::setOpen( b );
|
|
}
|
|
|
|
|
|
void
|
|
DeviceItem::stateChange( bool b )
|
|
{
|
|
if( collectionSetup->recursive() )
|
|
for( TQListViewItem *item = firstChild(); item; item = item->nextSibling() )
|
|
static_cast<TQCheckListItem*>(item)->TQCheckListItem::setOn( b );
|
|
|
|
if (text(1) != "devices")
|
|
{
|
|
// Update folder list
|
|
TQStringList::Iterator it = collectionSetup->m_dirs.find( text(1) );
|
|
if ( isOn() ) {
|
|
if ( it == collectionSetup->m_dirs.end() )
|
|
{
|
|
collectionSetup->m_dirs << text(1);
|
|
mountDevice(text(2));
|
|
collectionSetup->m_refcount[text(1)] = 1;
|
|
}
|
|
else
|
|
collectionSetup->m_refcount[text(1)]++;
|
|
|
|
}
|
|
else if ( collectionSetup->m_refcount.find(text(1)) != collectionSetup->m_refcount.end() )
|
|
{
|
|
if ( --collectionSetup->m_refcount[text(1)] == 0 )
|
|
{
|
|
collectionSetup->m_dirs.erase( it );
|
|
collectionSetup->m_refcount.remove(text(1));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Redraw parent items
|
|
listView()->triggerUpdate();
|
|
}
|
|
|
|
|
|
void
|
|
DeviceItem::activate()
|
|
{
|
|
if( !isDisabled() )
|
|
TQCheckListItem::activate();
|
|
}
|
|
|
|
|
|
void
|
|
DeviceItem::newItems( const KFileItemList &list ) //TQ_SLOT
|
|
{
|
|
for( KFileItemListIterator it( list ); *it; ++it )
|
|
{
|
|
kdDebug() << (*it)->name() << " " << (*it)->url() << " " << (*it)->text() << endl;
|
|
if (this->listView()->findItem((*it)->name(),0) == 0){
|
|
DeviceItem *item = new DeviceItem( this, collectionSetup, (*it)->name(), (*it)->url() );
|
|
|
|
item->setOn( collectionSetup->recursive() && isOn() ||
|
|
collectionSetup->m_dirs.contains( item->fullPath() ) );
|
|
|
|
item->setPixmap( 0, (*it)->pixmap( TDEIcon::SizeSmall ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
DeviceItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int align )
|
|
{
|
|
bool dirty = false;
|
|
|
|
TQColorGroup _cg = cg;
|
|
|
|
////kdDebug() << text(1) << endl;
|
|
if (text(1) != "devices")
|
|
{
|
|
// Figure out if a child folder is activated
|
|
for ( uint i = 0; i < collectionSetup->m_dirs.count(); i++ )
|
|
{
|
|
if ( collectionSetup->m_dirs[i] == text(1) )
|
|
{
|
|
dirty = true;
|
|
}
|
|
else if ( collectionSetup->m_dirs[i].startsWith( text(1) + "/" ) )
|
|
dirty = true;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
for( TQListViewItem *item = firstChild(); item; item = item->nextSibling() )
|
|
{
|
|
DeviceItem *itm = dynamic_cast<DeviceItem*>(item);
|
|
for ( uint i = 0; i < collectionSetup->m_dirs.count(); i++ )
|
|
{
|
|
if ( collectionSetup->m_dirs[i] == itm->fullPath() )
|
|
{
|
|
dirty = true;
|
|
break;
|
|
}
|
|
else if ( collectionSetup->m_dirs[i].startsWith( itm->fullPath() ) )
|
|
{
|
|
dirty = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Use a different color if this folder has an activated child folder
|
|
if ( dirty ) _cg.setColor( TQColorGroup::Text, TQt::blue );
|
|
TQCheckListItem::paintCell( p, isDisabled() ? listView()->palette().disabled() : _cg, column, width, align );
|
|
}
|
|
|
|
TQString DeviceItem::getMountPoint( const TQString & device )
|
|
{
|
|
DCOPRef mediamanager("kded", "mediamanager");
|
|
DCOPReply reply = mediamanager.call( "properties", device );
|
|
|
|
TQStringList properties;
|
|
reply.get( properties, "TQStringList" );
|
|
|
|
TQString mountpoint = * (properties.at(7) );
|
|
|
|
return mountpoint;
|
|
|
|
}
|
|
|
|
void
|
|
DeviceItem::mountDevice( const TQString & device)
|
|
{
|
|
|
|
if (!kapp->dcopClient()->isAttached())
|
|
kapp->dcopClient()->attach();
|
|
|
|
TQString mountpoint;
|
|
mountpoint = getMountPoint(device);
|
|
|
|
if( mountpoint != TQString::null ) // already mounted
|
|
return;
|
|
|
|
DCOPRef mediamanager("kded", "mediamanager");
|
|
DCOPReply reply = mediamanager.call( "mountByNode", device );
|
|
|
|
bool success;
|
|
reply.get( success, "bool" );
|
|
|
|
mountpoint = getMountPoint(device);
|
|
|
|
if(! success || mountpoint == TQString::null ) {
|
|
KMessageBox::sorry( 0, i18n("Cannot mount device '%1'. Please check that you have the permissions needed to mount the device, as well as the needed kernel modules loaded.").arg(device) );
|
|
}
|
|
}
|
|
|
|
void DeviceItem::reset() { this->setOn(false); }
|
|
|
|
TQStringList CollectionSetup::pruneSelectedDirs( TQStringList listOfUrls ){
|
|
// This gets rid of redundant sub-directories
|
|
// from the list of dirs to be scanned.
|
|
|
|
TQStringList filepattern;
|
|
|
|
listOfUrls.sort();
|
|
|
|
TQString prev;
|
|
TQStringList prevdirs;
|
|
struct stat sb;
|
|
|
|
for (TQStringList::Iterator it = listOfUrls.begin(); it != listOfUrls.end(); it++ ){
|
|
//kdDebug() << "dir: " << (*it) << endl;
|
|
(*it) = (*it).stripWhiteSpace();
|
|
|
|
// replace block devices with mountpoints
|
|
lstat( (*it).ascii(), &sb );
|
|
if ( (sb.st_mode & S_IFMT) == S_IFBLK ) {
|
|
// This is actually from directorylist.cpp
|
|
DCOPRef mediamanager("kded", "mediamanager");
|
|
DCOPReply reply = mediamanager.call( "properties", (*it) );
|
|
|
|
TQStringList properties;
|
|
reply.get( properties, "TQStringList" );
|
|
|
|
(*it) = * (properties.at(7) );
|
|
} else {
|
|
(*it) = (*it) + "/";
|
|
}
|
|
|
|
if (prevdirs.isEmpty()){
|
|
//kdDebug() << (*it) << endl;
|
|
filepattern.append(*it);
|
|
prevdirs.append((*it));
|
|
}else{
|
|
filepattern.append(*it);
|
|
bool shouldappend = true;
|
|
for (TQStringList::Iterator it2 = prevdirs.begin(); it2 != prevdirs.end(); it2++ ){
|
|
if ((*it).contains(*it2)){
|
|
//kdDebug() << (*it) << endl;
|
|
filepattern.remove((*it));
|
|
shouldappend = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (shouldappend)
|
|
prevdirs.append((*it));
|
|
}
|
|
}
|
|
|
|
return filepattern;
|
|
}
|
|
|
|
void CollectionSetup::writeConfig( const char* optGroup, const char* optName )
|
|
{
|
|
TDEConfig *config = TDEGlobal::config();
|
|
config->setGroup( optGroup );
|
|
config->writeEntry( optName, dirs() );
|
|
config->sync();
|
|
}
|
|
|
|
void CollectionSetup::reset()
|
|
{
|
|
emit resetDirs();
|
|
}
|
|
|
|
#include "directorylist.moc"
|