X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Fcomponents%2Fplaylist%2Fstandardpanel.cpp;h=bf81375978f5676fefe9c9d848ee7560f14433df;hb=05d736eac9cb11e55fca0552ff4150cb48004ed8;hp=641600d2d3c616c22450ccd6750b3b0b779452af;hpb=df20afd774d8b62de3606edb6a1586011dc11804;p=vlc diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp index 641600d2d3..bf81375978 100644 --- a/modules/gui/qt4/components/playlist/standardpanel.cpp +++ b/modules/gui/qt4/components/playlist/standardpanel.cpp @@ -1,10 +1,11 @@ /***************************************************************************** * standardpanel.cpp : The "standard" playlist panel : just a treeview **************************************************************************** - * Copyright (C) 2000-2005 the VideoLAN team + * Copyright (C) 2000-2009 VideoLAN * $Id$ * * Authors: Clément Stenac + * JB Kempf * * 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 @@ -25,321 +26,530 @@ # include "config.h" #endif -#include "qt4.hpp" #include "dialogs_provider.hpp" #include "components/playlist/playlist_model.hpp" -#include "components/playlist/panels.hpp" +#include "components/playlist/standardpanel.hpp" +#include "components/playlist/icon_view.hpp" #include "util/customwidgets.hpp" +#include "menus.hpp" #include #include -#include -#include #include #include #include #include -#include #include #include +#include +#include +#include +#include + #include #include "sorting.h" +static const QString viewNames[] = { qtr( "Detailed View" ), + qtr( "Icon View" ), + qtr( "List View" ) }; + StandardPLPanel::StandardPLPanel( PlaylistWidget *_parent, intf_thread_t *_p_intf, playlist_t *p_playlist, playlist_item_t *p_root ): - PLPanel( _parent, _p_intf ) + QWidget( _parent ), p_intf( _p_intf ) { - model = new PLModel( p_playlist, p_intf, p_root, -1, this ); - - QVBoxLayout *layout = new QVBoxLayout(); + layout = new QGridLayout( this ); layout->setSpacing( 0 ); layout->setMargin( 0 ); + setMinimumWidth( 300 ); - /* Create and configure the QTreeView */ - view = new QVLCTreeView; - view->header()->setSortIndicator( 0 , Qt::AscendingOrder ); - view->setSortingEnabled( true ); - view->setModel( model ); - view->setIconSize( QSize( 20, 20 ) ); - view->setAlternatingRowColors( true ); - view->setAnimated( true ); - view->setSelectionBehavior( QAbstractItemView::SelectRows ); - view->setSelectionMode( QAbstractItemView::ExtendedSelection ); - view->setDragEnabled( true ); - view->setAcceptDrops( true ); - view->setDropIndicatorShown( true ); - view->setAutoScroll( true ); - + iconView = NULL; + treeView = NULL; + listView = NULL; - getSettings()->beginGroup("Playlist"); - if( getSettings()->contains( "headerState" ) ) - { - view->header()->restoreState( - getSettings()->value( "headerState" ).toByteArray() ); - } - else + model = new PLModel( p_playlist, p_intf, p_root, this ); + currentRootId = -1; + currentRootIndexId = -1; + lastActivatedId = -1; + + locationBar = new LocationBar( model ); + locationBar->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred ); + layout->addWidget( locationBar, 0, 0 ); + layout->setColumnStretch( 0, 5 ); + CONNECT( locationBar, invoked( const QModelIndex & ), + this, browseInto( const QModelIndex & ) ); + + searchEdit = new SearchLineEdit( this ); + searchEdit->setMaximumWidth( 250 ); + searchEdit->setMinimumWidth( 80 ); + layout->addWidget( searchEdit, 0, 2 ); + CONNECT( searchEdit, textChanged( const QString& ), + this, search( const QString& ) ); + layout->setColumnStretch( 2, 3 ); + + /* Button to switch views */ + QToolButton *viewButton = new QToolButton( this ); + viewButton->setIcon( style()->standardIcon( QStyle::SP_FileDialogDetailedView ) ); + layout->addWidget( viewButton, 0, 1 ); + + /* View selection menu */ + viewSelectionMapper = new QSignalMapper( this ); + CONNECT( viewSelectionMapper, mapped( int ), this, showView( int ) ); + + QActionGroup *actionGroup = new QActionGroup( this ); + + for( int i = 0; i < VIEW_COUNT; i++ ) { - /* Configure the size of the header */ - view->header()->resizeSection( 0, 200 ); - view->header()->resizeSection( 1, 80 ); + viewActions[i] = actionGroup->addAction( viewNames[i] ); + viewActions[i]->setCheckable( true ); + viewSelectionMapper->setMapping( viewActions[i], i ); + CONNECT( viewActions[i], triggered(), viewSelectionMapper, map() ); } - view->header()->setSortIndicatorShown( true ); - view->header()->setClickable( true ); - view->header()->setContextMenuPolicy( Qt::CustomContextMenu ); + + BUTTONACT( viewButton, cycleViews() ); + QMenu *viewMenu = new QMenu( this ); + viewMenu->addActions( actionGroup->actions() ); + + viewButton->setMenu( viewMenu ); + + /* Saved Settings */ + getSettings()->beginGroup("Playlist"); + + int i_viewMode = getSettings()->value( "view-mode", TREE_VIEW ).toInt(); + showView( i_viewMode ); + getSettings()->endGroup(); - /* Connections for the TreeView */ - CONNECT( view, activated( const QModelIndex& ) , - model,activateItem( const QModelIndex& ) ); - CONNECT( view, rightClicked( QModelIndex , QPoint ), - this, doPopup( QModelIndex, QPoint ) ); - CONNECT( model, dataChanged( const QModelIndex&, const QModelIndex& ), + CONNECT( THEMIM, leafBecameParent( input_item_t *), + this, browseInto( input_item_t * ) ); + + CONNECT( model, currentChanged( const QModelIndex& ), this, handleExpansion( const QModelIndex& ) ); - CONNECT( view->header(), customContextMenuRequested( const QPoint & ), - this, popupSelectColumn( QPoint ) ); + CONNECT( model, rootChanged(), this, handleRootChange() ); +} - currentRootId = -1; - CONNECT( parent, rootChanged( int ), this, setCurrentRootId( int ) ); - - /* Buttons configuration */ - QHBoxLayout *buttons = new QHBoxLayout; - - /* Add item to the playlist button */ - addButton = new QPushButton; - addButton->setIcon( QIcon( ":/buttons/playlist/playlist_add" ) ); - addButton->setMaximumWidth( 30 ); - BUTTONACT( addButton, popupAdd() ); - buttons->addWidget( addButton ); - - /* Random 2-state button */ - randomButton = new QPushButton( this ); - randomButton->setIcon( QIcon( ":/buttons/playlist/shuffle_on" )); - randomButton->setToolTip( qtr( I_PL_RANDOM )); - randomButton->setCheckable( true ); - randomButton->setChecked( model->hasRandom() ); - BUTTONACT( randomButton, toggleRandom() ); - buttons->addWidget( randomButton ); - - /* Repeat 3-state button */ - repeatButton = new QPushButton( this ); - repeatButton->setToolTip( qtr( "Click to toggle between loop one, loop all" ) ); - repeatButton->setCheckable( true ); - - if( model->hasRepeat() ) - { - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_one" ) ); - repeatButton->setChecked( true ); - } - else if( model->hasLoop() ) - { - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_all" ) ); - repeatButton->setChecked( true ); - } - else - { - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_one" ) ); - repeatButton->setChecked( false ); - } - BUTTONACT( repeatButton, toggleRepeat() ); - buttons->addWidget( repeatButton ); +StandardPLPanel::~StandardPLPanel() +{ + getSettings()->beginGroup("Playlist"); + if( treeView ) + getSettings()->setValue( "headerStateV2", treeView->header()->saveState() ); + if( currentView == treeView ) + getSettings()->setValue( "view-mode", TREE_VIEW ); + else if( currentView == listView ) + getSettings()->setValue( "view-mode", LIST_VIEW ); + else if( currentView == iconView ) + getSettings()->setValue( "view-mode", ICON_VIEW ); + getSettings()->endGroup(); +} - /* Goto */ - gotoPlayingButton = new QPushButton; - BUTTON_SET_ACT_I( gotoPlayingButton, "", buttons/playlist/jump_to, - qtr( "Show the current item" ), gotoPlayingItem() ); - buttons->addWidget( gotoPlayingButton ); +/* Unused anymore, but might be useful, like in right-click menu */ +void StandardPLPanel::gotoPlayingItem() +{ + currentView->scrollTo( model->currentIndex() ); +} - /* A Spacer and the search possibilities */ - QSpacerItem *spacer = new QSpacerItem( 10, 20 ); - buttons->addItem( spacer ); +void StandardPLPanel::handleExpansion( const QModelIndex& index ) +{ + assert( currentView ); + currentView->scrollTo( index ); +} - QLabel *filter = new QLabel( qtr(I_PL_SEARCH) + " " ); - buttons->addWidget( filter ); +void StandardPLPanel::handleRootChange() +{ + browseInto(); +} - SearchLineEdit *search = new SearchLineEdit( this ); - buttons->addWidget( search ); - filter->setBuddy( search ); - CONNECT( search, textChanged( const QString& ), this, search( const QString& ) ); +void StandardPLPanel::popupPlView( const QPoint &point ) +{ + QModelIndex index = currentView->indexAt( point ); + QPoint globalPoint = currentView->viewport()->mapToGlobal( point ); + QItemSelectionModel *selection = currentView->selectionModel(); + QModelIndexList list = selection->selectedIndexes(); - /* Finish the layout */ - layout->addWidget( view ); - layout->addLayout( buttons ); -// layout->addWidget( bar ); - setLayout( layout ); + if( !model->popup( index, globalPoint, list ) ) + QVLCMenu::PopupMenu( p_intf, true ); } -/* Function to toggle between the Repeat states */ -void StandardPLPanel::toggleRepeat() +void StandardPLPanel::popupSelectColumn( QPoint pos ) { - if( model->hasRepeat() ) + QMenu menu; + assert( treeView ); + + /* We do not offer the option to hide index 0 column, or + * QTreeView will behave weird */ + int i, j; + for( i = 1 << 1, j = 1; i < COLUMN_END; i <<= 1, j++ ) { - model->setRepeat( false ); model->setLoop( true ); - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_all" ) ); - repeatButton->setChecked( true ); + QAction* option = menu.addAction( + qfu( psz_column_title( i ) ) ); + option->setCheckable( true ); + option->setChecked( !treeView->isColumnHidden( j ) ); + selectColumnsSigMapper->setMapping( option, j ); + CONNECT( option, triggered(), selectColumnsSigMapper, map() ); } - else if( model->hasLoop() ) + menu.exec( QCursor::pos() ); +} + +void StandardPLPanel::toggleColumnShown( int i ) +{ + treeView->setColumnHidden( i, !treeView->isColumnHidden( i ) ); +} + +/* Search in the playlist */ +void StandardPLPanel::search( const QString& searchText ) +{ + bool flat = currentView == iconView || currentView == listView; + model->search( searchText, + flat ? currentView->rootIndex() : QModelIndex(), + !flat ); +} + +/* Set the root of the new Playlist */ +/* This activated by the selector selection */ +void StandardPLPanel::setRoot( playlist_item_t *p_item ) +{ + model->rebuild( p_item ); +} + +void StandardPLPanel::browseInto( const QModelIndex &index ) +{ + if( currentView == iconView || currentView == listView ) { - model->setRepeat( false ) ; model->setLoop( false ); - repeatButton->setChecked( false ); - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_one" ) ); + currentRootIndexId = model->itemId( index );; + currentView->setRootIndex( index ); } - else + + locationBar->setIndex( index ); + model->search( QString(), index, false ); + searchEdit->clear(); +} + +void StandardPLPanel::browseInto( ) +{ + browseInto( currentRootIndexId != -1 && currentView != treeView ? + model->index( currentRootIndexId, 0 ) : + QModelIndex() ); +} + +void StandardPLPanel::wheelEvent( QWheelEvent *e ) +{ + // Accept this event in order to prevent unwanted volume up/down changes + e->accept(); +} + +bool StandardPLPanel::eventFilter ( QObject * watched, QEvent * event ) +{ + if (event->type() == QEvent::KeyPress) { - model->setRepeat( true ); model->setLoop( false ); - repeatButton->setChecked( true ); - repeatButton->setIcon( QIcon( ":/buttons/playlist/repeat_one" ) ); + QKeyEvent *keyEvent = static_cast(event); + if( keyEvent->key() == Qt::Key_Delete || + keyEvent->key() == Qt::Key_Backspace ) + { + deleteSelection(); + return true; + } } + return false; } -/* Function to toggle between the Random states */ -void StandardPLPanel::toggleRandom() +void StandardPLPanel::deleteSelection() { - bool prev = model->hasRandom(); - model->setRandom( !prev ); + QItemSelectionModel *selection = currentView->selectionModel(); + QModelIndexList list = selection->selectedIndexes(); + model->doDelete( list ); } -void StandardPLPanel::gotoPlayingItem() +void StandardPLPanel::createIconView() { - view->scrollTo( view->currentIndex() ); + iconView = new PlIconView( model, this ); + iconView->setContextMenuPolicy( Qt::CustomContextMenu ); + CONNECT( iconView, customContextMenuRequested( const QPoint & ), + this, popupPlView( const QPoint & ) ); + CONNECT( iconView, activated( const QModelIndex & ), + this, activate( const QModelIndex & ) ); + iconView->installEventFilter( this ); + layout->addWidget( iconView, 1, 0, 1, -1 ); } -void StandardPLPanel::handleExpansion( const QModelIndex &index ) +void StandardPLPanel::createListView() { - if( model->isCurrent( index ) ) - view->scrollTo( index, QAbstractItemView::EnsureVisible ); + listView = new PlListView( model, this ); + listView->setContextMenuPolicy( Qt::CustomContextMenu ); + CONNECT( listView, customContextMenuRequested( const QPoint & ), + this, popupPlView( const QPoint & ) ); + CONNECT( listView, activated( const QModelIndex & ), + this, activate( const QModelIndex & ) ); + listView->installEventFilter( this ); + layout->addWidget( listView, 1, 0, 1, -1 ); } -void StandardPLPanel::setCurrentRootId( int _new ) + +void StandardPLPanel::createTreeView() { - currentRootId = _new; - if( currentRootId == THEPL->p_local_category->i_id || - currentRootId == THEPL->p_local_onelevel->i_id ) + /* Create and configure the QTreeView */ + treeView = new QTreeView; + + treeView->setIconSize( QSize( 20, 20 ) ); + treeView->setAlternatingRowColors( true ); + treeView->setAnimated( true ); + treeView->setUniformRowHeights( true ); + treeView->setSortingEnabled( true ); + treeView->header()->setSortIndicator( -1 , Qt::AscendingOrder ); + treeView->header()->setSortIndicatorShown( true ); + treeView->header()->setClickable( true ); + treeView->header()->setContextMenuPolicy( Qt::CustomContextMenu ); + + treeView->setSelectionBehavior( QAbstractItemView::SelectRows ); + treeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); + treeView->setDragEnabled( true ); + treeView->setAcceptDrops( true ); + treeView->setDropIndicatorShown( true ); + treeView->setContextMenuPolicy( Qt::CustomContextMenu ); + + /* setModel after setSortingEnabled(true), or the model will sort immediately! */ + treeView->setModel( model ); + + if( getSettings()->contains( "headerStateV2" ) ) { - addButton->setEnabled( true ); - addButton->setToolTip( qtr(I_PL_ADDPL) ); + treeView->header()->restoreState( + getSettings()->value( "headerStateV2" ).toByteArray() ); } - else if( ( THEPL->p_ml_category && - currentRootId == THEPL->p_ml_category->i_id ) || - ( THEPL->p_ml_onelevel && - currentRootId == THEPL->p_ml_onelevel->i_id ) ) + else { - addButton->setEnabled( true ); - addButton->setToolTip( qtr(I_PL_ADDML) ); + for( int m = 1, c = 0; m != COLUMN_END; m <<= 1, c++ ) + { + treeView->setColumnHidden( c, !( m & COLUMN_DEFAULT ) ); + if( m == COLUMN_TITLE ) treeView->header()->resizeSection( c, 200 ); + else if( m == COLUMN_DURATION ) treeView->header()->resizeSection( c, 80 ); + } } - else - addButton->setEnabled( false ); + + /* Connections for the TreeView */ + CONNECT( treeView, activated( const QModelIndex& ), + this, activate( const QModelIndex& ) ); + CONNECT( treeView->header(), customContextMenuRequested( const QPoint & ), + this, popupSelectColumn( QPoint ) ); + CONNECT( treeView, customContextMenuRequested( const QPoint & ), + this, popupPlView( const QPoint & ) ); + treeView->installEventFilter( this ); + + /* SignalMapper for columns */ + selectColumnsSigMapper = new QSignalMapper( this ); + CONNECT( selectColumnsSigMapper, mapped( int ), + this, toggleColumnShown( int ) ); + + /* Finish the layout */ + layout->addWidget( treeView, 1, 0, 1, -1 ); } -/* PopupAdd Menu for the Add Menu */ -void StandardPLPanel::popupAdd() +void StandardPLPanel::showView( int i_view ) { - QMenu popup; - if( currentRootId == THEPL->p_local_category->i_id || - currentRootId == THEPL->p_local_onelevel->i_id ) + switch( i_view ) { - popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT(PLAppendDialog( OPEN_FILE_TAB )) ); - popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT(PLAppendDialog( OPEN_DISC_TAB )) ); - popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT(PLAppendDialog( OPEN_NETWORK_TAB )) ); - popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT(PLAppendDialog( OPEN_FILE_TAB )) ); - popup.addAction( qtr(I_PL_ADDDIR), THEDP, SLOT( PLAppendDir()) ); + case TREE_VIEW: + { + if( treeView == NULL ) + createTreeView(); + if( iconView ) iconView->hide(); + if( listView ) listView->hide(); + treeView->show(); + currentView = treeView; + viewActions[i_view]->setChecked( true ); + break; } - else if( ( THEPL->p_ml_category && - currentRootId == THEPL->p_ml_category->i_id ) || - ( THEPL->p_ml_onelevel && - currentRootId == THEPL->p_ml_onelevel->i_id ) ) + case ICON_VIEW: { - popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT( MLAppendDialog() ) ); - popup.addAction( qtr(I_PL_ADDDIR), THEDP, SLOT( MLAppendDir() ) ); + if( iconView == NULL ) + createIconView(); + + if( treeView ) treeView->hide(); + if( listView ) listView->hide(); + iconView->show(); + currentView = iconView; + viewActions[i_view]->setChecked( true ); + break; + } + case LIST_VIEW: + { + if( listView == NULL ) + createListView(); + + if( treeView ) treeView->hide(); + if( iconView ) iconView->hide(); + listView->show(); + currentView = listView; + viewActions[i_view]->setChecked( true ); + break; + } + default: return; } - popup.exec( QCursor::pos() - addButton->mapFromGlobal( QCursor::pos() ) - + QPoint( 0, addButton->height() ) ); + browseInto(); + gotoPlayingItem(); } -void StandardPLPanel::popupSelectColumn( QPoint pos ) +void StandardPLPanel::cycleViews() +{ + if( currentView == iconView ) + showView( TREE_VIEW ); + else if( currentView == treeView ) + showView( LIST_VIEW ); + else if( currentView == listView ) + showView( ICON_VIEW ); + else + assert( 0 ); +} + +void StandardPLPanel::activate( const QModelIndex &index ) +{ + if( model->hasChildren( index ) ) + { + if( currentView != treeView ) + browseInto( index ); + } + else + { + playlist_Lock( THEPL ); + playlist_item_t *p_item = playlist_ItemGetById( THEPL, model->itemId( index ) ); + p_item->i_flags |= PLAYLIST_SUBITEM_STOP_FLAG; + lastActivatedId = p_item->p_input->i_id; + playlist_Unlock( THEPL ); + model->activateItem( index ); + } +} + +void StandardPLPanel::browseInto( input_item_t *p_input ) { - ContextUpdateMapper = new QSignalMapper(this); - QMenu selectColMenu; + if( p_input->i_id != lastActivatedId ) return; - CONNECT( ContextUpdateMapper, mapped( int ), model, viewchanged( int ) ); + playlist_Lock( THEPL ); - int i_column = 1; - for( i_column = 1; i_column != COLUMN_END; i_column<<=1 ) + playlist_item_t *p_item = playlist_ItemGetByInput( THEPL, p_input ); + if( !p_item ) { - QAction* option = selectColMenu.addAction( - qfu( psz_column_title( i_column ) ) ); - option->setCheckable( true ); - option->setChecked( model->shownFlags() & i_column ); - ContextUpdateMapper->setMapping( option, i_column ); - CONNECT( option, triggered(), ContextUpdateMapper, map() ); + playlist_Unlock( THEPL ); + return; } - selectColMenu.exec( QCursor::pos() ); -} + QModelIndex index = model->index( p_item->i_id, 0 ); + + playlist_Unlock( THEPL ); + + if( currentView == treeView ) + treeView->setExpanded( index, true ); + else + browseInto( index ); + + lastActivatedId = -1; + -/* Search in the playlist */ -void StandardPLPanel::search( const QString& searchText ) -{ - model->search( searchText ); } -void StandardPLPanel::doPopup( QModelIndex index, QPoint point ) +LocationBar::LocationBar( PLModel *m ) { - if( !index.isValid() ) return; - QItemSelectionModel *selection = view->selectionModel(); - QModelIndexList list = selection->selectedIndexes(); - model->popup( index, point, list ); + model = m; + mapper = new QSignalMapper( this ); + CONNECT( mapper, mapped( int ), this, invoke( int ) ); + + box = new QHBoxLayout; + box->setSpacing( 0 ); + box->setContentsMargins( 0, 0, 0, 0 ); + setLayout( box ); } -/* Set the root of the new Playlist */ -/* This activated by the selector selection */ -void StandardPLPanel::setRoot( int i_root_id ) +void LocationBar::setIndex( const QModelIndex &index ) { - QPL_LOCK; - playlist_item_t *p_item = playlist_ItemGetById( THEPL, i_root_id ); - assert( p_item ); - p_item = playlist_GetPreferredNode( THEPL, p_item ); - assert( p_item ); - QPL_UNLOCK; + qDeleteAll( buttons ); + buttons.clear(); + QModelIndex i = index; + bool bold = true; + box->addStretch(); + while( true ) + { + PLItem *item = model->getItem( i ); - model->rebuild( p_item ); + char *fb_name = input_item_GetTitleFbName( item->inputItem() ); + QString text = qfu(fb_name); + free(fb_name); + QAbstractButton *btn = new LocationButton( text, bold, i.isValid() ); + btn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed ); + box->insertWidget( 0, btn ); + buttons.append( btn ); + + mapper->setMapping( btn, item->id() ); + CONNECT( btn, clicked( ), mapper, map( ) ); + + bold = false; + + if( i.isValid() ) i = i.parent(); + else break; + } } -void StandardPLPanel::removeItem( int i_id ) +void LocationBar::setRootIndex() { - model->removeItem( i_id ); + setIndex( QModelIndex() ); } -/* Delete and Suppr key remove the selection - FilterKey function and code function */ -void StandardPLPanel::keyPressEvent( QKeyEvent *e ) +void LocationBar::invoke( int i_id ) { - switch( e->key() ) - { - case Qt::Key_Back: - case Qt::Key_Delete: - deleteSelection(); - break; - } + QModelIndex index = model->index( i_id, 0 ); + emit invoked ( index ); } -void StandardPLPanel::deleteSelection() +LocationButton::LocationButton( const QString &text, bool bold, bool arrow ) + : b_arrow( arrow ) { - QItemSelectionModel *selection = view->selectionModel(); - QModelIndexList list = selection->selectedIndexes(); - model->doDelete( list ); + QFont font; + font.setBold( bold ); + setFont( font ); + setText( text ); } -StandardPLPanel::~StandardPLPanel() +#define PADDING 4 + +void LocationButton::paintEvent ( QPaintEvent * event ) { - getSettings()->beginGroup("Playlist"); - getSettings()->setValue( "headerState", view->header()->saveState() ); - getSettings()->endGroup(); + QStyleOptionButton option; + option.initFrom( this ); + option.state |= QStyle::State_Enabled; + QPainter p( this ); + + if( underMouse() ) + style()->drawControl( QStyle::CE_PushButtonBevel, &option, &p ); + + int margin = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this) + PADDING; + + QRect rect = option.rect.adjusted( b_arrow ? 15 + margin : margin, 0, -margin, 0 ); + + QString str( text() ); + /* This check is absurd, but either it is not done properly inside elidedText(), + or boundingRect() is wrong */ + if( rect.width() < fontMetrics().boundingRect( text() ).width() ) + str = fontMetrics().elidedText( text(), Qt::ElideRight, rect.width() ); + p.drawText( rect, Qt::AlignVCenter | Qt::AlignLeft, str ); + + if( b_arrow ) + { + option.rect.setX( margin ); + option.rect.setWidth( 8 ); + style()->drawPrimitive( QStyle::PE_IndicatorArrowRight, &option, &p ); + } } +QSize LocationButton::sizeHint() const +{ + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this); + QSize s( fontMetrics().boundingRect( text() ).size() ); + /* Add two pixels to width: font metrics are buggy, if you pass text through elidation + with exactly the width of its bounding rect, sometimes it still elides */ + s.setWidth( s.width() + ( 2 * frameWidth ) + ( 2 * PADDING ) + ( b_arrow ? 15 : 0 ) + 2 ); + s.setHeight( QPushButton::sizeHint().height() ); + return s; +} +#undef PADDING