|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2004 Mark Kretschmann <markey@web.de>
|
|
|
|
Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net>
|
|
|
|
Copyright (C) 2003 Roberto Raggi <roberto@kdevelop.org>
|
|
|
|
Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
|
|
|
|
Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
|
|
|
|
Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "amarok.h"
|
|
|
|
#include "browserToolBar.h"
|
|
|
|
#include "clicklineedit.h"
|
|
|
|
#include "enginecontroller.h"
|
|
|
|
#include "filebrowser.h"
|
|
|
|
#include "k3bexporter.h"
|
|
|
|
|
|
|
|
#include <tdeaction.h>
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include "kbookmarkhandler.h"
|
|
|
|
#include <tdediroperator.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include <tdelistview.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include <kpushbutton.h> ///@see SearchPane
|
|
|
|
#include <tdetoolbarbutton.h> ///@see ctor
|
|
|
|
#include <kurlcombobox.h>
|
|
|
|
#include <kurlcompletion.h>
|
|
|
|
|
|
|
|
#include "mediabrowser.h"
|
|
|
|
#include "medium.h"
|
|
|
|
#include "mydirlister.h"
|
|
|
|
#include "mydiroperator.h"
|
|
|
|
#include "playlist.h"
|
|
|
|
#include "playlistbrowser.h"
|
|
|
|
#include "playlistloader.h"
|
|
|
|
#include "playlistwindow.h"
|
|
|
|
#include "collectionbrowser.h"
|
|
|
|
#include "statusbar.h"
|
|
|
|
#include "tagdialog.h"
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqhbox.h>
|
|
|
|
#include <tqiconview.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqtooltip.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//BEGIN Constructor/destructor
|
|
|
|
|
|
|
|
FileBrowser::FileBrowser( const char * name, Medium * medium )
|
|
|
|
: TQVBox( 0, name )
|
|
|
|
{
|
|
|
|
TDEActionCollection *actionCollection;
|
|
|
|
SearchPane *searchPane;
|
|
|
|
|
|
|
|
KURL *location;
|
|
|
|
|
|
|
|
// Try to keep filebrowser working even if not in a medium context
|
|
|
|
// so if a medium object not passed in, keep earlier behavior
|
|
|
|
if (!medium) {
|
|
|
|
m_medium = 0;
|
|
|
|
location = new KURL( Amarok::config( "Filebrowser" )->readPathEntry( "Location", TQDir::homeDirPath() ) );
|
|
|
|
KFileItem *currentFolder = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, *location );
|
|
|
|
//TDEIO sucks, NetAccess::exists puts up a dialog and has annoying error message boxes
|
|
|
|
//if there is a problem so there is no point in using it anyways.
|
|
|
|
//so... setting the diroperator to ~ is the least sucky option
|
|
|
|
if ( !location->isLocalFile() || !currentFolder->isReadable() ) {
|
|
|
|
delete location;
|
|
|
|
location = new KURL( TQDir::homeDirPath() ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
m_medium = medium;
|
|
|
|
location = new KURL( m_medium->mountPoint() );
|
|
|
|
}
|
|
|
|
|
|
|
|
TDEActionCollection* ac = new TDEActionCollection( this );
|
|
|
|
KStdAction::selectAll( TQT_TQOBJECT(this), TQT_SLOT( selectAll() ), ac, "filebrowser_select_all" );
|
|
|
|
|
|
|
|
TDEToolBar *toolbar = new Browser::ToolBar( this );
|
|
|
|
|
|
|
|
{ //Filter LineEdit
|
|
|
|
TDEToolBar* searchToolBar = new Browser::ToolBar( this );
|
|
|
|
TDEToolBarButton *button = new TDEToolBarButton( "locationbar_erase", 0, searchToolBar );
|
|
|
|
m_filter = new ClickLineEdit( i18n( "Enter search terms here" ), searchToolBar );
|
|
|
|
|
|
|
|
searchToolBar->setStretchableWidget( m_filter );
|
|
|
|
|
|
|
|
connect( button, TQT_SIGNAL(clicked()), m_filter, TQT_SLOT(clear()) );
|
|
|
|
|
|
|
|
TQToolTip::add( button, i18n( "Clear search field" ) );
|
|
|
|
TQToolTip::add( m_filter, i18n( "Enter space-separated terms to search in the directory-listing" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
{ //Directory Listing
|
|
|
|
TQVBox *container; TQHBox *box;
|
|
|
|
|
|
|
|
container = new TQVBox( this );
|
|
|
|
container->setFrameStyle( m_filter->frameStyle() );
|
|
|
|
container->setMargin( 3 );
|
|
|
|
container->setSpacing( 2 );
|
|
|
|
container->setBackgroundMode( TQt::PaletteBase );
|
|
|
|
|
|
|
|
box = new TQHBox( container );
|
|
|
|
box->setMargin( 3 );
|
|
|
|
box->setBackgroundMode( TQt::PaletteBase );
|
|
|
|
|
|
|
|
//folder selection combo box
|
|
|
|
m_combo = new KURLComboBox( KURLComboBox::Directories, true, box, "path combo" );
|
|
|
|
|
|
|
|
if (!m_medium){
|
|
|
|
m_combo->setCompletionObject( new KURLCompletion( KURLCompletion::DirCompletion ) );
|
|
|
|
m_combo->setAutoDeleteCompletionObject( true );
|
|
|
|
}
|
|
|
|
m_combo->setMaxItems( 9 );
|
|
|
|
m_combo->setURLs( Amarok::config( "Filebrowser" )->readPathListEntry( "Dir History" ) );
|
|
|
|
|
|
|
|
if (!m_medium)
|
|
|
|
m_combo->lineEdit()->setText( location->path() );
|
|
|
|
else
|
|
|
|
m_combo->lineEdit()->setText( "/" );
|
|
|
|
|
|
|
|
//The main widget with file listings and that
|
|
|
|
m_dir = new MyDirOperator( *location, container, m_medium );
|
|
|
|
m_dir->setEnableDirHighlighting( true );
|
|
|
|
m_dir->setMode( KFile::Mode((int)KFile::Files | (int)KFile::Directory) ); //allow selection of multiple files + dirs
|
|
|
|
m_dir->setOnlyDoubleClickSelectsFiles( true ); //Amarok type settings
|
|
|
|
m_dir->readConfig( Amarok::config( "Filebrowser" ) );
|
|
|
|
m_dir->setView( KFile::Default ); //will set userconfigured view, will load URL
|
|
|
|
m_dir->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Expanding );
|
|
|
|
m_dir->setAcceptDrops( true );
|
|
|
|
//Automatically open folder after hovering above it...probably a good thing
|
|
|
|
//but easily disabled by commenting this line out
|
|
|
|
//Disabled for now because can't show . and .. folders.
|
|
|
|
//TODO: Find out a way to fix this?
|
|
|
|
//m_dir->setDropOptions( KFileView::AutoOpenDirs );
|
|
|
|
|
|
|
|
static_cast<TQFrame*>(m_dir->viewWidget())->setFrameStyle( TQFrame::NoFrame );
|
|
|
|
static_cast<TQIconView*>(m_dir->viewWidget())->setSpacing( 1 );
|
|
|
|
|
|
|
|
actionCollection = m_dir->actionCollection();
|
|
|
|
|
|
|
|
searchPane = new SearchPane( this );
|
|
|
|
|
|
|
|
setStretchFactor( container, 2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
TQPopupMenu* const menu = static_cast<TDEActionMenu*>(actionCollection->action("popupMenu"))->popupMenu();
|
|
|
|
|
|
|
|
menu->clear();
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "files" ) ), i18n( "&Load" ), MakePlaylist );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), AppendToPlaylist );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "queue_track" ) ), i18n( "&Queue Track" ), QueueTrack );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "queue_track" ) ), i18n( "&Queue Tracks" ), QueueTracks );
|
|
|
|
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "save" ) ), i18n( "&Save as Playlist..." ), SavePlaylist );
|
|
|
|
menu->insertSeparator();
|
|
|
|
|
|
|
|
if (!m_medium)
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "device" ) ), i18n( "&Transfer to Media Device" ), MediaDevice );
|
|
|
|
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "collection" ) ), i18n( "&Organize Files..." ), OrganizeFiles );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "collection" ) ), i18n( "&Copy Files to Collection..." ), CopyToCollection );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "collection" ) ), i18n( "&Move Files to Collection..." ), MoveToCollection );
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "burn" ) ), i18n("Burn to CD..."), BurnCd );
|
|
|
|
menu->insertSeparator();
|
|
|
|
menu->insertItem( i18n( "&Select All Files" ), SelectAllFiles );
|
|
|
|
menu->insertSeparator();
|
|
|
|
actionCollection->action( "delete" )->setIcon( Amarok::icon( "remove" ) );
|
|
|
|
actionCollection->action( "delete" )->plug( menu );
|
|
|
|
menu->insertSeparator();
|
|
|
|
menu->insertItem( SmallIconSet( Amarok::icon( "info" ) ), i18n( "Edit Track &Information..." ), EditTags );
|
|
|
|
actionCollection->action( "properties" )->plug( menu );
|
|
|
|
|
|
|
|
menu->setItemEnabled( BurnCd, K3bExporter::isAvailable() );
|
|
|
|
|
|
|
|
connect( menu, TQT_SIGNAL(aboutToShow()), TQT_SLOT(prepareContextMenu()) );
|
|
|
|
connect( menu, TQT_SIGNAL(activated( int )), TQT_SLOT(contextMenuActivated( int )) );
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
TDEActionMenu *a;
|
|
|
|
|
|
|
|
a = static_cast<TDEActionMenu*>( actionCollection->action( "sorting menu" ) );
|
|
|
|
a->setIcon( Amarok::icon( "configure" ) );
|
|
|
|
a->setDelayed( false ); //TODO should be done by KDirOperator
|
|
|
|
|
|
|
|
actionCollection->action( "delete" )->setShortcut( TDEShortcut( SHIFT + Key_Delete ) );
|
|
|
|
|
|
|
|
a = new TDEActionMenu( i18n("Bookmarks"), "bookmark", actionCollection, "bookmarks" );
|
|
|
|
a->setDelayed( false );
|
|
|
|
|
|
|
|
new KBookmarkHandler( m_dir, a->popupMenu() );
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
if ( TDEAction *a = actionCollection->action( "up" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "back" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "forward" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "home" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "reload" ) ) {
|
|
|
|
a->setIcon( Amarok::icon( "refresh" ) );
|
|
|
|
a->plug( toolbar );
|
|
|
|
}
|
|
|
|
|
|
|
|
toolbar->insertLineSeparator();
|
|
|
|
|
|
|
|
if ( TDEAction *a = actionCollection->action( "short view" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "detailed view" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
|
|
|
|
toolbar->insertLineSeparator();
|
|
|
|
|
|
|
|
if ( TDEAction *a = actionCollection->action( "sorting menu" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
if ( TDEAction *a = actionCollection->action( "bookmarks" ) )
|
|
|
|
a->plug( toolbar );
|
|
|
|
|
|
|
|
|
|
|
|
TDEAction *gotoCurrent = new TDEAction( i18n("Go To Current Track Folder"), Amarok::icon( "music" ), 0,
|
|
|
|
TQT_TQOBJECT(this), TQT_SLOT( gotoCurrentFolder() ), actionCollection );
|
|
|
|
gotoCurrent->plug( toolbar );
|
|
|
|
|
|
|
|
disconnect( actionCollection->action( "up" ), TQT_SIGNAL( activated() ), m_dir, TQT_SLOT( cdUp() ) );
|
|
|
|
connect( actionCollection->action( "up" ), TQT_SIGNAL( activated() ), m_dir, TQT_SLOT( myCdUp() ) );
|
|
|
|
disconnect( actionCollection->action( "home" ), TQT_SIGNAL( activated() ), m_dir, TQT_SLOT( home() ) );
|
|
|
|
connect( actionCollection->action( "home" ), TQT_SIGNAL( activated() ), m_dir, TQT_SLOT( myHome() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
connect( m_filter, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(setFilter( const TQString& )) );
|
|
|
|
connect( m_combo, TQT_SIGNAL(urlActivated( const KURL& )), TQT_SLOT(setUrl( const KURL& )) );
|
|
|
|
connect( m_combo, TQT_SIGNAL(returnPressed( const TQString& )), TQT_SLOT(setUrl( const TQString& )) );
|
|
|
|
connect( m_dir, TQT_SIGNAL(viewChanged( KFileView* )), TQT_SLOT(slotViewChanged( KFileView* )) );
|
|
|
|
connect( m_dir, TQT_SIGNAL(fileSelected( const KFileItem* )), TQT_SLOT(activate( const KFileItem* )) );
|
|
|
|
connect( m_dir, TQT_SIGNAL(urlEntered( const KURL& )), TQT_SLOT(urlChanged( const KURL& )) );
|
|
|
|
connect( m_dir, TQT_SIGNAL(urlEntered( const KURL& )), searchPane, TQT_SLOT(urlChanged( const KURL& )) );
|
|
|
|
connect( m_dir, TQT_SIGNAL(dropped( const KFileItem*, TQDropEvent*, const KURL::List& )),
|
|
|
|
TQT_SLOT(dropped( const KFileItem*, TQDropEvent*, const KURL::List& )) );
|
|
|
|
|
|
|
|
setSpacing( 4 );
|
|
|
|
setFocusProxy( m_dir ); //so the dirOperator is focused when we get focus events
|
|
|
|
// Toolbar is more than 250px wide, BrowserBar doesn't allow that. -> Resizing issues.
|
|
|
|
setMinimumWidth( 250 /* toolbar->sizeHint().width() */ );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FileBrowser::~FileBrowser()
|
|
|
|
{
|
|
|
|
TDEConfig* const c = Amarok::config( "Filebrowser" );
|
|
|
|
|
|
|
|
m_dir->writeConfig( c ); //uses currently set group
|
|
|
|
|
|
|
|
c->writePathEntry( "Location", m_dir->url().url() );
|
|
|
|
c->writePathEntry( "Dir History", m_combo->urls() );
|
|
|
|
}
|
|
|
|
|
|
|
|
//END Constructor/Destructor
|
|
|
|
|
|
|
|
void FileBrowser::setUrl( const KURL &url )
|
|
|
|
{
|
|
|
|
m_dir->setFocus();
|
|
|
|
if (!m_medium)
|
|
|
|
m_dir->setURL( url, true );
|
|
|
|
else {
|
|
|
|
TQString urlpath = url.isLocalFile() ? url.path() : url.prettyURL();
|
|
|
|
KURL newURL( urlpath.prepend( m_medium->mountPoint() ).remove("..") );
|
|
|
|
//debug() << "set-url-kurl: changing to: " << newURL.path() << endl;
|
|
|
|
m_dir->setURL( newURL, true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBrowser::setUrl( const TQString &url )
|
|
|
|
{
|
|
|
|
if (!m_medium)
|
|
|
|
m_dir->setURL( KURL(url), true );
|
|
|
|
else{
|
|
|
|
KURL newURL( TQString(url).prepend( m_medium->mountPoint() ).remove("..") );
|
|
|
|
//debug() << "set-url-qstring: changing to: " << newURL.path() << endl;
|
|
|
|
m_dir->setURL( newURL, true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//BEGIN Private Methods
|
|
|
|
|
|
|
|
KURL::List FileBrowser::selectedItems()
|
|
|
|
{
|
|
|
|
KURL::List list;
|
|
|
|
for( KFileItemListIterator it( m_dir->selectedItems()->count() ? *m_dir->selectedItems() : *m_dir->view()->items() ); *it; ++it )
|
|
|
|
list.append( (*it)->url() );
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBrowser::playlistFromURLs( const KURL::List &urls )
|
|
|
|
{
|
|
|
|
TQString suggestion;
|
|
|
|
if( urls.count() == 1 && TQFileInfo( urls.first().path() ).isDir() )
|
|
|
|
suggestion = urls.first().fileName();
|
|
|
|
else
|
|
|
|
suggestion = i18n( "Untitled" );
|
|
|
|
const TQString path = PlaylistDialog::getSaveFileName( suggestion );
|
|
|
|
if( path.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( PlaylistBrowser::savePlaylist( path, urls ) )
|
|
|
|
{
|
|
|
|
//FIXME: uncomment after string freeze
|
|
|
|
//Amarok::StatusBar::instance()->shortMessage( "Playlist saved to playlist browser" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//END Private Methods
|
|
|
|
|
|
|
|
|
|
|
|
//BEGIN Public Slots
|
|
|
|
|
|
|
|
void
|
|
|
|
FileBrowser::setFilter( const TQString &text )
|
|
|
|
{
|
|
|
|
if ( text.isEmpty() )
|
|
|
|
m_dir->clearFilter();
|
|
|
|
|
|
|
|
else {
|
|
|
|
TQString filter;
|
|
|
|
|
|
|
|
const TQStringList terms = TQStringList::split( ' ', text );
|
|
|
|
foreach( terms ) {
|
|
|
|
filter += '*';
|
|
|
|
filter += *it;
|
|
|
|
}
|
|
|
|
filter += '*';
|
|
|
|
|
|
|
|
m_dir->setNameFilter( filter );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_dir->updateDir();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FileBrowser::dropped( const KFileItem* /*item*/, TQDropEvent* event, const KURL::List &urls){
|
|
|
|
//Do nothing right now
|
|
|
|
event->ignore();
|
|
|
|
//Run into const problems iterating over the list, so copy it to a malleable one
|
|
|
|
//(besides, need to filter for local giles)
|
|
|
|
KURL::List list(urls);
|
|
|
|
|
|
|
|
for ( KURL::List::iterator it = list.begin(); it != list.end(); ){
|
|
|
|
if ( m_medium && !(*it).isLocalFile() )
|
|
|
|
it = list.erase( it );
|
|
|
|
else{
|
|
|
|
debug() << "Dropped: " << (*it) << endl;
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//END Public Slots
|
|
|
|
|
|
|
|
|
|
|
|
//BEGIN Private Slots
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::urlChanged( const KURL &u )
|
|
|
|
{
|
|
|
|
//the DirOperator's URL has changed
|
|
|
|
|
|
|
|
TQString url = u.isLocalFile() ? u.path() : u.prettyURL();
|
|
|
|
|
|
|
|
if( m_medium ){
|
|
|
|
//remove the leading mountPoint value
|
|
|
|
url.remove( 0, m_medium->mountPoint().length() );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList urls = m_combo->urls();
|
|
|
|
urls.remove( url );
|
|
|
|
urls.prepend( url );
|
|
|
|
|
|
|
|
m_combo->setURLs( urls, KURLComboBox::RemoveBottom );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::slotViewChanged( KFileView *view )
|
|
|
|
{
|
|
|
|
if( view->widget()->inherits( "TDEListView" ) )
|
|
|
|
{
|
|
|
|
using namespace Amarok::ColorScheme;
|
|
|
|
|
|
|
|
static_cast<TDEListView*>(view->widget())->setAlternateBackground( AltBase );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::activate( const KFileItem *item )
|
|
|
|
{
|
|
|
|
Playlist::instance()->insertMedia( item->url(), Playlist::DefaultOptions );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::prepareContextMenu()
|
|
|
|
{
|
|
|
|
const KFileItemList &items = *m_dir->selectedItems();
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( SavePlaylist,
|
|
|
|
items.count() > 1 || ( items.count() == 1 && items.getFirst()->isDir() ) );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( QueueTrack,
|
|
|
|
items.count() == 1 );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( QueueTracks,
|
|
|
|
items.count() > 1 );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( MediaDevice,
|
|
|
|
MediaBrowser::isAvailable() );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( MoveToCollection, !CollectionDB::instance()->isDirInCollection( url().path() ) );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( CopyToCollection, !CollectionDB::instance()->isDirInCollection( url().path() ) );
|
|
|
|
static_cast<TDEActionMenu*>(m_dir->actionCollection()->action("popupMenu"))->popupMenu()->setItemVisible( OrganizeFiles, CollectionDB::instance()->isDirInCollection( url().path() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::contextMenuActivated( int id )
|
|
|
|
{
|
|
|
|
switch( id )
|
|
|
|
{
|
|
|
|
case MakePlaylist:
|
|
|
|
Playlist::instance()->insertMedia( selectedItems(), Playlist::Replace );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SavePlaylist:
|
|
|
|
playlistFromURLs( selectedItems() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AppendToPlaylist:
|
|
|
|
Playlist::instance()->insertMedia( selectedItems() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QueueTrack:
|
|
|
|
case QueueTracks:
|
|
|
|
Playlist::instance()->insertMedia( selectedItems(), Playlist::Queue );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EditTags:
|
|
|
|
{
|
|
|
|
KURL::List list = Amarok::recursiveUrlExpand( selectedItems() );
|
|
|
|
TagDialog *dialog = NULL;
|
|
|
|
if( list.count() == 1 )
|
|
|
|
{
|
|
|
|
dialog = new TagDialog( list.first(), this );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dialog = new TagDialog( list, this );
|
|
|
|
}
|
|
|
|
dialog->show();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CopyToCollection:
|
|
|
|
CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Copy Files To Collection" ), true );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MoveToCollection:
|
|
|
|
CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Move Files To Collection" ), false );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OrganizeFiles:
|
|
|
|
CollectionView::instance()->organizeFiles( selectedItems(), i18n( "Organize Collection Files" ), false );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MediaDevice:
|
|
|
|
MediaBrowser::queue()->addURLs( selectedItems() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SelectAllFiles:
|
|
|
|
selectAll();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BurnCd:
|
|
|
|
K3bExporter::instance()->exportTracks( selectedItems() );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
FileBrowser::gotoCurrentFolder()
|
|
|
|
{
|
|
|
|
const KURL &url = EngineController::instance()->bundle().url();
|
|
|
|
KURL dirURL = KURL::fromPathOrURL( url.directory() );
|
|
|
|
|
|
|
|
m_combo->setURL( dirURL );
|
|
|
|
setUrl( dirURL );
|
|
|
|
}
|
|
|
|
|
|
|
|
//END Private Slots
|
|
|
|
|
|
|
|
void
|
|
|
|
FileBrowser::selectAll()
|
|
|
|
{
|
|
|
|
KFileItemList list( *m_dir->view()->items() );
|
|
|
|
|
|
|
|
// Select all items which represent files
|
|
|
|
for( KFileItem* item = list.first(); item; item = list.next() )
|
|
|
|
m_dir->view()->setSelected( item, item->isFile() );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <kurldrag.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqsimplerichtext.h>
|
|
|
|
|
|
|
|
class KURLView : public TDEListView
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
KURLView( TQWidget *parent ) : TDEListView( parent )
|
|
|
|
{
|
|
|
|
reinterpret_cast<TQWidget*>(header())->hide();
|
|
|
|
addColumn( TQString() );
|
|
|
|
setResizeMode( TDEListView::LastColumn );
|
|
|
|
setDragEnabled( true );
|
|
|
|
setSelectionMode( TQListView::Extended );
|
|
|
|
}
|
|
|
|
|
|
|
|
class Item : public TDEListViewItem {
|
|
|
|
public:
|
|
|
|
Item( const KURL &url, KURLView *parent ) : TDEListViewItem( parent, url.fileName() ), m_url( url ) {}
|
|
|
|
KURL m_url;
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual TQDragObject *dragObject()
|
|
|
|
{
|
|
|
|
TQPtrList<TQListViewItem> items = selectedItems();
|
|
|
|
KURL::List urls;
|
|
|
|
|
|
|
|
for( Item *item = static_cast<Item*>( items.first() ); item; item = static_cast<Item*>( items.next() ) )
|
|
|
|
urls += item->m_url;
|
|
|
|
|
|
|
|
return new KURLDrag( urls, this );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void viewportPaintEvent( TQPaintEvent *e )
|
|
|
|
{
|
|
|
|
TDEListView::viewportPaintEvent( e );
|
|
|
|
|
|
|
|
if ( childCount() == 0 ) {
|
|
|
|
TQPainter p( viewport() );
|
|
|
|
|
|
|
|
if ( m_text.isEmpty() ) {
|
|
|
|
//TODO Perhaps it's time to put this in some header, as we use it in three places now
|
|
|
|
TQSimpleRichText t( i18n(
|
|
|
|
"<div align=center>"
|
|
|
|
"Enter a search term above; you can use wildcards like * and ?"
|
|
|
|
"</div>" ), font() );
|
|
|
|
|
|
|
|
t.setWidth( width() - 50 );
|
|
|
|
|
|
|
|
const uint w = t.width() + 20;
|
|
|
|
const uint h = t.height() + 20;
|
|
|
|
|
|
|
|
p.setBrush( colorGroup().background() );
|
|
|
|
p.drawRoundRect( 15, 15, w, h, (8*200)/w, (8*200)/h );
|
|
|
|
t.draw( &p, 20, 20, TQRect(), colorGroup() );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
p.setPen( palette().color( TQPalette::Disabled, TQColorGroup::Text ) );
|
|
|
|
p.drawText( rect(), TQt::AlignCenter | TQt::WordBreak, m_text );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void unsetText() { setText( TQString() ); }
|
|
|
|
void setText( const TQString &text ) { m_text = text; viewport()->update(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQString m_text;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SearchPane::SearchPane( FileBrowser *parent )
|
|
|
|
: TQVBox( parent )
|
|
|
|
, m_lineEdit( 0 )
|
|
|
|
, m_listView( 0 )
|
|
|
|
, m_lister( 0 )
|
|
|
|
{
|
|
|
|
TQFrame *container = new TQVBox( this, "container" );
|
|
|
|
container->hide();
|
|
|
|
|
|
|
|
{
|
|
|
|
TQFrame *box = new TQHBox( container );
|
|
|
|
box->setMargin( 5 );
|
|
|
|
box->setBackgroundMode( TQt::PaletteBase );
|
|
|
|
|
|
|
|
m_lineEdit = new ClickLineEdit( i18n("Search here..."), box );
|
|
|
|
connect( m_lineEdit, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(searchTextChanged( const TQString& )) );
|
|
|
|
|
|
|
|
m_listView = new KURLView( container );
|
|
|
|
|
|
|
|
container->setFrameStyle( m_listView->frameStyle() );
|
|
|
|
container->setMargin( 5 );
|
|
|
|
container->setBackgroundMode( TQt::PaletteBase );
|
|
|
|
|
|
|
|
m_listView->setFrameStyle( TQFrame::NoFrame );
|
|
|
|
connect( m_listView, TQT_SIGNAL(executed( TQListViewItem* )), TQT_SLOT(activate( TQListViewItem* )) );
|
|
|
|
}
|
|
|
|
|
|
|
|
KPushButton *button = new KPushButton( KGuiItem( i18n("&Show Search Panel"), "edit-find" ), this );
|
|
|
|
button->setToggleButton( true );
|
|
|
|
connect( button, TQT_SIGNAL(toggled( bool )), TQT_SLOT(toggle( bool )) );
|
|
|
|
|
|
|
|
m_lister = new MyDirLister( true /*delay mimetypes*/ );
|
|
|
|
insertChild( m_lister );
|
|
|
|
connect( m_lister, TQT_SIGNAL(newItems( const KFileItemList& )), TQT_SLOT(searchMatches( const KFileItemList& )) );
|
|
|
|
connect( m_lister, TQT_SIGNAL(completed()), TQT_SLOT(searchComplete()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::toggle( bool toggled )
|
|
|
|
{
|
|
|
|
if ( toggled )
|
|
|
|
m_lineEdit->setFocus();
|
|
|
|
|
|
|
|
TQT_TQWIDGET(child("container"))->setShown( toggled );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::urlChanged( const KURL& )
|
|
|
|
{
|
|
|
|
searchTextChanged( m_lineEdit->text() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::searchTextChanged( const TQString &text )
|
|
|
|
{
|
|
|
|
//TODO if user changes search directory then we need to update the search too
|
|
|
|
|
|
|
|
m_lister->stop();
|
|
|
|
m_listView->clear();
|
|
|
|
m_dirs.clear();
|
|
|
|
|
|
|
|
if ( text.isEmpty() ) {
|
|
|
|
m_listView->unsetText();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_filter = TQRegExp( text.contains( "*" ) ? text : '*'+text+'*', false, true );
|
|
|
|
|
|
|
|
m_lister->openURL( searchURL() );
|
|
|
|
|
|
|
|
m_listView->setText( i18n( "Searching..." ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::searchMatches( const KFileItemList &list )
|
|
|
|
{
|
|
|
|
for( KFileItemList::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) {
|
|
|
|
if( (*it)->isDir() )
|
|
|
|
m_dirs += (*it)->url();
|
|
|
|
else if( m_filter.exactMatch( (*it)->name() ) )
|
|
|
|
new KURLView::Item( (*it)->url(), static_cast<KURLView*>( m_listView ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::searchComplete()
|
|
|
|
{
|
|
|
|
//KDirLister crashes if you call openURL() from a slot
|
|
|
|
//connected to KDirLister::complete()
|
|
|
|
//TODO fix crappy KDElibs
|
|
|
|
|
|
|
|
TQTimer::singleShot( 0, this, TQT_SLOT(_searchComplete()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::_searchComplete()
|
|
|
|
{
|
|
|
|
if ( !m_dirs.isEmpty() ) {
|
|
|
|
KURL url = m_dirs.first();
|
|
|
|
m_dirs.pop_front();
|
|
|
|
m_lister->openURL( url );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_listView->setText( i18n("No results found") ); //only displayed if the listview is empty
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SearchPane::activate( TQListViewItem *item )
|
|
|
|
{
|
|
|
|
Playlist::instance()->insertMedia( static_cast<KURLView::Item*>(item)->m_url, Playlist::DirectPlay );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "filebrowser.moc"
|