/***************************************************************************
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 : : s_instance ;
CollectionSetup : : CollectionSetup ( TQWidget * parent , bool recursive , bool fullMode , TQStringList dirs )
: TQVBox ( parent )
{
s_instance = this ;
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 , i18n ( " System Folder " ) , " / " , " folder_red " ) ;
new Item ( m_view , i18n ( " Home Folder " ) , TQDir : : homeDirPath ( ) , " folder_home " ) ;
if ( fullMode ) new DeviceItem ( m_view ) ;
setSpacing ( 6 ) ;
}
void CollectionSetup : : slotRecursiveToggled ( bool on )
{
m_recursive = on ;
}
//////////////////////////////////////////////////////////////////////////////////////////
// CLASS Item
//////////////////////////////////////////////////////////////////////////////////////////
Item : : Item ( TQListView * parent , const TQString & name , const TQString & path , const TQString & icon )
: TQCheckListItem ( parent , name , TQCheckListItem : : CheckBox )
, m_lister ( true )
, m_url ( " file: " + path )
, m_listed ( false )
{
m_lister . setDirOnlyMode ( true ) ;
m_lister . setShowingDotFiles ( true ) ;
connect ( & m_lister , SIGNAL ( newItems ( const KFileItemList & ) ) , SLOT ( newItems ( const KFileItemList & ) ) ) ;
setText ( 1 , path ) ;
setOpen ( true ) ;
if ( ! icon . isNull ( ) )
setPixmap ( 0 , SmallIcon ( icon ) ) ;
else
setPixmap ( 0 , SmallIcon ( " folder " ) ) ;
setVisible ( true ) ;
}
Item : : Item ( TQListViewItem * parent , const KURL & url )
: TQCheckListItem ( parent , url . fileName ( ) , TQCheckListItem : : CheckBox )
, m_lister ( true )
, m_url ( url )
, m_listed ( false )
{
m_lister . setDirOnlyMode ( true ) ;
m_lister . setShowingDotFiles ( true ) ;
setText ( 1 , url . fileName ( ) ) ;
setExpandable ( true ) ;
connect ( & m_lister , SIGNAL ( newItems ( const KFileItemList & ) ) , SLOT ( newItems ( const KFileItemList & ) ) ) ;
connect ( & m_lister , SIGNAL ( completed ( ) ) , SLOT ( completed ( ) ) ) ;
connect ( & m_lister , SIGNAL ( canceled ( ) ) , SLOT ( completed ( ) ) ) ;
}
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 : : instance ( ) - > recursive ( ) )
for ( TQListViewItem * item = firstChild ( ) ; item ; item = item - > nextSibling ( ) )
static_cast < TQCheckListItem * > ( item ) - > TQCheckListItem : : setOn ( b ) ;
// Update folder list
TQStringList : : Iterator it = CollectionSetup : : instance ( ) - > m_dirs . find ( m_url . path ( ) ) ;
if ( isOn ( ) ) {
if ( it = = CollectionSetup : : instance ( ) - > m_dirs . end ( ) )
{
CollectionSetup : : instance ( ) - > m_dirs < < m_url . path ( ) ;
CollectionSetup : : instance ( ) - > m_refcount [ m_url . path ( ) ] = 1 ;
}
else
CollectionSetup : : instance ( ) - > m_refcount [ m_url . path ( ) ] + + ;
}
else if ( CollectionSetup : : instance ( ) - > m_refcount . find ( m_url . path ( ) ) ! = CollectionSetup : : instance ( ) - > m_refcount . end ( ) )
{
if ( - - CollectionSetup : : instance ( ) - > m_refcount [ m_url . path ( ) ] = = 0 )
{
CollectionSetup : : instance ( ) - > m_dirs . erase ( it ) ;
CollectionSetup : : instance ( ) - > m_refcount . remove ( m_url . path ( ) ) ;
}
}
// Redraw parent items
listView ( ) - > triggerUpdate ( ) ;
}
void
Item : : activate ( )
{
if ( ! isDisabled ( ) )
TQCheckListItem : : activate ( ) ;
}
void
Item : : newItems ( const KFileItemList & list ) //SLOT
{
for ( KFileItemListIterator it ( list ) ; * it ; + + it )
{
Item * item = new Item ( this , ( * it ) - > url ( ) ) ;
item - > setOn ( CollectionSetup : : instance ( ) - > recursive ( ) & & isOn ( ) | |
CollectionSetup : : instance ( ) - > 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 : : instance ( ) - > m_dirs . count ( ) ; i + + )
{
if ( CollectionSetup : : instance ( ) - > m_dirs [ i ] = = m_url . path ( ) )
{
dirty = true ;
}
else if ( CollectionSetup : : instance ( ) - > 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 ) ;
}
//////////////////////////////////////////////////////////////////////////////////////////
// CLASS DeviceItem
//////////////////////////////////////////////////////////////////////////////////////////
DeviceItem : : DeviceItem ( TQListView * parent )
: TQCheckListItem ( parent , i18n ( " Devices " ) , TQCheckListItem : : CheckBox )
, m_lister ( true )
, m_listed ( false )
{
m_lister . setDirOnlyMode ( true ) ;
connect ( & m_lister , SIGNAL ( newItems ( const KFileItemList & ) ) , SLOT ( newItems ( const KFileItemList & ) ) ) ;
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 , const TQString & name , const KURL & url )
: TQCheckListItem ( parent , name , TQCheckListItem : : CheckBox )
, m_lister ( true )
, m_url ( url )
, m_listed ( false )
{
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 , SIGNAL ( newItems ( const KFileItemList & ) ) , SLOT ( newItems ( const KFileItemList & ) ) ) ;
connect ( & m_lister , SIGNAL ( completed ( ) ) , SLOT ( completed ( ) ) ) ;
connect ( & m_lister , SIGNAL ( canceled ( ) ) , SLOT ( completed ( ) ) ) ;
}
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 : : instance ( ) - > 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 : : instance ( ) - > m_dirs . find ( text ( 1 ) ) ;
if ( isOn ( ) ) {
if ( it = = CollectionSetup : : instance ( ) - > m_dirs . end ( ) )
{
CollectionSetup : : instance ( ) - > m_dirs < < text ( 1 ) ;
mountDevice ( text ( 2 ) ) ;
CollectionSetup : : instance ( ) - > m_refcount [ text ( 1 ) ] = 1 ;
}
else
CollectionSetup : : instance ( ) - > m_refcount [ text ( 1 ) ] + + ;
}
else if ( CollectionSetup : : instance ( ) - > m_refcount . find ( text ( 1 ) ) ! = CollectionSetup : : instance ( ) - > m_refcount . end ( ) )
{
if ( - - CollectionSetup : : instance ( ) - > m_refcount [ text ( 1 ) ] = = 0 )
{
CollectionSetup : : instance ( ) - > m_dirs . erase ( it ) ;
CollectionSetup : : instance ( ) - > m_refcount . remove ( text ( 1 ) ) ;
}
}
}
// Redraw parent items
listView ( ) - > triggerUpdate ( ) ;
}
void
DeviceItem : : activate ( )
{
if ( ! isDisabled ( ) )
TQCheckListItem : : activate ( ) ;
}
void
DeviceItem : : newItems ( const KFileItemList & list ) //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 , ( * it ) - > name ( ) , ( * it ) - > url ( ) ) ;
item - > setOn ( CollectionSetup : : instance ( ) - > recursive ( ) & & isOn ( ) | |
CollectionSetup : : instance ( ) - > 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 : : instance ( ) - > m_dirs . count ( ) ; i + + )
{
if ( CollectionSetup : : instance ( ) - > m_dirs [ i ] = = text ( 1 ) )
{
dirty = true ;
}
else if ( CollectionSetup : : instance ( ) - > 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 : : instance ( ) - > m_dirs . count ( ) ; i + + )
{
if ( CollectionSetup : : instance ( ) - > m_dirs [ i ] = = itm - > fullPath ( ) )
{
dirty = true ;
break ;
}
else if ( CollectionSetup : : instance ( ) - > 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 ) ) ;
}
}
TQStringList CollectionSetup : : pruneSelectedDirs ( ) {
// This gets rid of redundant sub-directories
// from the list of dirs to be scanned.
TQStringList filepattern ;
TQStringList listOfUrls = dirs ( ) ;
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 ( ) ;
}
# include "directorylist.moc"