/**
* Copyright ( c ) 2000 - 2004 Charles Samuels < charles @ kde . org >
* 2000 - 2001 Neil Stevens < neil @ qualityassistant . com >
*
* Copyright ( c ) from the patches of :
* 2001 Klas Kalass < klas . kalass @ gmx . de >
* 2001 Anno v . Heimburg < doktor . dos @ gmx . de >
* */
// Abandon All Hope, Ye Who Enter Here
# include <tqdragobject.h>
# include <tqheader.h>
# include <tqlayout.h>
# include <tqmap.h>
# include <tqregexp.h>
# include <tqtextstream.h>
# include <tqpainter.h>
# include <kaction.h>
# include <kdebug.h>
# include <tdefiledialog.h>
# include <tdefileitem.h>
# include <tdeio/job.h>
# include <tdeio/netaccess.h>
# include <klocale.h>
# include <kmenubar.h>
# include <ksimpleconfig.h>
# include <kstandarddirs.h>
# include <kstdaction.h>
# include <kedittoolbar.h>
# include <kurldrag.h>
# include <kmessagebox.h>
# include <noatun/app.h>
# include <noatun/player.h>
# include <noatun/playlistsaver.h>
# include "playlist.h"
# include "view.h"
# include "find.h"
# define SPL SplitPlaylist::SPL()
SafeListViewItem : : SafeListViewItem ( TQListView * parent , TQListViewItem * after , const KURL & text )
: TQCheckListItem ( parent , 0 , TQCheckListItem : : CheckBox ) , PlaylistItemData ( ) , removed ( false )
{
addRef ( ) ;
setUrl ( text ) ;
static_cast < KListView * > ( TQT_TQWIDGET ( parent ) ) - > moveItem ( this , 0 , after ) ;
setOn ( true ) ;
// is this really needed, it makes the listview too wide for me :(
// setText(0,text.filename());
// if (!isDownloaded()) setText(1, "0%");
// mProperties.setAutoDelete(true);
if ( ! streamable ( ) & & enqueue ( url ( ) ) )
setUrl ( KURL ( localFilename ( ) ) ) ;
PlaylistItemData : : added ( ) ;
}
SafeListViewItem : : SafeListViewItem ( TQListView * parent , TQListViewItem * after , const TQMap < TQString , TQString > & props )
: TQCheckListItem ( parent , 0 , TQCheckListItem : : CheckBox ) , removed ( false )
{
addRef ( ) ;
setOn ( true ) ;
// A version of setProperty that assumes a key is unique,
// and doesn't call modified for every new key.
// Ugly, but this function is a very hot path on playlist loading
for ( TQMap < TQString , TQString > : : ConstIterator i = props . begin ( ) ; i ! = props . end ( ) ; + + i )
{
TQString n = i . key ( ) ;
TQString val = i . data ( ) ;
if ( n = = " enabled " )
{
setOn ( val ! = " false " & & val ! = " 0 " ) ;
}
else
{
Property p = { n , val } ;
mProperties + = p ;
}
}
static_cast < KListView * > ( TQT_TQWIDGET ( parent ) ) - > moveItem ( this , 0 , after ) ;
modified ( ) ;
if ( ! streamable ( ) & & enqueue ( url ( ) ) )
{
KURL u ;
u . setPath ( localFilename ( ) ) ;
setUrl ( u ) ;
}
PlaylistItemData : : added ( ) ;
}
SafeListViewItem : : ~ SafeListViewItem ( )
{
remove ( ) ;
}
TQString SafeListViewItem : : file ( ) const
{
return localFilename ( ) ;
}
static void pad ( TQString & str )
{
int len = str . length ( ) ;
int at = 0 ;
int blocklen = 0 ;
static const int paddingsize = 12 ;
// not static for reason
const TQChar chars [ paddingsize ] =
{
TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) ,
TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) ,
TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' ) , TQChar ( ' 0 ' )
} ;
for ( int i = 0 ; i < len ; i + + )
{
if ( str [ i ] . isNumber ( ) )
{
if ( ! blocklen )
at = i ;
blocklen + + ;
}
else if ( blocklen )
{
int pads = paddingsize ;
pads - = blocklen ;
str . insert ( at , chars , pads ) ;
i + = pads ;
blocklen = 0 ;
}
}
if ( blocklen )
{
int pads = paddingsize ;
pads - = blocklen ;
str . insert ( at , chars , pads ) ;
}
}
int SafeListViewItem : : compare ( TQListViewItem * i , int col , bool ) const
{
TQString text1 = text ( col ) ;
TQString text2 = i - > text ( col ) ;
pad ( text1 ) ;
pad ( text2 ) ;
return text1 . compare ( text2 ) ;
}
TQString SafeListViewItem : : property ( const TQString & n , const TQString & def ) const
{
for ( TQValueList < Property > : : ConstIterator i = mProperties . begin ( ) ; i ! = mProperties . end ( ) ; + + i )
{
if ( ( * i ) . key = = n )
return ( * i ) . value ;
}
if ( n = = " enabled " )
{
if ( isOn ( ) ) return " true " ;
else return " false " ;
}
return def ;
}
void SafeListViewItem : : setProperty ( const TQString & n , const TQString & val )
{
if ( n = = " enabled " )
{
setOn ( val ! = " false " & & val ! = " 0 " ) ;
}
else
{
if ( property ( n , " " ) = = val )
{
// kdDebug(66666) << "SafeListViewItem::setProperty(), property unchanged!" << endl;
return ;
}
clearProperty ( n ) ;
Property p = { n , val } ;
mProperties + = p ;
}
modified ( ) ;
}
void SafeListViewItem : : clearProperty ( const TQString & n )
{
if ( n = = " enabled " )
{
setOn ( true ) ;
modified ( ) ;
return ;
}
for ( TQValueList < Property > : : Iterator i = mProperties . begin ( ) ; i ! = mProperties . end ( ) ; + + i )
{
if ( ( * i ) . key = = n )
{
mProperties . remove ( i ) ;
modified ( ) ;
break ;
}
}
}
TQStringList SafeListViewItem : : properties ( ) const
{
TQStringList list ;
for ( TQValueList < Property > : : ConstIterator i = mProperties . begin ( ) ; i ! = mProperties . end ( ) ; + + i )
list + = ( * i ) . key ;
list + = " enabled " ;
return list ;
}
bool SafeListViewItem : : isProperty ( const TQString & n ) const
{
for ( TQValueList < Property > : : ConstIterator i = mProperties . begin ( ) ; i ! = mProperties . end ( ) ; + + i )
{
if ( ( * i ) . key = = n )
return true ;
}
return n = = " enabled " ;
}
void SafeListViewItem : : downloaded ( int percent )
{
if ( ! removed )
setText ( 1 , TQString : : number ( percent ) + ' % ' ) ;
}
void SafeListViewItem : : downloadTimeout ( )
{
if ( ! removed )
setText ( 1 , " - " ) ;
}
void SafeListViewItem : : downloadFinished ( )
{
if ( ! removed )
setText ( 1 , " " ) ;
}
void SafeListViewItem : : modified ( )
{
bool widthChangeNeeded = false ;
if ( text ( 0 ) ! = title ( ) )
{
setText ( 0 , title ( ) ) ;
widthChangeNeeded = true ;
}
if ( isDownloaded ( ) & & length ( ) ! = - 1 & & text ( 1 ) ! = lengthString ( ) )
{
setText ( 1 , lengthString ( ) ) ;
widthChangeNeeded = true ;
}
if ( widthChangeNeeded )
widthChanged ( - 1 ) ;
PlaylistItemData : : modified ( ) ;
}
void SafeListViewItem : : stateChange ( bool s )
{
// if you uncheck this, uncheck thet others that
// are selected too
TQPtrList < TQListViewItem > list = SPL - > view - > listView ( ) - > selectedItems ( ) ;
// but not if I'm not selected
if ( list . containsRef ( this ) )
for ( TQListViewItem * i = list . first ( ) ; i ! = 0 ; i = list . next ( ) )
static_cast < TQCheckListItem * > ( i ) - > setOn ( s ) ;
else
TQCheckListItem : : stateChange ( s ) ;
}
void SafeListViewItem : : paintCell ( TQPainter * p , const TQColorGroup & cg , int column , int width , int align )
{
TQCheckListItem : : paintCell ( p , cg , column , width , align ) ;
if ( SPL - > current ( ) = = this )
{
p - > save ( ) ;
p - > setRasterOp ( XorROP ) ;
p - > fillRect ( 0 , 0 , width , height ( ) , TQColor ( 255 , 255 , 255 ) ) ;
p - > restore ( ) ;
}
}
void SafeListViewItem : : remove ( )
{
removed = true ;
if ( napp - > player ( ) - > current ( ) = = this & & ! itemAbove ( ) & & ! itemBelow ( ) )
{
napp - > player ( ) - > stop ( ) ;
SPL - > setCurrent ( 0 ) ;
}
else if ( napp - > player ( ) - > current ( ) = = this )
{
// SPL->setCurrent(0);
// napp->player()->playCurrent();
if ( napp - > player ( ) - > isPlaying ( ) & & ! SPL - > exiting ( ) )
napp - > player ( ) - > forward ( ) ;
else
SPL - > setCurrent ( 0 ) ;
}
if ( listView ( ) )
{
if ( SPL - > currentItem = = this ) // just optimizing for least unreadably
SPL - > setCurrent ( static_cast < SafeListViewItem * > ( itemBelow ( ) ) ) ;
listView ( ) - > takeItem ( this ) ;
}
else if ( SPL - > currentItem = = this )
{
SPL - > setCurrent ( 0 ) ;
}
dequeue ( ) ;
PlaylistItemData : : removed ( ) ;
}
List : : List ( View * parent )
: KListView ( parent ) , recursiveAddAfter ( 0 ) , listJob ( 0 )
{
addColumn ( i18n ( " File " ) ) ;
addColumn ( i18n ( " Time " ) ) ;
setAcceptDrops ( true ) ;
setSorting ( - 1 ) ;
setDropVisualizer ( true ) ;
setDragEnabled ( true ) ;
setItemsMovable ( true ) ;
setSelectionMode ( TQListView : : Extended ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( dropped ( TQDropEvent * , TQListViewItem * ) ) , TQT_SLOT ( dropEvent ( TQDropEvent * , TQListViewItem * ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( moved ( ) ) , TQT_SLOT ( move ( ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( aboutToMove ( ) ) , parent , TQT_SLOT ( setNoSorting ( ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( deleteCurrentItem ( ) ) , parent , TQT_SLOT ( deleteSelected ( ) ) ) ;
}
List : : ~ List ( )
{
}
void List : : move ( )
{
emit modified ( ) ;
}
bool List : : acceptDrag ( TQDropEvent * event ) const
{
return KURLDrag : : canDecode ( event ) | | KListView : : acceptDrag ( event ) ;
}
void List : : dropEvent ( TQDropEvent * event , TQListViewItem * after )
{
static_cast < View * > ( TQT_TQWIDGET ( parent ( ) ) ) - > setNoSorting ( ) ;
KURL : : List textlist ;
if ( ! KURLDrag : : decode ( event , textlist ) ) return ;
event - > acceptAction ( ) ;
for ( KURL : : List : : Iterator i = textlist . begin ( ) ; i ! = textlist . end ( ) ; + + i )
{
after = addFile ( * i , false , after ) ;
}
emit modified ( ) ;
}
void List : : keyPressEvent ( TQKeyEvent * e )
{
if ( e - > key ( ) = = Key_Enter | | e - > key ( ) = = Key_Return )
{
if ( currentItem ( ) )
{
emit KListView : : executed ( currentItem ( ) ) ;
}
return ;
}
if ( e - > key ( ) = = Key_Delete )
{
if ( currentItem ( ) )
{
emit deleteCurrentItem ( ) ;
}
return ;
}
KListView : : keyPressEvent ( e ) ;
}
/**
* use this only once ! ! !
* */
class NoatunSaver : public PlaylistSaver
{
List * mList ;
SafeListViewItem * after , * mFirst ;
public :
NoatunSaver ( List * l , TQListViewItem * after = 0 )
: mList ( l )
{
this - > after = static_cast < SafeListViewItem * > ( after ) ;
mFirst = 0 ;
}
TQListViewItem * getAfter ( ) { return after ; }
TQListViewItem * getFirst ( ) { return mFirst ; }
protected :
virtual void readItem ( const TQMap < TQString , TQString > & properties )
{
after = new SafeListViewItem ( mList , after , properties ) ;
if ( mFirst = = 0 )
mFirst = after ;
}
virtual PlaylistItem writeItem ( )
{
if ( ! after )
{
after = static_cast < SafeListViewItem * > ( mList - > firstChild ( ) ) ;
}
else
{
after = static_cast < SafeListViewItem * > ( static_cast < SafeListViewItem * > ( after ) - > nextSibling ( ) ) ;
}
return PlaylistItem ( after ) ;
}
} ;
bool View : : saveToURL ( const KURL & url )
{
NoatunSaver saver ( list ) ;
if ( saver . save ( url ) )
{
return true ;
}
else
{
KMessageBox : : error ( this , i18n ( " Could not write to %1. " ) . arg ( url . prettyURL ( ) ) ) ;
return false ;
}
}
void View : : exportTo ( const KURL & url )
{
TQString local ( napp - > tempSaveName ( url . path ( ) ) ) ;
TQFile saver ( local ) ;
saver . open ( IO_ReadWrite | IO_Truncate ) ;
TQTextStream t ( & saver ) ;
// navigate the list
for ( SafeListViewItem * i = static_cast < SafeListViewItem * > ( listView ( ) - > firstChild ( ) ) ;
i ! = 0 ; i = static_cast < SafeListViewItem * > ( i - > itemBelow ( ) ) )
{
KURL u = i - > url ( ) ;
if ( u . isLocalFile ( ) )
t < < u . path ( ) < < ' \n ' ;
else
t < < u . url ( ) < < ' \n ' ;
}
saver . close ( ) ;
TDEIO : : NetAccess : : upload ( local , url , this ) ;
saver . remove ( ) ;
}
TQListViewItem * List : : openGlobal ( const KURL & u , TQListViewItem * after )
{
clear ( ) ;
NoatunSaver saver ( this , after ) ;
saver . metalist ( u ) ;
return saver . getAfter ( ) ;
}
// for m3u files
TQListViewItem * List : : importGlobal ( const KURL & u , TQListViewItem * after )
{
NoatunSaver saver ( this , after ) ;
if ( ! saver . metalist ( u ) )
{
after = new SafeListViewItem ( this , after , u ) ;
// SPL->listItemSelected(after);
return after ;
}
// return the first item added from this playlist
// that way noatun can start playing the first item
if ( saver . getFirst ( ) )
return saver . getFirst ( ) ;
// failsafe in case nothing was added, getFirst() may return 0
return saver . getAfter ( ) ;
}
TQListViewItem * List : : addFile ( const KURL & url , bool play , TQListViewItem * after )
{
// when a new item is added, we don't want to sort anymore
SPL - > view - > setNoSorting ( ) ;
if (
url . path ( ) . right ( 4 ) . lower ( ) = = " .m3u "
| | url . path ( ) . right ( 4 ) . lower ( ) = = " .pls "
| | url . protocol ( ) . lower ( ) = = " http "
)
{
// a playlist is requested
TQListViewItem * i = importGlobal ( url , after ) ;
if ( play )
SPL - > listItemSelected ( i ) ;
return i ;
}
else
{
if ( ! after ) after = lastItem ( ) ;
KFileItem fileItem ( KFileItem : : Unknown , KFileItem : : Unknown , url ) ;
if ( fileItem . isDir ( ) )
{
addDirectoryRecursive ( url , after ) ;
return after ; // don't (and can't) know better!?
}
else
{
TQListViewItem * i = new SafeListViewItem ( this , after , url ) ;
if ( play )
SPL - > listItemSelected ( i ) ;
return i ;
}
}
}
// starts a new listJob if there is no active but work to do
void List : : addNextPendingDirectory ( )
{
KURL : : List : : Iterator pendingIt = pendingAddDirectories . begin ( ) ;
if ( ! listJob & & ( pendingIt ! = pendingAddDirectories . end ( ) ) )
{
currentJobURL = * pendingIt ;
listJob = TDEIO : : listRecursive ( currentJobURL , false , false ) ;
connect (
listJob , TQT_SIGNAL ( entries ( TDEIO : : Job * , const TDEIO : : UDSEntryList & ) ) ,
TQT_SLOT ( slotEntries ( TDEIO : : Job * , const TDEIO : : UDSEntryList & ) )
) ;
connect (
listJob , TQT_SIGNAL ( result ( TDEIO : : Job * ) ) ,
TQT_SLOT ( slotResult ( TDEIO : : Job * ) )
) ;
connect (
listJob , TQT_SIGNAL ( redirection ( TDEIO : : Job * , const KURL & ) ) ,
TQT_SLOT ( slotRedirection ( TDEIO : : Job * , const KURL & ) )
) ;
pendingAddDirectories . remove ( pendingIt ) ;
}
}
void List : : addDirectoryRecursive ( const KURL & dir , TQListViewItem * after )
{
if ( ! after ) after = lastItem ( ) ;
recursiveAddAfter = after ;
pendingAddDirectories . append ( dir ) ;
addNextPendingDirectory ( ) ;
}
void List : : slotResult ( TDEIO : : Job * job )
{
listJob = 0 ;
if ( job & & job - > error ( ) )
job - > showErrorDialog ( ) ;
addNextPendingDirectory ( ) ;
}
void List : : slotEntries ( TDEIO : : Job * , const TDEIO : : UDSEntryList & entries )
{
TQMap < TQString , KURL > __list ; // temp list to sort entries
TDEIO : : UDSEntryListConstIterator it = entries . begin ( ) ;
TDEIO : : UDSEntryListConstIterator end = entries . end ( ) ;
for ( ; it ! = end ; + + it )
{
KFileItem file ( * it , currentJobURL , false /* no mimetype detection */ , true ) ;
// "prudhomm:
// insert the path + url in the map to sort automatically by path
// note also that you use audiocd to rip your CDs then it will be sorted the right way
// now it is an easy fix to have a nice sort BUT it is not the best
// we should sort based on the tracknumber"
// - copied over from old kdirlister hack <hans_meine@gmx.de>
if ( ! file . isDir ( ) )
__list . insert ( file . url ( ) . path ( ) , file . url ( ) ) ;
}
TQMap < TQString , KURL > : : Iterator __it ;
for ( __it = __list . begin ( ) ; __it ! = __list . end ( ) ; + + __it )
{
recursiveAddAfter = addFile ( __it . data ( ) , false , recursiveAddAfter ) ;
}
}
void List : : slotRedirection ( TDEIO : : Job * , const KURL & url )
{
currentJobURL = url ;
}
/////////////////////////////////
View : : View ( SplitPlaylist * )
: KMainWindow ( 0 , " NoatunSplitplaylistView " )
{
list = new List ( this ) ;
setCentralWidget ( list ) ;
connect ( list , TQT_SIGNAL ( modified ( void ) ) , TQT_TQOBJECT ( this ) , TQT_SLOT ( setModified ( void ) ) ) ;
// connect the click on the header with sorting
connect ( list - > header ( ) , TQT_SIGNAL ( clicked ( int ) ) , this , TQT_SLOT ( headerClicked ( int ) ) ) ;
mOpen = new KAction ( i18n ( " Add &Files... " ) , " queue " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( addFiles ( ) ) , actionCollection ( ) , " add_files " ) ;
( void ) new KAction ( i18n ( " Add Fol&ders... " ) , " folder " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( addDirectory ( ) ) , actionCollection ( ) , " add_dir " ) ;
mDelete = new KAction ( i18n ( " Delete " ) , " editdelete " , Key_Delete , TQT_TQOBJECT ( this ) , TQT_SLOT ( deleteSelected ( ) ) , actionCollection ( ) , " delete " ) ;
mClose = KStdAction : : close ( TQT_TQOBJECT ( this ) , TQT_SLOT ( close ( ) ) , actionCollection ( ) ) ;
mFind = KStdAction : : find ( TQT_TQOBJECT ( this ) , TQT_SLOT ( find ( ) ) , actionCollection ( ) ) ;
( void ) KStdAction : : configureToolbars ( TQT_TQOBJECT ( this ) , TQT_SLOT ( configureToolBars ( ) ) , actionCollection ( ) ) ;
mOpenNew = KStdAction : : openNew ( TQT_TQOBJECT ( this ) , TQT_SLOT ( openNew ( ) ) , actionCollection ( ) ) ;
mOpenpl = KStdAction : : open ( TQT_TQOBJECT ( this ) , TQT_SLOT ( open ( ) ) , actionCollection ( ) ) ;
mSave = KStdAction : : save ( TQT_TQOBJECT ( this ) , TQT_SLOT ( save ( ) ) , actionCollection ( ) ) ;
mSaveAs = KStdAction : : saveAs ( TQT_TQOBJECT ( this ) , TQT_SLOT ( saveAs ( ) ) , actionCollection ( ) ) ;
( void ) new KAction ( i18n ( " Shuffle " ) , " misc " , 0 , TQT_TQOBJECT ( SPL ) , TQT_SLOT ( randomize ( ) ) , actionCollection ( ) , " shuffle " ) ;
( void ) new KAction ( i18n ( " Clear " ) , " editclear " , 0 , TQT_TQOBJECT ( list ) , TQT_SLOT ( clear ( ) ) , actionCollection ( ) , " clear " ) ;
createGUI ( " splui.rc " ) ;
mFinder = new Finder ( this ) ;
applyMainWindowSettings ( TDEGlobal : : config ( ) , " SPL Window " ) ;
list - > setFocus ( ) ;
}
void View : : find ( )
{
mFinder - > show ( ) ;
connect ( mFinder , TQT_SIGNAL ( search ( Finder * ) ) , TQT_SLOT ( findIt ( Finder * ) ) ) ;
}
static bool testWord ( TQListViewItem * i , const TQString & finder )
{
PlaylistItemData * item = static_cast < SafeListViewItem * > ( i ) ;
if ( item - > title ( ) . find ( finder , 0 , false ) > = 0 )
return true ;
if ( item - > file ( ) . find ( finder , 0 , false ) > = 0 )
return true ;
if ( item - > url ( ) . path ( ) . find ( finder . local8Bit ( ) . data ( ) , 0 , false ) > = 0 )
return true ;
if ( item - > lengthString ( ) . find ( finder , 0 , false ) > = 0 )
return true ;
if ( item - > mimetype ( ) . find ( finder . local8Bit ( ) . data ( ) , 0 , false ) > = 0 )
return true ;
return false ;
}
static bool testWord ( TQListViewItem * i , const TQRegExp & finder )
{
PlaylistItemData * item = static_cast < SafeListViewItem * > ( i ) ;
if ( item - > title ( ) . find ( finder ) > = 0 )
return true ;
if ( item - > file ( ) . find ( finder ) > = 0 )
return true ;
if ( item - > url ( ) . path ( ) . find ( finder ) > = 0 )
return true ;
if ( item - > lengthString ( ) . find ( finder ) > = 0 )
return true ;
if ( item - > mimetype ( ) . find ( finder ) > = 0 )
return true ;
return false ;
}
void View : : findIt ( Finder * f )
{
TQListViewItem * search = list - > currentItem ( ) ;
if ( list - > currentItem ( ) )
{
if ( f - > isForward ( ) )
search = list - > currentItem ( ) - > itemBelow ( ) ;
else
search = list - > currentItem ( ) - > itemAbove ( ) ;
}
else
{
if ( f - > isForward ( ) )
search = list - > firstChild ( ) ;
else
search = list - > lastChild ( ) ;
}
while ( search )
{
if ( f - > regexp ( ) )
{
if ( testWord ( search , TQRegExp ( f - > string ( ) , false ) ) )
break ;
}
else
{
if ( testWord ( search , f - > string ( ) ) )
break ;
}
if ( f - > isForward ( ) )
search = search - > itemBelow ( ) ;
else
search = search - > itemAbove ( ) ;
if ( ! search )
{
if ( f - > isForward ( ) )
{
if ( KMessageBox : : questionYesNo ( this , i18n ( " End of playlist reached. Continue searching from beginning? " ) , TQString ( ) , KStdGuiItem : : cont ( ) , KStdGuiItem : : cancel ( ) ) = = KMessageBox : : Yes )
search = list - > firstChild ( ) ;
}
else
{
if ( KMessageBox : : questionYesNo ( this , i18n ( " Beginning of playlist reached. Continue searching from end? " ) , TQString ( ) , KStdGuiItem : : cont ( ) , KStdGuiItem : : cancel ( ) ) = = KMessageBox : : Yes )
search = list - > lastChild ( ) ;
}
}
}
if ( search )
{
{ // select none
TQPtrList < TQListViewItem > sel = list - > selectedItems ( ) ;
for ( TQListViewItem * i = sel . first ( ) ; i ! = 0 ; i = sel . next ( ) )
list - > setSelected ( i , false ) ;
}
list - > setSelected ( search , true ) ;
list - > setCurrentItem ( search ) ;
list - > ensureItemVisible ( search ) ;
}
}
View : : ~ View ( )
{
napp - > player ( ) - > stop ( ) ;
hide ( ) ;
saveState ( ) ;
delete list ;
}
void View : : init ( )
{
// see if we are importing an old-style list
bool importing = ! TQFile ( napp - > dirs ( ) - > saveLocation ( " data " , " noatun/ " ) + " splitplaylist.xml " ) . exists ( ) ;
if ( importing )
{
KURL internalURL ;
internalURL . setPath ( napp - > dirs ( ) - > saveLocation ( " data " , " noatun/ " ) + " splitplaylistdata " ) ;
NoatunSaver saver ( list , 0 ) ;
saver . load ( internalURL , PlaylistSaver : : M3U ) ;
}
else
{
KURL internalURL ;
internalURL . setPath ( napp - > dirs ( ) - > saveLocation ( " data " , " noatun/ " ) + " splitplaylist.xml " ) ;
list - > openGlobal ( internalURL ) ;
}
TDEConfig & config = * TDEGlobal : : config ( ) ;
config . setGroup ( " splitplaylist " ) ;
// this has to come after openGlobal, since openGlobal emits modified()
setModified ( config . readBoolEntry ( " modified " , false ) ) ;
TQString path = config . readPathEntry ( " file " ) ;
// don't call setPath with an empty path, that would make the url "valid"
if ( ! path . isEmpty ( ) )
mPlaylistFile . setPath ( path ) ;
SPL - > reset ( ) ;
int saved = config . readNumEntry ( " current " , 0 ) ;
PlaylistItem item = SPL - > getFirst ( ) ;
for ( int i = 0 ; i < saved ; i + + )
{
item = SPL - > getAfter ( item ) ;
}
if ( item )
SPL - > setCurrent ( item ) ;
}
void View : : save ( )
{
if ( mPlaylistFile . isEmpty ( ) | | ! mPlaylistFile . isValid ( ) )
{
saveAs ( ) ;
return ;
}
if ( saveToURL ( mPlaylistFile ) )
setModified ( false ) ;
}
void View : : saveAs ( )
{
KURL u = KFileDialog : : getSaveURL ( 0 , " *.xml splitplaylistdata *.pls *.m3u \n * " , this , i18n ( " Save Playlist " ) ) ;
if ( ! u . isValid ( ) )
return ;
mPlaylistFile = u ;
save ( ) ;
}
void View : : open ( )
{
KURL u = KFileDialog : : getOpenURL ( 0 , " *.xml splitplaylistdata *.pls *.m3u \n * " , this , i18n ( " Open Playlist " ) ) ;
if ( ! u . isValid ( ) )
return ;
mPlaylistFile = u ;
list - > openGlobal ( u ) ;
setModified ( false ) ;
}
void View : : openNew ( )
{
mPlaylistFile = " " ;
listView ( ) - > clear ( ) ;
}
void List : : clear ( )
{
SPL - > setCurrent ( 0 ) ;
TQListView : : clear ( ) ;
}
void View : : deleteSelected ( )
{
TQPtrList < TQListViewItem > items ( list - > selectedItems ( ) ) ;
bool stopped = false ;
// noatun shouldn't play files for now
TQListViewItem * afterLast = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( items ) ; it . current ( ) ; + + it )
{
SafeListViewItem * i = static_cast < SafeListViewItem * > ( * it ) ;
if ( ! stopped & & SPL - > current ( ) = = i )
{
napp - > player ( ) - > stop ( ) ;
SPL - > setCurrent ( 0 ) ;
stopped = true ;
}
i - > remove ( ) ;
afterLast = i - > itemBelow ( ) ;
}
if ( stopped )
SPL - > setCurrent ( static_cast < SafeListViewItem * > ( afterLast ) ) ;
setModified ( true ) ;
}
void View : : addFiles ( )
{
KURL : : List files = KFileDialog : : getOpenURLs ( " :mediadir " , napp - > mimeTypes ( ) , this , i18n ( " Select File to Play " ) ) ;
TQListViewItem * last = list - > lastItem ( ) ;
for ( KURL : : List : : Iterator it = files . begin ( ) ; it ! = files . end ( ) ; + + it )
last = addFile ( KURL ( * it ) , false ) ;
setModified ( true ) ;
}
void View : : addDirectory ( )
{
TQString file = KFileDialog : : getExistingDirectory ( 0 , this , i18n ( " Select Folder " ) ) ;
if ( ! file ) return ;
KURL url ;
url . setPath ( file ) ;
list - > addDirectoryRecursive ( url ) ;
setModified ( true ) ;
}
void View : : closeEvent ( TQCloseEvent * )
{
hide ( ) ;
}
void View : : showEvent ( TQShowEvent * )
{
emit shown ( ) ;
}
void View : : hideEvent ( TQHideEvent * )
{
emit hidden ( ) ;
}
void View : : setModified ( bool b )
{
modified = b ;
setCaption ( i18n ( " Playlist " ) , modified ) ;
}
void View : : setModified ( void )
{
setModified ( true ) ;
}
void View : : saveState ( void )
{
TDEConfig & config = * TDEGlobal : : config ( ) ;
config . setGroup ( " splitplaylist " ) ;
config . writeEntry ( " modified " , modified ) ;
config . writePathEntry ( " file " , mPlaylistFile . path ( ) ) ;
saveToURL ( napp - > dirs ( ) - > saveLocation ( " data " , " noatun/ " ) + " splitplaylist.xml " ) ;
unsigned int i ;
PlaylistItem item = SPL - > getFirst ( ) ;
for ( i = 0 ; item & & item ! = SPL - > current ( ) ; )
item = SPL - > getAfter ( item ) , i + + ;
config . writeEntry ( " current " , i ) ;
saveMainWindowSettings ( TDEGlobal : : config ( ) , " SPL Window " ) ;
config . sync ( ) ;
}
void View : : configureToolBars ( )
{
saveMainWindowSettings ( TDEGlobal : : config ( ) , " SPL Window " ) ;
KEditToolbar dlg ( actionCollection ( ) , " splui.rc " ) ;
connect ( & dlg , TQT_SIGNAL ( newToolbarConfig ( ) ) , TQT_SLOT ( newToolBarConfig ( ) ) ) ;
dlg . exec ( ) ;
}
void View : : newToolBarConfig ( )
{
createGUI ( " splui.rc " ) ;
applyMainWindowSettings ( TDEGlobal : : config ( ) , " SPL Window " ) ;
}
// turns the sorting on or off
void View : : setSorting ( bool on , int column )
{
if ( on )
{
list - > setSorting ( column , true ) ;
list - > setShowSortIndicator ( true ) ;
}
else
{
list - > setShowSortIndicator ( false ) ;
list - > setSorting ( - 1 ) ;
}
}
void View : : headerClicked ( int column )
{
// this is to avoid that if we already have it sorted,
// we sort it again ascendingly this way, clicking on
// the header a second time will correctly toggle
// ascending/descending sort
if ( list - > showSortIndicator ( ) )
{
return ;
}
else
{
setSorting ( true , column ) ;
}
}
# include "view.moc"