Warning, file /multimedia/juk/playlist.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /** 0002 * Copyright (C) 2002-2004 Scott Wheeler <wheeler@kde.org> 0003 * Copyright (C) 2007 Michael Pyne <mpyne@kde.org> 0004 * 0005 * This program is free software; you can redistribute it and/or modify it under 0006 * the terms of the GNU General Public License as published by the Free Software 0007 * Foundation; either version 2 of the License, or (at your option) any later 0008 * version. 0009 * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU General Public License along with 0015 * this program. If not, see <http://www.gnu.org/licenses/>. 0016 */ 0017 0018 #ifndef JUK_PLAYLIST_H 0019 #define JUK_PLAYLIST_H 0020 0021 #include <QVector> 0022 #include <QEvent> 0023 #include <QList> 0024 #include <QTreeWidget> 0025 #include <QFuture> 0026 0027 #include "covermanager.h" 0028 #include "stringhash.h" 0029 #include "playlistsearch.h" 0030 #include "tagguesser.h" 0031 #include "playlistinterface.h" 0032 #include "filehandle.h" 0033 #include "juk_debug.h" 0034 0035 class KActionMenu; 0036 0037 class QAction; 0038 class QFileInfo; 0039 class QMimeData; 0040 class QTimer; 0041 0042 class WebImageFetcher; 0043 class PlaylistItem; 0044 class PlaylistCollection; 0045 class CollectionListItem; 0046 0047 typedef QVector<PlaylistItem *> PlaylistItemList; 0048 0049 class Playlist : public QTreeWidget, public PlaylistInterface 0050 { 0051 Q_OBJECT 0052 0053 public: 0054 0055 explicit Playlist(PlaylistCollection *collection, const QString &name = QString(), 0056 const QString &iconName = "audio-midi"); 0057 Playlist(PlaylistCollection *collection, const PlaylistItemList &items, 0058 const QString &name = QString(), const QString &iconName = "audio-midi"); 0059 Playlist(PlaylistCollection *collection, const QFileInfo &playlistFile, 0060 const QString &iconName = "audio-midi"); 0061 0062 /** 0063 * This constructor should generally only be used either by the cache 0064 * restoration methods or by subclasses that want to handle calls to 0065 * PlaylistCollection::setupPlaylist() differently. 0066 * 0067 * @param extraColumns is used to preallocate columns for subclasses that 0068 * need them (since extra columns are assumed to start from 0). extraColumns 0069 * should be equal to columnOffset() (we can't use columnOffset until the 0070 * ctor has run). 0071 */ 0072 Playlist(PlaylistCollection *collection, bool delaySetup, int extraColumns = 0); 0073 0074 virtual ~Playlist(); 0075 0076 0077 // The following group of functions implement the PlaylistInterface API. 0078 0079 virtual QString name() const override; 0080 virtual FileHandle currentFile() const override; 0081 virtual int count() const override { return model()->rowCount(); } 0082 virtual int time() const override { return m_time; } 0083 virtual void playNext() override; 0084 virtual void playPrevious() override; 0085 virtual void stop() override; 0086 0087 /** 0088 * Plays the top item of the playlist. 0089 */ 0090 void playFirst(); 0091 0092 /** 0093 * Plays the next album in the playlist. Only useful when in album random 0094 * play mode. 0095 */ 0096 void playNextAlbum(); 0097 0098 /** 0099 * Saves the file to the currently set file name. If there is no filename 0100 * currently set, the default behavior is to prompt the user for a file 0101 * name. 0102 */ 0103 virtual void save(); 0104 0105 /** 0106 * Standard "save as". Prompts the user for a location where to save the 0107 * playlist to. 0108 */ 0109 virtual void saveAs(); 0110 0111 /** 0112 * Removes \a item from the Playlist, but not from the disk. 0113 * 0114 * Since the GUI updates after an item is cleared, you should use clearItems() if you have 0115 * a list of items to remove, as that will remove the whole batch before updating 0116 * other components/GUI to the change. 0117 */ 0118 virtual void clearItem(PlaylistItem *item); 0119 0120 /** 0121 * Remove \a items from the playlist and emit a signal indicating 0122 * that the number of items in the list has changed. 0123 */ 0124 virtual void clearItems(const PlaylistItemList &items); 0125 0126 /** 0127 * Accessor function to return a pointer to the currently playing file. 0128 * 0129 * @return 0 if no file is playing, otherwise a pointer to the PlaylistItem 0130 * of the track that is currently playing. 0131 */ 0132 static PlaylistItem *playingItem(); 0133 0134 /** 0135 * All of the (media) files in the list. 0136 */ 0137 QStringList files() const; 0138 0139 /** 0140 * Returns a list of all of the items in the playlist. 0141 */ 0142 virtual PlaylistItemList items(); 0143 0144 /** 0145 * Returns a list of all of the \e visible items in the playlist. 0146 */ 0147 PlaylistItemList visibleItems(); 0148 0149 /** 0150 * Returns a list of the currently selected items. 0151 */ 0152 PlaylistItemList selectedItems(); 0153 0154 /** 0155 * Returns properly casted first child item in list. 0156 */ 0157 PlaylistItem *firstChild() const; 0158 0159 /** 0160 * Allow duplicate files in the playlist. 0161 */ 0162 void setAllowDuplicates(bool allow) { m_allowDuplicates = allow; } 0163 0164 /** 0165 * This is being used as a mini-factory of sorts to make the construction 0166 * of PlaylistItems virtual. In this case it allows for the creation of 0167 * both PlaylistItems and CollectionListItems. 0168 */ 0169 virtual PlaylistItem *createItem(const FileHandle &file, 0170 QTreeWidgetItem *after = nullptr); 0171 0172 /** 0173 * This is implemented as a template method to allow subclasses to 0174 * instantiate their PlaylistItem subclasses using the same method. 0175 */ 0176 template <class ItemType> 0177 ItemType *createItem(const FileHandle &file, 0178 QTreeWidgetItem *after = nullptr); 0179 0180 virtual void createItems(const PlaylistItemList &siblings, PlaylistItem *after = nullptr); 0181 0182 /** 0183 * This handles adding files of various types -- music, playlist or directory 0184 * files. Music files that are found will be added to this playlist. New 0185 * playlist files that are found will result in new playlists being created. 0186 * 0187 * Note that this should not be used in the case of adding *only* playlist 0188 * items since it has the overhead of checking to see if the file is a playlist 0189 * or directory first. 0190 */ 0191 virtual void addFiles(const QStringList &files, PlaylistItem *after = nullptr); 0192 0193 /** 0194 * Returns the file name associated with this playlist (an m3u file) or 0195 * an empty QString if no such file exists. 0196 */ 0197 QString fileName() const { return m_fileName; } 0198 0199 /** 0200 * Sets the file name to be associated with this playlist; this file should 0201 * have the "m3u" extension. 0202 */ 0203 void setFileName(const QString &n) { m_fileName = n; } 0204 0205 /** 0206 * Hides column \a c. If \a updateSearch is true then a signal that the 0207 * visible columns have changed will be emitted and things like the search 0208 * will be updated. 0209 */ 0210 void hideColumn(int c, bool updateSearch = true); 0211 0212 /** 0213 * Shows column \a c. If \a updateSearch is true then a signal that the 0214 * visible columns have changed will be emitted and things like the search 0215 * will be updated. 0216 */ 0217 void showColumn(int c, bool updateSearch = true); 0218 0219 void sortByColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); 0220 0221 /** 0222 * This sets a name for the playlist that is \e different from the file name. 0223 */ 0224 void setName(const QString &n); 0225 0226 /** 0227 * Returns the KActionMenu that allows this to be embedded in menus outside 0228 * of the playlist. 0229 */ 0230 KActionMenu *columnVisibleAction() const { return m_columnVisibleAction; } 0231 0232 /** 0233 * Set item to be the playing item. If \a item is null then this will clear 0234 * the playing indicator. 0235 */ 0236 void setPlaying(PlaylistItem *item, bool addToHistory = true); 0237 0238 /** 0239 * Returns true if this playlist is currently playing. 0240 */ 0241 bool playing() const override; 0242 0243 /** 0244 * This forces an update of the left most visible column, but does not save 0245 * the settings for this. 0246 */ 0247 void updateLeftColumn(); 0248 0249 /** 0250 * Returns the leftmost visible column of the listview. 0251 */ 0252 int leftColumn() const { return m_leftColumn; } 0253 0254 /** 0255 * Sets the items in the list to be either visible based on the value of 0256 * visible. This is useful for search operations and such. 0257 */ 0258 void setItemsVisible(const QModelIndexList &indexes, bool visible = true); 0259 0260 /** 0261 * Returns the search associated with this list, or an empty search if one 0262 * has not yet been set. 0263 */ 0264 PlaylistSearch* search() const { return m_search; } 0265 0266 /** 0267 * Set the search associated with this playlist. 0268 */ 0269 void setSearch(PlaylistSearch* s); 0270 0271 /** 0272 * If the search is disabled then all items will be shown, not just those that 0273 * match the current search. 0274 */ 0275 void setSearchEnabled(bool searchEnabled); 0276 0277 /** 0278 * Subclasses of Playlist which add new columns will set this value to 0279 * specify how many of those columns exist. This allows the Playlist 0280 * class to do some internal calculations on the number and positions 0281 * of columns. 0282 */ 0283 virtual int columnOffset() const { return 0; } 0284 0285 /** 0286 * Some subclasses of Playlist will be "read only" lists (i.e. the history 0287 * playlist). This is a way for those subclasses to indicate that to the 0288 * Playlist internals. 0289 */ 0290 virtual bool readOnly() const { return false; } 0291 0292 /** 0293 * Returns true if it's possible to reload this playlist. 0294 */ 0295 virtual bool canReload() const { return !m_fileName.isEmpty(); } 0296 0297 /** 0298 * Returns true if the playlist is a search playlist and the search should be 0299 * editable. 0300 */ 0301 virtual bool searchIsEditable() const { return false; } 0302 0303 /** 0304 * Synchronizes the playing item in this playlist with the playing item 0305 * in \a playlist. If \a setMaster is true, this list will become the source 0306 * for determining the next item. 0307 */ 0308 void synchronizePlayingItems(Playlist *playlist, bool setMaster); 0309 0310 /** 0311 * Synchronizes the playing item in this playlist with the playing item 0312 * in \a sources. If \a setMaster is true, this list will become the source 0313 * for determining the next item. 0314 */ 0315 void synchronizePlayingItems(const PlaylistList &sources, bool setMaster); 0316 0317 /** 0318 * Playlists have a common set of shared settings such as visible columns 0319 * that should be applied just before the playlist is shown. Calling this 0320 * method applies those. 0321 */ 0322 void applySharedSettings(); 0323 0324 void read(QDataStream &s); 0325 0326 static void setShuttingDown() { m_shuttingDown = true; } 0327 0328 void playlistItemsChanged() override; 0329 0330 public slots: 0331 /** 0332 * Remove the currently selected items from the playlist and disk. 0333 */ 0334 void slotRemoveSelectedItems() { removeFromDisk(selectedItems()); } 0335 0336 /* 0337 * The edit slots are required to use the canonical names so that they are 0338 * detected by the application wide framework. 0339 */ 0340 virtual void cut() { copy(); clear(); } 0341 0342 /** 0343 * Puts a list of URLs pointing to the files in the current selection on the 0344 * clipboard. 0345 */ 0346 virtual void copy(); 0347 0348 /** 0349 * Checks the clipboard for local URLs to be inserted into this playlist. 0350 */ 0351 virtual void paste(); 0352 0353 /** 0354 * Removes the selected items from the list, but not the disk. 0355 * 0356 * @see clearItem() 0357 * @see clearItems() 0358 */ 0359 virtual void clear(); 0360 0361 /** 0362 * Refreshes the tags of the selection from disk, or all of the files in the 0363 * list if there is no selection. 0364 */ 0365 virtual void slotRefresh(); 0366 0367 /** 0368 * Opens the containing folder of the selected files. 0369 */ 0370 virtual void slotOpenItemDir(); 0371 0372 void slotGuessTagInfo(TagGuesser::Type type); 0373 0374 /** 0375 * Renames the selected items' files based on their tags contents. 0376 * 0377 * @see PlaylistItem::renameFile() 0378 */ 0379 void slotRenameFile(); 0380 0381 /** 0382 * Select a track to play after being stopped. 0383 * 0384 * @see playNext() 0385 */ 0386 void slotBeginPlayback(); 0387 0388 /** 0389 * Sets the cover of the selected items, pass in true if you want to load from the local system, 0390 * false if you want to load from the internet. 0391 */ 0392 void slotAddCover(bool fromLocal); 0393 0394 /** 0395 * Shows a large image of the cover 0396 */ 0397 void slotViewCover(); 0398 0399 /** 0400 * Removes covers from the selected items 0401 */ 0402 void slotRemoveCover(); 0403 0404 /** 0405 * Shows the cover manager GUI dialog 0406 */ 0407 void slotShowCoverManager(); 0408 0409 /** 0410 * Reload the playlist contents from the m3u file. 0411 */ 0412 virtual void slotReload(); 0413 0414 /** 0415 * Ensures the random sequence of playlist items is built. Ignored if we're 0416 * not in random playback mode so it is safe to call in any mode. 0417 */ 0418 void refillRandomList(); 0419 0420 /** 0421 * Tells the listview that the next time that it paints that the weighted 0422 * column widths must be recalculated. If this is called without a column 0423 * all visible columns are marked as dirty. 0424 */ 0425 void slotWeightDirty(int column = -1); 0426 0427 void slotShowPlaying(); 0428 0429 void slotColumnResizeModeChanged(); 0430 0431 protected: 0432 /** 0433 * Remove \a items from the playlist and disk. This will ignore items that 0434 * are not actually in the list. 0435 */ 0436 void removeFromDisk(const PlaylistItemList &items); 0437 0438 /** 0439 * Adds and removes items from this Playlist as necessary to ensure that 0440 * the same items are present in this Playlist as in @p itemList. 0441 * 0442 * No ordering guarantees are imposed, just that the playlist will have the 0443 * same items as in the given list afterwards. 0444 */ 0445 void synchronizeItemsTo(const PlaylistItemList &itemList); 0446 0447 /** 0448 * Completes the actions with the parent PlaylistCollection needed to 0449 * actually start playing back the given PlaylistItem. 0450 */ 0451 virtual void beginPlayingItem(PlaylistItem *itemToPlay); 0452 0453 // the following are all reimplemented from base classes 0454 0455 virtual bool eventFilter(QObject *watched, QEvent *e) override; 0456 virtual void keyPressEvent(QKeyEvent *e) override; 0457 QStringList mimeTypes() const override; 0458 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0459 QMimeData* mimeData(const QList<QTreeWidgetItem *> items) const override; 0460 #else 0461 QMimeData* mimeData(const QList<QTreeWidgetItem *> &items) const override; 0462 #endif 0463 virtual bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override; 0464 virtual void dropEvent(QDropEvent *e) override; 0465 virtual void dragEnterEvent(QDragEnterEvent *e) override; 0466 virtual void showEvent(QShowEvent *e) override; 0467 virtual void paintEvent(QPaintEvent *pe) override; 0468 virtual void resizeEvent(QResizeEvent *re) override; 0469 0470 virtual void drawRow(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const override; 0471 0472 virtual void insertItem(QTreeWidgetItem *item); 0473 virtual void takeItem(QTreeWidgetItem *item); 0474 0475 virtual bool hasItem(const QString &file) const { return m_members.contains(file); } 0476 0477 /** 0478 * Do some final initialization of created items. Notably ensure that they 0479 * are shown or hidden based on the contents of the current PlaylistSearch. 0480 * 0481 * This is called by the PlaylistItem constructor. 0482 */ 0483 void setupItem(PlaylistItem *item); 0484 0485 /** 0486 * Forwards the call to the parent to enable or disable automatic deletion 0487 * of tree view playlists. Used by CollectionListItem. 0488 */ 0489 void setDynamicListsFrozen(bool frozen); 0490 0491 template <class ItemType, class SiblingType> 0492 ItemType *createItem(SiblingType *sibling, ItemType *after = nullptr); 0493 0494 /** 0495 * As a template this allows us to use the same code to initialize the items 0496 * in subclasses. ItemType should be a PlaylistItem subclass. 0497 */ 0498 template <template <typename> class Container, class ItemType, class SiblingType> 0499 void createItems(const Container<SiblingType *> &siblings, ItemType *after = nullptr); 0500 0501 protected slots: 0502 void slotPopulateBackMenu() const; 0503 void slotPlayFromBackMenu(QAction *); 0504 0505 signals: 0506 0507 /** 0508 * This is connected to the PlaylistBox::Item to let it know when the 0509 * playlist's name has changed. 0510 */ 0511 void signalNameChanged(const QString &name); 0512 0513 /** 0514 * This signal is emitted just before a playlist item is removed from the 0515 * list allowing for any cleanup that needs to happen. Typically this 0516 * is used to remove the item from the history and safeguard against 0517 * dangling pointers. 0518 */ 0519 void signalAboutToRemove(PlaylistItem *item); 0520 0521 void signalEnableDirWatch(bool enable); 0522 0523 void signalPlaylistItemsDropped(Playlist *p); 0524 0525 void signalMoveFocusAway(); 0526 0527 private: 0528 // Common constructor routines, inherited by other constructors 0529 Playlist( 0530 bool delaySetup, const QString &name, 0531 PlaylistCollection *collection, const QString &iconName, 0532 int extraCols); 0533 0534 void setup(int numColumnsToReserve); 0535 0536 /** 0537 * This function is called to let the user know that JuK has automatically enabled 0538 * manual column width adjust mode. 0539 */ 0540 void notifyUserColumnWidthModeChanged(); 0541 0542 /** 0543 * Load the playlist from a file. \a fileName should be the absolute path. 0544 * \a fileInfo should point to the same file as \a fileName. This is a 0545 * little awkward API-wise, but keeps us from throwing away useful 0546 * information. 0547 */ 0548 void loadFile(const QString &fileName, const QFileInfo &fileInfo); 0549 0550 /** 0551 * Writes \a text to \a item in \a column. This is used by the inline tag 0552 * editor. Returns false if the tag update failed. 0553 */ 0554 bool editTag(PlaylistItem *item, const QString &text, int column); 0555 0556 /** 0557 * Returns the index of the left most visible column in the playlist. 0558 * 0559 * \see isColumnHidden() 0560 */ 0561 int leftMostVisibleColumn() const; 0562 0563 /// Creates the context menu on demand 0564 void createPlaylistRMBMenu(); 0565 0566 /** 0567 * This method is used internally to provide the backend to the other item 0568 * lists. 0569 * 0570 * \see items() 0571 * \see visibleItems() 0572 * \see selectedItems() 0573 */ 0574 PlaylistItemList items(QTreeWidgetItemIterator::IteratorFlags flags); 0575 0576 /** 0577 * Build the column "weights" for the weighted width mode. 0578 */ 0579 void calculateColumnWeights(); 0580 0581 void addPlaylistFile(const QString &m3uFile); 0582 QFuture<void> addFilesFromDirectory(const QString &dirPath); 0583 QFuture<void> addUntypedFile(const QString &file, PlaylistItem *after = nullptr); 0584 void cleanupAfterAllFileLoadsCompleted(); 0585 void addFilesFromMimeData(const QMimeData *urls, PlaylistItem *after = nullptr); 0586 0587 void redisplaySearch() { setSearch(m_search); } 0588 0589 /** 0590 * Sets the cover for items to the cover identified by id. 0591 */ 0592 void refreshAlbums(const PlaylistItemList &items, coverKey id = CoverManager::NoMatch); 0593 0594 void refreshAlbum(const QString &artist, const QString &album); 0595 0596 void updatePlaying() const; 0597 0598 /** 0599 * This function should be called when item is deleted to ensure that any 0600 * internal bookkeeping is performed. It is automatically called by 0601 * PlaylistItem::~PlaylistItem and by clearItem() and clearItems(). 0602 */ 0603 void updateDeletedItem(PlaylistItem *item); 0604 0605 /** 0606 * Used as a helper to implement template<> createItem(). This grabs the 0607 * CollectionListItem for file if it exists, otherwise it creates a new one and 0608 * returns that. If nullptr is returned then some kind of error occurred, 0609 * and you should probably do nothing with the FileHandle you have. 0610 */ 0611 CollectionListItem *collectionListItem(const FileHandle &file); 0612 0613 /** 0614 * This class is used internally to store settings that are shared by all 0615 * of the playlists, such as column order. It is implemented as a singleton. 0616 */ 0617 class SharedSettings; 0618 0619 private slots: 0620 0621 /** 0622 * Handle the necessary tasks needed to create and setup the playlist that 0623 * don't need to happen in the ctor, such as setting up the columns, 0624 * initializing the RMB menu, and setting up signal/slot connections. 0625 * 0626 * Used to be a subclass of K3ListView::polish() but the timing of the 0627 * call is not consistent and therefore lead to crashes. 0628 */ 0629 void slotInitialize(int numColumnsToReserve); 0630 0631 void slotUpdateColumnWidths(); 0632 0633 void slotAddToUpcoming(); 0634 0635 /** 0636 * Show the RMB menu. Matches the signature for the signal 0637 * QListView::contextMenuRequested(). 0638 */ 0639 void slotShowRMBMenu(const QPoint &point); 0640 0641 /** 0642 * This slot is called when the inline tag editor has completed its editing 0643 * and starts the process of renaming the values. 0644 */ 0645 void slotInlineEditDone(QTreeWidgetItem *, int column); 0646 0647 /** 0648 * The image fetcher will update the cover asynchronously, this internal 0649 * slot is called when it happens. 0650 */ 0651 void slotCoverChanged(int coverId); 0652 0653 /** 0654 * Moves the column \a from to the position \a to. This matches the signature 0655 * for the signal QHeader::indexChange(). 0656 */ 0657 void slotColumnOrderChanged(int, int from, int to); 0658 0659 /** 0660 * Toggles a columns visible status. Useful for KActions. 0661 * 0662 * \see hideColumn() 0663 * \see showColumn() 0664 */ 0665 void slotToggleColumnVisible(QAction *action); 0666 0667 /** 0668 * Prompts the user to create a new playlist with from the selected items. 0669 */ 0670 void slotCreateGroup(); 0671 0672 /** 0673 * This slot is called when the user drags the slider in the listview header 0674 * to manually set the size of the column. 0675 */ 0676 void columnResized(int column, int oldSize, int newSize); 0677 0678 void slotPlayCurrent(); 0679 void slotUpdateTime(); 0680 0681 private: 0682 friend class PlaylistItem; 0683 0684 PlaylistCollection *m_collection = nullptr; 0685 StringHash m_members; 0686 0687 // This is only defined if the playlist name is something other than the 0688 // file name. 0689 QString m_playlistName; 0690 QString m_fileName; 0691 0692 int m_time = 0; 0693 bool m_allowDuplicates = true; 0694 0695 /** 0696 * The average minimum widths of columns to be used in balancing calculations. 0697 */ 0698 QVector<int> m_columnWeights; 0699 QVector<int> m_columnFixedWidths; 0700 QVector<int> m_weightDirty; 0701 KActionMenu *m_columnVisibleAction = nullptr; 0702 bool m_columnWidthModeChanged = false; 0703 bool m_disableColumnWidthUpdates = true; 0704 bool m_widthsDirty = true; 0705 bool m_applySharedSettings = true; 0706 0707 /// Used for random play and album random play 0708 PlaylistItemList m_randomSequence; 0709 QTimer *m_refillDebounce; 0710 0711 PlaylistSearch* m_search; 0712 bool m_searchEnabled = true; 0713 0714 int m_itemsLoading = 0; /// Count of pending file loads outstanding 0715 bool m_blockDataChanged = false; 0716 0717 QAction *m_rmbEdit = nullptr; 0718 QMenu *m_rmbMenu = nullptr; 0719 QMenu *m_headerMenu = nullptr; 0720 WebImageFetcher *m_fetcher = nullptr; 0721 0722 /** 0723 * This is used to indicate if the list of visible items has changed (via a 0724 * call to setVisibleItems()) while random play is playing. 0725 */ 0726 static bool m_visibleChanged; 0727 static PlaylistItemList m_history; 0728 static bool m_shuttingDown; 0729 static int m_leftColumn; 0730 static QVector<PlaylistItem *> m_backMenuItems; 0731 }; 0732 0733 typedef QVector<Playlist *> PlaylistList; 0734 0735 bool processEvents(); 0736 0737 QDataStream &operator<<(QDataStream &s, const Playlist &p); 0738 QDataStream &operator>>(QDataStream &s, Playlist &p); 0739 0740 // template method implementations 0741 0742 template <class ItemType> 0743 ItemType *Playlist::createItem(const FileHandle &file, QTreeWidgetItem *after) 0744 { 0745 CollectionListItem *item = collectionListItem(file); 0746 if(item && (!m_members.insert(file.absFilePath()) || m_allowDuplicates)) { 0747 auto i = new ItemType(item, this, after); 0748 setupItem(i); 0749 return i; 0750 } 0751 else 0752 return nullptr; 0753 } 0754 0755 template <class ItemType, class SiblingType> 0756 ItemType *Playlist::createItem(SiblingType *sibling, ItemType *after) 0757 { 0758 m_disableColumnWidthUpdates = true; 0759 0760 if(!m_members.insert(sibling->file().absFilePath()) || m_allowDuplicates) { 0761 after = new ItemType(sibling->collectionItem(), this, after); 0762 setupItem(after); 0763 } 0764 0765 m_disableColumnWidthUpdates = false; 0766 0767 return after; 0768 } 0769 0770 template <template <typename> class Container, class ItemType, class SiblingType> 0771 void Playlist::createItems(const Container<SiblingType *> &siblings, ItemType *after) 0772 { 0773 if(siblings.isEmpty()) 0774 return; 0775 0776 foreach(SiblingType *sibling, siblings) 0777 after = createItem(sibling, after); 0778 0779 playlistItemsChanged(); 0780 slotWeightDirty(); 0781 } 0782 0783 #endif 0784 0785 // vim: set et sw=4 tw=0 sta: