1 /* This file is part of the KDE project
2 Copyright (C) 2004 Mark Kretschmann <markey@web.de>
3 Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net>
4 Copyright (C) 2003 Roberto Raggi <roberto@kdevelop.org>
5 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
6 Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
7 Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License version 2 as published by the Free Software Foundation.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21 Boston, MA 02110-1301, USA.
25 #include "browserToolBar.h"
26 #include "enginecontroller.h"
27 #include "filebrowser.h"
28 #include "k3bexporter.h"
31 #include <kapplication.h>
32 #include "kbookmarkhandler.h"
33 #include <kdiroperator.h>
34 #include <kiconloader.h>
35 #include <kio/netaccess.h>
36 #include <k3listview.h>
37 #include <k3urldrag.h>
39 #include <kconfiggroup.h>
41 #include <kpushbutton.h> ///@see SearchPane
43 #include <kurlcombobox.h>
44 #include <kurlcompletion.h>
45 #include <klineedit.h>
47 #include "mediabrowser.h"
49 #include "mydirlister.h"
50 #include "mydiroperator.h"
52 #include "playlistbrowser.h"
53 #include "playlistloader.h"
54 #include "playlistwindow.h"
55 #include "collectionbrowser.h"
56 #include "statusbar.h"
57 #include "tagdialog.h"
61 #include <q3iconview.h>
65 #include <QToolButton>
69 #include <Q3PopupMenu>
70 #include <QPaintEvent>
74 //BEGIN Constructor/destructor
76 FileBrowser::FileBrowser( const char * name
, Medium
* medium
)
79 KActionCollection
*actionCollection
;
80 SearchPane
*searchPane
;
84 // Try to keep filebrowser working even if not in a medium context
85 // so if a medium object not passed in, keep earlier behavior
88 location
= new KUrl( Amarok::config( "Filebrowser" ).readEntry( "Location", QDir::homePath() ) );
89 KFileItem
*currentFolder
= new KFileItem( KFileItem::Unknown
, KFileItem::Unknown
, *location
);
90 //KIO sucks, NetAccess::exists puts up a dialog and has annoying error message boxes
91 //if there is a problem so there is no point in using it anyways.
92 //so... setting the diroperator to ~ is the least sucky option
93 if ( !location
->isLocalFile() || !currentFolder
->isReadable() ) {
95 location
= new KUrl( QDir::homePath() ) ;
100 location
= new KUrl( m_medium
->mountPoint() );
103 KActionCollection
* ac
= new KActionCollection( this );
104 KStandardAction::selectAll( this, SLOT( selectAll() ), ac
);
106 KToolBar
*toolbar
= new Browser::ToolBar( this );
107 toolbar
->setToolButtonStyle( Qt::ToolButtonIconOnly
);
110 // KToolBar* searchToolBar = new Browser::ToolBar( this );
112 m_filter
= new KLineEdit( 0 );
113 toolbar
->addWidget(m_filter
);
114 m_filter
->setClearButtonShown( true );
115 m_filter
->setClickMessage( i18n( "Enter search terms here" ) );
117 m_filter
->setSizePolicy(QSizePolicy::Expanding
,QSizePolicy::Minimum
);
119 m_filter
->setToolTip( i18n( "Enter space-separated terms to search in the directory-listing" ) );
122 { //Directory Listing
123 KVBox
*container
; KHBox
*box
;
125 container
= new KVBox( this );
126 container
->setFrameStyle( m_filter
->frameStyle() );
127 container
->setMargin( 3 );
128 container
->setSpacing( 2 );
129 container
->setBackgroundMode( Qt::PaletteBase
);
131 box
= new KHBox( container
);
133 box
->setBackgroundMode( Qt::PaletteBase
);
135 //folder selection combo box
136 m_combo
= new KUrlComboBox( KUrlComboBox::Directories
, true, box
);
137 m_combo
->setObjectName( "path combo" );
140 m_combo
->setCompletionObject( new KUrlCompletion( KUrlCompletion::DirCompletion
) );
141 m_combo
->setAutoDeleteCompletionObject( true );
143 m_combo
->setMaxItems( 9 );
144 m_combo
->setUrls( Amarok::config( "Filebrowser" ).readEntry( "Dir History", QStringList() ) );
147 m_combo
->lineEdit()->setText( location
->path() );
149 m_combo
->lineEdit()->setText( "/" );
151 //The main widget with file listings and that
152 m_dir
= new MyDirOperator( *location
, container
, m_medium
);
153 m_dir
->setEnableDirHighlighting( true );
154 m_dir
->setMode( KFile::Mode((int)KFile::Files
| (int)KFile::Directory
) ); //allow selection of multiple files + dirs
155 m_dir
->setOnlyDoubleClickSelectsFiles( true ); //Amarok type settings
156 KConfigGroup
cg(Amarok::config( "Filebrowser" ));
157 m_dir
->readConfig( cg
);
158 m_dir
->setView( KFile::Default
); //will set userconfigured view, will load URL
159 m_dir
->setSizePolicy( QSizePolicy::Preferred
, QSizePolicy::Expanding
);
160 m_dir
->setAcceptDrops( true );
161 //Automatically open folder after hovering above it...probably a good thing
162 //but easily disabled by commenting this line out
163 //Disabled for now because can't show . and .. folders.
164 //TODO: Find out a way to fix this?
165 //m_dir->setDropOptions( KFileView::AutoOpenDirs );
167 static_cast<QFrame
*>(m_dir
->viewWidget())->setFrameStyle( QFrame::NoFrame
);
168 static_cast<Q3IconView
*>(m_dir
->viewWidget())->setSpacing( 1 );
170 actionCollection
= m_dir
->actionCollection();
172 searchPane
= new SearchPane( this );
174 setStretchFactor( container
, 2 );
178 KMenu
* const menu
= static_cast<KActionMenu
*>(actionCollection
->action("popupMenu"))->popupMenu();
181 menu
->insertItem( KIcon( Amarok::icon( "files" ) ), i18n( "&Load" ), MakePlaylist
);
182 menu
->insertItem( KIcon( Amarok::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), AppendToPlaylist
);
183 menu
->insertItem( KIcon( Amarok::icon( "queue_track" ) ), i18n( "&Queue Track" ), QueueTrack
);
184 menu
->insertItem( KIcon( Amarok::icon( "queue_track" ) ), i18n( "&Queue Tracks" ), QueueTracks
);
186 menu
->insertItem( KIcon( Amarok::icon( "save" ) ), i18n( "&Save as Playlist..." ), SavePlaylist
);
187 menu
->insertSeparator();
190 menu
->insertItem( KIcon( Amarok::icon( "device" ) ), i18n( "&Transfer to Media Device" ), MediaDevice
);
192 menu
->insertItem( KIcon( Amarok::icon( "collection" ) ), i18n( "&Organize Files..." ), OrganizeFiles
);
193 menu
->insertItem( KIcon( Amarok::icon( "collection" ) ), i18n( "&Copy Files to Collection..." ), CopyToCollection
);
194 menu
->insertItem( KIcon( Amarok::icon( "collection" ) ), i18n( "&Move Files to Collection..." ), MoveToCollection
);
195 menu
->insertItem( KIcon( Amarok::icon( "burn" ) ), i18n("Burn to CD..."), BurnCd
);
196 menu
->insertSeparator();
197 menu
->insertItem( i18n( "&Select All Files" ), SelectAllFiles
);
198 menu
->insertSeparator();
199 actionCollection
->action( "delete" )->setIcon( KIcon( Amarok::icon( "remove" ) ) );
200 menu
->addAction( actionCollection
->action( "delete" ) );
201 menu
->insertSeparator();
202 menu
->insertItem( KIcon( Amarok::icon( "info" ) ), i18n( "Edit Track &Information..." ), EditTags
);
203 menu
->addAction( actionCollection
->action( "properties" ) );
205 menu
->setItemEnabled( BurnCd
, K3bExporter::isAvailable() );
207 connect( menu
, SIGNAL(aboutToShow()), SLOT(prepareContextMenu()) );
208 connect( menu
, SIGNAL(activated( int )), SLOT(contextMenuActivated( int )) );
214 a
= static_cast<KActionMenu
*>( actionCollection
->action( "sorting menu" ) );
215 a
->setIcon( KIcon( Amarok::icon( "configure" ) ) );
216 a
->setDelayed( false ); //TODO should be done by KDirOperator
218 static_cast<KAction
*>(actionCollection
->action( "delete" ))->setShortcut( KShortcut( Qt::ShiftModifier
+ Qt::Key_Delete
) );
220 a
= new KActionMenu( this );
222 a
->setText( i18n("Bookmarks") );
223 a
->setIcon(KIcon("bookmark-toolbar"));
224 actionCollection
->addAction( "bookmarks", a
);
226 a
->setDelayed( false );
228 new KBookmarkHandler( m_dir
, a
->popupMenu() );
232 if ( QAction
*a
= actionCollection
->action( "up" ) )
233 toolbar
->addAction(a
);
234 if ( QAction
*a
= actionCollection
->action( "back" ) )
235 toolbar
->addAction(a
);
236 if ( QAction
*a
= actionCollection
->action( "forward" ) )
237 toolbar
->addAction(a
);
238 if ( QAction
*a
= actionCollection
->action( "home" ) )
239 toolbar
->addAction(a
);
240 if ( QAction
*a
= actionCollection
->action( "reload" ) ) {
241 a
->setIcon( KIcon(Amarok::icon( "refresh" )) );
242 toolbar
->addAction(a
);
245 toolbar
->addSeparator();
247 if ( QAction
*a
= actionCollection
->action( "short view" ) )
248 toolbar
->addAction(a
);
249 if ( QAction
*a
= actionCollection
->action( "detailed view" ) )
250 toolbar
->addAction(a
);
252 toolbar
->addSeparator();
254 if ( QAction
*a
= actionCollection
->action( "sorting menu" ) )
255 toolbar
->addAction(a
);
256 if ( QAction
*a
= actionCollection
->action( "bookmarks" ) )
257 toolbar
->addAction(a
);
260 KAction
*gotoCurrent
= new KAction( i18n("Go To Current Track Folder"), this );
261 actionCollection
->addAction("Go To Current Track Folder", gotoCurrent
);
262 gotoCurrent
->setIcon( KIcon(Amarok::icon( "music" )) );
263 connect( gotoCurrent
, SIGNAL( triggered() ), this, SLOT( gotoCurrentFolder() ) );
265 toolbar
->addAction(gotoCurrent
);
267 //disconnect( actionCollection->action( "up" ), SIGNAL( triggered() ), m_dir, SLOT( cdUp() ) );
268 //connect( actionCollection->action( "up" ), SIGNAL( triggered() ), m_dir, SLOT( myCdUp() ) );
269 //disconnect( actionCollection->action( "home" ), SIGNAL( triggered() ), m_dir, SLOT( home() ) );
270 //connect( actionCollection->action( "home" ), SIGNAL( triggered() ), m_dir, SLOT( myHome() ) );
273 connect( m_filter
, SIGNAL(textChanged( const QString
& )), SLOT(setFilter( const QString
& )) );
274 connect( m_combo
, SIGNAL(urlActivated( const KUrl
& )), SLOT(setUrl( const KUrl
& )) );
275 connect( m_combo
, SIGNAL(returnPressed( const QString
& )), SLOT(setUrl( const QString
& )) );
276 connect( m_dir
, SIGNAL(viewChanged( KFileView
* )), SLOT(slotViewChanged( KFileView
* )) );
277 connect( m_dir
, SIGNAL(fileSelected( const KFileItem
* )), SLOT(activate( const KFileItem
* )) );
278 connect( m_dir
, SIGNAL(urlEntered( const KUrl
& )), SLOT(urlChanged( const KUrl
& )) );
279 connect( m_dir
, SIGNAL(urlEntered( const KUrl
& )), searchPane
, SLOT(urlChanged( const KUrl
& )) );
280 connect( m_dir
, SIGNAL(dropped( const KFileItem
*, QDropEvent
*, const KUrl::List
& )),
281 SLOT(dropped( const KFileItem
*, QDropEvent
*, const KUrl::List
& )) );
284 setFocusProxy( m_dir
); //so the dirOperator is focused when we get focus events
285 // Toolbar is more than 250px wide, BrowserBar doesn't allow that. -> Resizing issues.
286 setMinimumWidth( 250 /* toolbar->sizeHint().width() */ );
290 FileBrowser::~FileBrowser()
292 KConfigGroup c
= Amarok::config( "Filebrowser" );
294 c
.writeEntry( "Location", m_dir
->url().url() );
295 c
.writeEntry( "Dir History", m_combo
->urls() );
298 //END Constructor/Destructor
300 void FileBrowser::setUrl( const KUrl
&url
)
304 m_dir
->setUrl( url
, true );
306 QString urlpath
= url
.isLocalFile() ? url
.path() : url
.prettyUrl();
307 KUrl
newURL( urlpath
.prepend( m_medium
->mountPoint() ).remove("..") );
308 //debug() << "set-url-kurl: changing to: " << newURL.path() << endl;
309 m_dir
->setUrl( newURL
, true );
313 void FileBrowser::setUrl( const QString
&url
)
316 m_dir
->setUrl( KUrl(url
), true );
318 KUrl
newURL( QString(url
).prepend( m_medium
->mountPoint() ).remove("..") );
319 //debug() << "set-url-qstring: changing to: " << newURL.path() << endl;
320 m_dir
->setUrl( newURL
, true );
324 //BEGIN Private Methods
326 KUrl::List
FileBrowser::selectedItems()
329 const KFileItemList
&source
= m_dir
->selectedItems()->count() ? *m_dir
->selectedItems() : *m_dir
->view()->items();
330 for( KFileItemList::const_iterator it
= source
.begin(); it
!= source
.end(); ++it
)
331 list
.append( (*it
)->url() );
336 void FileBrowser::playlistFromURLs( const KUrl::List
&urls
)
339 if( urls
.count() == 1 && QFileInfo( urls
.first().path() ).isDir() )
340 suggestion
= urls
.first().fileName();
342 suggestion
= i18n( "Untitled" );
343 const QString path
= PlaylistDialog::getSaveFileName( suggestion
);
347 if( PlaylistBrowser::savePlaylist( path
, urls
) )
349 Amarok::StatusBar::instance()->shortMessage( "Playlist saved to playlist browser" );
354 //END Private Methods
360 FileBrowser::setFilter( const QString
&text
)
362 if ( text
.isEmpty() )
363 m_dir
->clearFilter();
368 const QStringList terms
= QStringList::split( ' ', text
);
369 oldForeach( terms
) {
375 m_dir
->setNameFilter( filter
);
382 FileBrowser::dropped( const KFileItem
* /*item*/, QDropEvent
* event
, const KUrl::List
&urls
){
383 //Do nothing right now
385 //Run into const problems iterating over the list, so copy it to a malleable one
386 //(besides, need to filter for local giles)
387 KUrl::List
list(urls
);
389 for ( KUrl::List::iterator it
= list
.begin(); it
!= list
.end(); ){
390 if ( m_medium
&& !(*it
).isLocalFile() )
391 it
= list
.erase( it
);
393 debug() << "Dropped: " << (*it
) << endl
;
402 //BEGIN Private Slots
405 FileBrowser::urlChanged( const KUrl
&u
)
407 //the DirOperator's URL has changed
409 QString url
= u
.isLocalFile() ? u
.path() : u
.prettyUrl();
412 //remove the leading mountPoint value
413 url
.remove( 0, m_medium
->mountPoint().length() );
416 QStringList urls
= m_combo
->urls();
420 m_combo
->setUrls( urls
, KUrlComboBox::RemoveBottom
);
424 FileBrowser::slotViewChanged( KFileView
*view
)
426 if( view
->widget()->inherits( "K3ListView" ) )
428 using namespace Amarok::ColorScheme
;
430 static_cast<K3ListView
*>(view
->widget())->setAlternateBackground( AltBase
);
435 FileBrowser::activate( const KFileItem
*item
)
437 Playlist::instance()->insertMedia( item
->url(), Playlist::DefaultOptions
);
441 FileBrowser::prepareContextMenu()
443 const KFileItemList
&items
= *m_dir
->selectedItems();
444 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( SavePlaylist
,
445 items
.count() > 1 || ( items
.count() == 1 && items
.first()->isDir() ) );
446 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( QueueTrack
,
447 items
.count() == 1 );
448 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( QueueTracks
,
450 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( MediaDevice
,
451 MediaBrowser::isAvailable() );
452 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( MoveToCollection
, !CollectionDB::instance()->isDirInCollection( url().path() ) );
453 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( CopyToCollection
, !CollectionDB::instance()->isDirInCollection( url().path() ) );
454 static_cast<KActionMenu
*>(m_dir
->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( OrganizeFiles
, CollectionDB::instance()->isDirInCollection( url().path() ) );
458 FileBrowser::contextMenuActivated( int id
)
463 Playlist::instance()->insertMedia( selectedItems(), Playlist::Replace
);
467 playlistFromURLs( selectedItems() );
470 case AppendToPlaylist
:
471 Playlist::instance()->insertMedia( selectedItems() );
476 Playlist::instance()->insertMedia( selectedItems(), Playlist::Queue
);
481 KUrl::List list
= Amarok::recursiveUrlExpand( selectedItems() );
482 TagDialog
*dialog
= NULL
;
483 if( list
.count() == 1 )
485 dialog
= new TagDialog( list
.first(), this );
489 dialog
= new TagDialog( list
, this );
495 case CopyToCollection
:
496 CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Copy Files To Collection" ), true );
499 case MoveToCollection
:
500 CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Move Files To Collection" ), false );
504 CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Organize Collection Files" ), false );
508 MediaBrowser::queue()->addUrls( selectedItems() );
516 K3bExporter::instance()->exportTracks( selectedItems() );
522 FileBrowser::gotoCurrentFolder()
524 const KUrl
&url
= EngineController::instance()->bundle().url();
525 KUrl dirURL
= KUrl( url
.directory() );
527 m_combo
->setUrl( dirURL
);
534 FileBrowser::selectAll()
536 KFileItemList
list( *m_dir
->view()->items() );
538 // Select all items which represent files
539 for( KFileItemList::const_iterator it
= list
.begin(); it
!= list
.end(); ++it
)
540 m_dir
->view()->setSelected( *it
, (*it
)->isFile() );
544 #include <q3simplerichtext.h>
546 class KURLView
: public K3ListView
549 KURLView( QWidget
*parent
) : K3ListView( parent
)
551 reinterpret_cast<QWidget
*>(header())->hide();
552 addColumn( QString() );
553 setResizeMode( K3ListView::LastColumn
);
554 setDragEnabled( true );
555 setSelectionMode( Q3ListView::Extended
);
558 class Item
: public K3ListViewItem
{
560 Item( const KUrl
&url
, KURLView
*parent
) : K3ListViewItem( parent
, url
.fileName() ), m_url( url
) {}
564 virtual Q3DragObject
*dragObject()
566 QList
<Q3ListViewItem
*> items
= selectedItems();
568 for( QList
<Q3ListViewItem
*>::const_iterator it
= items
.begin(); it
!= items
.end(); ++it
) {
569 urls
+= ( static_cast<Item
*>(*it
) )->m_url
;
572 return new K3URLDrag( urls
, this );
575 virtual void viewportPaintEvent( QPaintEvent
*e
)
577 K3ListView::viewportPaintEvent( e
);
579 if ( childCount() == 0 ) {
580 QPainter
p( viewport() );
582 if ( m_text
.isEmpty() ) {
583 //TODO Perhaps it's time to put this in some header, as we use it in three places now
584 Q3SimpleRichText
t( i18n(
586 "Enter a search term above; you can use wildcards like * and ?"
587 "</div>" ), font() );
589 t
.setWidth( width() - 50 );
591 const uint w
= t
.width() + 20;
592 const uint h
= t
.height() + 20;
594 p
.setBrush( colorGroup().background() );
595 p
.drawRoundRect( 15, 15, w
, h
, (8*200)/w
, (8*200)/h
);
596 t
.draw( &p
, 20, 20, QRect(), colorGroup() );
599 p
.setPen( palette().color( QPalette::Disabled
, QColorGroup::Text
) );
600 p
.drawText( rect(), Qt::AlignCenter
| Qt::TextWordWrap
, m_text
);
605 void unsetText() { setText( QString() ); }
606 void setText( const QString
&text
) { m_text
= text
; viewport()->update(); }
614 SearchPane::SearchPane( FileBrowser
*parent
)
620 KVBox
*container
= new KVBox( this );
621 container
->setObjectName( "container" );
625 KHBox
*box
= new KHBox( container
);
626 //box->setMargin( 5 );
627 box
->setBackgroundMode( Qt::PaletteBase
);
629 m_lineEdit
= new KLineEdit( box
);
630 m_lineEdit
->setClickMessage( i18n("Search here...") );
631 connect( m_lineEdit
, SIGNAL(textChanged( const QString
& )), SLOT(searchTextChanged( const QString
& )) );
633 m_listView
= new KURLView( container
);
635 container
->setFrameStyle( m_listView
->frameStyle() );
636 //container->setMargin( 5 );
637 container
->setBackgroundMode( Qt::PaletteBase
);
639 m_listView
->setFrameStyle( QFrame::NoFrame
);
640 connect( m_listView
, SIGNAL(executed( Q3ListViewItem
* )), SLOT(activate( Q3ListViewItem
* )) );
643 KPushButton
*button
= new KPushButton( KGuiItem( i18n("&Show Search Panel"), "find" ), this );
644 button
->setToggleButton( true );
645 connect( button
, SIGNAL(toggled( bool )), SLOT(toggle( bool )) );
647 m_lister
= new MyDirLister( true /*delay mimetypes*/ );
648 insertChild( m_lister
);
649 connect( m_lister
, SIGNAL(newItems( const KFileItemList
& )), SLOT(searchMatches( const KFileItemList
& )) );
650 connect( m_lister
, SIGNAL(completed()), SLOT(searchComplete()) );
654 SearchPane::toggle( bool toggled
)
657 m_lineEdit
->setFocus();
659 findChild
<QWidget
*>("container")->setShown( toggled
);
663 SearchPane::urlChanged( const KUrl
& )
665 searchTextChanged( m_lineEdit
->text() );
669 SearchPane::searchTextChanged( const QString
&text
)
671 //TODO if user changes search directory then we need to update the search too
677 if ( text
.isEmpty() ) {
678 m_listView
->unsetText();
682 m_filter
= QRegExp( text
.contains( "*" ) ? text
: '*'+text
+'*', false, true );
684 m_lister
->openUrl( searchURL() );
686 m_listView
->setText( i18n( "Searching..." ) );
690 SearchPane::searchMatches( const KFileItemList
&list
)
692 for( KFileItemList::ConstIterator it
= list
.begin(), end
= list
.end(); it
!= end
; ++it
) {
694 m_dirs
+= (*it
)->url();
695 else if( m_filter
.exactMatch( (*it
)->name() ) )
696 new KURLView::Item( (*it
)->url(), static_cast<KURLView
*>( m_listView
) );
701 SearchPane::searchComplete()
703 //KDirLister crashes if you call openUrl() from a slot
704 //connected to KDirLister::complete()
705 //TODO fix crappy KDElibs
707 QTimer::singleShot( 0, this, SLOT(_searchComplete()) );
711 SearchPane::_searchComplete()
713 if ( !m_dirs
.isEmpty() ) {
714 KUrl url
= m_dirs
.first();
716 m_lister
->openUrl( url
);
719 m_listView
->setText( i18n("No results found") ); //only displayed if the listview is empty
723 SearchPane::activate( Q3ListViewItem
*item
)
725 Playlist::instance()->insertMedia( static_cast<KURLView::Item
*>(item
)->m_url
, Playlist::DirectPlay
);
728 #include "filebrowser.moc"