File indexing completed on 2024-05-19 04:48:39
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Daniel Jones <danielcjones@gmail.com> * 0003 * Copyright (c) 2009-2010 Leo Franchi <lfranchi@kde.org> * 0004 * Copyright (c) 2009 Mark Kretschmann <kretschmann@kde.org> * 0005 * Copyright (c) 2010-2011 Ralf Engels <ralf-engels@gmx.de> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify it under * 0008 * the terms of the GNU General Public License as published by the Free Software * 0009 * Foundation; either version 2 of the License, or (at your option) any later * 0010 * version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0013 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0014 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License along with * 0017 * this program. If not, see <http://www.gnu.org/licenses/>. * 0018 ****************************************************************************************/ 0019 0020 #include "DynamicCategory.h" 0021 #include "DynamicView.h" 0022 0023 #include "amarokconfig.h" 0024 #include "core/support/Amarok.h" 0025 #include "core/support/Debug.h" 0026 #include "playlist/PlaylistActions.h" 0027 #include "playlist/PlaylistModelStack.h" 0028 #include "dynamic/DynamicModel.h" 0029 #include "dynamic/BiasedPlaylist.h" 0030 0031 #include <QCheckBox> 0032 #include <QIcon> 0033 #include <QInputDialog> 0034 #include <QLabel> 0035 #include <QPushButton> 0036 #include <QSpinBox> 0037 #include <QStandardPaths> 0038 #include <QToolButton> 0039 0040 #include <KToolBar> 0041 0042 0043 PlaylistBrowserNS::DynamicCategory::DynamicCategory( QWidget* parent ) 0044 : BrowserCategory( QStringLiteral("dynamic category"), parent ) 0045 { 0046 setPrettyName( i18n( "Dynamic Playlists" ) ); 0047 setShortDescription( i18n( "Dynamically updating parameter based playlists" ) ); 0048 setIcon( QIcon::fromTheme( QStringLiteral("dynamic-amarok") ) ); 0049 0050 setLongDescription( i18n( "With a dynamic playlist, Amarok becomes your own personal dj, automatically selecting tracks for you, based on a number of parameters that you select." ) ); 0051 0052 setImagePath( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/hover_info_dynamic_playlists.png") ) ); 0053 0054 // set background 0055 if( AmarokConfig::showBrowserBackgroundImage() ) 0056 setBackgroundImage( imagePath() ); 0057 0058 bool enabled = AmarokConfig::dynamicMode(); 0059 0060 setContentsMargins( 0, 0, 0, 0 ); 0061 0062 BoxWidget* controls2Layout = new BoxWidget( false, this ); 0063 0064 QLabel *label; 0065 label = new QLabel( i18n( "Previous:" ), controls2Layout ); 0066 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); 0067 0068 m_previous = new QSpinBox( controls2Layout ); 0069 m_previous->setMinimum( 0 ); 0070 m_previous->setToolTip( i18n( "Number of previous tracks to remain in the playlist." ) ); 0071 m_previous->setValue( AmarokConfig::previousTracks() ); 0072 connect( m_previous, QOverload<int>::of(&QSpinBox::valueChanged), 0073 this, &PlaylistBrowserNS::DynamicCategory::setPreviousTracks ); 0074 0075 label = new QLabel( i18n( "Upcoming:" ), controls2Layout ); 0076 // label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); 0077 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); 0078 0079 m_upcoming = new QSpinBox( controls2Layout ); 0080 m_upcoming->setMinimum( 1 ); 0081 m_upcoming->setToolTip( i18n( "Number of upcoming tracks to add to the playlist." ) ); 0082 m_upcoming->setValue( AmarokConfig::upcomingTracks() ); 0083 connect( m_upcoming, QOverload<int>::of(&QSpinBox::valueChanged), 0084 this, &PlaylistBrowserNS::DynamicCategory::setUpcomingTracks ); 0085 0086 0087 connect( Amarok::actionCollection()->action( QStringLiteral("playlist_clear") ), &QAction::triggered, this, &DynamicCategory::playlistCleared ); 0088 connect( Amarok::actionCollection()->action( QStringLiteral("disable_dynamic") ), &QAction::triggered, this, &DynamicCategory::playlistCleared, Qt::DirectConnection ); 0089 0090 0091 // -- the tool bar 0092 0093 BoxWidget* presetLayout = new BoxWidget( false, this ); 0094 KToolBar* presetToolbar = new KToolBar( presetLayout ); 0095 presetToolbar->setIconSize( QSize( 22, 22 ) ); 0096 0097 presetToolbar->setToolButtonStyle( Qt::ToolButtonIconOnly ); 0098 presetToolbar->setMovable( false ); 0099 presetToolbar->setFloatable( false ); 0100 presetToolbar->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); 0101 0102 m_onOffButton = new QToolButton( presetToolbar ); 0103 m_onOffButton->setText( i18nc( "Turn dynamic mode on", "On") ); 0104 m_onOffButton->setCheckable( true ); 0105 m_onOffButton->setIcon( QIcon::fromTheme( QStringLiteral("dynamic-amarok") ) ); 0106 m_onOffButton->setToolTip( i18n( "Turn dynamic mode on." ) ); 0107 presetToolbar->addWidget( m_onOffButton ); 0108 0109 m_duplicateButton = new QToolButton( presetToolbar ); 0110 m_duplicateButton->setText( i18n("Duplicates") ); 0111 m_duplicateButton->setCheckable( true ); 0112 m_duplicateButton->setChecked( allowDuplicates() ); 0113 m_duplicateButton->setIcon( QIcon::fromTheme( QStringLiteral("edit-copy") ) ); 0114 m_duplicateButton->setToolTip( i18n( "Allow duplicate songs in result" ) ); 0115 presetToolbar->addWidget( m_duplicateButton ); 0116 0117 m_addButton = new QToolButton( presetToolbar ); 0118 m_addButton->setText( i18n("New") ); 0119 m_addButton->setIcon( QIcon::fromTheme( QStringLiteral("document-new") ) ); 0120 m_addButton->setToolTip( i18n( "New playlist" ) ); 0121 presetToolbar->addWidget( m_addButton ); 0122 0123 m_editButton = new QToolButton( presetToolbar ); 0124 m_editButton->setText( i18n("Edit") ); 0125 m_editButton->setIcon( QIcon::fromTheme( QStringLiteral("document-properties-amarok") ) ); 0126 m_editButton->setToolTip( i18n( "Edit the selected playlist or bias" ) ); 0127 presetToolbar->addWidget( m_editButton ); 0128 0129 m_deleteButton = new QToolButton( presetToolbar ); 0130 m_deleteButton->setText( i18n("Delete") ); 0131 m_deleteButton->setEnabled( false ); 0132 m_deleteButton->setIcon( QIcon::fromTheme( QStringLiteral("edit-delete") ) ); 0133 m_deleteButton->setToolTip( i18n( "Delete the selected playlist or bias") ); 0134 presetToolbar->addWidget( m_deleteButton ); 0135 0136 m_repopulateButton = new QPushButton( presetLayout ); 0137 m_repopulateButton->setText( i18n("Repopulate") ); 0138 m_repopulateButton->setToolTip( i18n("Replace the upcoming tracks with fresh ones.") ); 0139 m_repopulateButton->setIcon( QIcon::fromTheme( QStringLiteral("view-refresh-amarok") ) ); 0140 m_repopulateButton->setEnabled( enabled ); 0141 // m_repopulateButton->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); 0142 QObject::connect( m_repopulateButton, &QAbstractButton::clicked, The::playlistActions(), &Playlist::Actions::repopulateDynamicPlaylist ); 0143 0144 0145 // -- the tree view 0146 0147 m_tree = new DynamicView( this ); 0148 connect( m_tree->selectionModel(), &QItemSelectionModel::selectionChanged, 0149 this, &DynamicCategory::selectionChanged ); 0150 0151 connect( m_onOffButton, &QAbstractButton::toggled, The::playlistActions(), &Playlist::Actions::enableDynamicMode ); 0152 connect( m_duplicateButton, &QAbstractButton::toggled, this, &DynamicCategory::setAllowDuplicates ); 0153 0154 connect( m_addButton, &QAbstractButton::clicked, m_tree, &DynamicView::addPlaylist ); 0155 connect( m_editButton, &QAbstractButton::clicked, m_tree, &DynamicView::editSelected ); 0156 connect( m_deleteButton, &QAbstractButton::clicked, m_tree, &DynamicView::removeSelected ); 0157 0158 navigatorChanged(); 0159 selectionChanged(); 0160 0161 connect( The::playlistActions(), &Playlist::Actions::navigatorChanged, 0162 this, &DynamicCategory::navigatorChanged ); 0163 } 0164 0165 0166 PlaylistBrowserNS::DynamicCategory::~DynamicCategory() 0167 { } 0168 0169 void 0170 PlaylistBrowserNS::DynamicCategory::navigatorChanged() 0171 { 0172 m_onOffButton->setChecked( AmarokConfig::dynamicMode() ); 0173 m_repopulateButton->setEnabled( AmarokConfig::dynamicMode() ); 0174 } 0175 0176 void 0177 PlaylistBrowserNS::DynamicCategory::selectionChanged() 0178 { 0179 DEBUG_BLOCK; 0180 0181 QModelIndexList indexes = m_tree->selectionModel()->selectedIndexes(); 0182 0183 if( indexes.isEmpty() ) 0184 { 0185 m_addButton->setEnabled( true ); 0186 m_editButton->setEnabled( false ); 0187 m_deleteButton->setEnabled( false ); 0188 return; 0189 } 0190 0191 QVariant v = m_tree->model()->data( indexes.first(), Dynamic::DynamicModel::PlaylistRole ); 0192 if( v.isValid() ) 0193 { 0194 m_addButton->setEnabled( true ); 0195 m_editButton->setEnabled( true ); 0196 m_deleteButton->setEnabled( true ); 0197 return; 0198 } 0199 0200 v = m_tree->model()->data( indexes.first(), Dynamic::DynamicModel::BiasRole ); 0201 if( v.isValid() ) 0202 { 0203 m_addButton->setEnabled( true ); 0204 m_editButton->setEnabled( true ); 0205 m_deleteButton->setEnabled( false ); // TODO 0206 return; 0207 } 0208 } 0209 0210 bool 0211 PlaylistBrowserNS::DynamicCategory::allowDuplicates() const 0212 { 0213 return AmarokConfig::dynamicDuplicates(); 0214 } 0215 0216 0217 void 0218 PlaylistBrowserNS::DynamicCategory::playlistCleared() // SLOT 0219 { 0220 The::playlistActions()->enableDynamicMode( false ); 0221 } 0222 0223 void 0224 PlaylistBrowserNS::DynamicCategory::setUpcomingTracks( int n ) // SLOT 0225 { 0226 if( n >= 1 ) 0227 AmarokConfig::setUpcomingTracks( n ); 0228 } 0229 0230 void 0231 PlaylistBrowserNS::DynamicCategory::setPreviousTracks( int n ) // SLOT 0232 { 0233 if( n >= 0 ) 0234 AmarokConfig::setPreviousTracks( n ); 0235 } 0236 0237 void 0238 PlaylistBrowserNS::DynamicCategory::setAllowDuplicates( bool value ) // SLOT 0239 { 0240 if( AmarokConfig::dynamicDuplicates() == value ) 0241 return; 0242 0243 AmarokConfig::setDynamicDuplicates( value ); 0244 AmarokConfig::self()->save(); 0245 0246 m_duplicateButton->setChecked( value ); 0247 } 0248 0249 0250