standardpanel.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * standardpanel.cpp : The "standard" playlist panel : just a treeview
  3.  ****************************************************************************
  4.  * Copyright (C) 2000-2005 the VideoLAN team
  5.  * $Id: ca421c61e252d3c35340a1936c814095c341685c $
  6.  *
  7.  * Authors: Clément Stenac <zorglub@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include "qt4.hpp"
  27. #include "dialogs_provider.hpp"
  28. #include "components/playlist/playlist_model.hpp"
  29. #include "components/playlist/panels.hpp"
  30. #include "util/customwidgets.hpp"
  31. #include <vlc_intf_strings.h>
  32. #include <QPushButton>
  33. #include <QHBoxLayout>
  34. #include <QVBoxLayout>
  35. #include <QHeaderView>
  36. #include <QKeyEvent>
  37. #include <QModelIndexList>
  38. #include <QLabel>
  39. #include <QSpacerItem>
  40. #include <QMenu>
  41. #include <QSignalMapper>
  42. #include <assert.h>
  43. #include "sorting.h"
  44. StandardPLPanel::StandardPLPanel( PlaylistWidget *_parent,
  45.                                   intf_thread_t *_p_intf,
  46.                                   playlist_t *p_playlist,
  47.                                   playlist_item_t *p_root ):
  48.                                   PLPanel( _parent, _p_intf )
  49. {
  50.     model = new PLModel( p_playlist, p_intf, p_root, -1, this );
  51.     QVBoxLayout *layout = new QVBoxLayout();
  52.     layout->setSpacing( 0 ); layout->setMargin( 0 );
  53.     /* Create and configure the QTreeView */
  54.     view = new QVLCTreeView;
  55.     view->setModel( model );
  56.     view->setIconSize( QSize( 20, 20 ) );
  57.     view->setAlternatingRowColors( true );
  58.     view->setAnimated( true );
  59.     view->setSelectionBehavior( QAbstractItemView::SelectRows );
  60.     view->setSelectionMode( QAbstractItemView::ExtendedSelection );
  61.     view->setDragEnabled( true );
  62.     view->setAcceptDrops( true );
  63.     view->setDropIndicatorShown( true );
  64.     view->header()->setSortIndicator( -1 , Qt::AscendingOrder );
  65.     view->setSortingEnabled( true );
  66.     getSettings()->beginGroup("Playlist");
  67.     if( getSettings()->contains( "headerState" ) )
  68.     {
  69.         view->header()->restoreState(
  70.                 getSettings()->value( "headerState" ).toByteArray() );
  71.     }
  72.     else
  73.     {
  74.         /* Configure the size of the header */
  75.         view->header()->resizeSection( 0, 200 );
  76.         view->header()->resizeSection( 1, 80 );
  77.     }
  78.     view->header()->setSortIndicatorShown( true );
  79.     view->header()->setClickable( true );
  80.     view->header()->setContextMenuPolicy( Qt::CustomContextMenu );
  81.     getSettings()->endGroup();
  82.     /* Connections for the TreeView */
  83.     CONNECT( view, activated( const QModelIndex& ) ,
  84.              model,activateItem( const QModelIndex& ) );
  85.     CONNECT( view, rightClicked( QModelIndex , QPoint ),
  86.              this, doPopup( QModelIndex, QPoint ) );
  87.     CONNECT( view->header(), customContextMenuRequested( const QPoint & ),
  88.              this, popupSelectColumn( QPoint ) );
  89.     CONNECT( model, currentChanged( const QModelIndex& ),
  90.              this, handleExpansion( const QModelIndex& ) );
  91.     CONNECT( model, columnsChanged( int ),
  92.             this, checkSortingIndicator( int ) );
  93.     currentRootId = -1;
  94.     CONNECT( parent, rootChanged( int ), this, setCurrentRootId( int ) );
  95.     /* Buttons configuration */
  96.     QHBoxLayout *buttons = new QHBoxLayout;
  97.     /* Add item to the playlist button */
  98.     addButton = new QPushButton;
  99.     addButton->setIcon( QIcon( ":/playlist_add" ) );
  100.     addButton->setMaximumWidth( 30 );
  101.     BUTTONACT( addButton, popupAdd() );
  102.     buttons->addWidget( addButton );
  103.     /* Random 2-state button */
  104.     randomButton = new QPushButton( this );
  105.     randomButton->setIcon( QIcon( ":/shuffle_on" ));
  106.     randomButton->setToolTip( qtr( I_PL_RANDOM ));
  107.     randomButton->setCheckable( true );
  108.     randomButton->setChecked( model->hasRandom() );
  109.     BUTTONACT( randomButton, toggleRandom() );
  110.     buttons->addWidget( randomButton );
  111.     /* Repeat 3-state button */
  112.     repeatButton = new QPushButton( this );
  113.     repeatButton->setToolTip( qtr( "Click to toggle between loop one, loop all" ) );
  114.     repeatButton->setCheckable( true );
  115.     if( model->hasRepeat() )
  116.     {
  117.         repeatButton->setIcon( QIcon( ":/repeat_one" ) );
  118.         repeatButton->setChecked( true );
  119.     }
  120.     else if( model->hasLoop() )
  121.     {
  122.         repeatButton->setIcon( QIcon( ":/repeat_all" ) );
  123.         repeatButton->setChecked( true );
  124.     }
  125.     else
  126.     {
  127.         repeatButton->setIcon( QIcon( ":/repeat_one" ) );
  128.         repeatButton->setChecked( false );
  129.     }
  130.     BUTTONACT( repeatButton, toggleRepeat() );
  131.     buttons->addWidget( repeatButton );
  132.     /* Goto */
  133.     gotoPlayingButton = new QPushButton;
  134.     BUTTON_SET_ACT_I( gotoPlayingButton, "", jump_to,
  135.             qtr( "Show the current item" ), gotoPlayingItem() );
  136.     buttons->addWidget( gotoPlayingButton );
  137.     /* A Spacer and the search possibilities */
  138.     QSpacerItem *spacer = new QSpacerItem( 10, 20 );
  139.     buttons->addItem( spacer );
  140.     QLabel *filter = new QLabel( qtr(I_PL_SEARCH) + " " );
  141.     buttons->addWidget( filter );
  142.     SearchLineEdit *search = new SearchLineEdit( this );
  143.     buttons->addWidget( search );
  144.     filter->setBuddy( search );
  145.     CONNECT( search, textChanged( const QString& ), this, search( const QString& ) );
  146.     /* Finish the layout */
  147.     layout->addWidget( view );
  148.     layout->addLayout( buttons );
  149. //    layout->addWidget( bar );
  150.     setLayout( layout );
  151. }
  152. /* Function to toggle between the Repeat states */
  153. void StandardPLPanel::toggleRepeat()
  154. {
  155.     if( model->hasRepeat() )
  156.     {
  157.         model->setRepeat( false ); model->setLoop( true );
  158.         repeatButton->setIcon( QIcon( ":/repeat_all" ) );
  159.         repeatButton->setChecked( true );
  160.     }
  161.     else if( model->hasLoop() )
  162.     {
  163.         model->setRepeat( false ) ; model->setLoop( false );
  164.         repeatButton->setChecked( false );
  165.         repeatButton->setIcon( QIcon( ":/repeat_one" ) );
  166.     }
  167.     else
  168.     {
  169.         model->setRepeat( true ); model->setLoop( false );
  170.         repeatButton->setChecked( true );
  171.         repeatButton->setIcon( QIcon( ":/repeat_one" ) );
  172.     }
  173. }
  174. /* Function to toggle between the Random states */
  175. void StandardPLPanel::toggleRandom()
  176. {
  177.     bool prev = model->hasRandom();
  178.     model->setRandom( !prev );
  179. }
  180. void StandardPLPanel::gotoPlayingItem()
  181. {
  182.     view->scrollTo( view->currentIndex() );
  183. }
  184. void StandardPLPanel::handleExpansion( const QModelIndex& index )
  185. {
  186.     view->scrollTo( index, QAbstractItemView::EnsureVisible );
  187. }
  188. void StandardPLPanel::setCurrentRootId( int _new )
  189. {
  190.     currentRootId = _new;
  191.     if( currentRootId == THEPL->p_local_category->i_id ||
  192.         currentRootId == THEPL->p_local_onelevel->i_id  )
  193.     {
  194.         addButton->setEnabled( true );
  195.         addButton->setToolTip( qtr(I_PL_ADDPL) );
  196.     }
  197.     else if( ( THEPL->p_ml_category &&
  198.                         currentRootId == THEPL->p_ml_category->i_id ) ||
  199.              ( THEPL->p_ml_onelevel &&
  200.                         currentRootId == THEPL->p_ml_onelevel->i_id ) )
  201.     {
  202.         addButton->setEnabled( true );
  203.         addButton->setToolTip( qtr(I_PL_ADDML) );
  204.     }
  205.     else
  206.         addButton->setEnabled( false );
  207. }
  208. /* PopupAdd Menu for the Add Menu */
  209. void StandardPLPanel::popupAdd()
  210. {
  211.     QMenu popup;
  212.     if( currentRootId == THEPL->p_local_category->i_id ||
  213.         currentRootId == THEPL->p_local_onelevel->i_id )
  214.     {
  215.         popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT( simplePLAppendDialog()) );
  216.         popup.addAction( qtr(I_PL_ADDDIR), THEDP, SLOT( PLAppendDir()) );
  217.         popup.addAction( qtr(I_OP_ADVOP), THEDP, SLOT( PLAppendDialog()) );
  218.     }
  219.     else if( ( THEPL->p_ml_category &&
  220.                 currentRootId == THEPL->p_ml_category->i_id ) ||
  221.              ( THEPL->p_ml_onelevel &&
  222.                 currentRootId == THEPL->p_ml_onelevel->i_id ) )
  223.     {
  224.         popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT( simpleMLAppendDialog()) );
  225.         popup.addAction( qtr(I_PL_ADDDIR), THEDP, SLOT( MLAppendDir() ) );
  226.         popup.addAction( qtr(I_OP_ADVOP), THEDP, SLOT( MLAppendDialog() ) );
  227.     }
  228.     popup.exec( QCursor::pos() - addButton->mapFromGlobal( QCursor::pos() )
  229.                         + QPoint( 0, addButton->height() ) );
  230. }
  231. /* Set sortingindicator to -1 if it's on column thats removed,
  232.  * else check that it's still showing on correct column
  233.  */
  234. void StandardPLPanel::checkSortingIndicator( int meta )
  235. {
  236.     int index=0;
  237.     if( view->header()->isSortIndicatorShown() == false )
  238.         return;
  239.     int sortIndex = view->header()->sortIndicatorSection();
  240.     if( sortIndex < 0 || sortIndex > view->header()->count() || meta == 0 )
  241.         return;
  242.     int _meta = meta;
  243.     while( _meta )
  244.     {
  245.         if( _meta & model->shownFlags() )
  246.             index++;
  247.         _meta >>= 1;
  248.     }
  249.     /* Adding column */
  250.     if( model->shownFlags() & meta )
  251.     {
  252.         /* If column is added before sortIndex, move it one to right*/
  253.         if( sortIndex >= index )
  254.         {
  255.             sortIndex += 1;
  256.         }
  257.     } else {
  258.         /* Column removed */
  259.         if( sortIndex == index )
  260.         {
  261.             sortIndex = -1;
  262.         } else if( sortIndex > index )
  263.         {
  264.             /* Move indicator left one step*/
  265.             sortIndex -= 1;
  266.         }
  267.     }
  268.     view->header()->setSortIndicator( sortIndex  ,
  269.                 view->header()->sortIndicatorOrder() );
  270. }
  271. void StandardPLPanel::popupSelectColumn( QPoint pos )
  272. {
  273.     ContextUpdateMapper = new QSignalMapper(this);
  274.     QMenu selectColMenu;
  275.     int i_column = 1;
  276.     for( i_column = 1; i_column != COLUMN_END; i_column<<=1 )
  277.     {
  278.         QAction* option = selectColMenu.addAction(
  279.             qfu( psz_column_title( i_column ) ) );
  280.         option->setCheckable( true );
  281.         option->setChecked( model->shownFlags() & i_column );
  282.         ContextUpdateMapper->setMapping( option, i_column );
  283.         CONNECT( option, triggered(), ContextUpdateMapper, map() );
  284.     }
  285.     CONNECT( ContextUpdateMapper, mapped( int ),  model, viewchanged( int ) );
  286.     selectColMenu.exec( QCursor::pos() );
  287. }
  288. /* Search in the playlist */
  289. void StandardPLPanel::search( const QString& searchText )
  290. {
  291.     model->search( searchText );
  292. }
  293. void StandardPLPanel::doPopup( QModelIndex index, QPoint point )
  294. {
  295.     if( !index.isValid() ) return;
  296.     QItemSelectionModel *selection = view->selectionModel();
  297.     QModelIndexList list = selection->selectedIndexes();
  298.     model->popup( index, point, list );
  299. }
  300. /* Set the root of the new Playlist */
  301. /* This activated by the selector selection */
  302. void StandardPLPanel::setRoot( int i_root_id )
  303. {
  304.     QPL_LOCK;
  305.     playlist_item_t *p_item = playlist_ItemGetById( THEPL, i_root_id );
  306.     assert( p_item );
  307.     p_item = playlist_GetPreferredNode( THEPL, p_item );
  308.     assert( p_item );
  309.     QPL_UNLOCK;
  310.     model->rebuild( p_item );
  311. }
  312. void StandardPLPanel::removeItem( int i_id )
  313. {
  314.     model->removeItem( i_id );
  315. }
  316. /* Delete and Suppr key remove the selection
  317.    FilterKey function and code function */
  318. void StandardPLPanel::keyPressEvent( QKeyEvent *e )
  319. {
  320.     switch( e->key() )
  321.     {
  322.     case Qt::Key_Back:
  323.     case Qt::Key_Delete:
  324.         deleteSelection();
  325.         break;
  326.     }
  327. }
  328. void StandardPLPanel::deleteSelection()
  329. {
  330.     QItemSelectionModel *selection = view->selectionModel();
  331.     QModelIndexList list = selection->selectedIndexes();
  332.     model->doDelete( list );
  333. }
  334. StandardPLPanel::~StandardPLPanel()
  335. {
  336.     getSettings()->beginGroup("Playlist");
  337.     getSettings()->setValue( "headerState", view->header()->saveState() );
  338.     getSettings()->endGroup();
  339. }