From 95894b0ff145201ae83c51ea63e5bc26caff9ba2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 09:56:28 +0200 Subject: [PATCH 001/552] Create button bar stub --- src/widget/wbuttonbar.cpp | 11 +++++++++++ src/widget/wbuttonbar.h | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/widget/wbuttonbar.cpp create mode 100644 src/widget/wbuttonbar.h diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp new file mode 100644 index 00000000000..21ac1405845 --- /dev/null +++ b/src/widget/wbuttonbar.cpp @@ -0,0 +1,11 @@ +#include "wbuttonbar.h" + +WButtonBar::WButtonBar(QWidget *parent) + : QWidget(parent) { + +} + +void WButtonBar::addItem(QIcon icon, QVariant title, QVariant data) { + +} + diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h new file mode 100644 index 00000000000..1620e84025c --- /dev/null +++ b/src/widget/wbuttonbar.h @@ -0,0 +1,22 @@ +#ifndef WBUTTONBAR_H +#define WBUTTONBAR_H + +#include +#include + +class WButtonBar : QWidget +{ + Q_OBJECT + public: + WButtonBar(QWidget* parent = nullptr); + + void addItem(QIcon icon, QVariant title, QVariant data); + + signals: + + void clicked(QVariant data); + + QLayout* m_pLayout; +}; + +#endif // WBUTTONBAR_H From cbed0842c3622f4fc840c133f43c042bfb3e4d37 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 09:57:00 +0200 Subject: [PATCH 002/552] Create LibraryViewManager and some basic functions --- src/library/libraryviewmanager.cpp | 24 +++++++++++++++++ src/library/libraryviewmanager.h | 43 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/library/libraryviewmanager.cpp create mode 100644 src/library/libraryviewmanager.h diff --git a/src/library/libraryviewmanager.cpp b/src/library/libraryviewmanager.cpp new file mode 100644 index 00000000000..5200fd4b2a4 --- /dev/null +++ b/src/library/libraryviewmanager.cpp @@ -0,0 +1,24 @@ +#include "libraryviewmanager.h" + +LibraryViewManager::LibraryViewManager(QObject* parent) + : QObject(parent) { + +} + +void LibraryViewManager::addFeature(LibraryViewFeature* feature) { + // Every feature ID will be it's position in the features' vector + int ID = m_pFeatures.size(); + m_pFeatures.append(feature); + + m_pLeftPane->addWidget(feature->getLeftPane()); + + for (QStackedWidget* stack : m_pRightPane) { + stack->addWidget(feature->getRightPane()); + } + + m_pButtonBar->addItem(feature->getIcon(), feature->getTitle(), ID); +} + +void LibraryViewManager::onFocusChange() { + +} diff --git a/src/library/libraryviewmanager.h b/src/library/libraryviewmanager.h new file mode 100644 index 00000000000..709d21923a5 --- /dev/null +++ b/src/library/libraryviewmanager.h @@ -0,0 +1,43 @@ +#ifndef LIBRARYVIEWMANAGER_H +#define LIBRARYVIEWMANAGER_H + +#include +#include +#include + +#include "library/libraryviewfeature.h" +#include "widget/wbuttonbar.h" + +class LibraryViewManager : public QObject { + Q_OBJECT + + public: + + LibraryViewManager(QObject* parent = nullptr); + + inline void setButtonBar(WButtonBar* button) { + m_pButtonBar = button; + } + inline void setLeftPane(QStackedWidget* pane) { + m_pLeftPane = pane; + } + inline void addRightPane(QStackedWidget* pane) { + m_pRightPane.append(pane); + } + + void addFeature(LibraryViewFeature* feature); + void featureSelected(); + + private: + + WButtonBar* m_pButtonBar; + QStackedWidget* m_pLeftPane; + QVector m_pRightPane; + QVector m_pFeatures; + + private slots: + + void onFocusChange(); +}; + +#endif // LIBRARYVIEWMANAGER_H From 471c011ca09c505c5a8be07c9bc99eac2acc436b Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 09:57:24 +0200 Subject: [PATCH 003/552] Create LibraryViewFeature interface and some basic methods --- src/library/libraryviewfeature.cpp | 6 ++++++ src/library/libraryviewfeature.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/library/libraryviewfeature.cpp create mode 100644 src/library/libraryviewfeature.h diff --git a/src/library/libraryviewfeature.cpp b/src/library/libraryviewfeature.cpp new file mode 100644 index 00000000000..8ff7bbf7f05 --- /dev/null +++ b/src/library/libraryviewfeature.cpp @@ -0,0 +1,6 @@ +#include "libraryviewfeature.h" + +LibraryViewFeature::LibraryViewFeature() { + +} + diff --git a/src/library/libraryviewfeature.h b/src/library/libraryviewfeature.h new file mode 100644 index 00000000000..0b49285e9d3 --- /dev/null +++ b/src/library/libraryviewfeature.h @@ -0,0 +1,29 @@ +#ifndef LIBRARYVIEWFEAUTRE_H +#define LIBRARYVIEWFEAUTRE_H + +#include + +class LibraryViewFeature { + Q_OBJECT + + public: + + LibraryViewFeature(); + + virtual QVariant getTitle() = 0; + virtual QIcon getIcon() = 0; + + // A LibraryViewFeature always has a right and a left pane + virtual QWidget* getLeftPane() = 0; + + // Since the right pane can be shown in two panes, this must return a new + // widget every time and handle the proper connections with the left pane + // Qt does not allow for a widget to have multiple parents + virtual QWidget* getRightPane() = 0; + + signals: + + void focused(); +}; + +#endif // LIBRARYVIEWFEAUTRE_H From 8c156d16131965b357166ee9ca2792cdb53d999e Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 09:57:36 +0200 Subject: [PATCH 004/552] Add created classes to build system --- build/depends.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/depends.py b/build/depends.py index 747bb99059a..01467bd3b91 100644 --- a/build/depends.py +++ b/build/depends.py @@ -807,6 +807,7 @@ def sources(self, build): "widget/wcoverartmenu.cpp", "widget/wsingletoncontainer.cpp", "widget/wmainmenubar.cpp", + "widget/wbuttonbar.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", @@ -886,6 +887,8 @@ def sources(self, build): "library/cratefeature.cpp", "library/sidebarmodel.cpp", "library/library.cpp", + "library/libraryviewmanager.cpp", + "library/libraryviewfeature.cpp", "library/scanner/libraryscanner.cpp", "library/scanner/libraryscannerdlg.cpp", From 7123cb1c1efa90dbac47112146dc77ae97dc3c1b Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 14:30:18 +0200 Subject: [PATCH 005/552] Add searchBar and change setters to getters --- src/library/libraryviewmanager.cpp | 36 +++++++++++++++++++++++++----- src/library/libraryviewmanager.h | 31 +++++++++++++++++-------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/library/libraryviewmanager.cpp b/src/library/libraryviewmanager.cpp index 5200fd4b2a4..0b1247b5e99 100644 --- a/src/library/libraryviewmanager.cpp +++ b/src/library/libraryviewmanager.cpp @@ -1,19 +1,45 @@ #include "libraryviewmanager.h" +#include "util/assert.h" LibraryViewManager::LibraryViewManager(QObject* parent) : QObject(parent) { } +bool LibraryViewManager::initialize() { + + m_pButtonBar = new WButtonBar; + m_pLeftPane = new QStackedWidget; + + + for (int i = 0; i < RIGHT_PANE_COUNT; ++i) { + m_rightPaneStack.append(new QStackedWidget); + m_searchBar.append(new WSearchLineEdit); + m_rightPane.append(new QWidget); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(m_searchBar[i]); + layout->addWidget(m_rightPaneStack[i]); + m_rightPane[i]->setLayout(layout); + + connect(m_searchBar[i], SIGNAL(search(QString)), + this, SLOT(onSearch(QString))); + } +} + +void LibraryViewManager::onSearch(QString& text) { + LibraryViewFeature *feature = m_features[m_currentFeature[m_currentPane]]; + feature->onSearch(text, m_rightPaneStack[m_currentPane]->currentIndex()); +} + void LibraryViewManager::addFeature(LibraryViewFeature* feature) { // Every feature ID will be it's position in the features' vector - int ID = m_pFeatures.size(); - m_pFeatures.append(feature); - + int ID = m_features.size(); + m_features.append(feature); m_pLeftPane->addWidget(feature->getLeftPane()); - for (QStackedWidget* stack : m_pRightPane) { - stack->addWidget(feature->getRightPane()); + for (QStackedWidget* pane : m_rightPaneStack) { + pane->addWidget(feature->getRightPane()); } m_pButtonBar->addItem(feature->getIcon(), feature->getTitle(), ID); diff --git a/src/library/libraryviewmanager.h b/src/library/libraryviewmanager.h index 709d21923a5..38eeb095866 100644 --- a/src/library/libraryviewmanager.h +++ b/src/library/libraryviewmanager.h @@ -7,36 +7,49 @@ #include "library/libraryviewfeature.h" #include "widget/wbuttonbar.h" +#include "widget/wsearchlineedit.h" class LibraryViewManager : public QObject { Q_OBJECT public: + const int RIGHT_PANE_COUNT = 2; + LibraryViewManager(QObject* parent = nullptr); - inline void setButtonBar(WButtonBar* button) { - m_pButtonBar = button; + bool initialize(); + + inline WButtonBar* getButtonBar() const { + return m_pButtonBar; } - inline void setLeftPane(QStackedWidget* pane) { - m_pLeftPane = pane; + inline QStackedWidget* getLeftPane() const { + return m_pLeftPane; } - inline void addRightPane(QStackedWidget* pane) { - m_pRightPane.append(pane); + inline const QVector& getRightPane() const { + return m_rightPane; } void addFeature(LibraryViewFeature* feature); - void featureSelected(); + public slots: + + void onSearch(QString& text); + private: WButtonBar* m_pButtonBar; QStackedWidget* m_pLeftPane; - QVector m_pRightPane; - QVector m_pFeatures; + QVector m_rightPane; + QVector m_rightPaneStack; + QVector m_searchBar; + QVector m_features; + QVector m_currentFeature; + int m_currentPane; private slots: + // TODO(jmigual): Still needs to v void onFocusChange(); }; From 8b395e5a7c533f6d0ccf69db30f5909109f73cc9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 14:30:32 +0200 Subject: [PATCH 006/552] Add comments and onSearch function --- src/library/libraryviewfeature.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/library/libraryviewfeature.h b/src/library/libraryviewfeature.h index 0b49285e9d3..4f3b29f8358 100644 --- a/src/library/libraryviewfeature.h +++ b/src/library/libraryviewfeature.h @@ -15,14 +15,24 @@ class LibraryViewFeature { // A LibraryViewFeature always has a right and a left pane virtual QWidget* getLeftPane() = 0; - + // Since the right pane can be shown in two panes, this must return a new // widget every time and handle the proper connections with the left pane // Qt does not allow for a widget to have multiple parents virtual QWidget* getRightPane() = 0; + // If it has not the search option, the search bar must be hidden + virtual bool hasSearch() = 0; + + public slots: + + // Receives the text to search text and the widget that will be affected by + // the onSearch() event (because every feature will have multiple widgets + // showing + virtual void onSearch(QString& text, QWidget* content) = 0; + signals: - + void focused(); }; From ad6947e9b6dcf2754f77348d8da2434ac980be42 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 1 Jun 2016 20:25:04 +0200 Subject: [PATCH 007/552] Add LibraryViewManager to Mixxxx code --- src/library/cratefeature.cpp | 2 +- src/library/cratefeature.h | 12 ++++++++- src/library/libraryviewfeature.cpp | 3 ++- src/library/libraryviewfeature.h | 20 +++++++------- src/library/libraryviewmanager.cpp | 42 ++++++++++++++++++------------ src/library/libraryviewmanager.h | 12 +++++---- src/mixxx.cpp | 6 +++++ src/mixxx.h | 4 +++ src/skin/legacyskinparser.cpp | 5 +++- src/skin/legacyskinparser.h | 4 ++- src/skin/skinloader.cpp | 5 ++-- src/skin/skinloader.h | 3 ++- src/widget/wbuttonbar.h | 10 ++++--- src/widget/wsearchlineedit.h | 2 +- 14 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index a0f8b118165..6f65d1cafaf 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -28,7 +28,7 @@ CrateFeature::CrateFeature(Library* pLibrary, TrackCollection* pTrackCollection, UserSettingsPointer pConfig) - : LibraryFeature(pConfig), + : LibraryViewFeature(pConfig), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_crateTableModel(this, pTrackCollection) { diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 495b74ad7c3..52523571b74 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -12,6 +12,7 @@ #include #include "library/libraryfeature.h" +#include "library/libraryviewfeature.h" #include "library/cratetablemodel.h" #include "library/library.h" @@ -21,7 +22,7 @@ class TrackCollection; -class CrateFeature : public LibraryFeature { +class CrateFeature : public LibraryViewFeature { Q_OBJECT public: CrateFeature(Library* pLibrary, @@ -30,7 +31,15 @@ class CrateFeature : public LibraryFeature { virtual ~CrateFeature(); QVariant title(); + inline QVariant getTitle() { return title(); } QIcon getIcon(); + + inline QString getName() { return "CRATE_FEATURE"; } + QWidget* getLeftPane() { return new QWidget(); } + QWidget* getRightPane() { return new QWidget(); } + + inline bool hasSearch() { return false; } + void onSearch(QString&) {} bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); @@ -103,6 +112,7 @@ class CrateFeature : public LibraryFeature { TreeItemModel m_childModel; TrackPointer m_pSelectedTrack; QSet m_cratesSelectedTrackIsIn; + UserSettingsPointer m_pConfig; }; #endif /* CRATEFEATURE_H */ diff --git a/src/library/libraryviewfeature.cpp b/src/library/libraryviewfeature.cpp index 8ff7bbf7f05..be9065ea03b 100644 --- a/src/library/libraryviewfeature.cpp +++ b/src/library/libraryviewfeature.cpp @@ -1,6 +1,7 @@ #include "libraryviewfeature.h" -LibraryViewFeature::LibraryViewFeature() { +LibraryViewFeature::LibraryViewFeature(UserSettingsPointer pConfig) + : LibraryFeature(pConfig) { } diff --git a/src/library/libraryviewfeature.h b/src/library/libraryviewfeature.h index 4f3b29f8358..ab7448e050e 100644 --- a/src/library/libraryviewfeature.h +++ b/src/library/libraryviewfeature.h @@ -3,22 +3,27 @@ #include -class LibraryViewFeature { +#include "library/libraryfeature.h" + +// This is a more simple interface that the existing LibraryFeature +// every feature has two widgets (left and right) +class LibraryViewFeature : public LibraryFeature { Q_OBJECT public: - LibraryViewFeature(); + LibraryViewFeature(UserSettingsPointer pConfig); virtual QVariant getTitle() = 0; virtual QIcon getIcon() = 0; + + // Must be a unique name for each feature type, it will be used in + // the button bar to distinguish one feature from another + virtual QString getName() = 0; // A LibraryViewFeature always has a right and a left pane virtual QWidget* getLeftPane() = 0; - // Since the right pane can be shown in two panes, this must return a new - // widget every time and handle the proper connections with the left pane - // Qt does not allow for a widget to have multiple parents virtual QWidget* getRightPane() = 0; // If it has not the search option, the search bar must be hidden @@ -26,10 +31,7 @@ class LibraryViewFeature { public slots: - // Receives the text to search text and the widget that will be affected by - // the onSearch() event (because every feature will have multiple widgets - // showing - virtual void onSearch(QString& text, QWidget* content) = 0; + virtual void onSearch(QString& text) = 0; signals: diff --git a/src/library/libraryviewmanager.cpp b/src/library/libraryviewmanager.cpp index 0b1247b5e99..c80ff6b7155 100644 --- a/src/library/libraryviewmanager.cpp +++ b/src/library/libraryviewmanager.cpp @@ -1,3 +1,5 @@ +#include + #include "libraryviewmanager.h" #include "util/assert.h" @@ -10,7 +12,7 @@ bool LibraryViewManager::initialize() { m_pButtonBar = new WButtonBar; m_pLeftPane = new QStackedWidget; - + m_features.resize(RIGHT_PANE_COUNT); for (int i = 0; i < RIGHT_PANE_COUNT; ++i) { m_rightPaneStack.append(new QStackedWidget); @@ -21,30 +23,38 @@ bool LibraryViewManager::initialize() { layout->addWidget(m_searchBar[i]); layout->addWidget(m_rightPaneStack[i]); m_rightPane[i]->setLayout(layout); - - connect(m_searchBar[i], SIGNAL(search(QString)), + + connect(m_searchBar[i], SIGNAL(search(QString)), this, SLOT(onSearch(QString))); + + } + return true; } void LibraryViewManager::onSearch(QString& text) { - LibraryViewFeature *feature = m_features[m_currentFeature[m_currentPane]]; - feature->onSearch(text, m_rightPaneStack[m_currentPane]->currentIndex()); + LibraryViewFeature* feature = m_features[m_currentPane][m_currentFeature[m_currentPane]]; + feature->onSearch(text); } -void LibraryViewManager::addFeature(LibraryViewFeature* feature) { - // Every feature ID will be it's position in the features' vector - int ID = m_features.size(); - m_features.append(feature); - m_pLeftPane->addWidget(feature->getLeftPane()); - - for (QStackedWidget* pane : m_rightPaneStack) { - pane->addWidget(feature->getRightPane()); +void LibraryViewManager::addFeature(LibraryViewFeature* feature, int pane) { + if (pane < 0 || pane >= RIGHT_PANE_COUNT) { + return; } - m_pButtonBar->addItem(feature->getIcon(), feature->getTitle(), ID); -} + m_features[pane].append(feature); + + m_pLeftPane->addWidget(feature->getLeftPane()); + m_rightPaneStack[pane]->addWidget(feature->getRightPane()); -void LibraryViewManager::onFocusChange() { + m_pButtonBar->addItem(feature->getIcon(), feature->getTitle(), feature->getName()); +} +bool LibraryViewManager::eventFilter(QObject* object, QEvent* event) { + //QObject::eventFilter(object, event); + + if (event->type() == QEvent::FocusIn) { + qDebug() << object; + } + return true; } diff --git a/src/library/libraryviewmanager.h b/src/library/libraryviewmanager.h index 38eeb095866..9d14acbcc66 100644 --- a/src/library/libraryviewmanager.h +++ b/src/library/libraryviewmanager.h @@ -30,12 +30,13 @@ class LibraryViewManager : public QObject { return m_rightPane; } - void addFeature(LibraryViewFeature* feature); + // To add a feature to the selected pane (0 <= pane < RIGHT_PANE_COUNT) + void addFeature(LibraryViewFeature* feature, int pane); public slots: void onSearch(QString& text); - + private: WButtonBar* m_pButtonBar; @@ -43,14 +44,15 @@ class LibraryViewManager : public QObject { QVector m_rightPane; QVector m_rightPaneStack; QVector m_searchBar; - QVector m_features; + QVector > m_features; QVector m_currentFeature; int m_currentPane; private slots: - // TODO(jmigual): Still needs to v - void onFocusChange(); + // Used to handle focus change + // TODO(jmigual): Still needs to be implemented + bool eventFilter(QObject* object, QEvent* event); }; #endif // LIBRARYVIEWMANAGER_H diff --git a/src/mixxx.cpp b/src/mixxx.cpp index a7b6c50bd19..d589872ca3d 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -34,6 +34,7 @@ #include "effects/native/nativebackend.h" #include "library/coverartcache.h" #include "library/library.h" +#include "library/libraryviewmanager.h" #include "library/library_preferences.h" #include "controllers/controllermanager.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -98,6 +99,7 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) #endif m_pKeyboard(nullptr), m_pLibrary(nullptr), + m_pLibraryViewManager(nullptr), m_pMenuBar(nullptr), m_pDeveloperToolsDlg(nullptr), m_pPrefDlg(nullptr), @@ -268,6 +270,8 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pRecordingManager); m_pPlayerManager->bindToLibrary(m_pLibrary); + m_pLibraryViewManager = new LibraryViewManager; + launchProgress(35); // Get Music dir @@ -340,6 +344,7 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pPlayerManager, m_pControllerManager, m_pLibrary, + m_pLibraryViewManager, m_pVCManager, m_pEffectsManager))) { reportCriticalErrorAndQuit( @@ -1065,6 +1070,7 @@ void MixxxMainWindow::rebootMixxxView() { m_pPlayerManager, m_pControllerManager, m_pLibrary, + m_pLibraryViewManager, m_pVCManager, m_pEffectsManager))) { diff --git a/src/mixxx.h b/src/mixxx.h index a1793d56b54..44c3479c03e 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -37,6 +37,7 @@ class EngineMaster; class GuiTick; class LaunchImage; class Library; +class LibraryViewManager; class KeyboardEventFilter; class PlayerManager; class RecordingManager; @@ -152,6 +153,9 @@ class MixxxMainWindow : public QMainWindow { KeyboardEventFilter* m_pKeyboard; // The library management object Library* m_pLibrary; + + // The library view management object + LibraryViewManager* m_pLibraryViewManager; WMainMenuBar* m_pMenuBar; diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 9fabb0cc05e..3969454f9fb 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -140,6 +140,7 @@ LegacySkinParser::LegacySkinParser() m_pPlayerManager(NULL), m_pControllerManager(NULL), m_pLibrary(NULL), + m_pLibraryViewManager(NULL), m_pVCManager(NULL), m_pEffectsManager(NULL), m_pParent(NULL), @@ -151,6 +152,7 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, Library* pLibrary, + LibraryViewManager* pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager) : m_pConfig(pConfig), @@ -158,6 +160,7 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, m_pPlayerManager(pPlayerManager), m_pControllerManager(pControllerManager), m_pLibrary(pLibrary), + m_pLibraryViewManager(pLibraryViewManager), m_pVCManager(pVCMan), m_pEffectsManager(pEffectsManager), m_pParent(NULL), @@ -1261,7 +1264,7 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { pLibrarySidebar->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); m_pLibrary->bindSidebarWidget(pLibrarySidebar); commonWidgetSetup(node, pLibrarySidebar, false); - return pLibrarySidebar; + return pLibrarySidebar; } QWidget* LegacySkinParser::parseTableView(const QDomElement& node) { diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index bd7d4b2eaa5..45a7a08c0c6 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -15,6 +15,7 @@ class WBaseWidget; class Library; +class LibraryViewManager; class KeyboardEventFilter; class PlayerManager; class EffectsManager; @@ -31,7 +32,7 @@ class LegacySkinParser : public QObject, public SkinParser { LegacySkinParser(UserSettingsPointer pConfig, KeyboardEventFilter* pKeyboard, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, - Library* pLibrary, VinylControlManager* pVCMan, + Library* pLibrary, LibraryViewManager *pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager); virtual ~LegacySkinParser(); @@ -131,6 +132,7 @@ class LegacySkinParser : public QObject, public SkinParser { PlayerManager* m_pPlayerManager; ControllerManager* m_pControllerManager; Library* m_pLibrary; + LibraryViewManager *m_pLibraryViewManager; VinylControlManager* m_pVCManager; EffectsManager* m_pEffectsManager; QWidget* m_pParent; diff --git a/src/skin/skinloader.cpp b/src/skin/skinloader.cpp index 2cc4bb3bf1d..648cd4c1973 100644 --- a/src/skin/skinloader.cpp +++ b/src/skin/skinloader.cpp @@ -114,6 +114,7 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, Library* pLibrary, + LibraryViewManager* pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager) { ScopedTimer timer("SkinLoader::loadDefaultSkin"); @@ -125,8 +126,8 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent, } LegacySkinParser legacy(m_pConfig, pKeyboard, pPlayerManager, - pControllerManager, pLibrary, pVCMan, - pEffectsManager); + pControllerManager, pLibrary, pLibraryViewManager, + pVCMan, pEffectsManager); return legacy.parseSkin(skinPath, pParent); } diff --git a/src/skin/skinloader.h b/src/skin/skinloader.h index ac76b0c9978..40ecaad16a3 100644 --- a/src/skin/skinloader.h +++ b/src/skin/skinloader.h @@ -11,6 +11,7 @@ class KeyboardEventFilter; class PlayerManager; class ControllerManager; class Library; +class LibraryViewManager; class VinylControlManager; class EffectsManager; class LaunchImage; @@ -24,7 +25,7 @@ class SkinLoader { KeyboardEventFilter* pKeyboard, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, - Library* pLibrary, + Library* pLibrary, LibraryViewManager *pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 1620e84025c..d3218c7526a 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -3,6 +3,8 @@ #include #include +#include +#include class WButtonBar : QWidget { @@ -11,11 +13,13 @@ class WButtonBar : QWidget WButtonBar(QWidget* parent = nullptr); void addItem(QIcon icon, QVariant title, QVariant data); - + signals: - + void clicked(QVariant data); - + + private: + QLayout* m_pLayout; }; diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 81a64ca217a..7f681ab8374 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -16,7 +16,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { Q_OBJECT public: - explicit WSearchLineEdit(QWidget* pParent); + explicit WSearchLineEdit(QWidget* pParent = nullptr); void setup(const QDomNode& node, const SkinContext& context); From 9b9253902059461b5187085e720bfc48d4f78c44 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 2 Jun 2016 09:56:47 +0200 Subject: [PATCH 008/552] Changed LibraryViewManager to LibraryPaneManager --- build/depends.py | 3 +-- .../{libraryviewmanager.cpp => librarypanemanager.cpp} | 0 src/library/{libraryviewmanager.h => librarypanemanager.h} | 0 src/mixxx.cpp | 6 +----- src/mixxx.h | 5 +---- src/skin/legacyskinparser.cpp | 3 --- src/skin/legacyskinparser.h | 5 ++--- src/skin/skinloader.cpp | 5 ++--- src/skin/skinloader.h | 4 ++-- 9 files changed, 9 insertions(+), 22 deletions(-) rename src/library/{libraryviewmanager.cpp => librarypanemanager.cpp} (100%) rename src/library/{libraryviewmanager.h => librarypanemanager.h} (100%) diff --git a/build/depends.py b/build/depends.py index 01467bd3b91..65f5918b9d5 100644 --- a/build/depends.py +++ b/build/depends.py @@ -887,8 +887,7 @@ def sources(self, build): "library/cratefeature.cpp", "library/sidebarmodel.cpp", "library/library.cpp", - "library/libraryviewmanager.cpp", - "library/libraryviewfeature.cpp", + "library/librarypanemanager.cpp", "library/scanner/libraryscanner.cpp", "library/scanner/libraryscannerdlg.cpp", diff --git a/src/library/libraryviewmanager.cpp b/src/library/librarypanemanager.cpp similarity index 100% rename from src/library/libraryviewmanager.cpp rename to src/library/librarypanemanager.cpp diff --git a/src/library/libraryviewmanager.h b/src/library/librarypanemanager.h similarity index 100% rename from src/library/libraryviewmanager.h rename to src/library/librarypanemanager.h diff --git a/src/mixxx.cpp b/src/mixxx.cpp index d589872ca3d..fc0f24a0acf 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -34,7 +34,7 @@ #include "effects/native/nativebackend.h" #include "library/coverartcache.h" #include "library/library.h" -#include "library/libraryviewmanager.h" +#include "library/librarypanemanager.h" #include "library/library_preferences.h" #include "controllers/controllermanager.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -99,7 +99,6 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) #endif m_pKeyboard(nullptr), m_pLibrary(nullptr), - m_pLibraryViewManager(nullptr), m_pMenuBar(nullptr), m_pDeveloperToolsDlg(nullptr), m_pPrefDlg(nullptr), @@ -269,8 +268,6 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pPlayerManager, m_pRecordingManager); m_pPlayerManager->bindToLibrary(m_pLibrary); - - m_pLibraryViewManager = new LibraryViewManager; launchProgress(35); @@ -344,7 +341,6 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pPlayerManager, m_pControllerManager, m_pLibrary, - m_pLibraryViewManager, m_pVCManager, m_pEffectsManager))) { reportCriticalErrorAndQuit( diff --git a/src/mixxx.h b/src/mixxx.h index 44c3479c03e..5ca96f3b4b0 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -37,7 +37,7 @@ class EngineMaster; class GuiTick; class LaunchImage; class Library; -class LibraryViewManager; +class LibraryPaneManager; class KeyboardEventFilter; class PlayerManager; class RecordingManager; @@ -153,9 +153,6 @@ class MixxxMainWindow : public QMainWindow { KeyboardEventFilter* m_pKeyboard; // The library management object Library* m_pLibrary; - - // The library view management object - LibraryViewManager* m_pLibraryViewManager; WMainMenuBar* m_pMenuBar; diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 3969454f9fb..49545e6c198 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -140,7 +140,6 @@ LegacySkinParser::LegacySkinParser() m_pPlayerManager(NULL), m_pControllerManager(NULL), m_pLibrary(NULL), - m_pLibraryViewManager(NULL), m_pVCManager(NULL), m_pEffectsManager(NULL), m_pParent(NULL), @@ -152,7 +151,6 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, Library* pLibrary, - LibraryViewManager* pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager) : m_pConfig(pConfig), @@ -160,7 +158,6 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, m_pPlayerManager(pPlayerManager), m_pControllerManager(pControllerManager), m_pLibrary(pLibrary), - m_pLibraryViewManager(pLibraryViewManager), m_pVCManager(pVCMan), m_pEffectsManager(pEffectsManager), m_pParent(NULL), diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index 45a7a08c0c6..9e0f3112bfc 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -15,7 +15,7 @@ class WBaseWidget; class Library; -class LibraryViewManager; +class LibraryPaneManager; class KeyboardEventFilter; class PlayerManager; class EffectsManager; @@ -32,7 +32,7 @@ class LegacySkinParser : public QObject, public SkinParser { LegacySkinParser(UserSettingsPointer pConfig, KeyboardEventFilter* pKeyboard, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, - Library* pLibrary, LibraryViewManager *pLibraryViewManager, VinylControlManager* pVCMan, + Library* pLibrary, VinylControlManager* pVCMan, EffectsManager* pEffectsManager); virtual ~LegacySkinParser(); @@ -132,7 +132,6 @@ class LegacySkinParser : public QObject, public SkinParser { PlayerManager* m_pPlayerManager; ControllerManager* m_pControllerManager; Library* m_pLibrary; - LibraryViewManager *m_pLibraryViewManager; VinylControlManager* m_pVCManager; EffectsManager* m_pEffectsManager; QWidget* m_pParent; diff --git a/src/skin/skinloader.cpp b/src/skin/skinloader.cpp index 648cd4c1973..426a19dfe98 100644 --- a/src/skin/skinloader.cpp +++ b/src/skin/skinloader.cpp @@ -114,7 +114,6 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, Library* pLibrary, - LibraryViewManager* pLibraryViewManager, VinylControlManager* pVCMan, EffectsManager* pEffectsManager) { ScopedTimer timer("SkinLoader::loadDefaultSkin"); @@ -126,8 +125,8 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent, } LegacySkinParser legacy(m_pConfig, pKeyboard, pPlayerManager, - pControllerManager, pLibrary, pLibraryViewManager, - pVCMan, pEffectsManager); + pControllerManager, pLibrary, pVCMan, + pEffectsManager); return legacy.parseSkin(skinPath, pParent); } diff --git a/src/skin/skinloader.h b/src/skin/skinloader.h index 40ecaad16a3..0f594eb8052 100644 --- a/src/skin/skinloader.h +++ b/src/skin/skinloader.h @@ -11,7 +11,7 @@ class KeyboardEventFilter; class PlayerManager; class ControllerManager; class Library; -class LibraryViewManager; +class LibraryPaneManager; class VinylControlManager; class EffectsManager; class LaunchImage; @@ -25,7 +25,7 @@ class SkinLoader { KeyboardEventFilter* pKeyboard, PlayerManager* pPlayerManager, ControllerManager* pControllerManager, - Library* pLibrary, LibraryViewManager *pLibraryViewManager, + Library* pLibrary, VinylControlManager* pVCMan, EffectsManager* pEffectsManager); From 46c0ff8af9ab5c706790a3d9215b2f34556c9c6b Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 2 Jun 2016 09:57:47 +0200 Subject: [PATCH 009/552] Changed bindWidget to bindRightPane --- src/library/analysisfeature.cpp | 2 +- src/library/analysisfeature.h | 6 +++++- src/library/autodj/autodjfeature.cpp | 2 +- src/library/autodj/autodjfeature.h | 4 +++- src/library/baseplaylistfeature.cpp | 2 +- src/library/baseplaylistfeature.h | 4 +++- src/library/browse/browsefeature.cpp | 2 +- src/library/browse/browsefeature.h | 4 +++- src/library/cratefeature.cpp | 4 ++-- src/library/cratefeature.h | 7 +++++-- src/library/library.cpp | 2 +- src/library/libraryfeature.h | 11 +++++++++-- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/mixxxlibraryfeature.h | 4 +++- src/library/recording/recordingfeature.cpp | 2 +- src/library/recording/recordingfeature.h | 4 +++- src/library/setlogfeature.cpp | 4 ++-- src/library/setlogfeature.h | 2 +- 18 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index ab925a9a2b7..fcf8a4d32a3 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -58,7 +58,7 @@ QIcon AnalysisFeature::getIcon() { return QIcon(":/images/library/ic_library_prepare.png"); } -void AnalysisFeature::bindWidget(WLibrary* libraryWidget, +void AnalysisFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { m_pAnalysisView = new DlgAnalysis(libraryWidget, m_pConfig, diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index bbdd853fc45..33f5e29d9a5 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -33,8 +33,12 @@ class AnalysisFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + + // TODO(jmigual): Still needs to be implemented + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); void refreshLibraryModels(); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index cb9322f6517..e15b75edd5a 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -94,7 +94,7 @@ QIcon AutoDJFeature::getIcon() { return QIcon(":/images/library/ic_library_autodj.png"); } -void AutoDJFeature::bindWidget(WLibrary* libraryWidget, +void AutoDJFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { m_pAutoDJView = new DlgAutoDJ(libraryWidget, m_pConfig, diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 7cc7d2803c8..f0ec38055c2 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -43,8 +43,10 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index f210b08d031..15c8f1d5c68 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -593,7 +593,7 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { return &m_childModel; } -void BasePlaylistFeature::bindWidget(WLibrary* libraryWidget, +void BasePlaylistFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 4b8583cc22d..cbf7d88d8ff 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -33,8 +33,10 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} signals: void showPage(const QUrl& page); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 9f6231b78c0..333b3977e47 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -207,7 +207,7 @@ TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } -void BrowseFeature::bindWidget(WLibrary* libraryWidget, +void BrowseFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 94188ee6b0d..7464427baa8 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -36,8 +36,10 @@ class BrowseFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 6f65d1cafaf..0cbf9d4d534 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -28,7 +28,7 @@ CrateFeature::CrateFeature(Library* pLibrary, TrackCollection* pTrackCollection, UserSettingsPointer pConfig) - : LibraryViewFeature(pConfig), + : LibraryFeature(pConfig), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_crateTableModel(this, pTrackCollection) { @@ -178,7 +178,7 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { return !locked && formatSupported; } -void CrateFeature::bindWidget(WLibrary* libraryWidget, +void CrateFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 52523571b74..f2dab7c919f 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -22,7 +22,7 @@ class TrackCollection; -class CrateFeature : public LibraryViewFeature { +class CrateFeature : public LibraryFeature { Q_OBJECT public: CrateFeature(Library* pLibrary, @@ -45,9 +45,12 @@ class CrateFeature : public LibraryViewFeature { QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} + TreeItemModel* getChildModel(); signals: diff --git a/src/library/library.cpp b/src/library/library.cpp index 99520e58e8c..59c4666cf47 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -209,7 +209,7 @@ void Library::bindWidget(WLibrary* pLibraryWidget, QListIterator feature_it(m_features); while(feature_it.hasNext()) { LibraryFeature* feature = feature_it.next(); - feature->bindWidget(pLibraryWidget, pKeyboard); + feature->bindRightPane(pLibraryWidget, pKeyboard); } // Set the current font and row height on all the WTrackTableViews that were diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index f750bf6cda1..8c237b1932f 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -60,9 +60,16 @@ class LibraryFeature : public QObject { return false; } - // Reimplement this to register custom views with the library widget. - virtual void bindWidget(WLibrary* /* libraryWidget */, + // Reimplement this to register custom views with the library widget + // at the right pane. + virtual void bindRightPane(WLibrary* /* libraryWidget */, KeyboardEventFilter* /* keyboard */) {} + + // Reimplement this to register custem views with the library widget, + // at the left pane + virtual void bindLeftPane(WLibrary*, + KeyboardEventFilter*) {} + virtual TreeItemModel* getChildModel() = 0; protected: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 60271e3a38e..d6b88f6b607 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -123,7 +123,7 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { delete m_pLibraryTableModel; } -void MixxxLibraryFeature::bindWidget(WLibrary* pLibraryWidget, +void MixxxLibraryFeature::bindRightPane(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, m_pTrackCollection, pKeyboard); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 54d0a14f51e..46ac2614585 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -39,8 +39,10 @@ class MixxxLibraryFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); - void bindWidget(WLibrary* pLibrary, + void bindRightPane(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} public slots: void activate(); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index e3a3c0d8c3a..7b29c1d9909 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -38,7 +38,7 @@ QIcon RecordingFeature::getIcon() { TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } -void RecordingFeature::bindWidget(WLibrary* pLibraryWidget, +void RecordingFeature::bindRightPane(WLibrary* pLibraryWidget, KeyboardEventFilter *keyboard) { //The view will be deleted by LibraryWidget DlgRecording* pRecordingView = new DlgRecording(pLibraryWidget, diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 7ff7e43ac46..4802b1fd327 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -29,8 +29,10 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - void bindWidget(WLibrary* libraryWidget, + void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); + void bindLeftPane(WLibrary* libraryWidget, + KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index 01e2ba7919d..252e1b1095a 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -53,9 +53,9 @@ QIcon SetlogFeature::getIcon() { return QIcon(":/images/library/ic_library_history.png"); } -void SetlogFeature::bindWidget(WLibrary* libraryWidget, +void SetlogFeature::bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { - BasePlaylistFeature::bindWidget(libraryWidget, + BasePlaylistFeature::bindRightPane(libraryWidget, keyboard); connect(&PlayerInfo::instance(), SIGNAL(currentPlayingTrackChanged(TrackPointer)), this, SLOT(slotPlayingTrackChanged(TrackPointer))); diff --git a/src/library/setlogfeature.h b/src/library/setlogfeature.h index d02b25e4e6e..1324f65879e 100644 --- a/src/library/setlogfeature.h +++ b/src/library/setlogfeature.h @@ -23,7 +23,7 @@ class SetlogFeature : public BasePlaylistFeature { QVariant title(); QIcon getIcon(); - virtual void bindWidget(WLibrary* libraryWidget, + virtual void bindRightPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); public slots: From d58e70cb61cc14cb2011fceeca78eb89ce7b5090 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 2 Jun 2016 09:58:08 +0200 Subject: [PATCH 010/552] Created new skeleton for Pane manager --- src/library/librarypanemanager.cpp | 48 +++++++++--------------------- src/library/librarypanemanager.h | 41 ++++++++++++------------- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index c80ff6b7155..a7577805d74 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -1,58 +1,38 @@ #include -#include "libraryviewmanager.h" +#include "librarypanemanager.h" #include "util/assert.h" -LibraryViewManager::LibraryViewManager(QObject* parent) +LibraryPaneManager::LibraryPaneManager(QObject* parent) : QObject(parent) { } -bool LibraryViewManager::initialize() { - - m_pButtonBar = new WButtonBar; - m_pLeftPane = new QStackedWidget; - m_features.resize(RIGHT_PANE_COUNT); - - for (int i = 0; i < RIGHT_PANE_COUNT; ++i) { - m_rightPaneStack.append(new QStackedWidget); - m_searchBar.append(new WSearchLineEdit); - m_rightPane.append(new QWidget); +bool LibraryPaneManager::initialize() { + m_pLeftPane = nullptr; + m_pRightPane = nullptr; +} - QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget(m_searchBar[i]); - layout->addWidget(m_rightPaneStack[i]); - m_rightPane[i]->setLayout(layout); +void LibraryPaneManager::bindLeftPane(WLibrary* leftWidget) { - connect(m_searchBar[i], SIGNAL(search(QString)), - this, SLOT(onSearch(QString))); +} +void LibraryPaneManager::bindRightPane(WLibrary* rightWidget) { - } - return true; } -void LibraryViewManager::onSearch(QString& text) { - LibraryViewFeature* feature = m_features[m_currentPane][m_currentFeature[m_currentPane]]; - feature->onSearch(text); -} +void LibraryPaneManager::search(QString& text) { -void LibraryViewManager::addFeature(LibraryViewFeature* feature, int pane) { - if (pane < 0 || pane >= RIGHT_PANE_COUNT) { - return; - } +} - m_features[pane].append(feature); +void LibraryPaneManager::addFeature(LibraryFeature* feature) { - m_pLeftPane->addWidget(feature->getLeftPane()); - m_rightPaneStack[pane]->addWidget(feature->getRightPane()); - m_pButtonBar->addItem(feature->getIcon(), feature->getTitle(), feature->getName()); } -bool LibraryViewManager::eventFilter(QObject* object, QEvent* event) { +bool LibraryPaneManager::eventFilter(QObject* object, QEvent* event) { //QObject::eventFilter(object, event); - + if (event->type() == QEvent::FocusIn) { qDebug() << object; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 9d14acbcc66..9dd00fef6d6 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -5,46 +5,43 @@ #include #include -#include "library/libraryviewfeature.h" +#include "library/libraryfeature.h" #include "widget/wbuttonbar.h" +#include "widget/wlibrary.h" #include "widget/wsearchlineedit.h" -class LibraryViewManager : public QObject { +class LibraryPaneManager : public QObject { Q_OBJECT public: const int RIGHT_PANE_COUNT = 2; - LibraryViewManager(QObject* parent = nullptr); - + LibraryPaneManager(QObject* parent = nullptr); + bool initialize(); - inline WButtonBar* getButtonBar() const { - return m_pButtonBar; - } - inline QStackedWidget* getLeftPane() const { - return m_pLeftPane; - } - inline const QVector& getRightPane() const { - return m_rightPane; - } + // All features must be added before adding a pane + void bindLeftPane(WLibrary* leftWidget); + void bindRightPane(WLibrary* rightWidget); + + inline WLibrary* getLeftPane() { return m_pLeftPane; } + inline WLibrary* getRightPane() { return m_pRightPane; } - // To add a feature to the selected pane (0 <= pane < RIGHT_PANE_COUNT) - void addFeature(LibraryViewFeature* feature, int pane); + void addFeature(LibraryFeature* feature); public slots: - void onSearch(QString& text); + void search(QString& text); + private: - WButtonBar* m_pButtonBar; - QStackedWidget* m_pLeftPane; - QVector m_rightPane; - QVector m_rightPaneStack; - QVector m_searchBar; - QVector > m_features; + WLibrary* m_pLeftPane; + WLibrary* m_pRightPane; + + QVector m_features; + QVector m_currentFeature; int m_currentPane; From 79ecf0b3c76434f1b7abd3ec209896d1f848a59d Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 2 Jun 2016 13:16:14 +0200 Subject: [PATCH 011/552] Changed destructor of library --- src/library/library.cpp | 15 +++++++++------ src/library/library.h | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 59c4666cf47..f4445e3dfc4 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -137,13 +137,16 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; - - QMutableListIterator features_it(m_features); - while(features_it.hasNext()) { - LibraryFeature* feature = features_it.next(); - features_it.remove(); - delete feature; + + for (LibraryFeature* f : m_features) { + delete f; + } + m_features.clear(); + + for (LibraryPaneManager* p : m_panes) { + delete p; } + m_panes.clear(); delete m_pLibraryControl; //IMPORTANT: m_pTrackCollection gets destroyed via the QObject hierarchy somehow. diff --git a/src/library/library.h b/src/library/library.h index dbc8c8323e3..3c0d78a024b 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -19,6 +19,7 @@ #include "library/coverartcache.h" #include "library/setlogfeature.h" #include "library/scanner/libraryscanner.h" +#include "library/librarypanemanager.h" class TrackModel; class TrackCollection; @@ -134,6 +135,7 @@ class Library : public QObject { LibraryScanner m_scanner; QFont m_trackTableFont; int m_iTrackTableRowHeight; + QList m_panes; }; #endif /* LIBRARY_H */ From 50a849c32a7550a13ae004037193fdf8024e6459 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 6 Jun 2016 13:10:07 +0200 Subject: [PATCH 012/552] Removed libraryViewManager from main --- src/mixxx.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index fc0f24a0acf..159fdcfbb12 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -1066,7 +1066,6 @@ void MixxxMainWindow::rebootMixxxView() { m_pPlayerManager, m_pControllerManager, m_pLibrary, - m_pLibraryViewManager, m_pVCManager, m_pEffectsManager))) { From f3e64d69a0e4e25b6bf8956696f1734b9b572a51 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 6 Jun 2016 13:18:00 +0200 Subject: [PATCH 013/552] Add bind right and left pane functions --- src/library/library.cpp | 6 +++++- src/library/library.h | 7 +++++-- src/skin/legacyskinparser.cpp | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index f4445e3dfc4..75cfd24b709 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -178,7 +178,7 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { pSidebarWidget, SLOT(slotSetFont(QFont))); } -void Library::bindWidget(WLibrary* pLibraryWidget, +void Library::bindRightPane(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); @@ -221,6 +221,10 @@ void Library::bindWidget(WLibrary* pLibraryWidget, emit(setTrackTableRowHeight(m_iTrackTableRowHeight)); } +void Library::bindLeftPane(WLibrary *leftPane, KeyboardEventFilter *pKeyboard) { + +} + void Library::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; diff --git a/src/library/library.h b/src/library/library.h index 3c0d78a024b..583051c0cc7 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -45,8 +45,11 @@ class Library : public QObject { RecordingManager* pRecordingManager); virtual ~Library(); - void bindWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard); + void bindRightPane(WLibrary* libraryWidget, + KeyboardEventFilter* pKeyboard); + void bindLeftPane(WLibrary* leftPane, + KeyboardEventFilter* pKeyboard); + void bindSidebarWidget(WLibrarySidebar* sidebarWidget); void addFeature(LibraryFeature* feature); diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 49545e6c198..ffc869eb5f9 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1246,7 +1246,7 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { connect(m_pLibrary, SIGNAL(search(const QString&)), pLibraryWidget, SLOT(search(const QString&))); - m_pLibrary->bindWidget(pLibraryWidget, m_pKeyboard); + m_pLibrary->bindRightPane(pLibraryWidget, m_pKeyboard); // This must come after the bindWidget or we will not style any of the // LibraryView's because they have not been added yet. From db6eaaa8cc75d41612082abe4f6cb1a761c283b6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 6 Jun 2016 13:18:22 +0200 Subject: [PATCH 014/552] Begin implementing right pane function and add keyboardeventfilter --- src/library/librarypanemanager.cpp | 14 +++++++++----- src/library/librarypanemanager.h | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index a7577805d74..ad3eccbfd1f 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -13,12 +13,17 @@ bool LibraryPaneManager::initialize() { m_pRightPane = nullptr; } -void LibraryPaneManager::bindLeftPane(WLibrary* leftWidget) { +void LibraryPaneManager::bindLeftPane(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard) { } -void LibraryPaneManager::bindRightPane(WLibrary* rightWidget) { - +void LibraryPaneManager::bindRightPane(WLibrary* rightWidget, + KeyboardEventFilter* pKeyboard) { + m_pRightPane = rightWidget; + + for (LibraryFeature* f : m_features) { + f->bindRightPane(m_pRightPane, pKeyboard); + } } void LibraryPaneManager::search(QString& text) { @@ -26,8 +31,7 @@ void LibraryPaneManager::search(QString& text) { } void LibraryPaneManager::addFeature(LibraryFeature* feature) { - - + m_features.append(feature); } bool LibraryPaneManager::eventFilter(QObject* object, QEvent* event) { diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 9dd00fef6d6..829f6abb8c8 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -22,8 +22,8 @@ class LibraryPaneManager : public QObject { bool initialize(); // All features must be added before adding a pane - void bindLeftPane(WLibrary* leftWidget); - void bindRightPane(WLibrary* rightWidget); + void bindLeftPane(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard); + void bindRightPane(WLibrary* rightWidget, KeyboardEventFilter *pKeyboard); inline WLibrary* getLeftPane() { return m_pLeftPane; } inline WLibrary* getRightPane() { return m_pRightPane; } From c3259d25583bb0a376d275621f9f892c83b9528c Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 09:05:23 +0200 Subject: [PATCH 015/552] Change names from left right pane to sidebar expanded and librarywidget --- src/library/analysisfeature.cpp | 2 +- src/library/analysisfeature.h | 2 +- src/library/autodj/autodjfeature.cpp | 2 +- src/library/autodj/autodjfeature.h | 2 +- src/library/baseplaylistfeature.cpp | 2 +- src/library/baseplaylistfeature.h | 2 +- src/library/browse/browsefeature.cpp | 2 +- src/library/browse/browsefeature.h | 2 +- src/library/cratefeature.cpp | 2 +- src/library/cratefeature.h | 2 +- src/library/libraryfeature.h | 2 +- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/mixxxlibraryfeature.h | 2 +- src/library/recording/recordingfeature.cpp | 2 +- src/library/recording/recordingfeature.h | 2 +- src/library/setlogfeature.cpp | 4 ++-- src/library/setlogfeature.h | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index fcf8a4d32a3..ff321e88108 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -58,7 +58,7 @@ QIcon AnalysisFeature::getIcon() { return QIcon(":/images/library/ic_library_prepare.png"); } -void AnalysisFeature::bindRightPane(WLibrary* libraryWidget, +void AnalysisFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { m_pAnalysisView = new DlgAnalysis(libraryWidget, m_pConfig, diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 33f5e29d9a5..02c0b3fc1ce 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -33,7 +33,7 @@ class AnalysisFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); // TODO(jmigual): Still needs to be implemented diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index e15b75edd5a..911e82902b0 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -94,7 +94,7 @@ QIcon AutoDJFeature::getIcon() { return QIcon(":/images/library/ic_library_autodj.png"); } -void AutoDJFeature::bindRightPane(WLibrary* libraryWidget, +void AutoDJFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { m_pAutoDJView = new DlgAutoDJ(libraryWidget, m_pConfig, diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index f0ec38055c2..1939f9e7588 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -43,7 +43,7 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); void bindLeftPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 15c8f1d5c68..60d0a4c63fb 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -593,7 +593,7 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { return &m_childModel; } -void BasePlaylistFeature::bindRightPane(WLibrary* libraryWidget, +void BasePlaylistFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index cbf7d88d8ff..ceee1e78450 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -33,7 +33,7 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); void bindLeftPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 333b3977e47..a68a0015e4f 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -207,7 +207,7 @@ TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } -void BrowseFeature::bindRightPane(WLibrary* libraryWidget, +void BrowseFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 7464427baa8..dda4d525302 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -36,7 +36,7 @@ class BrowseFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); void bindLeftPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 0cbf9d4d534..a4a808b7334 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -178,7 +178,7 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { return !locked && formatSupported; } -void CrateFeature::bindRightPane(WLibrary* libraryWidget, +void CrateFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index f2dab7c919f..64947daca71 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -45,7 +45,7 @@ class CrateFeature : public LibraryFeature { QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); void bindLeftPane(WLibrary* libraryWidget, diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 8c237b1932f..da195a2bf4c 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -62,7 +62,7 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget // at the right pane. - virtual void bindRightPane(WLibrary* /* libraryWidget */, + virtual void bindLibraryWidget(WLibrary* /* libraryWidget */, KeyboardEventFilter* /* keyboard */) {} // Reimplement this to register custem views with the library widget, diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index d6b88f6b607..85619af2b05 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -123,7 +123,7 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { delete m_pLibraryTableModel; } -void MixxxLibraryFeature::bindRightPane(WLibrary* pLibraryWidget, +void MixxxLibraryFeature::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, m_pTrackCollection, pKeyboard); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 46ac2614585..0fe27dbfe0d 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -39,7 +39,7 @@ class MixxxLibraryFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); - void bindRightPane(WLibrary* pLibrary, + void bindLibraryWidget(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard); void bindLeftPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 7b29c1d9909..24dbb46a823 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -38,7 +38,7 @@ QIcon RecordingFeature::getIcon() { TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } -void RecordingFeature::bindRightPane(WLibrary* pLibraryWidget, +void RecordingFeature::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter *keyboard) { //The view will be deleted by LibraryWidget DlgRecording* pRecordingView = new DlgRecording(pLibraryWidget, diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 4802b1fd327..2fb1aa7549b 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -29,7 +29,7 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - void bindRightPane(WLibrary* libraryWidget, + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); void bindLeftPane(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index 252e1b1095a..acec453f553 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -53,9 +53,9 @@ QIcon SetlogFeature::getIcon() { return QIcon(":/images/library/ic_library_history.png"); } -void SetlogFeature::bindRightPane(WLibrary* libraryWidget, +void SetlogFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { - BasePlaylistFeature::bindRightPane(libraryWidget, + BasePlaylistFeature::bindLibraryWidget(libraryWidget, keyboard); connect(&PlayerInfo::instance(), SIGNAL(currentPlayingTrackChanged(TrackPointer)), this, SLOT(slotPlayingTrackChanged(TrackPointer))); diff --git a/src/library/setlogfeature.h b/src/library/setlogfeature.h index 1324f65879e..008477e9e38 100644 --- a/src/library/setlogfeature.h +++ b/src/library/setlogfeature.h @@ -23,7 +23,7 @@ class SetlogFeature : public BasePlaylistFeature { QVariant title(); QIcon getIcon(); - virtual void bindRightPane(WLibrary* libraryWidget, + virtual void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); public slots: From 1f51cfd29ed25c48378a855ca3ea88ae7b1f41ab Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 09:05:53 +0200 Subject: [PATCH 016/552] Add destructor and more name refactoring --- src/library/librarypanemanager.cpp | 39 ++++++++++++++++++++++++------ src/library/librarypanemanager.h | 14 ++++++----- src/skin/legacyskinparser.cpp | 2 +- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index ad3eccbfd1f..eb0c9f5ab6e 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -8,21 +8,29 @@ LibraryPaneManager::LibraryPaneManager(QObject* parent) } +LibraryPaneManager::~LibraryPaneManager() { + for (LibraryFeature* f : m_features) { + delete f; + } + m_features.clear(); +} + bool LibraryPaneManager::initialize() { - m_pLeftPane = nullptr; - m_pRightPane = nullptr; + m_pSidebarExpanded = nullptr; + m_pLibraryWidget = nullptr; } -void LibraryPaneManager::bindLeftPane(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard) { +void LibraryPaneManager::bindSidebarExpanded(WLibrary* leftWidget, + KeyboardEventFilter* pKeyboard) { } -void LibraryPaneManager::bindRightPane(WLibrary* rightWidget, - KeyboardEventFilter* pKeyboard) { - m_pRightPane = rightWidget; - +void LibraryPaneManager::bindLibraryWidget(WLibrary* rightWidget, + KeyboardEventFilter* pKeyboard) { + m_pLibraryWidget = rightWidget; + for (LibraryFeature* f : m_features) { - f->bindRightPane(m_pRightPane, pKeyboard); + f->bindLibraryWidget(m_pLibraryWidget, pKeyboard); } } @@ -32,6 +40,21 @@ void LibraryPaneManager::search(QString& text) { void LibraryPaneManager::addFeature(LibraryFeature* feature) { m_features.append(feature); + + connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), + this, SLOT(slotShowTrackModel(QAbstractItemModel*))); + connect(feature, SIGNAL(switchToView(const QString&)), + this, SLOT(slotSwitchToView(const QString&))); + connect(feature, SIGNAL(loadTrack(TrackPointer)), + this, SLOT(slotLoadTrack(TrackPointer))); + connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), + this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); + connect(feature, SIGNAL(restoreSearch(const QString&)), + this, SLOT(slotRestoreSearch(const QString&))); + connect(feature, SIGNAL(enableCoverArtDisplay(bool)), + this, SIGNAL(enableCoverArtDisplay(bool))); + connect(feature, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); } bool LibraryPaneManager::eventFilter(QObject* object, QEvent* event) { diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 829f6abb8c8..56826ae23e6 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -19,14 +19,16 @@ class LibraryPaneManager : public QObject { LibraryPaneManager(QObject* parent = nullptr); + ~LibraryPaneManager(); + bool initialize(); // All features must be added before adding a pane - void bindLeftPane(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard); - void bindRightPane(WLibrary* rightWidget, KeyboardEventFilter *pKeyboard); + void bindSidebarExpanded(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard); + void bindLibraryWidget(WLibrary* rightWidget, KeyboardEventFilter *pKeyboard); - inline WLibrary* getLeftPane() { return m_pLeftPane; } - inline WLibrary* getRightPane() { return m_pRightPane; } + inline WLibrary* getLeftPane() { return m_pSidebarExpanded; } + inline WLibrary* getRightPane() { return m_pLibraryWidget; } void addFeature(LibraryFeature* feature); @@ -37,8 +39,8 @@ class LibraryPaneManager : public QObject { private: - WLibrary* m_pLeftPane; - WLibrary* m_pRightPane; + WLibrary* m_pSidebarExpanded; + WLibrary* m_pLibraryWidget; QVector m_features; diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index ffc869eb5f9..d06d5dcb89b 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1246,7 +1246,7 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { connect(m_pLibrary, SIGNAL(search(const QString&)), pLibraryWidget, SLOT(search(const QString&))); - m_pLibrary->bindRightPane(pLibraryWidget, m_pKeyboard); + m_pLibrary->bindLibraryWidget(pLibraryWidget, m_pKeyboard); // This must come after the bindWidget or we will not style any of the // LibraryView's because they have not been added yet. From 1f3a6d5d999615d3ec3161b948449636b8febead Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 09:06:11 +0200 Subject: [PATCH 017/552] Moved features constructor to function --- src/library/library.cpp | 111 ++++++++++++++++++++-------------------- src/library/library.h | 11 ++-- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 75cfd24b709..1b0fc8e1617 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -63,53 +63,7 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, // TODO(rryan) -- turn this construction / adding of features into a static // method or something -- CreateDefaultLibrary - m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); - addFeature(m_pMixxxLibraryFeature); - - addFeature(new AutoDJFeature(this, pConfig, pPlayerManager, m_pTrackCollection)); - m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, m_pConfig); - addFeature(m_pPlaylistFeature); - m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, m_pConfig); - addFeature(m_pCrateFeature); - BrowseFeature* browseFeature = new BrowseFeature( - this, pConfig, m_pTrackCollection, m_pRecordingManager); - connect(browseFeature, SIGNAL(scanLibrary()), - &m_scanner, SLOT(scan())); - connect(&m_scanner, SIGNAL(scanStarted()), - browseFeature, SLOT(slotLibraryScanStarted())); - connect(&m_scanner, SIGNAL(scanFinished()), - browseFeature, SLOT(slotLibraryScanFinished())); - - addFeature(browseFeature); - addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); - addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); - m_pAnalysisFeature = new AnalysisFeature(this, pConfig, m_pTrackCollection); - connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), - m_pAnalysisFeature, SLOT(analyzeTracks(QList))); - connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), - m_pAnalysisFeature, SLOT(analyzeTracks(QList))); - addFeature(m_pAnalysisFeature); - //iTunes and Rhythmbox should be last until we no longer have an obnoxious - //messagebox popup when you select them. (This forces you to reach for your - //mouse or keyboard if you're using MIDI control and you scroll through them...) - if (RhythmboxFeature::isSupported() && - pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { - addFeature(new RhythmboxFeature(this, m_pTrackCollection)); - } - if (pConfig->getValueString(ConfigKey("[Library]","ShowBansheeLibrary"),"1").toInt()) { - BansheeFeature::prepareDbPath(pConfig); - if (BansheeFeature::isSupported()) { - addFeature(new BansheeFeature(this, m_pTrackCollection, pConfig)); - } - } - if (ITunesFeature::isSupported() && - pConfig->getValueString(ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()) { - addFeature(new ITunesFeature(this, m_pTrackCollection)); - } - if (TraktorFeature::isSupported() && - pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { - addFeature(new TraktorFeature(this, m_pTrackCollection)); - } + createFeatures(); // On startup we need to check if all of the user's library folders are // accessible to us. If the user is using a database from <1.12.0 with @@ -138,11 +92,6 @@ Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; - for (LibraryFeature* f : m_features) { - delete f; - } - m_features.clear(); - for (LibraryPaneManager* p : m_panes) { delete p; } @@ -178,7 +127,7 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { pSidebarWidget, SLOT(slotSetFont(QFont))); } -void Library::bindRightPane(WLibrary* pLibraryWidget, +void Library::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); @@ -221,7 +170,7 @@ void Library::bindRightPane(WLibrary* pLibraryWidget, emit(setTrackTableRowHeight(m_iTrackTableRowHeight)); } -void Library::bindLeftPane(WLibrary *leftPane, KeyboardEventFilter *pKeyboard) { +void Library::bindSidebarExpanded(WLibrary *leftPane, KeyboardEventFilter *pKeyboard) { } @@ -229,7 +178,9 @@ void Library::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; } - m_features.push_back(feature); + + m_panes.last()->addFeature(feature); + m_pSidebarModel->addLibraryFeature(feature); connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), this, SLOT(slotShowTrackModel(QAbstractItemModel*))); @@ -384,3 +335,53 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { m_iTrackTableRowHeight = rowHeight; emit(setTrackTableRowHeight(rowHeight)); } + +void Library::createFeatures() { + m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); + addFeature(m_pMixxxLibraryFeature); + + addFeature(new AutoDJFeature(this, pConfig, pPlayerManager, m_pTrackCollection)); + m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, m_pConfig); + addFeature(m_pPlaylistFeature); + m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, m_pConfig); + addFeature(m_pCrateFeature); + BrowseFeature* browseFeature = new BrowseFeature( + this, pConfig, m_pTrackCollection, m_pRecordingManager); + connect(browseFeature, SIGNAL(scanLibrary()), + &m_scanner, SLOT(scan())); + connect(&m_scanner, SIGNAL(scanStarted()), + browseFeature, SLOT(slotLibraryScanStarted())); + connect(&m_scanner, SIGNAL(scanFinished()), + browseFeature, SLOT(slotLibraryScanFinished())); + + addFeature(browseFeature); + addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); + addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); + m_pAnalysisFeature = new AnalysisFeature(this, pConfig, m_pTrackCollection); + connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), + m_pAnalysisFeature, SLOT(analyzeTracks(QList))); + connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), + m_pAnalysisFeature, SLOT(analyzeTracks(QList))); + addFeature(m_pAnalysisFeature); + //iTunes and Rhythmbox should be last until we no longer have an obnoxious + //messagebox popup when you select them. (This forces you to reach for your + //mouse or keyboard if you're using MIDI control and you scroll through them...) + if (RhythmboxFeature::isSupported() && + pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { + addFeature(new RhythmboxFeature(this, m_pTrackCollection)); + } + if (pConfig->getValueString(ConfigKey("[Library]","ShowBansheeLibrary"),"1").toInt()) { + BansheeFeature::prepareDbPath(pConfig); + if (BansheeFeature::isSupported()) { + addFeature(new BansheeFeature(this, m_pTrackCollection, pConfig)); + } + } + if (ITunesFeature::isSupported() && + pConfig->getValueString(ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()) { + addFeature(new ITunesFeature(this, m_pTrackCollection)); + } + if (TraktorFeature::isSupported() && + pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { + addFeature(new TraktorFeature(this, m_pTrackCollection)); + } +} diff --git a/src/library/library.h b/src/library/library.h index 583051c0cc7..9c7a3e3a07d 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -45,10 +45,10 @@ class Library : public QObject { RecordingManager* pRecordingManager); virtual ~Library(); - void bindRightPane(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard); - void bindLeftPane(WLibrary* leftPane, - KeyboardEventFilter* pKeyboard); + void bindLibraryWidget(WLibrary* libraryWidget, + KeyboardEventFilter* pKeyboard); + void bindSidebarExpanded(WLibrary* leftPane, + KeyboardEventFilter* pKeyboard); void bindSidebarWidget(WLibrarySidebar* sidebarWidget); @@ -126,7 +126,6 @@ class Library : public QObject { UserSettingsPointer m_pConfig; SidebarModel* m_pSidebarModel; TrackCollection* m_pTrackCollection; - QList m_features; const static QString m_sTrackViewName; const static QString m_sAutoDJViewName; MixxxLibraryFeature* m_pMixxxLibraryFeature; @@ -139,6 +138,8 @@ class Library : public QObject { QFont m_trackTableFont; int m_iTrackTableRowHeight; QList m_panes; + + void createFeatures(); }; #endif /* LIBRARY_H */ From 13919989a4072c7597d7fb8f9655929ce4c8880e Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 09:32:41 +0200 Subject: [PATCH 018/552] Missed to commit rename --- src/library/library.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 1b0fc8e1617..9ccc2973efd 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -161,7 +161,7 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, QListIterator feature_it(m_features); while(feature_it.hasNext()) { LibraryFeature* feature = feature_it.next(); - feature->bindRightPane(pLibraryWidget, pKeyboard); + feature->bindLibraryWidget(pLibraryWidget, pKeyboard); } // Set the current font and row height on all the WTrackTableViews that were From 4ed43ae3d1621f9ca2307a0387aaf5bc1a5fc063 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 11:47:37 +0200 Subject: [PATCH 019/552] Move many functions from library to library pane manager --- src/library/library.cpp | 9 +++++++-- src/library/librarypanemanager.h | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 9ccc2973efd..44d6a3fd113 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -129,7 +129,7 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { void Library::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { - WTrackTableView* pTrackTableView = + /*WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); pTrackTableView->installEventFilter(pKeyboard); connect(this, SIGNAL(showTrackModel(QAbstractItemModel*)), @@ -156,6 +156,11 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, connect(this, SIGNAL(searchCleared()), pTrackTableView, SLOT(onSearchCleared())); + */ + + m_panes.append(new LibraryPaneManager); + m_panes.last()->bindLibraryWidget(pLibraryWidget, pKeyboard); + m_pLibraryControl->bindWidget(pLibraryWidget, pKeyboard); QListIterator feature_it(m_features); @@ -163,7 +168,7 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, LibraryFeature* feature = feature_it.next(); feature->bindLibraryWidget(pLibraryWidget, pKeyboard); } - + // Set the current font and row height on all the WTrackTableViews that were // just connected to us. emit(setTrackTableFont(m_trackTableFont)); diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 56826ae23e6..3ea258dbfb2 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -34,7 +34,21 @@ class LibraryPaneManager : public QObject { public slots: - void search(QString& text); + void slotShowTrackModel(QAbstractItemModel* model); + void slotSwitchToView(const QString& view); + void slotLoadTrack(TrackPointer pTrack); + void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); + void slotLoadLocationToPlayer(QString location, QString group); + void slotRestoreSearch(const QString& text); + void slotRefreshLibraryModels(); + //void slotCreatePlaylist(); + //void slotCreateCrate(); + //void slotRequestAddDir(QString directory); + //void slotRequestRemoveDir(QString directory, Library::RemovalType removalType); + //void slotRequestRelocateDir(QString previousDirectory, QString newDirectory); + void onSkinLoadFinished(); + void slotSetTrackTableFont(const QFont& font); + void slotSetTrackTableRowHeight(int rowHeight); private: From 6525b48ed6fff6762a4e9d28e174f706e65f7a05 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 13:33:58 +0200 Subject: [PATCH 020/552] Change features names --- src/library/analysisfeature.h | 2 +- src/library/baseplaylistfeature.h | 2 +- src/library/browse/browsefeature.h | 2 +- src/library/cratefeature.h | 2 +- src/library/library.cpp | 19 ++++--------------- src/library/library.h | 6 ++++-- src/library/libraryfeature.h | 2 +- src/library/mixxxlibraryfeature.h | 2 +- src/library/recording/recordingfeature.h | 2 +- 9 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 02c0b3fc1ce..5e406325ea7 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -37,7 +37,7 @@ class AnalysisFeature : public LibraryFeature { KeyboardEventFilter* keyboard); // TODO(jmigual): Still needs to be implemented - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index ceee1e78450..1d4544095fd 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -35,7 +35,7 @@ class BasePlaylistFeature : public LibraryFeature { void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} signals: diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index dda4d525302..0ae04fd903e 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,7 @@ class BrowseFeature : public LibraryFeature { void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 64947daca71..bb596b29596 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -48,7 +48,7 @@ class CrateFeature : public LibraryFeature { void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); diff --git a/src/library/library.cpp b/src/library/library.cpp index 44d6a3fd113..9129eece14e 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -63,7 +63,7 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, // TODO(rryan) -- turn this construction / adding of features into a static // method or something -- CreateDefaultLibrary - createFeatures(); + createFeatures(pConfig, pPlayerManager); // On startup we need to check if all of the user's library folders are // accessible to us. If the user is using a database from <1.12.0 with @@ -91,11 +91,6 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; - - for (LibraryPaneManager* p : m_panes) { - delete p; - } - m_panes.clear(); delete m_pLibraryControl; //IMPORTANT: m_pTrackCollection gets destroyed via the QObject hierarchy somehow. @@ -129,7 +124,7 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { void Library::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { - /*WTrackTableView* pTrackTableView = + WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); pTrackTableView->installEventFilter(pKeyboard); connect(this, SIGNAL(showTrackModel(QAbstractItemModel*)), @@ -155,12 +150,8 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, pTrackTableView, SLOT(onSearchStarting())); connect(this, SIGNAL(searchCleared()), pTrackTableView, SLOT(onSearchCleared())); - - */ - - m_panes.append(new LibraryPaneManager); - m_panes.last()->bindLibraryWidget(pLibraryWidget, pKeyboard); + m_panes.append(pLibraryWidget); m_pLibraryControl->bindWidget(pLibraryWidget, pKeyboard); QListIterator feature_it(m_features); @@ -184,8 +175,6 @@ void Library::addFeature(LibraryFeature* feature) { return; } - m_panes.last()->addFeature(feature); - m_pSidebarModel->addLibraryFeature(feature); connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), this, SLOT(slotShowTrackModel(QAbstractItemModel*))); @@ -341,7 +330,7 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::createFeatures() { +void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); addFeature(m_pMixxxLibraryFeature); diff --git a/src/library/library.h b/src/library/library.h index 9c7a3e3a07d..ef638186e40 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -137,9 +137,11 @@ class Library : public QObject { LibraryScanner m_scanner; QFont m_trackTableFont; int m_iTrackTableRowHeight; - QList m_panes; + //QList m_panes; + QList m_features; + QList m_panes; - void createFeatures(); + void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); }; #endif /* LIBRARY_H */ diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index da195a2bf4c..8dc62cc0140 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -67,7 +67,7 @@ class LibraryFeature : public QObject { // Reimplement this to register custem views with the library widget, // at the left pane - virtual void bindLeftPane(WLibrary*, + virtual void bindSidebarWidget(WLibrary*, KeyboardEventFilter*) {} virtual TreeItemModel* getChildModel() = 0; diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 0fe27dbfe0d..34a0b9c7d99 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -41,7 +41,7 @@ class MixxxLibraryFeature : public LibraryFeature { TreeItemModel* getChildModel(); void bindLibraryWidget(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} public slots: diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 2fb1aa7549b..82b2b6ec4ca 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -31,7 +31,7 @@ class RecordingFeature : public LibraryFeature { void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); From 2763551a22cbca508a2cbbb86101bd0fbff3a51e Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 13:53:21 +0200 Subject: [PATCH 021/552] Missed name change --- src/library/autodj/autodjfeature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 1939f9e7588..febd158fcdf 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -45,7 +45,7 @@ class AutoDJFeature : public LibraryFeature { void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard); - void bindLeftPane(WLibrary* libraryWidget, + void bindSidebarWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) {} TreeItemModel* getChildModel(); From 37c433e03bdef75e2e1c2ac60f90d869ddaa0695 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 13:53:40 +0200 Subject: [PATCH 022/552] Add again features vector --- src/library/library.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/library/library.cpp b/src/library/library.cpp index 9129eece14e..2f23e9d4f17 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -91,6 +91,11 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; + + for (LibraryFeature* f : m_features) { + delete f; + } + m_features.clear(); delete m_pLibraryControl; //IMPORTANT: m_pTrackCollection gets destroyed via the QObject hierarchy somehow. @@ -174,6 +179,7 @@ void Library::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; } + m_features.append(feature); m_pSidebarModel->addLibraryFeature(feature); connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), From bf599dc9b84a8bb8bdbdb36e879693654042b939 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 13:54:04 +0200 Subject: [PATCH 023/552] Add focused() signal in wlibrary --- src/widget/wlibrary.cpp | 11 +++++++++++ src/widget/wlibrary.h | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrary.cpp index bcd01d52edd..128369b06de 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrary.cpp @@ -12,6 +12,7 @@ WLibrary::WLibrary(QWidget* parent) : QStackedWidget(parent), WBaseWidget(this), m_mutex(QMutex::Recursive) { + } bool WLibrary::registerView(QString name, QWidget* view) { @@ -25,6 +26,7 @@ bool WLibrary::registerView(QString name, QWidget* view) { << "Ignoring."; return false; } + view->installEventFilter(this); addWidget(view); m_viewMap[name] = view; return true; @@ -67,9 +69,18 @@ LibraryView* WLibrary::getActiveView() const { return dynamic_cast(currentWidget()); } +bool WLibrary::eventFilter(QObject*, QEvent* pEvent) { + if (pEvent->type() == QEvent::FocusIn) { + emit(focused()); + } + return false; +} + + bool WLibrary::event(QEvent* pEvent) { if (pEvent->type() == QEvent::ToolTip) { updateTooltip(); } + return QStackedWidget::event(pEvent); } diff --git a/src/widget/wlibrary.h b/src/widget/wlibrary.h index 6c6ccb943ff..35a03a8f16d 100644 --- a/src/widget/wlibrary.h +++ b/src/widget/wlibrary.h @@ -29,6 +29,12 @@ class WLibrary : public QStackedWidget, public WBaseWidget { bool registerView(QString name, QWidget* view); LibraryView* getActiveView() const; + + bool eventFilter(QObject*, QEvent* pEvent); + + signals: + + void focused(); public slots: // Show the view registered with the given name. Does nothing if the current From e708c84d3aff688b9ef6d7796b87c7f201a6764b Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 18:40:46 +0200 Subject: [PATCH 024/552] Comment code to allow compiling --- src/library/librarypanemanager.cpp | 155 ++++++++++++++++++++++++++--- src/library/librarypanemanager.h | 11 +- 2 files changed, 146 insertions(+), 20 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index eb0c9f5ab6e..74b6ecd3036 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -15,16 +15,6 @@ LibraryPaneManager::~LibraryPaneManager() { m_features.clear(); } -bool LibraryPaneManager::initialize() { - m_pSidebarExpanded = nullptr; - m_pLibraryWidget = nullptr; -} - -void LibraryPaneManager::bindSidebarExpanded(WLibrary* leftWidget, - KeyboardEventFilter* pKeyboard) { - -} - void LibraryPaneManager::bindLibraryWidget(WLibrary* rightWidget, KeyboardEventFilter* pKeyboard) { m_pLibraryWidget = rightWidget; @@ -33,11 +23,7 @@ void LibraryPaneManager::bindLibraryWidget(WLibrary* rightWidget, f->bindLibraryWidget(m_pLibraryWidget, pKeyboard); } } - -void LibraryPaneManager::search(QString& text) { - -} - +/* void LibraryPaneManager::addFeature(LibraryFeature* feature) { m_features.append(feature); @@ -57,6 +43,145 @@ void LibraryPaneManager::addFeature(LibraryFeature* feature) { this, SIGNAL(trackSelected(TrackPointer))); } + +void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { + //qDebug() << "LibraryPaneManager::slotShowTrackModel" << model; + TrackModel* trackModel = dynamic_cast(model); + DEBUG_ASSERT_AND_HANDLE(trackModel) { + return; + } + emit(showTrackModel(model)); + emit(switchToView(m_sTrackViewName)); + emit(restoreSearch(trackModel->currentSearch())); +} + +void LibraryPaneManager::slotSwitchToView(const QString& view) { + //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; + emit(switchToView(view)); +} + +void LibraryPaneManager::slotLoadTrack(TrackPointer pTrack) { + emit(loadTrack(pTrack)); +} + +void LibraryPaneManager::slotLoadLocationToPlayer(QString location, QString group) { + TrackPointer pTrack = m_pTrackCollection->getTrackDAO() + .getOrAddTrack(location, true, NULL); + if (!pTrack.isNull()) { + emit(loadTrackToPlayer(pTrack, group)); + } +} + +void LibraryPaneManager::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play) { + emit(loadTrackToPlayer(pTrack, group, play)); +} + +void LibraryPaneManager::slotRestoreSearch(const QString& text) { + emit(restoreSearch(text)); +} + +void LibraryPaneManager::slotRefreshLibraryModels() { + m_pMixxxLibraryFeature->refreshLibraryModels(); + m_pAnalysisFeature->refreshLibraryModels(); +} +/* +void LibraryPaneManager::slotCreatePlaylist() { + m_pPlaylistFeature->slotCreatePlaylist(); +} + +void LibraryPaneManager::slotCreateCrate() { + m_pCrateFeature->slotCreateCrate(); +} + +void LibraryPaneManager::onSkinLoadFinished() { + // Enable the default selection when a new skin is loaded. + m_pSidebarModel->activateDefaultSelection(); +} + +void LibraryPaneManager::slotRequestAddDir(QString dir) { + // We only call this method if the user has picked a new directory via a + // file dialog. This means the system sandboxer (if we are sandboxed) has + // granted us permission to this folder. Create a security bookmark while we + // have permission so that we can access the folder on future runs. We need + // to canonicalize the path so we first wrap the directory string with a + // QDir. + QDir directory(dir); + Sandbox::createSecurityToken(directory); + + if (!m_pTrackCollection->getDirectoryDAO().addDirectory(dir)) { + QMessageBox::information(0, tr("Add Directory to Library"), + tr("Could not add the directory to your library. Either this " + "directory is already in your library or you are currently " + "rescanning your library.")); + } + // set at least one directory in the config file so that it will be possible + // to downgrade from 1.12 + if (m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR).length() < 1) { + m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, dir); + } +} + +void LibraryPaneManager::slotRequestRemoveDir(QString dir, RemovalType removalType) { + switch (removalType) { + case LibraryPaneManager::HideTracks: + // Mark all tracks in this directory as deleted but DON'T purge them + // in case the user re-adds them manually. + m_pTrackCollection->getTrackDAO().markTracksAsMixxxDeleted(dir); + break; + case LibraryPaneManager::PurgeTracks: + // The user requested that we purge all metadata. + m_pTrackCollection->getTrackDAO().purgeTracks(dir); + break; + case LibraryPaneManager::LeaveTracksUnchanged: + default: + break; + + } + + // Remove the directory from the directory list. + m_pTrackCollection->getDirectoryDAO().removeDirectory(dir); + + // Also update the config file if necessary so that downgrading is still + // possible. + QString confDir = m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR); + + if (QDir(dir) == QDir(confDir)) { + QStringList dirList = m_pTrackCollection->getDirectoryDAO().getDirs(); + if (!dirList.isEmpty()) { + m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, dirList.first()); + } else { + // Save empty string so that an old version of mixxx knows it has to + // ask for a new directory. + m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, QString()); + } + } +} + +void LibraryPaneManager::slotRequestRelocateDir(QString oldDir, QString newDir) { + m_pTrackCollection->relocateDirectory(oldDir, newDir); + + // also update the config file if necessary so that downgrading is still + // possible + QString conDir = m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR); + if (oldDir == conDir) { + m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, newDir); + } +} + +*/ +/* + +void LibraryPaneManager::slotSetTrackTableFont(const QFont& font) { + m_trackTableFont = font; + emit(setTrackTableFont(font)); +} + +void LibraryPaneManager::slotSetTrackTableRowHeight(int rowHeight) { + m_iTrackTableRowHeight = rowHeight; + emit(setTrackTableRowHeight(rowHeight)); +} +*/ + bool LibraryPaneManager::eventFilter(QObject* object, QEvent* event) { //QObject::eventFilter(object, event); diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 3ea258dbfb2..772ac1fbe4f 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -24,16 +24,15 @@ class LibraryPaneManager : public QObject { bool initialize(); // All features must be added before adding a pane - void bindSidebarExpanded(WLibrary* leftWidget, KeyboardEventFilter *pKeyboard); void bindLibraryWidget(WLibrary* rightWidget, KeyboardEventFilter *pKeyboard); - inline WLibrary* getLeftPane() { return m_pSidebarExpanded; } inline WLibrary* getRightPane() { return m_pLibraryWidget; } void addFeature(LibraryFeature* feature); + //void addFeatures(Q) public slots: - +/* void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); void slotLoadTrack(TrackPointer pTrack); @@ -49,17 +48,19 @@ class LibraryPaneManager : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - + */ private: - WLibrary* m_pSidebarExpanded; WLibrary* m_pLibraryWidget; QVector m_features; QVector m_currentFeature; int m_currentPane; + + QFont m_trackTableFont; + int m_iTrackTableRowHeight; private slots: From 5108305dfe4844b8ca2d5fe689baa6caa08b8403 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 19:39:29 +0200 Subject: [PATCH 025/552] Create button bar --- src/widget/wbuttonbar.cpp | 20 +++++++++++++++++--- src/widget/wbuttonbar.h | 19 +++++++++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 21ac1405845..5d4675e595b 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -1,11 +1,25 @@ #include "wbuttonbar.h" -WButtonBar::WButtonBar(QWidget *parent) - : QWidget(parent) { +WButtonBar::WButtonBar(QWidget* parent) + : QWidget(parent) { + m_pLayout = new QVBoxLayout(this); + this->setLayout(m_pLayout); + + m_pButtonGroup = new QButtonGroup(this); + connect(m_pButtonGroup, SIGNAL(buttonClicked(int)), + this, SLOT(slotButtonClicked(int))); +} + +void WButtonBar::slotButtonClicked(int id) { + emit(buttonClicked(m_data[id])); } -void WButtonBar::addItem(QIcon icon, QVariant title, QVariant data) { +void WButtonBar::addItem(const QIcon& icon, const QVariant& title, const QVariant& data) { + QPushButton* button = new QPushButton(icon, title.toString(), this); + m_pButtonGroup->addButton(button, m_data.size()); + m_pLayout->addWidget(button); + m_data.append(data); } diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index d3218c7526a..e027d9fda68 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -1,26 +1,33 @@ #ifndef WBUTTONBAR_H #define WBUTTONBAR_H -#include #include #include #include +#include +#include -class WButtonBar : QWidget +#include "widget/wwidget.h" + +class WButtonBar : WWidget { - Q_OBJECT + Q_OBJECT public: WButtonBar(QWidget* parent = nullptr); - - void addItem(QIcon icon, QVariant title, QVariant data); signals: - void clicked(QVariant data); + void buttonClicked(QVariant data); + + private slots: + + void slotButtonClicked(int id); private: QLayout* m_pLayout; + QButtonGroup* m_pButtonGroup; + QList m_data; }; #endif // WBUTTONBAR_H From 96abc8527a6be07561c39aab51e2cf4075985c2b Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 19:39:52 +0200 Subject: [PATCH 026/552] Handle focus --- src/library/library.cpp | 19 ++++++++++++++++++- src/library/library.h | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 2f23e9d4f17..f894c828b3b 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -50,7 +50,8 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, m_pTrackCollection(new TrackCollection(pConfig)), m_pLibraryControl(new LibraryControl(this)), m_pRecordingManager(pRecordingManager), - m_scanner(m_pTrackCollection, pConfig) { + m_scanner(m_pTrackCollection, pConfig), + m_pSidebarExpanded(nullptr) { qRegisterMetaType("Library::RemovalType"); connect(&m_scanner, SIGNAL(scanStarted()), @@ -336,6 +337,22 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } +void Library::libraryWidgetFocused() { + WLibrary* pane = dynamic_cast(sender()); + DEBUG_ASSERT_AND_HANDLE(pane) { + return; + } + + if (pane == m_pSidebarExpanded) m_focusedWidget = -1; + + for (int i = 0; i < m_panes; ++i) { + if (m_panes[i] == pane) { + m_focusedWidget = i; + break; + } + } +} + void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); addFeature(m_pMixxxLibraryFeature); diff --git a/src/library/library.h b/src/library/library.h index ef638186e40..35bc172c448 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -97,6 +97,7 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); + void libraryWidgetFocused(); void scan() { m_scanner.scan(); @@ -140,6 +141,10 @@ class Library : public QObject { //QList m_panes; QList m_features; QList m_panes; + WLibrary* m_pSidebarExpanded; + + // -1 for the Sidebar Expanded and >= 0 for the other widgets + int m_focusedWidget; void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); }; From 46505399b7271b28e1db0bd765a9d1b423e1760a Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 19:43:38 +0200 Subject: [PATCH 027/552] Rename add button function --- src/widget/wbuttonbar.cpp | 4 ++-- src/widget/wbuttonbar.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 5d4675e595b..25f50cee536 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -4,7 +4,7 @@ WButtonBar::WButtonBar(QWidget* parent) : QWidget(parent) { m_pLayout = new QVBoxLayout(this); - this->setLayout(m_pLayout); + setLayout(m_pLayout); m_pButtonGroup = new QButtonGroup(this); connect(m_pButtonGroup, SIGNAL(buttonClicked(int)), @@ -15,7 +15,7 @@ void WButtonBar::slotButtonClicked(int id) { emit(buttonClicked(m_data[id])); } -void WButtonBar::addItem(const QIcon& icon, const QVariant& title, const QVariant& data) { +void WButtonBar::addButton(const QIcon& icon, const QVariant& title, const QVariant& data) { QPushButton* button = new QPushButton(icon, title.toString(), this); m_pButtonGroup->addButton(button, m_data.size()); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index e027d9fda68..3adb9d87dd5 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -15,12 +15,14 @@ class WButtonBar : WWidget public: WButtonBar(QWidget* parent = nullptr); + void addButton(const QIcon& icon, const QVariant& title, const QVariant& data); + signals: void buttonClicked(QVariant data); private slots: - + void slotButtonClicked(int id); private: From 6baa8d0eb10d47f50d2c891e8792a01b0f6b27ab Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 20:05:17 +0200 Subject: [PATCH 028/552] Added stub --- src/library/cratefeature.h | 2 +- src/library/libraryfeature.h | 6 ++++++ src/library/libraryviewfeature.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index bb596b29596..91da6811838 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -34,7 +34,7 @@ class CrateFeature : public LibraryFeature { inline QVariant getTitle() { return title(); } QIcon getIcon(); - inline QString getName() { return "CRATE_FEATURE"; } + inline QString getDefaultNameView() { return "CRATE_FEATURE"; } QWidget* getLeftPane() { return new QWidget(); } QWidget* getRightPane() { return new QWidget(); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 8dc62cc0140..4d9eac4bcb4 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -37,6 +37,12 @@ class LibraryFeature : public QObject { virtual QVariant title() = 0; virtual QIcon getIcon() = 0; + // Must be a unique name for each feature, it must be a unique name for each + // different feature + virtual QString getDefaultNameView() { + // TODO(jmigual): This is a STUB must be removed later + return "DEFAULT_FEATURE"; + } virtual bool dropAccept(QList urls, QObject* pSource) { Q_UNUSED(urls); diff --git a/src/library/libraryviewfeature.h b/src/library/libraryviewfeature.h index ab7448e050e..06e435a707f 100644 --- a/src/library/libraryviewfeature.h +++ b/src/library/libraryviewfeature.h @@ -19,7 +19,7 @@ class LibraryViewFeature : public LibraryFeature { // Must be a unique name for each feature type, it will be used in // the button bar to distinguish one feature from another - virtual QString getName() = 0; + virtual QString getDefaultNameView() = 0; // A LibraryViewFeature always has a right and a left pane virtual QWidget* getLeftPane() = 0; From e8b96f320a782b18c90c38f6afb8347891fe7fd5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 7 Jun 2016 20:05:36 +0200 Subject: [PATCH 029/552] Added button bar bind function --- src/library/library.cpp | 11 ++++++++++- src/library/library.h | 2 ++ src/widget/wbuttonbar.cpp | 4 ++-- src/widget/wbuttonbar.h | 8 ++++---- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index f894c828b3b..546b009b11d 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -128,6 +128,15 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { pSidebarWidget, SLOT(slotSetFont(QFont))); } +void Library::bindSidebar(WButtonBar* sidebar) { + connect(sidebar, SIGNAL(buttonClicked(const QString&)), + this, SIGNAL(switchToView(const QString&))); + + for (LibraryFeature* f : m_features) { + sidebar->addButton(f->getIcon(), f->title(), f->getDefaultNameView()); + } +} + void Library::bindLibraryWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { WTrackTableView* pTrackTableView = @@ -345,7 +354,7 @@ void Library::libraryWidgetFocused() { if (pane == m_pSidebarExpanded) m_focusedWidget = -1; - for (int i = 0; i < m_panes; ++i) { + for (int i = 0; i < m_panes.size(); ++i) { if (m_panes[i] == pane) { m_focusedWidget = i; break; diff --git a/src/library/library.h b/src/library/library.h index 35bc172c448..facbec607de 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -51,6 +51,8 @@ class Library : public QObject { KeyboardEventFilter* pKeyboard); void bindSidebarWidget(WLibrarySidebar* sidebarWidget); + + void bindSidebar(WButtonBar* sidebar); void addFeature(LibraryFeature* feature); QStringList getDirs(); diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 25f50cee536..7e6eff28e99 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -1,7 +1,7 @@ #include "wbuttonbar.h" WButtonBar::WButtonBar(QWidget* parent) - : QWidget(parent) { + : WWidget(parent) { m_pLayout = new QVBoxLayout(this); setLayout(m_pLayout); @@ -15,7 +15,7 @@ void WButtonBar::slotButtonClicked(int id) { emit(buttonClicked(m_data[id])); } -void WButtonBar::addButton(const QIcon& icon, const QVariant& title, const QVariant& data) { +void WButtonBar::addButton(const QIcon& icon, const QVariant& title, const QString& data) { QPushButton* button = new QPushButton(icon, title.toString(), this); m_pButtonGroup->addButton(button, m_data.size()); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 3adb9d87dd5..cccaa30535e 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -9,17 +9,17 @@ #include "widget/wwidget.h" -class WButtonBar : WWidget +class WButtonBar : public WWidget { Q_OBJECT public: WButtonBar(QWidget* parent = nullptr); - void addButton(const QIcon& icon, const QVariant& title, const QVariant& data); + void addButton(const QIcon& icon, const QVariant& title, const QString& data); signals: - void buttonClicked(QVariant data); + void buttonClicked(const QString&); private slots: @@ -29,7 +29,7 @@ class WButtonBar : WWidget QLayout* m_pLayout; QButtonGroup* m_pButtonGroup; - QList m_data; + QList m_data; }; #endif // WBUTTONBAR_H From ba81ef76d6dac854bf2c95d83eba830debfe7aa0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 09:11:42 +0200 Subject: [PATCH 030/552] Changed pointers implementations --- src/library/library.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 546b009b11d..5680e83dddb 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -93,9 +93,7 @@ Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; - for (LibraryFeature* f : m_features) { - delete f; - } + qDeleteAll(m_features); m_features.clear(); delete m_pLibraryControl; @@ -347,7 +345,7 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { } void Library::libraryWidgetFocused() { - WLibrary* pane = dynamic_cast(sender()); + WLibrary* pane = qobject_cast(sender()); DEBUG_ASSERT_AND_HANDLE(pane) { return; } From bf93228fd73114dc9fb15a350adf64a60337ed42 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 16:37:44 +0200 Subject: [PATCH 031/552] Changed button bar for better compatibility with current code --- src/library/library.cpp | 3 ++- src/widget/wbuttonbar.cpp | 10 ++++------ src/widget/wbuttonbar.h | 12 +----------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 5680e83dddb..87e18044142 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -131,7 +131,8 @@ void Library::bindSidebar(WButtonBar* sidebar) { this, SIGNAL(switchToView(const QString&))); for (LibraryFeature* f : m_features) { - sidebar->addButton(f->getIcon(), f->title(), f->getDefaultNameView()); + QAbstractButton* button = sidebar->addButton(f->getIcon(), f->title()); + connect(button, SIGNAL(clicked()), f, SLOT(activate())); } } diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 7e6eff28e99..3de9278bffe 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -7,19 +7,17 @@ WButtonBar::WButtonBar(QWidget* parent) setLayout(m_pLayout); m_pButtonGroup = new QButtonGroup(this); - connect(m_pButtonGroup, SIGNAL(buttonClicked(int)), - this, SLOT(slotButtonClicked(int))); } void WButtonBar::slotButtonClicked(int id) { emit(buttonClicked(m_data[id])); } -void WButtonBar::addButton(const QIcon& icon, const QVariant& title, const QString& data) { +QAbstractButton* WButtonBar::addButton(const QIcon& icon, const QVariant& title) { + QPushButton* button = new QPushButton(icon, title.toString(), this); - - m_pButtonGroup->addButton(button, m_data.size()); + m_pLayout->addWidget(button); - m_data.append(data); + return button; } diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index cccaa30535e..57f3f1c1b72 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -15,21 +15,11 @@ class WButtonBar : public WWidget public: WButtonBar(QWidget* parent = nullptr); - void addButton(const QIcon& icon, const QVariant& title, const QString& data); - - signals: - - void buttonClicked(const QString&); - - private slots: - - void slotButtonClicked(int id); + QAbstractButton* addButton(const QIcon& icon, const QVariant& title); private: QLayout* m_pLayout; - QButtonGroup* m_pButtonGroup; - QList m_data; }; #endif // WBUTTONBAR_H From 694faa4eeb8ee6fa2bd0fc5e49d4318bb491e8f7 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 16:59:07 +0200 Subject: [PATCH 032/552] Added more widgets to handle --- src/library/library.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/library/library.h b/src/library/library.h index facbec607de..0b056a23d2f 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -142,7 +142,9 @@ class Library : public QObject { int m_iTrackTableRowHeight; //QList m_panes; QList m_features; + QList m_trackTables; QList m_panes; + QList m_searches; WLibrary* m_pSidebarExpanded; // -1 for the Sidebar Expanded and >= 0 for the other widgets From 10cf1925021488daaa221a577c4cfbb1b36367ea Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 16:59:57 +0200 Subject: [PATCH 033/552] Added new slots and handle multiple panes slot --- src/library/library.cpp | 30 +++++++++++++++++++++++++----- src/library/library.h | 6 ++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 87e18044142..6bf3f39d652 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -29,8 +29,6 @@ #include "util/sandbox.h" #include "util/assert.h" -#include "widget/wtracktableview.h" -#include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -213,9 +211,19 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { DEBUG_ASSERT_AND_HANDLE(trackModel) { return; } - emit(showTrackModel(model)); - emit(switchToView(m_sTrackViewName)); - emit(restoreSearch(trackModel->currentSearch())); + + if (m_focusedWidget < 0) { + // The sidebar expanded has not a track model + return; + } + + m_trackTables[m_focusedWidget]->loadTrackModel(model); + m_panes[m_focusedWidget]->switchToView(m_sTrackViewName); + m_searches[m_focusedWidget]->restoreSearch(trackModel->currentSearch()); + + //emit(showTrackModel(model)); + //emit(switchToView(m_sTrackViewName)); + //emit(restoreSearch(trackModel->currentSearch())); } void Library::slotSwitchToView(const QString& view) { @@ -361,6 +369,18 @@ void Library::libraryWidgetFocused() { } } +void Library::slotSearch(const QString& text) { + +} + +void Library::slotSearchCleared() { + +} + +void Library::slotSearchStarting() { + +} + void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); addFeature(m_pMixxxLibraryFeature); diff --git a/src/library/library.h b/src/library/library.h index 0b056a23d2f..061b07c2785 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -21,6 +21,9 @@ #include "library/scanner/libraryscanner.h" #include "library/librarypanemanager.h" +#include "widget/wtracktableview.h" +#include "widget/wlibrary.h" + class TrackModel; class TrackCollection; class SidebarModel; @@ -100,6 +103,9 @@ class Library : public QObject { void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); void libraryWidgetFocused(); + void slotSearch(const QString& text); + void slotSearchCleared(); + void slotSearchStarting(); void scan() { m_scanner.scan(); From a4e0a46612aaa5dbf1aff69d49e72caee54dc2f8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 17:17:52 +0200 Subject: [PATCH 034/552] Add more bind functions and add event filters --- src/library/librarypanemanager.cpp | 26 ++++++++++++++++----- src/library/librarypanemanager.h | 36 +++++++++++++++++++----------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 74b6ecd3036..6c6ee3a21d4 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -3,6 +3,8 @@ #include "librarypanemanager.h" #include "util/assert.h" +const QString Library::m_sTrackViewName = QString("WTrackTableView"); + LibraryPaneManager::LibraryPaneManager(QObject* parent) : QObject(parent) { @@ -15,14 +17,30 @@ LibraryPaneManager::~LibraryPaneManager() { m_features.clear(); } -void LibraryPaneManager::bindLibraryWidget(WLibrary* rightWidget, +void LibraryPaneManager::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard) { - m_pLibraryWidget = rightWidget; + m_pLibraryWidget = libraryWidget; + m_pLibraryWidget->installEventFilter(this); + + connect(this, SIGNAL(switchToView(const QString&)), + m_pLibraryWidget, SLOT(switchToView(const QString&)); for (LibraryFeature* f : m_features) { f->bindLibraryWidget(m_pLibraryWidget, pKeyboard); + + } } + +void LibraryPaneManager::bindTrackTable(WTrackTableView *pTrackTable) { + m_pTrackTable = pTrackTable; + m_pTrackTable->installEventFilter(this); +} + +void LibraryPaneManager::bindSearchBar(WSearchLineEdit *pSearchLine) { + m_pSearchLine = pSearchLine; + m_pSearchLine->installEventFilter(this); +} /* void LibraryPaneManager::addFeature(LibraryFeature* feature) { m_features.append(feature); @@ -182,11 +200,9 @@ void LibraryPaneManager::slotSetTrackTableRowHeight(int rowHeight) { } */ -bool LibraryPaneManager::eventFilter(QObject* object, QEvent* event) { - //QObject::eventFilter(object, event); +bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (event->type() == QEvent::FocusIn) { - qDebug() << object; } return true; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 772ac1fbe4f..ab3a08791e7 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -2,13 +2,12 @@ #define LIBRARYVIEWMANAGER_H #include -#include -#include #include "library/libraryfeature.h" #include "widget/wbuttonbar.h" #include "widget/wlibrary.h" #include "widget/wsearchlineedit.h" +#include "widget/wtracktableview.h" class LibraryPaneManager : public QObject { Q_OBJECT @@ -24,20 +23,29 @@ class LibraryPaneManager : public QObject { bool initialize(); // All features must be added before adding a pane - void bindLibraryWidget(WLibrary* rightWidget, KeyboardEventFilter *pKeyboard); + void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter *pKeyboard); - inline WLibrary* getRightPane() { return m_pLibraryWidget; } + void bindTrackTable(WTrackTableView* pTrackTable); + + void bindSearchBar(WSearchLineEdit* pSearchLine); void addFeature(LibraryFeature* feature); + +signals: + + void focused(); + + void switchToView(const QString&); + //void addFeatures(Q) public slots: -/* + void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); - void slotLoadTrack(TrackPointer pTrack); - void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); - void slotLoadLocationToPlayer(QString location, QString group); + //void slotLoadTrack(TrackPointer pTrack); + //void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); + //void slotLoadLocationToPlayer(QString location, QString group); void slotRestoreSearch(const QString& text); void slotRefreshLibraryModels(); //void slotCreatePlaylist(); @@ -48,16 +56,18 @@ class LibraryPaneManager : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - */ + private: + const static QString m_sTrackViewName; + WLibrary* m_pLibraryWidget; + WTrackTableView* m_pTrackTable; + WSearchLineEdit* m_pSearchLine; - QVector m_features; + QList m_features; - QVector m_currentFeature; - int m_currentPane; QFont m_trackTableFont; int m_iTrackTableRowHeight; @@ -66,7 +76,7 @@ class LibraryPaneManager : public QObject { // Used to handle focus change // TODO(jmigual): Still needs to be implemented - bool eventFilter(QObject* object, QEvent* event); + bool eventFilter(QObject*, QEvent* event); }; #endif // LIBRARYVIEWMANAGER_H From 00bb5c237db2d9bb4323997f70e294825fadeadd Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 17:18:11 +0200 Subject: [PATCH 035/552] Begin moving some functions to libraryPaneManager --- src/library/library.cpp | 17 ++++++++++++++--- src/library/library.h | 5 +++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 6bf3f39d652..d1b9739f087 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -145,10 +145,11 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, this, SLOT(slotLoadTrack(TrackPointer))); connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); + pLibraryWidget->registerView(m_sTrackViewName, pTrackTableView); - connect(this, SIGNAL(switchToView(const QString&)), - pLibraryWidget, SLOT(switchToView(const QString&))); + //connect(this, SIGNAL(switchToView(const QString&)), + // pLibraryWidget, SLOT(switchToView(const QString&))); connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); @@ -228,7 +229,14 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { void Library::slotSwitchToView(const QString& view) { //qDebug() << "Library::slotSwitchToView" << view; - emit(switchToView(view)); + + if (m_focusedWidget == -1) { + m_pSidebarExpanded->switchToView(view); + } + else { + m_panes[m_focusedWidget]->switchToView(view); + } + //emit(switchToView(view)); } void Library::slotLoadTrack(TrackPointer pTrack) { @@ -248,6 +256,9 @@ void Library::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool pla } void Library::slotRestoreSearch(const QString& text) { + if (m_focusedWidget == -1) { + + } emit(restoreSearch(text)); } diff --git a/src/library/library.h b/src/library/library.h index 061b07c2785..85c55370901 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -147,11 +147,16 @@ class Library : public QObject { QFont m_trackTableFont; int m_iTrackTableRowHeight; //QList m_panes; + + // Panes widgets QList m_features; QList m_trackTables; QList m_panes; QList m_searches; + + // Sidebar Expanded widgets WLibrary* m_pSidebarExpanded; + WSearchLineEdit* m_pSidebarExpanded; // -1 for the Sidebar Expanded and >= 0 for the other widgets int m_focusedWidget; From 2b7a210957c75b4be854bcb039d81a5a7a9f4c5c Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 17:27:45 +0200 Subject: [PATCH 036/552] Added track view name --- src/library/librarypanemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 6c6ee3a21d4..0a588d6242b 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -3,7 +3,7 @@ #include "librarypanemanager.h" #include "util/assert.h" -const QString Library::m_sTrackViewName = QString("WTrackTableView"); +const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); LibraryPaneManager::LibraryPaneManager(QObject* parent) : QObject(parent) { From be5d694eb8cf56ce58062ae4d996b7919e35e411 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:27:05 +0200 Subject: [PATCH 037/552] Add id to Library and SearchBar nodes --- src/skin/legacyskinparser.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index d06d5dcb89b..aef149d31a8 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1138,9 +1138,14 @@ QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { WSearchLineEdit* pLineEditSearch = new WSearchLineEdit(m_pParent); commonWidgetSetup(node, pLineEditSearch, false); pLineEditSearch->setup(node, *m_pContext); + + int id; + if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { + m_pLibrary->bindSearchBar(pLineEditSearch, id); + } // Connect search box signals to the library - connect(pLineEditSearch, SIGNAL(search(const QString&)), + /*connect(pLineEditSearch, SIGNAL(search(const QString&)), m_pLibrary, SIGNAL(search(const QString&))); connect(pLineEditSearch, SIGNAL(searchCleared()), m_pLibrary, SIGNAL(searchCleared())); @@ -1148,7 +1153,7 @@ QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { m_pLibrary, SIGNAL(searchStarting())); connect(m_pLibrary, SIGNAL(restoreSearch(const QString&)), pLineEditSearch, SLOT(restoreSearch(const QString&))); - + */ return pLineEditSearch; } @@ -1246,8 +1251,11 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { connect(m_pLibrary, SIGNAL(search(const QString&)), pLibraryWidget, SLOT(search(const QString&))); - m_pLibrary->bindLibraryWidget(pLibraryWidget, m_pKeyboard); - + int id; + if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { + m_pLibrary->bindLibraryWidget(pLibraryWidget, m_pKeyboard, id); + } + // This must come after the bindWidget or we will not style any of the // LibraryView's because they have not been added yet. commonWidgetSetup(node, pLibraryWidget, false); From 54f4095b4aab09738a5d18c20e942079376deb96 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:29:35 +0200 Subject: [PATCH 038/552] Add create Pane function --- src/library/library.cpp | 21 ++++++++++++++++++++- src/library/library.h | 12 ++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index d1b9739f087..368c7fd23e5 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -91,6 +91,9 @@ Library::~Library() { // Delete the sidebar model first since it depends on the LibraryFeatures. delete m_pSidebarModel; + qDeleteAll(m_panes); + m_panes.clear(); + qDeleteAll(m_features); m_features.clear(); @@ -124,6 +127,14 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { pSidebarWidget, SLOT(slotSetFont(QFont))); } +void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { + if (!m_panes.contains(id)) { + createPane(id); + } + + m_panes[id]->bindSearchBar(searchLine); +} + void Library::bindSidebar(WButtonBar* sidebar) { connect(sidebar, SIGNAL(buttonClicked(const QString&)), this, SIGNAL(switchToView(const QString&))); @@ -380,8 +391,16 @@ void Library::libraryWidgetFocused() { } } -void Library::slotSearch(const QString& text) { +void Library::createPane(int id) { + if (m_panes.contains(id)) { + return; + } + LibraryPaneManager* pane = new LibraryPaneManager; + pane->addFeatures(m_features); + m_panes.insert(id, pane); + connect(pane, SIGNAL(focused()), + this, SLOT(slotPaneFocused())); } void Library::slotSearchCleared() { diff --git a/src/library/library.h b/src/library/library.h index 85c55370901..c18451a2cbb 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -49,12 +49,11 @@ class Library : public QObject { virtual ~Library(); void bindLibraryWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard); - void bindSidebarExpanded(WLibrary* leftPane, + KeyboardEventFilter* pKeyboard, int id); + void bindSearchBar(WSearchLineEdit* searchLine, int id); + void bindSidebarExpanded(WLibrary* leftPane, KeyboardEventFilter* pKeyboard); - void bindSidebarWidget(WLibrarySidebar* sidebarWidget); - void bindSidebar(WButtonBar* sidebar); void addFeature(LibraryFeature* feature); @@ -132,6 +131,11 @@ class Library : public QObject { void scanFinished(); private: + + void createPane(int id); + + LibraryPaneManager* getFocusedPane(); + UserSettingsPointer m_pConfig; SidebarModel* m_pSidebarModel; TrackCollection* m_pTrackCollection; From cbf6cd20d04ecbfaedd5687bed7995f1017c1fa0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:30:54 +0200 Subject: [PATCH 039/552] Create new bind LibraryWidget function --- src/library/library.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 368c7fd23e5..c76dd965c4b 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -146,12 +146,13 @@ void Library::bindSidebar(WButtonBar* sidebar) { } void Library::bindLibraryWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard) { + KeyboardEventFilter* pKeyboard, int id) { WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); pTrackTableView->installEventFilter(pKeyboard); - connect(this, SIGNAL(showTrackModel(QAbstractItemModel*)), - pTrackTableView, SLOT(loadTrackModel(QAbstractItemModel*))); + /*connect(this, SIGNAL(showTrackModel(QAbstractItemModel*)), + pTrackTableView, SLOT(loadTrackModel(QAbstractItemModel*)));*/ + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), @@ -170,19 +171,28 @@ void Library::bindLibraryWidget(WLibrary* pLibraryWidget, connect(this, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - connect(this, SIGNAL(searchStarting()), + /*connect(this, SIGNAL(searchStarting()), pTrackTableView, SLOT(onSearchStarting())); connect(this, SIGNAL(searchCleared()), pTrackTableView, SLOT(onSearchCleared())); + */ + + if (! m_panes.contains(id)) { + createPane(id); + } + + m_panes[id]->bindLibraryWidget(pLibraryWidget, pKeyboard); + m_panes[id]->bindTrackTable(pTrackTableView); - m_panes.append(pLibraryWidget); m_pLibraryControl->bindWidget(pLibraryWidget, pKeyboard); - - QListIterator feature_it(m_features); + + + + /*QListIterator feature_it(m_features); while(feature_it.hasNext()) { LibraryFeature* feature = feature_it.next(); feature->bindLibraryWidget(pLibraryWidget, pKeyboard); - } + }*/ // Set the current font and row height on all the WTrackTableViews that were // just connected to us. From 02cf254b9b450eb15f51e21b18619d97bb35fca8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:32:06 +0200 Subject: [PATCH 040/552] Use getFocusedPane function() --- src/library/library.cpp | 56 ++++++++++++++++++----------------------- src/library/library.h | 18 ++++++------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index c76dd965c4b..96b9552e6c9 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -229,19 +229,16 @@ void Library::addFeature(LibraryFeature* feature) { void Library::slotShowTrackModel(QAbstractItemModel* model) { //qDebug() << "Library::slotShowTrackModel" << model; - TrackModel* trackModel = dynamic_cast(model); + /*TrackModel* trackModel = dynamic_cast(model); DEBUG_ASSERT_AND_HANDLE(trackModel) { return; - } + }*/ - if (m_focusedWidget < 0) { - // The sidebar expanded has not a track model + LibraryPaneManager* pane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pane) { return; } - - m_trackTables[m_focusedWidget]->loadTrackModel(model); - m_panes[m_focusedWidget]->switchToView(m_sTrackViewName); - m_searches[m_focusedWidget]->restoreSearch(trackModel->currentSearch()); + pane->slotShowTrackModel(model); //emit(showTrackModel(model)); //emit(switchToView(m_sTrackViewName)); @@ -251,12 +248,11 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { void Library::slotSwitchToView(const QString& view) { //qDebug() << "Library::slotSwitchToView" << view; - if (m_focusedWidget == -1) { - m_pSidebarExpanded->switchToView(view); - } - else { - m_panes[m_focusedWidget]->switchToView(view); + LibraryPaneManager* pane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pane) { + return; } + pane->slotSwitchToView(view); //emit(switchToView(view)); } @@ -277,10 +273,12 @@ void Library::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool pla } void Library::slotRestoreSearch(const QString& text) { - if (m_focusedWidget == -1) { - + LibraryPaneManager* pane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pane) { + return; } - emit(restoreSearch(text)); + pane->slotRestoreSearch(text); + //emit(restoreSearch(text)); } void Library::slotRefreshLibraryModels() { @@ -385,20 +383,14 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::libraryWidgetFocused() { - WLibrary* pane = qobject_cast(sender()); +void Library::slotPaneFocused() { + LibraryPaneManager* pane = qobject_cast(sender()); DEBUG_ASSERT_AND_HANDLE(pane) { return; } if (pane == m_pSidebarExpanded) m_focusedWidget = -1; - - for (int i = 0; i < m_panes.size(); ++i) { - if (m_panes[i] == pane) { - m_focusedWidget = i; - break; - } - } + m_focusedWidget = m_panes.key(pane, -1); } void Library::createPane(int id) { @@ -413,12 +405,14 @@ void Library::createPane(int id) { this, SLOT(slotPaneFocused())); } -void Library::slotSearchCleared() { - -} - -void Library::slotSearchStarting() { - +LibraryPaneManager *Library::getFocusedPane() { + if (m_focusedWidget == -1) { + return m_pSidebarExpanded; + } + else if (m_panes.contains(m_focusedWidget)) { + return m_panes[m_focusedWidget]; + } + return nullptr; } void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { diff --git a/src/library/library.h b/src/library/library.h index c18451a2cbb..feb2012c2ab 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -101,10 +101,7 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - void libraryWidgetFocused(); - void slotSearch(const QString& text); - void slotSearchCleared(); - void slotSearchStarting(); + void slotPaneFocused(); void scan() { m_scanner.scan(); @@ -150,17 +147,16 @@ class Library : public QObject { LibraryScanner m_scanner; QFont m_trackTableFont; int m_iTrackTableRowHeight; - //QList m_panes; - // Panes widgets + QHash m_panes; + LibraryPaneManager* m_pSidebarExpanded; QList m_features; + + /*// Panes widgets QList m_trackTables; - QList m_panes; - QList m_searches; + //QList m_panes; + QList m_searches;*/ - // Sidebar Expanded widgets - WLibrary* m_pSidebarExpanded; - WSearchLineEdit* m_pSidebarExpanded; // -1 for the Sidebar Expanded and >= 0 for the other widgets int m_focusedWidget; From 6cc1ba85c8e479c1b7ee58d9e7203266c95eb5b9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:32:38 +0200 Subject: [PATCH 041/552] Removed unnecessary signals --- src/library/library.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/library/library.h b/src/library/library.h index feb2012c2ab..c1d8542a736 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -108,14 +108,14 @@ class Library : public QObject { } signals: - void showTrackModel(QAbstractItemModel* model); - void switchToView(const QString& view); + //void showTrackModel(QAbstractItemModel* model); + //void switchToView(const QString& view); void loadTrack(TrackPointer pTrack); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); - void restoreSearch(const QString&); - void search(const QString& text); - void searchCleared(); - void searchStarting(); + //void restoreSearch(const QString&); + //void search(const QString& text); + //void searchCleared(); + //void searchStarting(); // emit this signal to enable/disable the cover art widget void enableCoverArtDisplay(bool); void trackSelected(TrackPointer pTrack); From c021ee245a32f34a46a579fd246036e5229a11e4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:34:38 +0200 Subject: [PATCH 042/552] Add new signals and removed unnecessary slots --- src/library/librarypanemanager.h | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index ab3a08791e7..659efd50922 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -2,6 +2,7 @@ #define LIBRARYVIEWMANAGER_H #include +#include #include "library/libraryfeature.h" #include "widget/wbuttonbar.h" @@ -24,39 +25,29 @@ class LibraryPaneManager : public QObject { // All features must be added before adding a pane void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter *pKeyboard); - void bindTrackTable(WTrackTableView* pTrackTable); - void bindSearchBar(WSearchLineEdit* pSearchLine); - + void addFeature(LibraryFeature* feature); + void addFeatures(const QList &features); signals: void focused(); + void showTrackModel(QAbstractItemModel* model); void switchToView(const QString&); - //void addFeatures(Q) + void restoreSearch(const QString&); + void search(const QString& text); + void searchCleared(); + void searchStarting(); public slots: void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); - //void slotLoadTrack(TrackPointer pTrack); - //void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); - //void slotLoadLocationToPlayer(QString location, QString group); - void slotRestoreSearch(const QString& text); - void slotRefreshLibraryModels(); - //void slotCreatePlaylist(); - //void slotCreateCrate(); - //void slotRequestAddDir(QString directory); - //void slotRequestRemoveDir(QString directory, Library::RemovalType removalType); - //void slotRequestRelocateDir(QString previousDirectory, QString newDirectory); - void onSkinLoadFinished(); - void slotSetTrackTableFont(const QFont& font); - void slotSetTrackTableRowHeight(int rowHeight); - + void slotRestoreSearch(const QString& text); private: From b8310ca2858e123ef95a28e56971ee86d0947f08 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 8 Jun 2016 21:35:31 +0200 Subject: [PATCH 043/552] Removed unnecessary slots and attributes --- src/library/librarypanemanager.cpp | 172 +++++++---------------------- src/library/librarypanemanager.h | 4 - 2 files changed, 40 insertions(+), 136 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 0a588d6242b..e3f95d5a57d 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -23,45 +23,70 @@ void LibraryPaneManager::bindLibraryWidget(WLibrary* libraryWidget, m_pLibraryWidget->installEventFilter(this); connect(this, SIGNAL(switchToView(const QString&)), - m_pLibraryWidget, SLOT(switchToView(const QString&)); + m_pLibraryWidget, SLOT(switchToView(const QString&))); for (LibraryFeature* f : m_features) { f->bindLibraryWidget(m_pLibraryWidget, pKeyboard); - - } } void LibraryPaneManager::bindTrackTable(WTrackTableView *pTrackTable) { m_pTrackTable = pTrackTable; m_pTrackTable->installEventFilter(this); + + + connect(this, SIGNAL(showTrackModel(QAbstractItemModel*)), + m_pTrackTable, SLOT(loadTrackModel(QAbstractItemModel*))); + connect(this, SIGNAL(searchStarting()), + m_pTrackTable, SLOT(onSearchStarting())); + connect(this, SIGNAL(searchCleared()), + m_pTrackTable, SLOT(onSearchCleared())); } void LibraryPaneManager::bindSearchBar(WSearchLineEdit *pSearchLine) { m_pSearchLine = pSearchLine; m_pSearchLine->installEventFilter(this); + + connect(m_pSearchLine, SIGNAL(search(const QString&)), + this, SIGNAL(search(const QString&))); + connect(m_pSearchLine, SIGNAL(searchCleared()), + this, SIGNAL(searchCleared())); + connect(m_pSearchLine, SIGNAL(searchStarting()), + this, SIGNAL(searchStarting())); + connect(this, SIGNAL(restoreSearch(const QString&)), + m_pSearchLine, SLOT(restoreSearch(const QString&))); } -/* + void LibraryPaneManager::addFeature(LibraryFeature* feature) { + DEBUG_ASSERT_AND_HANDLE(feature) { + return; + } + m_features.append(feature); - connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), + + /*connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), this, SLOT(slotShowTrackModel(QAbstractItemModel*))); connect(feature, SIGNAL(switchToView(const QString&)), this, SLOT(slotSwitchToView(const QString&))); - connect(feature, SIGNAL(loadTrack(TrackPointer)), + /*connect(feature, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); - connect(feature, SIGNAL(restoreSearch(const QString&)), - this, SLOT(slotRestoreSearch(const QString&))); - connect(feature, SIGNAL(enableCoverArtDisplay(bool)), - this, SIGNAL(enableCoverArtDisplay(bool))); - connect(feature, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); + this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool)));*/ + /*connect(feature, SIGNAL(restoreSearch(const QString&)), + this, SLOT(slotRestoreSearch(const QString&)));*/ + /*connect(feature, SIGNAL(enableCoverArtDisplay(bool)), + this, SIGNAL(enableCoverArtDisplay(bool)));*/ + /*connect(feature, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer)));*/ +} + +void LibraryPaneManager::addFeatures(const QList &features) { + for (LibraryFeature* f : features) { + addFeature(f); + } } - void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { //qDebug() << "LibraryPaneManager::slotShowTrackModel" << model; TrackModel* trackModel = dynamic_cast(model); @@ -78,131 +103,14 @@ void LibraryPaneManager::slotSwitchToView(const QString& view) { emit(switchToView(view)); } -void LibraryPaneManager::slotLoadTrack(TrackPointer pTrack) { - emit(loadTrack(pTrack)); -} - -void LibraryPaneManager::slotLoadLocationToPlayer(QString location, QString group) { - TrackPointer pTrack = m_pTrackCollection->getTrackDAO() - .getOrAddTrack(location, true, NULL); - if (!pTrack.isNull()) { - emit(loadTrackToPlayer(pTrack, group)); - } -} - -void LibraryPaneManager::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play) { - emit(loadTrackToPlayer(pTrack, group, play)); -} - void LibraryPaneManager::slotRestoreSearch(const QString& text) { emit(restoreSearch(text)); } -void LibraryPaneManager::slotRefreshLibraryModels() { - m_pMixxxLibraryFeature->refreshLibraryModels(); - m_pAnalysisFeature->refreshLibraryModels(); -} -/* -void LibraryPaneManager::slotCreatePlaylist() { - m_pPlaylistFeature->slotCreatePlaylist(); -} - -void LibraryPaneManager::slotCreateCrate() { - m_pCrateFeature->slotCreateCrate(); -} - -void LibraryPaneManager::onSkinLoadFinished() { - // Enable the default selection when a new skin is loaded. - m_pSidebarModel->activateDefaultSelection(); -} - -void LibraryPaneManager::slotRequestAddDir(QString dir) { - // We only call this method if the user has picked a new directory via a - // file dialog. This means the system sandboxer (if we are sandboxed) has - // granted us permission to this folder. Create a security bookmark while we - // have permission so that we can access the folder on future runs. We need - // to canonicalize the path so we first wrap the directory string with a - // QDir. - QDir directory(dir); - Sandbox::createSecurityToken(directory); - - if (!m_pTrackCollection->getDirectoryDAO().addDirectory(dir)) { - QMessageBox::information(0, tr("Add Directory to Library"), - tr("Could not add the directory to your library. Either this " - "directory is already in your library or you are currently " - "rescanning your library.")); - } - // set at least one directory in the config file so that it will be possible - // to downgrade from 1.12 - if (m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR).length() < 1) { - m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, dir); - } -} - -void LibraryPaneManager::slotRequestRemoveDir(QString dir, RemovalType removalType) { - switch (removalType) { - case LibraryPaneManager::HideTracks: - // Mark all tracks in this directory as deleted but DON'T purge them - // in case the user re-adds them manually. - m_pTrackCollection->getTrackDAO().markTracksAsMixxxDeleted(dir); - break; - case LibraryPaneManager::PurgeTracks: - // The user requested that we purge all metadata. - m_pTrackCollection->getTrackDAO().purgeTracks(dir); - break; - case LibraryPaneManager::LeaveTracksUnchanged: - default: - break; - - } - - // Remove the directory from the directory list. - m_pTrackCollection->getDirectoryDAO().removeDirectory(dir); - - // Also update the config file if necessary so that downgrading is still - // possible. - QString confDir = m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR); - - if (QDir(dir) == QDir(confDir)) { - QStringList dirList = m_pTrackCollection->getDirectoryDAO().getDirs(); - if (!dirList.isEmpty()) { - m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, dirList.first()); - } else { - // Save empty string so that an old version of mixxx knows it has to - // ask for a new directory. - m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, QString()); - } - } -} - -void LibraryPaneManager::slotRequestRelocateDir(QString oldDir, QString newDir) { - m_pTrackCollection->relocateDirectory(oldDir, newDir); - - // also update the config file if necessary so that downgrading is still - // possible - QString conDir = m_pConfig->getValueString(PREF_LEGACY_LIBRARY_DIR); - if (oldDir == conDir) { - m_pConfig->set(PREF_LEGACY_LIBRARY_DIR, newDir); - } -} - -*/ -/* - -void LibraryPaneManager::slotSetTrackTableFont(const QFont& font) { - m_trackTableFont = font; - emit(setTrackTableFont(font)); -} - -void LibraryPaneManager::slotSetTrackTableRowHeight(int rowHeight) { - m_iTrackTableRowHeight = rowHeight; - emit(setTrackTableRowHeight(rowHeight)); -} -*/ - bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (event->type() == QEvent::FocusIn) { + emit(focused()); } return true; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 659efd50922..0864cb729e4 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -58,10 +58,6 @@ class LibraryPaneManager : public QObject { WSearchLineEdit* m_pSearchLine; QList m_features; - - - QFont m_trackTableFont; - int m_iTrackTableRowHeight; private slots: From f5a6774a16495b26dc1cf6d664ab73eef2ddf524 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 9 Jun 2016 08:54:40 +0200 Subject: [PATCH 044/552] Added parseLibrarySidebar and SidebarExpanded --- src/skin/legacyskinparser.cpp | 23 +++++++++++++++++++++-- src/skin/legacyskinparser.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index aef149d31a8..752f530aae1 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -65,6 +65,7 @@ #include "widget/wsearchlineedit.h" #include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" +#include "widget/wbuttonbar.h" #include "widget/wskincolor.h" #include "widget/wpixmapstore.h" #include "widget/wwidgetstack.h" @@ -553,6 +554,8 @@ QList LegacySkinParser::parseNode(const QDomElement& node) { result = wrapWidget(parseSplitter(node)); } else if (nodeName == "LibrarySidebar") { result = wrapWidget(parseLibrarySidebar(node)); + } else if (nodeName == "LibrarySidebarExpanded") { + result = wrapWidget(parseLibrarySidebarExpanded(node)); } else if (nodeName == "Library") { result = wrapWidget(parseLibrary(node)); } else if (nodeName == "Key") { @@ -1264,12 +1267,28 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { } QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { - WLibrarySidebar* pLibrarySidebar = new WLibrarySidebar(m_pParent); + + + WButtonBar* pLibrarySidebar = new WButtonBar(m_pParent); + pLibrarySidebar->installEventFilter(m_pKeyboard); + m_pLibrary->bindSidebarWidget(pLibrarySidebar); + commonWidgetSetup(node, pLibrarySidebar, false); + return pLibrarySidebar; + + /*WLibrarySidebar* pLibrarySidebar = new WLibrarySidebar(m_pParent); pLibrarySidebar->installEventFilter(m_pKeyboard); pLibrarySidebar->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); m_pLibrary->bindSidebarWidget(pLibrarySidebar); commonWidgetSetup(node, pLibrarySidebar, false); - return pLibrarySidebar; + return pLibrarySidebar; */ +} + +QWidget *LegacySkinParser::parseLibrarySidebarExpanded(const QDomElement &node) { + WLibrary* pLibrarySidebarExpanded = new WLibrary(m_pParent); + pLibrarySidebarExpanded->installEventFilter(m_pKeyboard); + m_pLibrary->bindSidebarExpanded(pLibrarySidebarExpanded, m_pKeyboard); + commonWidgetSetup(node, pLibrarySidebarExpanded, false); + return pLibrarySidebarExpanded; } QWidget* LegacySkinParser::parseTableView(const QDomElement& node) { diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index 9e0f3112bfc..776e77057bb 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -101,6 +101,7 @@ class LegacySkinParser : public QObject, public SkinParser { QWidget* parseSearchBox(const QDomElement& node); QWidget* parseLibrary(const QDomElement& node); QWidget* parseLibrarySidebar(const QDomElement& node); + QWidget* parseLibrarySidebarExpanded(const QDomElement& node); QWidget* parseBattery(const QDomElement& node); QWidget* parseCoverArt(const QDomElement& node); From 19616754dd35367639091732b695602a349eef46 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 9 Jun 2016 08:55:25 +0200 Subject: [PATCH 045/552] Renamed some functions and removed unnecessary code --- src/library/library.cpp | 18 ++++++------------ src/library/library.h | 4 ++-- src/widget/wbuttonbar.cpp | 6 ------ 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 96b9552e6c9..68aafa9fc76 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -106,6 +106,7 @@ Library::~Library() { delete m_pTrackCollection; } +/* void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { m_pLibraryControl->bindSidebarWidget(pSidebarWidget); @@ -124,8 +125,9 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { pSidebarWidget->slotSetFont(m_trackTableFont); connect(this, SIGNAL(setTrackTableFont(QFont)), - pSidebarWidget, SLOT(slotSetFont(QFont))); + pSidebarWidget, SLOT(slotSetFont(QFont))); } +*/ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { if (!m_panes.contains(id)) { @@ -135,7 +137,7 @@ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { m_panes[id]->bindSearchBar(searchLine); } -void Library::bindSidebar(WButtonBar* sidebar) { +void Library::bindSidebarWidget(WButtonBar* sidebar) { connect(sidebar, SIGNAL(buttonClicked(const QString&)), this, SIGNAL(switchToView(const QString&))); @@ -204,6 +206,7 @@ void Library::bindSidebarExpanded(WLibrary *leftPane, KeyboardEventFilter *pKeyb } + void Library::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; @@ -229,20 +232,12 @@ void Library::addFeature(LibraryFeature* feature) { void Library::slotShowTrackModel(QAbstractItemModel* model) { //qDebug() << "Library::slotShowTrackModel" << model; - /*TrackModel* trackModel = dynamic_cast(model); - DEBUG_ASSERT_AND_HANDLE(trackModel) { - return; - }*/ LibraryPaneManager* pane = getFocusedPane(); DEBUG_ASSERT_AND_HANDLE(pane) { return; } pane->slotShowTrackModel(model); - - //emit(showTrackModel(model)); - //emit(switchToView(m_sTrackViewName)); - //emit(restoreSearch(trackModel->currentSearch())); } void Library::slotSwitchToView(const QString& view) { @@ -253,7 +248,6 @@ void Library::slotSwitchToView(const QString& view) { return; } pane->slotSwitchToView(view); - //emit(switchToView(view)); } void Library::slotLoadTrack(TrackPointer pTrack) { @@ -278,7 +272,6 @@ void Library::slotRestoreSearch(const QString& text) { return; } pane->slotRestoreSearch(text); - //emit(restoreSearch(text)); } void Library::slotRefreshLibraryModels() { @@ -393,6 +386,7 @@ void Library::slotPaneFocused() { m_focusedWidget = m_panes.key(pane, -1); } + void Library::createPane(int id) { if (m_panes.contains(id)) { return; diff --git a/src/library/library.h b/src/library/library.h index c1d8542a736..d94ce5119f2 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -53,8 +53,8 @@ class Library : public QObject { void bindSearchBar(WSearchLineEdit* searchLine, int id); void bindSidebarExpanded(WLibrary* leftPane, KeyboardEventFilter* pKeyboard); - void bindSidebarWidget(WLibrarySidebar* sidebarWidget); - void bindSidebar(WButtonBar* sidebar); + //void bindSidebarWidget(WLibrarySidebar* sidebarWidget); + void bindSidebarWidget(WButtonBar* sidebar); void addFeature(LibraryFeature* feature); QStringList getDirs(); diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 3de9278bffe..934587e3a02 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -5,12 +5,6 @@ WButtonBar::WButtonBar(QWidget* parent) m_pLayout = new QVBoxLayout(this); setLayout(m_pLayout); - - m_pButtonGroup = new QButtonGroup(this); -} - -void WButtonBar::slotButtonClicked(int id) { - emit(buttonClicked(m_data[id])); } QAbstractButton* WButtonBar::addButton(const QIcon& icon, const QVariant& title) { From 08d21ed57e93af08498c97032b9d71e3a27a0bd2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 9 Jun 2016 08:58:33 +0200 Subject: [PATCH 046/552] Added Experiment skin --- res/skins/Experiment/button_1state.xml | 16 ++ res/skins/Experiment/pressed.svg | 63 ++++++++ res/skins/Experiment/skin.xml | 160 ++++++++++++++++++++ res/skins/Experiment/style.qss | 199 +++++++++++++++++++++++++ res/skins/Experiment/unpressed.svg | 63 ++++++++ 5 files changed, 501 insertions(+) create mode 100644 res/skins/Experiment/button_1state.xml create mode 100644 res/skins/Experiment/pressed.svg create mode 100644 res/skins/Experiment/skin.xml create mode 100644 res/skins/Experiment/style.qss create mode 100644 res/skins/Experiment/unpressed.svg diff --git a/res/skins/Experiment/button_1state.xml b/res/skins/Experiment/button_1state.xml new file mode 100644 index 00000000000..ff50f993ff1 --- /dev/null +++ b/res/skins/Experiment/button_1state.xml @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/res/skins/Experiment/pressed.svg b/res/skins/Experiment/pressed.svg new file mode 100644 index 00000000000..3a236980107 --- /dev/null +++ b/res/skins/Experiment/pressed.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/res/skins/Experiment/skin.xml b/res/skins/Experiment/skin.xml new file mode 100644 index 00000000000..c22682808d1 --- /dev/null +++ b/res/skins/Experiment/skin.xml @@ -0,0 +1,160 @@ + + + + Experiment + jmigual + 0.0 + An experiment + en + Creative Commons Attribution, Share-Alike 3.0 Unported + + + Mixxx + + 1280,700 + me,me + vertical + + vertical - - CoverArtSplitter me,me - 1,1 + 30,30 + 2,8 [LateNight],CoverArtSplitSize vertical 0,0 - + + LibrarySidebarExpanded + me,me - 40,40 + 30,30, [Library],show_coverart visible @@ -48,15 +52,30 @@ + + vertical + + + 1 + + + 1 + + + vertical - + + 2 + + + 2 #585858 #eece33 - + From 997d01686bf6f2715c6b2ec5673c7107e73549d9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 11:09:49 +0200 Subject: [PATCH 133/552] Added CSS to new Library Layout --- res/skins/LateNight/style.qss | 56 ++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 048b542d72e..2786a049d3a 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1156,7 +1156,39 @@ /* Library styling is hard */ -QTableView, QTextBrowser, QTreeView { +#LibrarySidebar, #LibrarySidebar WButtonBar { + background-color: #0f0f0f; + margin-right: 10px; +} + +#LibrarySidebarExpanded QWidget { + background-color: #0f0f0f; +} + +#LibrarySidebarExpanded QScrollArea { + border: 1px solid #585858; +} + +#LibrarySidebar QAbstractButton, +#LibrarySidebarExpanded QAbstractButton { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + border: none; + color: #cfb32c; + background-color: #191919; +} + +#LibrarySidebar QAbstractButton:hover, +#LibrarySidebarExpanded QAbstractButton:hover { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + border: 1px solid #585858; + background-color: #232323; + border-radius: 2px; + color: #cfb32c; +} + +#LibrarySidebar, QTableView, QTextBrowser, QTreeView { border: 1px solid #585858; /*font: 15px/18px;*/ color: #cfb32c; @@ -1286,28 +1318,36 @@ WCoverArt { background: transparent; color: #ACACAC; } QLabel, QRadioButton { background: transparent; color: #cfb32c; } /* Additional space for QRadionButtons and QLabels */ -WLibrary QRadioButton, WLibrary QLabel { margin: 9px 3px 6px 3px; } +WBaseLibrary QRadioButton, WBaseLibrary QLabel { margin: 9px 3px 6px 3px; } /* Additional space for the first QRadionButton in the row */ -WLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } +WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } /* Additional space for the QPushButtons */ #DlgMissing > QPushButton, #DlgHidden > QPushButton, #DlgAutoDJ > QPushButton, #DlgRecording > QPushButton, -#DlgAnalysis > QPushButton { margin: 9px 3px 6px 3px; padding: 3px 8px; min-width: 65px; } +#DlgAnalysis > QPushButton { + margin: 2px 3px 2px 3px; + padding: 4px 6px; + min-width: 65px; +} + +#DlgMissing > QPushButton:!enabled, +#DlgHidden > QPushButton:!enabled, +#DlgAutoDJ > QPushButton:!enabled, +#DlgRecording > QPushButton:!enabled, +#DlgAnalysis > QPushButton:!enabled { + color: #666666; +} /* Additional space for the first QPushButton in the row */ #DlgMissing > QPushButton#btnPurge, #DlgHidden > QPushButton#btnUnhide, -#DlgAutoDJ > QPushButton#pushButtonAutoDJ, #DlgRecording > QPushButton#pushButtonRecording, #DlgAnalysis > QPushButton#pushButtonAnalyze { margin: 9px 12px 6px 3px; } -/* Additional space for the last QPushButton in the row */ -#DlgAutoDJ > QPushButton#pushButtonShuffle { margin: 9px 3px 6px 12px; } - /* Spacing between treeview and searchbar */ QTreeView { margin: 10px 0px 0px 0px; } From 6d42ff4767b11f2a506785bc9f32ed08fc79b48a Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 11:11:30 +0200 Subject: [PATCH 134/552] Added deleteLater to pane widgets and remove some debugs --- src/library/library.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 32fa14afd40..31aeed4e0cb 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "mixer/playermanager.h" #include "library/library.h" @@ -167,6 +168,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard) { + //qDebug() << "Library::bindSidebarExpanded"; m_pSidebarExpanded = new LibraryPaneManager; connect(m_pSidebarExpanded, SIGNAL(focused()), this, SLOT(slotPaneFocused())); @@ -176,9 +178,11 @@ void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, } void Library::destroyInterface() { - delete m_pSidebarExpanded; + m_pSidebarExpanded->deleteLater(); - qDeleteAll(m_panes); + for (LibraryPaneManager* p : m_panes) { + p->deleteLater(); + } m_panes.clear(); } @@ -275,9 +279,13 @@ void Library::onSkinLoadFinished() { // Enable the default selection when a new skin is loaded. //m_pSidebarModel->activateDefaultSelection(); if (m_panes.size() > 0) { + m_focusedPane = m_panes.begin().key(); + m_features.first()->activate(); + } + else { + qDebug() << "Library::onSkinLoadFinished No Panes loaded!"; } - m_features.first()->activate(); } void Library::slotRequestAddDir(QString dir) { @@ -377,7 +385,7 @@ void Library::slotPaneFocused() { } } - qDebug() << "Library::slotPaneFocused" << m_focusedPane; + //qDebug() << "Library::slotPaneFocused" << m_focusedPane; } From c331f46d5fd28ee1f7d953dd0daa169a3a564ada Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 11:12:20 +0200 Subject: [PATCH 135/552] Remove some unnecesary code and set Margin to 0 by default in Wbuttonbar --- src/library/mixxxlibraryfeature.cpp | 2 +- src/skin/legacyskinparser.cpp | 10 +--------- src/widget/wbuttonbar.cpp | 2 ++ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index d5ef1a3eda5..666782b4a95 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -20,7 +20,7 @@ #include "library/dlghidden.h" #include "library/dlgmissing.h" -const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = QString("MixxxLibraryFeature"); +const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = "MixxxLibraryFeature"; MixxxLibraryFeature::MixxxLibraryFeature(Library* pLibrary, TrackCollection* pTrackCollection, diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index f383b01018c..2fe83a3d2c8 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1263,8 +1263,7 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { QScrollArea* scroll = new QScrollArea(m_pParent); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - scroll->setWidgetResizable(false); - scroll->setAlignment(Qt::AlignCenter); + scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); WButtonBar* pLibrarySidebar = new WButtonBar(m_pParent); pLibrarySidebar->installEventFilter(m_pKeyboard); @@ -1274,13 +1273,6 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { commonWidgetSetup(node, pLibrarySidebar, false); setupWidget(node, scroll); return scroll; - - /*WLibrarySidebar* pLibrarySidebar = new WLibrarySidebar(m_pParent); - pLibrarySidebar->installEventFilter(m_pKeyboard); - pLibrarySidebar->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); - m_pLibrary->bindSidebarWidget(pLibrarySidebar); - commonWidgetSetup(node, pLibrarySidebar, false); - return pLibrarySidebar; */ } QWidget *LegacySkinParser::parseLibrarySidebarExpanded(const QDomElement &node) { diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 8c5a92e502b..e3ec446fbe6 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -4,6 +4,8 @@ WButtonBar::WButtonBar(QWidget* parent) : WWidget(parent) { m_pLayout = new QVBoxLayout(this); + m_pLayout->setContentsMargins(0,0,0,0); + m_pLayout->setSpacing(0); setLayout(m_pLayout); } From 0ae467e21d4a7038ba7812b3a4383f08e11b9527 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 14:42:18 +0200 Subject: [PATCH 136/552] Remove unnecessary items in LateNight --- res/skins/LateNight/library.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index b872179f8e0..c9341c883f4 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -64,8 +64,6 @@ - - vertical @@ -73,8 +71,6 @@ 2 - #585858 - #eece33 From 8a7f0751a9ff4fbb189593251a7227286a629c8f Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 14:42:46 +0200 Subject: [PATCH 137/552] Added style to handle focus --- res/skins/LateNight/style.qss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 2786a049d3a..e00e3e3d0db 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1373,3 +1373,13 @@ QTreeView::item:selected { background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); color: #cfb32c; } + +WBaseLibrary[showFocus="0"] { + padding: 1px 1px 1px 1px; + border: none; +} + +WBaseLibrary[showFocus="1"] { + padding: 1px 1px 1px 1px; + border: 1px solid #FF7100 !important; +} \ No newline at end of file From 7a2839146be68ff8dd84098d8baccf91ac04ee77 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 14:43:36 +0200 Subject: [PATCH 138/552] Add smart option to switch between panes --- src/library/baseplaylistfeature.cpp | 1 + src/library/cratefeature.cpp | 1 + src/library/library.cpp | 72 +++++++++++++++++++++++++++-- src/library/library.h | 4 ++ src/library/libraryfeature.cpp | 10 +++- src/library/libraryfeature.h | 8 ++++ 6 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 60e553f0111..949b58397eb 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -131,6 +131,7 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { } void BasePlaylistFeature::activate() { + m_featureFocus = -1; emit(switchToView(m_rootViewName)); emit(restoreSearch(QString())); // Null String disables search box emit(enableCoverArtDisplay(true)); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 34549df0659..82375331ea2 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -196,6 +196,7 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { + m_featureFocus = -1; emit(switchToView(m_sCrateViewName)); emit(restoreSearch(QString())); //disable search on crate home emit(enableCoverArtDisplay(true)); diff --git a/src/library/library.cpp b/src/library/library.cpp index 31aeed4e0cb..2d72ce7a115 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -114,10 +114,13 @@ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { void Library::bindSidebarWidget(WButtonBar* sidebar) { for (LibraryFeature* f : m_features) { - QAbstractButton* button = sidebar->addButton(f->getIcon(), f->title()); + WRightClickButton* button = sidebar->addButton(f->getIcon(), f->title(), + f->getViewName()); + connect(button, SIGNAL(clicked(const QString&)), + this, SLOT(slotActivateFeature(const QString&))); - connect(button, SIGNAL(clicked()), f, SLOT(activate())); + //connect(button, SIGNAL(clicked()), f, SLOT(activate())); connect(button, SIGNAL(rightClicked(const QPoint&)), f, SLOT(onRightClick(const QPoint&))); } @@ -201,6 +204,7 @@ void Library::addFeature(LibraryFeature* feature) { return; } m_features.append(feature); + m_featuresMap.insert(feature->getViewName(), feature); m_pSidebarModel->addLibraryFeature(feature); connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), @@ -227,14 +231,39 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { } void Library::slotSwitchToView(const QString& view) { - //qDebug() << "Library::slotSwitchToView" << view; - + qDebug() << "Library::slotSwitchToView" << view; m_pSidebarExpanded->slotSwitchToView(view); - m_panes[m_focusedPane]->slotSwitchToView(view); + + WBaseLibrary* wLibrary = m_panes[m_focusedPane]->getPaneWidget(); + // Only change the current pane if it's not shown already + if (wLibrary->getCurrentViewName() != view) { + m_panes[m_focusedPane]->slotSwitchToView(view); + } + + m_panes[m_focusedPane]->setFocus(); + for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { + if (it.key() != m_focusedPane) { + it.value()->clearFocus(); + } + } + emit(switchToView(view)); } void Library::slotSwitchToViewChild(const QString &view) { + qDebug() << "Library::slotSwitchToViewChild"; + m_panes[m_focusedPane]->slotSwitchToView(view); +} + +void Library::slotSwitchToNotFocusedView(const QString &view) { + + // Search for the view not being shown already + for (LibraryPaneManager* p : m_panes) { + if (p->getPaneWidget()->getCurrentViewName() == view) { + return; + } + } + m_panes[m_focusedPane]->slotSwitchToView(view); } @@ -362,6 +391,32 @@ QStringList Library::getDirs() { return m_pTrackCollection->getDirectoryDAO().getDirs(); } +void Library::slotActivateFeature(const QString &featureName) { + LibraryFeature* pFeature = m_featuresMap[featureName]; + + // The feature is being shown currently in the focused pane + if (m_panes[m_focusedPane]->getFocusedFeature() == featureName) { + return; + } + + // The feature is not focused anywhere + if (pFeature->getFeatureFocus() < 0) { + + // Remove the previous focused feature in this pane + for (LibraryFeature* f : m_features) { + if (f->getFeatureFocus() == m_focusedPane) { + f->setFeatureFocus(-1); + } + } + } else { + m_focusedPane = pFeature->getFeatureFocus(); + } + + m_panes[m_focusedPane]->setFocusedFeature(featureName); + pFeature->setFeatureFocus(m_focusedPane); + pFeature->activate(); +} + void Library::slotSetTrackTableFont(const QFont& font) { m_trackTableFont = font; emit(setTrackTableFont(font)); @@ -383,6 +438,13 @@ void Library::slotPaneFocused() { DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } + pane->setFocus(); + // Clear the focus from the other panes + for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { + if (it.key() != m_focusedPane) { + it.value()->clearFocus(); + } + } } //qDebug() << "Library::slotPaneFocused" << m_focusedPane; diff --git a/src/library/library.h b/src/library/library.h index 4c6951b3357..aabeb4e75af 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "preferences/usersettings.h" #include "track/track.h" @@ -87,9 +88,11 @@ class Library : public QObject { static const int kDefaultRowHeightPx; public slots: + void slotActivateFeature(const QString& featureName); void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); void slotSwitchToViewChild(const QString& view); + void slotSwitchToNotFocusedView(const QString& view); void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); void slotLoadLocationToPlayer(QString location, QString group); @@ -150,6 +153,7 @@ class Library : public QObject { QHash m_panes; LibraryPaneManager* m_pSidebarExpanded; QList m_features; + QHash m_featuresMap; // Can be any integer as it's used with a HashMap int m_focusedPane; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 0dc31302fdf..891e7dd7bf7 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -7,13 +7,15 @@ // The reason for this is that LibraryFeature uses slots/signals and for this // to work the code has to be precompiles by moc LibraryFeature::LibraryFeature(QObject *parent) - : QObject(parent) { + : QObject(parent), + m_featureFocus(-1) { } LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, QObject* parent) : QObject(parent), - m_pConfig(pConfig) { + m_pConfig(pConfig), + m_featureFocus(-1) { } LibraryFeature::~LibraryFeature() { @@ -43,6 +45,10 @@ void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEve this, SLOT(onLazyChildExpandation(const QModelIndex&))); } +void LibraryFeature::setFeatureFocus(int focus) { + m_featureFocus = focus; +} + QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) { QString lastPlaylistDirectory = m_pConfig->getValueString( ConfigKey("[Library]", "LastImportExportPlaylistDirectory"), diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index e30de517e2b..0237af33161 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -79,11 +79,19 @@ class LibraryFeature : public QObject { KeyboardEventFilter*); virtual TreeItemModel* getChildModel() = 0; + + void setFeatureFocus(int focus); + + int getFeatureFocus() { + return m_featureFocus; + } protected: inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } UserSettingsPointer m_pConfig; + + int m_featureFocus; public slots: // called when you single click on the root item From 83d194b04cffa4a1c05dc7e555adc549f720c885 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 14:44:19 +0200 Subject: [PATCH 139/552] Add visuals for focus change in pane --- src/library/librarypanemanager.cpp | 17 ++++++++++++++++- src/library/librarypanemanager.h | 12 ++++++++++++ src/widget/wbaselibrary.cpp | 25 +++++++++++++++++++++++-- src/widget/wbaselibrary.h | 12 ++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index fbe87eebcc7..40dc302d254 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -73,6 +73,20 @@ WBaseLibrary *LibraryPaneManager::getPaneWidget() { return m_pPaneWidget; } +void LibraryPaneManager::setFocusedFeature(const QString &featureName) { + m_focusedFeature = featureName; +} + +void LibraryPaneManager::setFocus() { + //qDebug() << "LibraryPaneManager::setFocus"; + m_pPaneWidget->setProperty("showFocus", 1); +} + +void LibraryPaneManager::clearFocus() { + //qDebug() << "LibraryPaneManager::clearFocus"; + m_pPaneWidget->setProperty("showFocus", 0); +} + void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { //qDebug() << "LibraryPaneManager::slotShowTrackModel" << model; TrackModel* trackModel = dynamic_cast(model); @@ -87,6 +101,7 @@ void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { void LibraryPaneManager::slotSwitchToView(const QString& view) { //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; emit(switchToView(view)); + m_pPaneWidget->setFocus(); } void LibraryPaneManager::slotRestoreSearch(const QString& text) { @@ -98,7 +113,7 @@ bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (event->type() == QEvent::MouseButtonPress && m_pPaneWidget->underMouse()) { - emit(focused()); + emit(focused()); } // Since this event filter is for the entire application (to handle the diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 906983145c5..3febb166b4d 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -36,6 +36,16 @@ class LibraryPaneManager : public QObject { WBaseLibrary* getPaneWidget(); + void setFocusedFeature(const QString& featureName); + + QString getFocusedFeature() { + return m_focusedFeature; + } + + void setFocus(); + + void clearFocus(); + signals: void focused(); @@ -61,6 +71,8 @@ class LibraryPaneManager : public QObject { WBaseLibrary* m_pPaneWidget; QList m_features; + + QString m_focusedFeature; private slots: diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 5d478ae7853..c8100be3a65 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -1,13 +1,15 @@ #include #include #include +#include #include "wbaselibrary.h" WBaseLibrary::WBaseLibrary(QWidget* parent) : QStackedWidget(parent), WBaseWidget(this), - m_mutex(QMutex::Recursive) { + m_mutex(QMutex::Recursive), + m_showFocus(0) { } @@ -19,16 +21,35 @@ bool WBaseLibrary::registerView(QString name, QWidget* view) { int index = addWidget(view); setCurrentIndex(index); + m_currentViewName = name; m_viewMap[name] = view; return true; } +QString WBaseLibrary::getCurrentViewName() { + return m_currentViewName; +} + +int WBaseLibrary::getShowFocus() { + return m_showFocus; +} + +void WBaseLibrary::setShowFocus(int sFocus) { + qDebug() << "WBaseLibrary::setShowFocus" << sFocus << this; + m_showFocus = sFocus; + + style()->unpolish(this); + style()->polish(this); + update(); +} + void WBaseLibrary::switchToView(const QString& name) { QMutexLocker lock(&m_mutex); qDebug() << "WBaseLibrary::switchToView" << name; QWidget* widget = m_viewMap.value(name, nullptr); if (widget != nullptr && currentWidget() != widget) { - qDebug() << "WBaseLibrary::setCurrentWidget" << name; + //qDebug() << "WBaseLibrary::setCurrentWidget" << name; + m_currentViewName = name; setCurrentWidget(widget); } } diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index f406623b90d..e57faeaaf2e 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -14,6 +14,14 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget WBaseLibrary(QWidget* parent = nullptr); virtual bool registerView(QString name, QWidget* view); + + QString getCurrentViewName(); + + Q_PROPERTY(int showFocus READ getShowFocus WRITE setShowFocus) + + int getShowFocus(); + + void setShowFocus(int sFocus); public slots: @@ -26,8 +34,12 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget QMap m_viewMap; private: + + QString m_currentViewName; QMutex m_mutex; + + int m_showFocus; }; #endif // WLIBRARYSIDEBAREXPANDED_H From db11089a7e6b4f54bbd82fbdb149cb8615563e83 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 16 Jun 2016 14:44:48 +0200 Subject: [PATCH 140/552] Set data to wbuttonbar --- src/widget/wbuttonbar.cpp | 5 ++++- src/widget/wbuttonbar.h | 2 +- src/widget/wrightclickbutton.cpp | 10 ++++++++++ src/widget/wrightclickbutton.h | 12 ++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index e3ec446fbe6..102388f293f 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -9,10 +9,13 @@ WButtonBar::WButtonBar(QWidget* parent) setLayout(m_pLayout); } -WRightClickButton* WButtonBar::addButton(const QIcon& icon, const QVariant& title) { +WRightClickButton* WButtonBar::addButton(const QIcon& icon, + const QVariant& title, + const QString& data) { WRightClickButton* button = new WRightClickButton(this); button->setIcon(icon); button->setText(title.toString()); + button->setData(data); button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index a99a96cd433..66ebdbde754 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -15,7 +15,7 @@ class WButtonBar : public WWidget public: WButtonBar(QWidget* parent = nullptr); - WRightClickButton* addButton(const QIcon& icon, const QVariant& title); + WRightClickButton* addButton(const QIcon& icon, const QVariant& title, const QString &data); private: diff --git a/src/widget/wrightclickbutton.cpp b/src/widget/wrightclickbutton.cpp index 9e5262c5484..ace538e3a39 100644 --- a/src/widget/wrightclickbutton.cpp +++ b/src/widget/wrightclickbutton.cpp @@ -2,9 +2,15 @@ WRightClickButton::WRightClickButton(QWidget* parent) : QToolButton(parent) { + connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); +} +void WRightClickButton::setData(const QString &data) { + m_data = data; } + + void WRightClickButton::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::RightButton) { emit(rightClicked(event->globalPos())); @@ -12,3 +18,7 @@ void WRightClickButton::mousePressEvent(QMouseEvent* event) { QToolButton::mousePressEvent(event); } +void WRightClickButton::slotClicked() { + emit(clicked(m_data)); +} + diff --git a/src/widget/wrightclickbutton.h b/src/widget/wrightclickbutton.h index a6ef6d2ef2d..c425d1e7c37 100644 --- a/src/widget/wrightclickbutton.h +++ b/src/widget/wrightclickbutton.h @@ -11,13 +11,25 @@ class WRightClickButton : public QToolButton public: WRightClickButton(QWidget* parent = nullptr); + void setData(const QString& data); + signals: + void clicked(const QString& view); + void rightClicked(const QPoint&); protected: void mousePressEvent(QMouseEvent* event); + +private slots: + + void slotClicked(); + +private: + + QString m_data; }; #endif // WRIGHTCLICKBUTTON_H From 19ee42a777a008b1582f046c5b5b05b5b8097884 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 09:22:25 +0200 Subject: [PATCH 141/552] Add new LibraryPaneManager inherited class --- src/library/librarysidebarexpandedmanager.cpp | 20 +++++++++++++++++++ src/library/librarysidebarexpandedmanager.h | 14 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/library/librarysidebarexpandedmanager.cpp create mode 100644 src/library/librarysidebarexpandedmanager.h diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp new file mode 100644 index 00000000000..5f165a19cc4 --- /dev/null +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -0,0 +1,20 @@ +#include "librarysidebarexpandedmanager.h" + +LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) + : LibraryPaneManager(parent) { + +} + +void LibrarySidebarExpandedManager::bindPaneWidget(WBaseLibrary* libraryWidget, + KeyboardEventFilter* pKeyboard) { + + m_pPaneWidget = libraryWidget; + + connect(this, SIGNAL(switchToView(const QString&)), + m_pPaneWidget, SLOT(switchToView(const QString&))); + + for (LibraryFeature* f : m_features) { + f->bindSidebarWidget(m_pPaneWidget, pKeyboard); + } +} + diff --git a/src/library/librarysidebarexpandedmanager.h b/src/library/librarysidebarexpandedmanager.h new file mode 100644 index 00000000000..0f1a659f75e --- /dev/null +++ b/src/library/librarysidebarexpandedmanager.h @@ -0,0 +1,14 @@ +#ifndef LIBRARYSIDEBAREXPANDEDMANAGER_H +#define LIBRARYSIDEBAREXPANDEDMANAGER_H +#include "library/librarypanemanager.h" + +class LibrarySidebarExpandedManager : public LibraryPaneManager +{ + public: + LibrarySidebarExpandedManager(QObject* parent = nullptr); + + void bindPaneWidget(WBaseLibrary* libraryWidget, + KeyboardEventFilter* pKeyboard) override; +}; + +#endif // LIBRARYSIDEBAREXPANDEDMANAGER_H From d724ab2167bed351518a991347164477938a187e Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 09:23:04 +0200 Subject: [PATCH 142/552] Remove switch from LibraryPaneManager --- src/library/librarypanemanager.cpp | 58 +++++++++++++----------------- src/library/librarypanemanager.h | 47 ++++++++++++------------ 2 files changed, 48 insertions(+), 57 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 40dc302d254..a06fc5198fa 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -7,7 +7,7 @@ const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); LibraryPaneManager::LibraryPaneManager(QObject* parent) : QObject(parent), - m_pPaneWidget(nullptr){ + m_pPaneWidget(nullptr) { qApp->installEventFilter(this); } @@ -15,38 +15,26 @@ LibraryPaneManager::~LibraryPaneManager() { } void LibraryPaneManager::bindPaneWidget(WBaseLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard, - FeaturePane pane) { + KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryPaneManager::bindLibraryWidget" << libraryWidget; m_pPaneWidget = libraryWidget; connect(this, SIGNAL(switchToView(const QString&)), - m_pPaneWidget, SLOT(switchToView(const QString&))); - - switch (pane) { - case FeaturePane::SidebarExpanded: - //qDebug() << "LibraryPaneManager::bindLibraryWidget:SidebarExpanded"; - for (LibraryFeature* f : m_features) { - f->bindSidebarWidget(m_pPaneWidget, pKeyboard); - } - break; - case FeaturePane::TrackTable: - //qDebug() << "LibraryPaneManager::bindLibraryWidget:TrackTable"; - WLibrary* lib = qobject_cast(m_pPaneWidget); - if (lib == nullptr) { - return; - } - for (LibraryFeature* f : m_features) { - f->bindPaneWidget(lib, pKeyboard); - } - break; + m_pPaneWidget, SLOT(switchToView(const QString&))); + + WLibrary* lib = qobject_cast(m_pPaneWidget); + if (lib == nullptr) { + return; + } + for (LibraryFeature* f : m_features) { + f->bindPaneWidget(lib, pKeyboard); } } -void LibraryPaneManager::bindSearchBar(WSearchLineEdit *pSearchLine) { +void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchLine) { pSearchLine->installEventFilter(this); - + connect(pSearchLine, SIGNAL(search(const QString&)), this, SIGNAL(search(const QString&))); connect(pSearchLine, SIGNAL(searchCleared()), @@ -61,19 +49,19 @@ void LibraryPaneManager::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; } - + m_features.append(feature); } -void LibraryPaneManager::addFeatures(const QList &features) { +void LibraryPaneManager::addFeatures(const QList& features) { m_features.append(features); } -WBaseLibrary *LibraryPaneManager::getPaneWidget() { +WBaseLibrary* LibraryPaneManager::getPaneWidget() { return m_pPaneWidget; } -void LibraryPaneManager::setFocusedFeature(const QString &featureName) { +void LibraryPaneManager::setFocusedFeature(const QString& featureName) { m_focusedFeature = featureName; } @@ -108,14 +96,16 @@ void LibraryPaneManager::slotRestoreSearch(const QString& text) { emit(restoreSearch(text)); } -bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { - if (m_pPaneWidget == nullptr) return false; - - if (event->type() == QEvent::MouseButtonPress && - m_pPaneWidget->underMouse()) { +bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { + if (m_pPaneWidget == nullptr) { + return false; + } + + if (event->type() == QEvent::MouseButtonPress && + m_pPaneWidget->underMouse()) { emit(focused()); } - + // Since this event filter is for the entire application (to handle the // mouse event), NEVER return true. If true is returned I will block all // application events and will block the entire application. diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 3febb166b4d..5a243fb4173 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -14,45 +14,45 @@ class LibraryPaneManager : public QObject { Q_OBJECT public: - + enum class FeaturePane { SidebarExpanded, TrackTable }; LibraryPaneManager(QObject* parent = nullptr); - + ~LibraryPaneManager(); - + bool initialize(); // All features must be added before adding a pane - void bindPaneWidget(WBaseLibrary *libraryWidget, - KeyboardEventFilter *pKeyboard, FeaturePane pane); + virtual void bindPaneWidget(WBaseLibrary* libraryWidget, + KeyboardEventFilter* pKeyboard); void bindSearchBar(WSearchLineEdit* pSearchLine); - + void addFeature(LibraryFeature* feature); - void addFeatures(const QList &features); - + void addFeatures(const QList& features); + WBaseLibrary* getPaneWidget(); - + void setFocusedFeature(const QString& featureName); - + QString getFocusedFeature() { return m_focusedFeature; } - + void setFocus(); - + void clearFocus(); - -signals: - + + signals: + void focused(); - + void showTrackModel(QAbstractItemModel* model); void switchToView(const QString&); - + void restoreSearch(const QString&); void search(const QString& text); void searchCleared(); @@ -62,22 +62,23 @@ class LibraryPaneManager : public QObject { void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); - void slotRestoreSearch(const QString& text); + void slotRestoreSearch(const QString& text); - private: + protected: - const static QString m_sTrackViewName; - WBaseLibrary* m_pPaneWidget; QList m_features; - + + private: + + const static QString m_sTrackViewName; + QString m_focusedFeature; private slots: // Used to handle focus change - // TODO(jmigual): Still needs to be implemented bool eventFilter(QObject*, QEvent* event); }; From 571d7b356f95315118b19953f899bb039e3800a4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 09:23:27 +0200 Subject: [PATCH 143/552] Use new LibrarySidebarExpandedManager in library --- build/depends.py | 1 + src/library/library.cpp | 9 ++++----- src/library/library.h | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build/depends.py b/build/depends.py index 78d01a69c47..9711344d985 100644 --- a/build/depends.py +++ b/build/depends.py @@ -895,6 +895,7 @@ def sources(self, build): "library/sidebarmodel.cpp", "library/library.cpp", "library/librarypanemanager.cpp", + "library/librarysidebarexpandedmanager.cpp", "library/scanner/libraryscanner.cpp", "library/scanner/libraryscannerdlg.cpp", diff --git a/src/library/library.cpp b/src/library/library.cpp index 2d72ce7a115..02be3a138ca 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -151,8 +151,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, createPane(id); } - m_panes[id]->bindPaneWidget(pLibraryWidget, pKeyboard, - LibraryPaneManager::FeaturePane::TrackTable); + m_panes[id]->bindPaneWidget(pLibraryWidget, pKeyboard); connect(m_panes[id], SIGNAL(showTrackModel(QAbstractItemModel*)), pTrackTableView, SLOT(loadTrackModel(QAbstractItemModel*))); @@ -172,12 +171,11 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard) { //qDebug() << "Library::bindSidebarExpanded"; - m_pSidebarExpanded = new LibraryPaneManager; + m_pSidebarExpanded = new LibrarySidebarExpandedManager; connect(m_pSidebarExpanded, SIGNAL(focused()), this, SLOT(slotPaneFocused())); m_pSidebarExpanded->addFeatures(m_features); - m_pSidebarExpanded->bindPaneWidget(expandedPane, pKeyboard, - LibraryPaneManager::FeaturePane::SidebarExpanded); + m_pSidebarExpanded->bindPaneWidget(expandedPane, pKeyboard); } void Library::destroyInterface() { @@ -310,6 +308,7 @@ void Library::onSkinLoadFinished() { if (m_panes.size() > 0) { m_focusedPane = m_panes.begin().key(); + m_features.first()->setFeatureFocus(m_focusedPane); m_features.first()->activate(); } else { diff --git a/src/library/library.h b/src/library/library.h index aabeb4e75af..4ed8506b80e 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -21,6 +21,7 @@ #include "library/setlogfeature.h" #include "library/scanner/libraryscanner.h" #include "library/librarypanemanager.h" +#include "library/librarysidebarexpandedmanager.h" #include "widget/wtracktableview.h" #include "widget/wlibrary.h" From cc24a084fb4d8edb811824480c89786d57016ae8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 09:37:04 +0200 Subject: [PATCH 144/552] Added focus indicator on deere skin and more minimal in LateNight --- res/skins/Deere/library.xml | 2 +- res/skins/Deere/style.qss | 19 +++++++++++++++---- res/skins/LateNight/style.qss | 6 +++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index 5c1da2cf9a2..21b2343f6ad 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -28,7 +28,7 @@ [Library],show_library - 120,-1 + LibrarySidebar diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 0fe33bdb885..4a64eeb3474 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -143,6 +143,16 @@ QTableView::indicator:unchecked { background: url(skin:/image/style_checkbox_unchecked.png); } +WBaseLibrary[showFocus="0"] { + padding: 1px 0 0 0; + border: none; +} + +WBaseLibrary[showFocus="1"] { + padding: 1px 1px 1px 1px; + border-top: 1px solid #DE6B0F; +} + /* BPM lock icon in the library "BPM" column. */ #LibraryBPMButton::indicator:checked { image: url(:/images/library/ic_library_checked.png); @@ -152,6 +162,11 @@ QTableView::indicator:unchecked { image: url(:/images/library/ic_library_unchecked.png); } +#LibrarySidebar, #LibrarySidebar WButtonBAr { + background-color: #222222; + margin-right: 10px; +} + /* button in library "Preview" column */ QPushButton#LibraryPreviewButton { width: 23px; @@ -224,10 +239,6 @@ WSearchLineEdit:focus { selection-color: #222222; } -WButtonBar { - background-color: #222222; -} - /* library preview deck */ #PreviewDeckContainer { margin: 4px 0px 0px 0px; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index e00e3e3d0db..f4ebe7c96c8 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1375,11 +1375,11 @@ QTreeView::item:selected { } WBaseLibrary[showFocus="0"] { - padding: 1px 1px 1px 1px; + padding: 1px 0 0 0; border: none; } WBaseLibrary[showFocus="1"] { - padding: 1px 1px 1px 1px; - border: 1px solid #FF7100 !important; + padding: 1px 0 0 0; + border-top: 1px solid #FF7100 !important; } \ No newline at end of file From 580d05156e422a4ac6eb9e0e46a8e1d4dafa2f04 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 10:22:25 +0200 Subject: [PATCH 145/552] Add paneId parameter in bindPaneWidget function --- src/library/analysisfeature.cpp | 2 +- src/library/analysisfeature.h | 2 +- src/library/autodj/autodjfeature.cpp | 12 ++++---- src/library/autodj/autodjfeature.h | 5 ++-- src/library/autodj/dlgautodj.cpp | 29 ++++++++++++------- src/library/autodj/dlgautodj.h | 7 ++++- src/library/baseplaylistfeature.cpp | 2 +- src/library/baseplaylistfeature.h | 2 +- src/library/browse/browsefeature.cpp | 2 +- src/library/browse/browsefeature.h | 2 +- src/library/cratefeature.cpp | 2 +- src/library/cratefeature.h | 2 +- src/library/library.cpp | 2 +- src/library/libraryfeature.h | 3 +- src/library/librarypanemanager.cpp | 7 +++-- src/library/librarypanemanager.h | 8 ++++- src/library/librarysidebarexpandedmanager.cpp | 2 +- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/mixxxlibraryfeature.h | 2 +- src/library/recording/recordingfeature.cpp | 2 +- src/library/recording/recordingfeature.h | 2 +- src/library/setlogfeature.cpp | 4 +-- src/library/setlogfeature.h | 2 +- 23 files changed, 65 insertions(+), 40 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 03ce8a20d43..3abf5cbf713 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -76,7 +76,7 @@ void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, } void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard) { + KeyboardEventFilter* pKeyboard, int) { m_pAnalysisView = new DlgAnalysis(libraryWidget, m_pTrackCollection); connect(m_pAnalysisView, SIGNAL(loadTrack(TrackPointer)), diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index fa3905a5ed3..3a2fb744410 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -38,7 +38,7 @@ class AnalysisFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*pKeyboard); void bindSidebarWidget(WBaseLibrary* libraryWidget, - KeyboardEventFilter*pKeyboard); + KeyboardEventFilter*pKeyboard, int); TreeItemModel* getChildModel(); void refreshLibraryModels(); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index f946e92f270..f89f6bb013b 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -101,7 +101,8 @@ QString AutoDJFeature::getViewName() { } void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard) { + KeyboardEventFilter* pKeyboard, + int paneId) { //qDebug() << "AutoDJFeature::bindPaneWidget" << pLibraryWidget; WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection, false); @@ -115,9 +116,9 @@ void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, pTrackTableView, SLOT(setTrackTableRowHeight(int))); if (m_pAutoDJView) { - m_pAutoDJView->setTrackTableView(pTrackTableView); + m_pAutoDJView->setTrackTableView(pTrackTableView, paneId); } else { - m_trackTables.append(pTrackTableView); + m_trackTables[paneId] = pTrackTableView; } } @@ -156,8 +157,8 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, pSidebarWidget->registerView(m_sAutoDJViewName, pContainer); - for (WTrackTableView* pT : m_trackTables) { - m_pAutoDJView->setTrackTableView(pT); + for (auto it = m_trackTables.begin(); it != m_trackTables.end(); ++it) { + m_pAutoDJView->setTrackTableView(it.value(), it.key()); } m_trackTables.clear(); } @@ -168,6 +169,7 @@ TreeItemModel* AutoDJFeature::getChildModel() { void AutoDJFeature::activate() { //qDebug() << "AutoDJFeature::activate()"; + m_pAutoDJView->setFocusedPane(m_featureFocus); m_pAutoDJView->onShow(); emit(switchToView(m_sAutoDJViewName)); emit(restoreSearch(QString())); //Null String disables search box diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index e749f0250d5..54803c80c4b 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -45,7 +45,7 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter*pKeyboard); + void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter*pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter*); TreeItemModel* getChildModel(); @@ -68,7 +68,8 @@ class AutoDJFeature : public LibraryFeature { const static QString m_sAutoDJViewName; TreeItemModel m_childModel; QPointer m_pAutoDJView; - QList m_trackTables; + //QList m_trackTables; + QHash m_trackTables; // Initialize the list of crates loaded into the auto-DJ queue. void constructCrateChildModel(); diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 59ebdc2a591..18ed0d0ff5b 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -15,12 +15,13 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, m_pAutoDJProcessor(pProcessor), // no sorting m_pAutoDJTableModel(nullptr), - m_pLibrary(pLibrary) { + m_pLibrary(pLibrary), + m_focusedPane(-1) { setupUi(this); // We do _NOT_ take ownership of this from AutoDJProcessor. m_pAutoDJTableModel = m_pAutoDJProcessor->getTableModel(); - + // Override some playlist-view properties: connect(pushButtonShuffle, SIGNAL(clicked(bool)), @@ -60,9 +61,11 @@ void DlgAutoDJ::onShow() { m_pAutoDJTableModel->select(); } -void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView) { +void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView, int pane) { pTrackTableView->loadTrackModel(m_pAutoDJTableModel); + m_trackTables[pane] = pTrackTableView; + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), @@ -75,6 +78,10 @@ void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView) { updateSelectionInfo(); } +void DlgAutoDJ::setFocusedPane(int focusedPane) { + m_focusedPane = focusedPane; +} + void DlgAutoDJ::shufflePlaylistButton(bool) { LibraryView* pView = m_pLibrary->getActiveView(); WTrackTableView* pTrackTable = dynamic_cast(pView); @@ -156,16 +163,19 @@ void DlgAutoDJ::autoDJStateChanged(AutoDJProcessor::AutoDJState state) { } void DlgAutoDJ::updateSelectionInfo() { - int duration = 0; - - LibraryView* pView = m_pLibrary->getActiveView(); - WTrackTableView* pTrackTable = dynamic_cast(pView); - if (!pView) { + if (!m_trackTables.contains(m_focusedPane)) { + labelSelectionInfo->setText(""); + labelSelectionInfo->setEnabled(false); return; } - QModelIndexList indices = pTrackTable->selectionModel()->selectedRows(); + int duration = 0; + WTrackTableView* pTrackTable = m_trackTables[m_focusedPane]; + if (!pTrackTable) { + return; + } + QModelIndexList indices = pTrackTable->selectionModel()->selectedRows(); for (int i = 0; i < indices.size(); ++i) { TrackPointer pTrack = m_pAutoDJTableModel->getTrack(indices.at(i)); if (pTrack) { @@ -174,7 +184,6 @@ void DlgAutoDJ::updateSelectionInfo() { } QString label; - if (!indices.isEmpty()) { label.append(Time::formatSeconds(duration)); label.append(QString(" (%1)").arg(indices.size())); diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index 8ebe1eaab54..b1199f76efc 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -24,7 +24,8 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { virtual ~DlgAutoDJ(); void onShow(); - void setTrackTableView(WTrackTableView* pTrackTableView); + void setTrackTableView(WTrackTableView* pTrackTableView, int pane); + void setFocusedPane(int focusedPane); public slots: void shufflePlaylistButton(bool buttonChecked); @@ -46,6 +47,10 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { AutoDJProcessor* m_pAutoDJProcessor; PlaylistTableModel* m_pAutoDJTableModel; Library* m_pLibrary; + + int m_focusedPane; + + QMap m_trackTables; }; #endif //DLGAUTODJ_H diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 949b58397eb..63828dafe03 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -595,7 +595,7 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { } void BasePlaylistFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard) { + KeyboardEventFilter* keyboard, int) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); edit->setHtml(getRootViewHtml()); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index d67f3993c5f..47d5a343755 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -34,7 +34,7 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard); + KeyboardEventFilter* keyboard, int); QString getViewName() { return m_rootViewName; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index d80f3cb394c..4813ed6c83d 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -214,7 +214,7 @@ TreeItemModel* BrowseFeature::getChildModel() { } void BrowseFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard) { + KeyboardEventFilter* keyboard, int) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); edit->setHtml(getRootViewHtml()); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 2745ab043c0..6f119a5eb5d 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,7 @@ class BrowseFeature : public LibraryFeature { virtual QString getViewName(); void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard); + KeyboardEventFilter* keyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 82375331ea2..ca5e403604a 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -181,7 +181,7 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { } void CrateFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* keyboard) { + KeyboardEventFilter* keyboard, int) { Q_UNUSED(keyboard); WLibraryTextBrowser* edit = new WLibraryTextBrowser(pLibraryWidget); edit->setHtml(getRootViewHtml()); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index eaf1a596b41..ec7ff503016 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -42,7 +42,7 @@ class CrateFeature : public LibraryFeature { bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); void bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* keyboard); + KeyboardEventFilter* keyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/library.cpp b/src/library/library.cpp index 02be3a138ca..3696310fed7 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -456,7 +456,7 @@ void Library::createPane(int id) { if (m_panes.contains(id)) { return; } - LibraryPaneManager* pane = new LibraryPaneManager; + LibraryPaneManager* pane = new LibraryPaneManager(id); pane->addFeatures(m_features); m_panes.insert(id, pane); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 0237af33161..14edcfdef35 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -70,7 +70,8 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget // at the right pane. virtual void bindPaneWidget(WLibrary* /* libraryWidget */, - KeyboardEventFilter* /* keyboard */) { + KeyboardEventFilter* /* keyboard */, + int /* paneId */) { } // Reimplement this to register custem views with the library widget, diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index a06fc5198fa..7436de40fe9 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -5,9 +5,10 @@ const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); -LibraryPaneManager::LibraryPaneManager(QObject* parent) +LibraryPaneManager::LibraryPaneManager(int paneId, QObject* parent) : QObject(parent), - m_pPaneWidget(nullptr) { + m_pPaneWidget(nullptr), + m_paneId(paneId) { qApp->installEventFilter(this); } @@ -28,7 +29,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* libraryWidget, return; } for (LibraryFeature* f : m_features) { - f->bindPaneWidget(lib, pKeyboard); + f->bindPaneWidget(lib, pKeyboard, m_paneId); } } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 5a243fb4173..156bea04233 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -20,7 +20,7 @@ class LibraryPaneManager : public QObject { TrackTable }; - LibraryPaneManager(QObject* parent = nullptr); + LibraryPaneManager(int paneId, QObject* parent = nullptr); ~LibraryPaneManager(); @@ -45,6 +45,10 @@ class LibraryPaneManager : public QObject { void setFocus(); void clearFocus(); + + inline int getPaneId() { + return m_paneId; + } signals: @@ -75,6 +79,8 @@ class LibraryPaneManager : public QObject { const static QString m_sTrackViewName; QString m_focusedFeature; + + int m_paneId; private slots: diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 5f165a19cc4..789427d5ea0 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -1,7 +1,7 @@ #include "librarysidebarexpandedmanager.h" LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) - : LibraryPaneManager(parent) { + : LibraryPaneManager(-1, parent) { } diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 666782b4a95..f5090ac566a 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -131,7 +131,7 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { } void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard) { + KeyboardEventFilter* pKeyboard, int) { m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, m_pTrackCollection, pKeyboard); pLibraryWidget->registerView(kHiddenTitle, m_pHiddenView); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 5676ac1dc24..ee69473cd30 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -40,7 +40,7 @@ class MixxxLibraryFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); void bindPaneWidget(WLibrary* pLibrary, - KeyboardEventFilter* pKeyboard); + KeyboardEventFilter* pKeyboard, int); inline QString getViewName() { return m_sMixxxLibraryViewName; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 989d2338701..89c61dae7c8 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -39,7 +39,7 @@ TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter *keyboard) { + KeyboardEventFilter *keyboard, int) { //The view will be deleted by LibraryWidget DlgRecording* pRecordingView = new DlgRecording(pLibraryWidget, m_pConfig, diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 9e1631a98c7..6aaafba6f68 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,7 +30,7 @@ class RecordingFeature : public LibraryFeature { QIcon getIcon(); void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard); + KeyboardEventFilter* keyboard, int); inline QString getViewName() { return m_sRecordingViewName; } diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index 437ae84eca9..ff6039fe97e 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -54,9 +54,9 @@ QIcon SetlogFeature::getIcon() { } void SetlogFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard) { + KeyboardEventFilter* keyboard, int paneId) { BasePlaylistFeature::bindPaneWidget(libraryWidget, - keyboard); + keyboard, paneId); connect(&PlayerInfo::instance(), SIGNAL(currentPlayingTrackChanged(TrackPointer)), this, SLOT(slotPlayingTrackChanged(TrackPointer))); } diff --git a/src/library/setlogfeature.h b/src/library/setlogfeature.h index 4d4bc815e28..2115076ac64 100644 --- a/src/library/setlogfeature.h +++ b/src/library/setlogfeature.h @@ -24,7 +24,7 @@ class SetlogFeature : public BasePlaylistFeature { QIcon getIcon(); virtual void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard); + KeyboardEventFilter* keyboard, int paneId); public slots: void onRightClick(const QPoint& globalPos); From 8e0918f6439ab1200cebd6d96f5dcfa65d262800 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 13:04:59 +0200 Subject: [PATCH 146/552] Add better focus engine --- src/library/library.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 3696310fed7..065d1061a52 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -229,7 +229,7 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { } void Library::slotSwitchToView(const QString& view) { - qDebug() << "Library::slotSwitchToView" << view; + //qDebug() << "Library::slotSwitchToView" << view; m_pSidebarExpanded->slotSwitchToView(view); WBaseLibrary* wLibrary = m_panes[m_focusedPane]->getPaneWidget(); @@ -249,7 +249,7 @@ void Library::slotSwitchToView(const QString& view) { } void Library::slotSwitchToViewChild(const QString &view) { - qDebug() << "Library::slotSwitchToViewChild"; + //qDebug() << "Library::slotSwitchToViewChild"; m_panes[m_focusedPane]->slotSwitchToView(view); } @@ -307,9 +307,21 @@ void Library::onSkinLoadFinished() { //m_pSidebarModel->activateDefaultSelection(); if (m_panes.size() > 0) { - m_focusedPane = m_panes.begin().key(); - m_features.first()->setFeatureFocus(m_focusedPane); - m_features.first()->activate(); + auto itF = m_features.begin(); + auto itP = m_panes.begin(); + + // Assign a feature to show on each pane unless there are more panes + // than features + while (itP != m_panes.end() && itF != m_features.end()) { + qDebug() << (*itF)->getViewName() << itP.key(); + m_focusedPane = itP.key(); + + (*itF)->setFeatureFocus(itP.key()); + (*itF)->activate(); + + ++itP; + ++itF; + } } else { qDebug() << "Library::onSkinLoadFinished No Panes loaded!"; @@ -395,7 +407,8 @@ void Library::slotActivateFeature(const QString &featureName) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getFocusedFeature() == featureName) { - return; + m_pSidebarExpanded->slotSwitchToView(featureName); + return; } // The feature is not focused anywhere @@ -510,6 +523,7 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { addFeature(new RhythmboxFeature(this, m_pTrackCollection)); } + if (pConfig->getValueString(ConfigKey("[Library]","ShowBansheeLibrary"),"1").toInt()) { BansheeFeature::prepareDbPath(pConfig); if (BansheeFeature::isSupported()) { From 6ef7a31060f27416f0f965c057350af1fc83ae05 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 13:09:56 +0200 Subject: [PATCH 147/552] Add feature click button to handle features --- build/depends.py | 2 +- src/library/library.cpp | 2 +- src/library/library.h | 2 +- src/widget/wbuttonbar.cpp | 4 +-- src/widget/wbuttonbar.h | 4 +-- src/widget/wfeatureclickbutton.cpp | 28 +++++++++++++++++++ ...ghtclickbutton.h => wfeatureclickbutton.h} | 6 ++-- src/widget/wrightclickbutton.cpp | 24 ---------------- 8 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 src/widget/wfeatureclickbutton.cpp rename src/widget/{wrightclickbutton.h => wfeatureclickbutton.h} (76%) delete mode 100644 src/widget/wrightclickbutton.cpp diff --git a/build/depends.py b/build/depends.py index 9711344d985..e34400778a0 100644 --- a/build/depends.py +++ b/build/depends.py @@ -813,7 +813,7 @@ def sources(self, build): "widget/wsingletoncontainer.cpp", "widget/wmainmenubar.cpp", "widget/wbuttonbar.cpp", - "widget/wrightclickbutton.cpp", + "widget/wfeatureclickbutton.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/src/library/library.cpp b/src/library/library.cpp index 065d1061a52..77d971e94cd 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -114,7 +114,7 @@ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { void Library::bindSidebarWidget(WButtonBar* sidebar) { for (LibraryFeature* f : m_features) { - WRightClickButton* button = sidebar->addButton(f->getIcon(), f->title(), + WFeatureClickButton* button = sidebar->addButton(f->getIcon(), f->title(), f->getViewName()); connect(button, SIGNAL(clicked(const QString&)), diff --git a/src/library/library.h b/src/library/library.h index 4ed8506b80e..0947cdfb09c 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -25,7 +25,7 @@ #include "widget/wtracktableview.h" #include "widget/wlibrary.h" -#include "widget/wrightclickbutton.h" +#include "widget/wfeatureclickbutton.h" class TrackModel; class TrackCollection; diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 102388f293f..ababf1a6e42 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -9,10 +9,10 @@ WButtonBar::WButtonBar(QWidget* parent) setLayout(m_pLayout); } -WRightClickButton* WButtonBar::addButton(const QIcon& icon, +WFeatureClickButton* WButtonBar::addButton(const QIcon& icon, const QVariant& title, const QString& data) { - WRightClickButton* button = new WRightClickButton(this); + WFeatureClickButton* button = new WFeatureClickButton(this); button->setIcon(icon); button->setText(title.toString()); button->setData(data); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 66ebdbde754..2e03a9f2f2c 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -7,7 +7,7 @@ #include #include "widget/wwidget.h" -#include "widget/wrightclickbutton.h" +#include "widget/wfeatureclickbutton.h" class WButtonBar : public WWidget { @@ -15,7 +15,7 @@ class WButtonBar : public WWidget public: WButtonBar(QWidget* parent = nullptr); - WRightClickButton* addButton(const QIcon& icon, const QVariant& title, const QString &data); + WFeatureClickButton* addButton(const QIcon& icon, const QVariant& title, const QString &data); private: diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp new file mode 100644 index 00000000000..5578986564f --- /dev/null +++ b/src/widget/wfeatureclickbutton.cpp @@ -0,0 +1,28 @@ +#include "wfeatureclickbutton.h" + +WFeatureClickButton::WFeatureClickButton(QWidget* parent) + : QToolButton(parent) { + connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); +} + +void WFeatureClickButton::setData(const QString& data) { + m_data = data; +} + + + +void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { + if (event->button() == Qt::RightButton) { + emit(rightClicked(event->globalPos())); + } + QToolButton::mousePressEvent(event); +} + +void WFeatureClickButton::dropEvent(QDropEvent* event) { + +} + +void WFeatureClickButton::slotClicked() { + emit(clicked(m_data)); +} + diff --git a/src/widget/wrightclickbutton.h b/src/widget/wfeatureclickbutton.h similarity index 76% rename from src/widget/wrightclickbutton.h rename to src/widget/wfeatureclickbutton.h index c425d1e7c37..e833f8088c9 100644 --- a/src/widget/wrightclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -4,12 +4,12 @@ #include #include -class WRightClickButton : public QToolButton +class WFeatureClickButton : public QToolButton { Q_OBJECT public: - WRightClickButton(QWidget* parent = nullptr); + WFeatureClickButton(QWidget* parent = nullptr); void setData(const QString& data); @@ -23,6 +23,8 @@ class WRightClickButton : public QToolButton void mousePressEvent(QMouseEvent* event); + void dropEvent(QDropEvent* event); + private slots: void slotClicked(); diff --git a/src/widget/wrightclickbutton.cpp b/src/widget/wrightclickbutton.cpp deleted file mode 100644 index ace538e3a39..00000000000 --- a/src/widget/wrightclickbutton.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "wrightclickbutton.h" - -WRightClickButton::WRightClickButton(QWidget* parent) - : QToolButton(parent) { - connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); -} - -void WRightClickButton::setData(const QString &data) { - m_data = data; -} - - - -void WRightClickButton::mousePressEvent(QMouseEvent* event) { - if (event->button() == Qt::RightButton) { - emit(rightClicked(event->globalPos())); - } - QToolButton::mousePressEvent(event); -} - -void WRightClickButton::slotClicked() { - emit(clicked(m_data)); -} - From a2a4f256c9abff9840a55d83b142c2299df32aea Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:42:31 +0200 Subject: [PATCH 148/552] Add hover code for feature click button --- src/widget/wbuttonbar.cpp | 10 ++---- src/widget/wbuttonbar.h | 2 +- src/widget/wfeatureclickbutton.cpp | 53 +++++++++++++++++++++++++++--- src/widget/wfeatureclickbutton.h | 18 +++++++++- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index ababf1a6e42..bac1c20f511 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -1,4 +1,5 @@ #include "wbuttonbar.h" +#include "library/libraryfeature.h" WButtonBar::WButtonBar(QWidget* parent) : WWidget(parent) { @@ -9,13 +10,8 @@ WButtonBar::WButtonBar(QWidget* parent) setLayout(m_pLayout); } -WFeatureClickButton* WButtonBar::addButton(const QIcon& icon, - const QVariant& title, - const QString& data) { - WFeatureClickButton* button = new WFeatureClickButton(this); - button->setIcon(icon); - button->setText(title.toString()); - button->setData(data); +WFeatureClickButton* WButtonBar::addButton(LibraryFeature* pFeature) { + WFeatureClickButton* button = new WFeatureClickButton(pFeature, this); button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 2e03a9f2f2c..e06dafb213a 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -15,7 +15,7 @@ class WButtonBar : public WWidget public: WButtonBar(QWidget* parent = nullptr); - WFeatureClickButton* addButton(const QIcon& icon, const QVariant& title, const QString &data); + WFeatureClickButton* addButton(LibraryFeature *pFeature); private: diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index 5578986564f..f3aa29602e6 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -1,16 +1,27 @@ #include "wfeatureclickbutton.h" +#include "util/assert.h" + +const int WFeatureClickButton::kHoverTime = 250; // milliseconds + +WFeatureClickButton::WFeatureClickButton(LibraryFeature* feature, QWidget* parent) + : QToolButton(parent), + m_feature(feature) { + DEBUG_ASSERT_AND_HANDLE(feature != nullptr) { + return; + } + + setIcon(m_feature->getIcon()); + setText(m_feature->title().toString()); + m_data = m_feature->getViewName(); -WFeatureClickButton::WFeatureClickButton(QWidget* parent) - : QToolButton(parent) { connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); + setAcceptDrops(true); } void WFeatureClickButton::setData(const QString& data) { m_data = data; } - - void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::RightButton) { emit(rightClicked(event->globalPos())); @@ -18,8 +29,40 @@ void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { QToolButton::mousePressEvent(event); } +void WFeatureClickButton::dragEnterEvent(QDragEnterEvent* event) { + qDebug() << "WFeatureClickButton::dragEnterEvent" << event; + if (!event->mimeData()->hasUrls() || event->source() == this) { + event->ignore(); + return; + } + if (m_feature->dragMoveAccept(event->mimeData()->urls().first())) { + event->acceptProposedAction(); + m_hoverTimer.start(kHoverTime, this); + } +} + +void WFeatureClickButton::dragLeaveEvent(QDragLeaveEvent* event) { + m_hoverTimer.stop(); +} + void WFeatureClickButton::dropEvent(QDropEvent* event) { - + event->acceptProposedAction(); + if (!event->mimeData()->hasUrls() || event->source() == this) { + event->ignore(); + return; + } + + if (m_feature->dropAccept(event->mimeData()->urls(), event->source())) { + event->acceptProposedAction(); + } +} + +void WFeatureClickButton::timerEvent(QTimerEvent* event) { + if (event->timerId() != m_hoverTimer.timerId()) { + QToolButton::timerEvent(event); + return; + } + emit(hoverShow(m_data)); } void WFeatureClickButton::slotClicked() { diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index e833f8088c9..d4a616ec60b 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -1,6 +1,7 @@ #ifndef WRIGHTCLICKBUTTON_H #define WRIGHTCLICKBUTTON_H +#include #include #include @@ -9,7 +10,8 @@ class WFeatureClickButton : public QToolButton Q_OBJECT public: - WFeatureClickButton(QWidget* parent = nullptr); + WFeatureClickButton(LibraryFeature* feature = nullptr, + QWidget* parent = nullptr); void setData(const QString& data); @@ -19,19 +21,33 @@ class WFeatureClickButton : public QToolButton void rightClicked(const QPoint&); + void hoverShow(const QString& feature); + protected: void mousePressEvent(QMouseEvent* event); + void dragEnterEvent(QDragEnterEvent* event); + + void dragLeaveEvent(QDragLeaveEvent* event); + void dropEvent(QDropEvent* event); + void timerEvent(QTimerEvent* event); + private slots: void slotClicked(); private: + static const int kHoverTime; + QString m_data; + + LibraryFeature* m_feature; + + QBasicTimer m_hoverTimer; }; #endif // WRIGHTCLICKBUTTON_H From 998c0ab9569efb5edbc1d78266251dd0dc99cab6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:43:03 +0200 Subject: [PATCH 149/552] Add forward declaration for fast compilation --- src/library/librarypanemanager.cpp | 2 ++ src/library/librarypanemanager.h | 10 +++------- src/library/librarysidebarexpandedmanager.cpp | 1 + 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 7436de40fe9..157a233386c 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -1,6 +1,8 @@ #include #include "librarypanemanager.h" +#include "widget/wbuttonbar.h" +#include "library/libraryfeature.h" #include "util/assert.h" const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 156bea04233..c8b9ee0c106 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -4,22 +4,18 @@ #include #include -#include "library/libraryfeature.h" -#include "widget/wbuttonbar.h" #include "widget/wlibrary.h" #include "widget/wsearchlineedit.h" #include "widget/wtracktableview.h" +class LibraryFeature; +class WButtonBar; + class LibraryPaneManager : public QObject { Q_OBJECT public: - enum class FeaturePane { - SidebarExpanded, - TrackTable - }; - LibraryPaneManager(int paneId, QObject* parent = nullptr); ~LibraryPaneManager(); diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 789427d5ea0..089342dbd20 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -1,4 +1,5 @@ #include "librarysidebarexpandedmanager.h" +#include "library/libraryfeature.h" LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) : LibraryPaneManager(-1, parent) { From 6e6ae0672e0b8adc6720408a4fbbeb09296344fe Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:43:54 +0200 Subject: [PATCH 150/552] Fix treeitem model not accepting some drop events --- src/library/treeitemmodel.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 95deee34063..3270c598a0c 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -219,12 +219,13 @@ bool TreeItemModel::dropAccept(const QModelIndex& index, QList urls, pFeature = m_pRootItem->getFeature(); } else { TreeItem* treeItem = (TreeItem*) index.internalPointer(); - if (treeItem) { - pFeature = treeItem->getFeature(); + if (!treeItem) { + return false; } + pFeature = treeItem->getFeature(); } - pFeature->dropAcceptChild(index, urls, pSource); + result = pFeature->dropAcceptChild(index, urls, pSource); } return result; } From e8ac1efe1ad13287e10f288bca5f6b343768d593 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:44:53 +0200 Subject: [PATCH 151/552] Add forward declaration and remove some debugs --- src/library/library.h | 2 +- src/widget/wbaselibrary.cpp | 4 ++-- src/widget/wlibrarysidebar.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/library/library.h b/src/library/library.h index 0947cdfb09c..952cf50cc7f 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -20,13 +20,13 @@ #include "library/coverartcache.h" #include "library/setlogfeature.h" #include "library/scanner/libraryscanner.h" -#include "library/librarypanemanager.h" #include "library/librarysidebarexpandedmanager.h" #include "widget/wtracktableview.h" #include "widget/wlibrary.h" #include "widget/wfeatureclickbutton.h" +class LibraryPaneManager; class TrackModel; class TrackCollection; class SidebarModel; diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index c8100be3a65..9a850461e33 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -35,7 +35,7 @@ int WBaseLibrary::getShowFocus() { } void WBaseLibrary::setShowFocus(int sFocus) { - qDebug() << "WBaseLibrary::setShowFocus" << sFocus << this; + //qDebug() << "WBaseLibrary::setShowFocus" << sFocus << this; m_showFocus = sFocus; style()->unpolish(this); @@ -45,7 +45,7 @@ void WBaseLibrary::setShowFocus(int sFocus) { void WBaseLibrary::switchToView(const QString& name) { QMutexLocker lock(&m_mutex); - qDebug() << "WBaseLibrary::switchToView" << name; + //qDebug() << "WBaseLibrary::switchToView" << name; QWidget* widget = m_viewMap.value(name, nullptr); if (widget != nullptr && currentWidget() != widget) { //qDebug() << "WBaseLibrary::setCurrentWidget" << name; diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 587b21daf91..3638159466c 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -39,7 +39,7 @@ void WLibrarySidebar::contextMenuEvent(QContextMenuEvent *event) { // Drag enter event, happens when a dragged item enters the track sources view void WLibrarySidebar::dragEnterEvent(QDragEnterEvent * event) { - qDebug() << "WLibrarySidebar::dragEnterEvent" << event->mimeData()->formats(); + //qDebug() << "WLibrarySidebar::dragEnterEvent" << event->mimeData()->formats(); if (event->mimeData()->hasUrls()) { // We don't have a way to ask the LibraryFeatures whether to accept a // drag so for now we accept all drags. Since almost every From b04fb4491e1c507ab128b13035e5d168bdc62527 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:45:51 +0200 Subject: [PATCH 152/552] Add autoexpanding on hover in wbuttonbar --- src/library/cratefeature.cpp | 6 ++++++ src/library/cratefeature.h | 1 + src/library/library.cpp | 42 ++++++++++++++++++++---------------- src/library/library.h | 3 +++ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index ca5e403604a..6d9042bcf6e 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -142,6 +142,12 @@ int CrateFeature::crateIdFromIndex(QModelIndex index) { return playlistId; } +bool CrateFeature::dragMoveAccept(QUrl url) { + return SoundSourceProxy::isUrlSupported(url) || + Parser::isPlaylistFilenameSupported(url.toLocalFile()); +} + + bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource) { int crateId = crateIdFromIndex(index); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index ec7ff503016..67fabca006c 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -37,6 +37,7 @@ class CrateFeature : public LibraryFeature { inline bool hasSearch() { return false; } void onSearch(QString&) {} + bool dragMoveAccept(QUrl url); bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); diff --git a/src/library/library.cpp b/src/library/library.cpp index 77d971e94cd..1052aa446c9 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -12,6 +12,7 @@ #include "library/library_preferences.h" #include "library/libraryfeature.h" #include "library/librarytablemodel.h" +#include "library/librarypanemanager.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" @@ -31,6 +32,7 @@ #include "util/assert.h" #include "widget/wlibrarysidebar.h" +#include "widget/wbuttonbar.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -114,13 +116,12 @@ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { void Library::bindSidebarWidget(WButtonBar* sidebar) { for (LibraryFeature* f : m_features) { - WFeatureClickButton* button = sidebar->addButton(f->getIcon(), f->title(), - f->getViewName()); + WFeatureClickButton* button = sidebar->addButton(f); connect(button, SIGNAL(clicked(const QString&)), this, SLOT(slotActivateFeature(const QString&))); - - //connect(button, SIGNAL(clicked()), f, SLOT(activate())); + connect(button, SIGNAL(hoverShow(const QString&)), + this, SLOT(slotHoverFeature(const QString&))); connect(button, SIGNAL(rightClicked(const QPoint&)), f, SLOT(onRightClick(const QPoint&))); } @@ -238,12 +239,7 @@ void Library::slotSwitchToView(const QString& view) { m_panes[m_focusedPane]->slotSwitchToView(view); } - m_panes[m_focusedPane]->setFocus(); - for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { - if (it.key() != m_focusedPane) { - it.value()->clearFocus(); - } - } + handleFocus(); emit(switchToView(view)); } @@ -413,7 +409,6 @@ void Library::slotActivateFeature(const QString &featureName) { // The feature is not focused anywhere if (pFeature->getFeatureFocus() < 0) { - // Remove the previous focused feature in this pane for (LibraryFeature* f : m_features) { if (f->getFeatureFocus() == m_focusedPane) { @@ -427,6 +422,14 @@ void Library::slotActivateFeature(const QString &featureName) { m_panes[m_focusedPane]->setFocusedFeature(featureName); pFeature->setFeatureFocus(m_focusedPane); pFeature->activate(); + handleFocus(); +} + +void Library::slotHoverFeature(const QString &featureName) { + // This function only changes the sidebar expanded to allow dropping items + // directly in some features sidebar panes + + m_pSidebarExpanded->slotSwitchToView(featureName); } void Library::slotSetTrackTableFont(const QFont& font) { @@ -450,13 +453,7 @@ void Library::slotPaneFocused() { DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } - pane->setFocus(); - // Clear the focus from the other panes - for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { - if (it.key() != m_focusedPane) { - it.value()->clearFocus(); - } - } + handleFocus(); } //qDebug() << "Library::slotPaneFocused" << m_focusedPane; @@ -539,3 +536,12 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(new TraktorFeature(this, m_pTrackCollection)); } } + +void Library::handleFocus() { + m_panes[m_focusedPane]->setFocus(); + for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { + if (it.key() != m_focusedPane) { + it.value()->clearFocus(); + } + } +} diff --git a/src/library/library.h b/src/library/library.h index 952cf50cc7f..1c4400bfa05 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -90,6 +90,7 @@ class Library : public QObject { public slots: void slotActivateFeature(const QString& featureName); + void slotHoverFeature(const QString& featureName); void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); void slotSwitchToViewChild(const QString& view); @@ -160,6 +161,8 @@ class Library : public QObject { int m_focusedPane; void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); + + void handleFocus(); }; #endif /* LIBRARY_H */ From 0cdfd61b9b361c5c61ed3ee26a98bcc9b88a36a0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 14:54:54 +0200 Subject: [PATCH 153/552] Add drag move support for playlist feature --- src/library/playlistfeature.cpp | 7 +++++++ src/library/playlistfeature.h | 1 + src/widget/wfeatureclickbutton.cpp | 2 +- src/widget/wfeatureclickbutton.h | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 902709d74b5..baa5b27cd29 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -85,6 +85,13 @@ void PlaylistFeature::onRightClickChild(const QPoint& globalPos, QModelIndex ind menu.exec(globalPos); } + +bool PlaylistFeature::dragMoveAccept(QUrl url) { + return SoundSourceProxy::isUrlSupported(url) || + Parser::isPlaylistFilenameSupported(url.toLocalFile()); +} + + bool PlaylistFeature::dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource) { int playlistId = playlistIdFromIndex(index); diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 0d129eff74b..488c947939f 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -27,6 +27,7 @@ class PlaylistFeature : public BasePlaylistFeature { QVariant title(); QIcon getIcon(); + bool dragMoveAccept(QUrl url); bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index f3aa29602e6..83678be505b 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -41,7 +41,7 @@ void WFeatureClickButton::dragEnterEvent(QDragEnterEvent* event) { } } -void WFeatureClickButton::dragLeaveEvent(QDragLeaveEvent* event) { +void WFeatureClickButton::dragLeaveEvent(QDragLeaveEvent*) { m_hoverTimer.stop(); } diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index d4a616ec60b..4043b22a941 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -29,7 +29,7 @@ class WFeatureClickButton : public QToolButton void dragEnterEvent(QDragEnterEvent* event); - void dragLeaveEvent(QDragLeaveEvent* event); + void dragLeaveEvent(QDragLeaveEvent*); void dropEvent(QDropEvent* event); From ce7f142e6b1f7af2d1db417b7d99c47579a0db2b Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 18 Jun 2016 18:56:52 +0200 Subject: [PATCH 154/552] Add new library layout to Shade skin --- res/skins/Deere/library.xml | 2 - res/skins/Deere/style.qss | 10 +- res/skins/LateNight/style.qss | 2 +- res/skins/Shade/skin.xml | 373 ++++++++++++++++++++-------------- src/library/dlganalysis.cpp | 26 +-- src/library/dlganalysis.h | 9 +- src/widget/wbaselibrary.cpp | 2 +- 7 files changed, 239 insertions(+), 185 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index 21b2343f6ad..d2e0597f151 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -19,8 +19,6 @@ vertical min,me - 0,0 - 120,-1 - - LibrarySidebar - + + LibrarySidebarButtons + diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index f96e3bd410c..d123b91970c 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -162,7 +162,7 @@ WBaseLibrary[showFocus="1"] { image: url(:/images/library/ic_library_unchecked.png); } -#LibrarySidebar, #LibrarySidebar WButtonBar { +#LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #222222; margin-right: 13px; } diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index c9341c883f4..84ee907fb63 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -13,9 +13,9 @@ horizontal - - LibrarySidebar - + + LibrarySidebarButtons + LibrarySplitter me,me diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 2e3cd17f9ba..139668d899b 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1156,7 +1156,7 @@ /* Library styling is hard */ -#LibrarySidebar, #LibrarySidebar WButtonBar { +#LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #0f0f0f; margin-right: 11px; } diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 59899664f72..71ed9602062 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -487,12 +487,12 @@ background-color: #aab2b7; } - #LibrarySidebar, #LibrarySidebar WButtonBar { + #LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #8d98a3; margin-right: 13px; } - #LibrarySidebar QScrollArea { + #LibrarySidebarButtons QScrollArea { background-color: #8d98a3; } @@ -775,9 +775,9 @@ horizontal - - LibrarySidebar - + + LibrarySidebarButtons + vertical diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 2fe83a3d2c8..54c2540fbf2 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -553,8 +553,8 @@ QList LegacySkinParser::parseNode(const QDomElement& node) { result = wrapWidget(parseLabelWidget(node)); } else if (nodeName == "Splitter") { result = wrapWidget(parseSplitter(node)); - } else if (nodeName == "LibrarySidebar") { - result = wrapWidget(parseLibrarySidebar(node)); + } else if (nodeName == "LibrarySidebarButtons") { + result = wrapWidget(parseLibrarySidebarButtons(node)); } else if (nodeName == "LibrarySidebarExpanded") { result = wrapWidget(parseLibrarySidebarExpanded(node)); } else if (nodeName == "LibraryPane") { @@ -1260,7 +1260,7 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { return pLibraryWidget; } -QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { +QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { QScrollArea* scroll = new QScrollArea(m_pParent); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); @@ -1313,7 +1313,7 @@ QWidget* LegacySkinParser::parseTableView(const QDomElement& node) { QWidget* pLibrarySidebarPage = new QWidget(pSplitter); m_pParent = pLibrarySidebarPage; - QWidget* pLibrarySidebar = parseLibrarySidebar(node); + QWidget* pLibrarySidebar = parseLibrarySidebarButtons(node); QWidget* pLineEditSearch = parseSearchBox(node); m_pParent = oldParent; diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index 2149f5be3c4..da94ec6c52f 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -100,7 +100,7 @@ class LegacySkinParser : public QObject, public SkinParser { QWidget* parseTableView(const QDomElement& node); QWidget* parseSearchBox(const QDomElement& node); QWidget* parseLibraryPane(const QDomElement& node); - QWidget* parseLibrarySidebar(const QDomElement& node); + QWidget* parseLibrarySidebarButtons(const QDomElement& node); QWidget* parseLibrarySidebarExpanded(const QDomElement& node); QWidget* parseBattery(const QDomElement& node); QWidget* parseCoverArt(const QDomElement& node); From 466e9c61aff074374a54913fb7c6052fad329ab6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 19 Jun 2016 18:39:53 +0200 Subject: [PATCH 157/552] Add support for 2.0 skins --- res/skins/LateNight/style.qss | 8 +++-- src/skin/legacyskinparser.cpp | 65 +++++++++++++++++++++++++++++++++-- src/skin/legacyskinparser.h | 3 ++ 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 139668d899b..f8ab7f87631 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1159,6 +1159,8 @@ #LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #0f0f0f; margin-right: 11px; + + } #LibrarySidebarExpanded QWidget { @@ -1169,7 +1171,7 @@ border: 1px solid #585858; } -#LibrarySidebar QAbstractButton, +#LibrarySidebarButtons QAbstractButton, #LibrarySidebarExpanded QAbstractButton { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; @@ -1178,7 +1180,7 @@ background-color: #191919; } -#LibrarySidebar QAbstractButton:hover, +#LibrarySidebarButtons QAbstractButton:hover, #LibrarySidebarExpanded QAbstractButton:hover { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; @@ -1188,7 +1190,7 @@ color: #cfb32c; } -#LibrarySidebar, QTableView, QTextBrowser, QTreeView { +#LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { border: 1px solid #585858; /*font: 15px/18px;*/ color: #cfb32c; diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 54c2540fbf2..ddc960f13fb 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -145,7 +145,8 @@ LegacySkinParser::LegacySkinParser() m_pVCManager(NULL), m_pEffectsManager(NULL), m_pParent(NULL), - m_pContext(NULL) { + m_pContext(NULL), + m_paneId(0) { } LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, @@ -163,7 +164,8 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig, m_pVCManager(pVCMan), m_pEffectsManager(pEffectsManager), m_pParent(NULL), - m_pContext(NULL) { + m_pContext(NULL), + m_paneId(0) { } LegacySkinParser::~LegacySkinParser() { @@ -555,10 +557,14 @@ QList LegacySkinParser::parseNode(const QDomElement& node) { result = wrapWidget(parseSplitter(node)); } else if (nodeName == "LibrarySidebarButtons") { result = wrapWidget(parseLibrarySidebarButtons(node)); + } else if (nodeName == "LibrarySidebar") { + result = wrapWidget(parseLibrarySidebar(node)); } else if (nodeName == "LibrarySidebarExpanded") { result = wrapWidget(parseLibrarySidebarExpanded(node)); } else if (nodeName == "LibraryPane") { result = wrapWidget(parseLibraryPane(node)); + } else if (nodeName == "Library") { + result = wrapWidget(parseLibrary(node)); } else if (nodeName == "Key") { result = wrapWidget(parseEngineKey(node)); } else if (nodeName == "Battery") { @@ -1260,12 +1266,65 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { return pLibraryWidget; } +QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { + // Must add both a SearchBox and a LibraryPane + QFrame* pContainer = new QFrame(m_pParent); + QVBoxLayout* pLayout = new QVBoxLayout(pContainer); + pContainer->setLayout(pLayout); + + WSearchLineEdit* pSearchBox = new WSearchLineEdit(pContainer); + pSearchBox->setup(node, *m_pContext); + commonWidgetSetup(node, pSearchBox); + pLayout->addWidget(pSearchBox); + + WLibrary* pLibraryWidget = new WLibrary(pContainer); + pLibraryWidget->installEventFilter(m_pKeyboard); + pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); + pLayout->addWidget(pLibraryWidget); + + m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, m_paneId); + commonWidgetSetup(node, pLibraryWidget, false); + qDebug() << "LegacySkinParser::parseLibrary"; + + ++m_paneId; + return pContainer; +} + + +QWidget *LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { + // We must create both LibrarySidebarButtons and LibrarySidebarExpanded + // to allow support for old skins + QFrame* pContainer = new QFrame(m_pParent); + QHBoxLayout* pLayout = new QHBoxLayout(pContainer); + pContainer->setLayout(pLayout); + + QScrollArea* scroll = new QScrollArea(pContainer); + scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + + WButtonBar* pLibrarySidebar = new WButtonBar(pContainer); + pLibrarySidebar->installEventFilter(m_pKeyboard); + m_pLibrary->bindSidebarWidget(pLibrarySidebar); + scroll->setWidget(pLibrarySidebar); + pLayout->addWidget(scroll); + + WBaseLibrary* pLibrarySidebarExpanded = new WBaseLibrary(pContainer); + pLibrarySidebarExpanded->installEventFilter(m_pKeyboard); + pLibrarySidebarExpanded->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); + m_pLibrary->bindSidebarExpanded(pLibrarySidebarExpanded, m_pKeyboard); + pLayout->addWidget(pLibrarySidebarExpanded); + + commonWidgetSetup(node, pLibrarySidebar, false); + commonWidgetSetup(node, pLibrarySidebarExpanded, false); + return pContainer; +} + QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { QScrollArea* scroll = new QScrollArea(m_pParent); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - WButtonBar* pLibrarySidebar = new WButtonBar(m_pParent); + WButtonBar* pLibrarySidebar = new WButtonBar(scroll); pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarWidget(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index da94ec6c52f..50fc39a78e7 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -100,8 +100,10 @@ class LegacySkinParser : public QObject, public SkinParser { QWidget* parseTableView(const QDomElement& node); QWidget* parseSearchBox(const QDomElement& node); QWidget* parseLibraryPane(const QDomElement& node); + QWidget* parseLibrarySidebar(const QDomElement& node); QWidget* parseLibrarySidebarButtons(const QDomElement& node); QWidget* parseLibrarySidebarExpanded(const QDomElement& node); + QWidget* parseLibrary(const QDomElement& node); QWidget* parseBattery(const QDomElement& node); QWidget* parseCoverArt(const QDomElement& node); @@ -141,6 +143,7 @@ class LegacySkinParser : public QObject, public SkinParser { QHash m_templateCache; static QList s_channelStrs; static QMutex s_safeStringMutex; + int m_paneId; }; From 4fbd75030d9bb59281c51a44ad8c04864f3e6144 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 19 Jun 2016 22:13:23 +0200 Subject: [PATCH 158/552] Add tabs to AutoDJ and style --- res/skins/LateNight/style.qss | 42 +++- res/skins/Shade/skin.xml | 10 + src/library/autodj/autodjfeature.cpp | 26 ++- src/library/autodj/dlgautodj.ui | 293 ++++++++++++++------------- src/widget/wbaselibrary.cpp | 2 +- 5 files changed, 220 insertions(+), 153 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index f8ab7f87631..d9066b9ee6b 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1171,6 +1171,46 @@ border: 1px solid #585858; } +#LibrarySidebarExpanded QTabWidget QTreeView, #DlgAutoDJ QScrollArea { + margin: 0; + border: none; +} + +#LibrarySidebarExpanded QTabWidget { + border: none +} + +#LibrarySidebarExpanded QTabWidget::pane { + border: 1px solid #585858; +} + +#LibrarySidebarExpanded QTabBar::tab { + padding: 5px; + border: none; + color: #cfb32c; + background-color: #191919; + border-radius: 2px; +} + +#LibrarySidebarExpanded QTabBar::tab:hover { + border: 1px solid #585858; + background-color: #232323; + border-radius: 2px; + color: #cfb32c; +} + +#LibrarySidebarExpanded QTabBar::tab:selected { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); +} + +#LibrarySidebarExpanded QScrollArea QAbstractButton { + padding: 3px !important; +} + +#LibrarySidebarExpanded QWidget:!enabled { + color: #666666; +} + #LibrarySidebarButtons QAbstractButton, #LibrarySidebarExpanded QAbstractButton { margin: 0px 0px 0px 0px; @@ -1328,7 +1368,6 @@ WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } /* Additional space for the QPushButtons */ #DlgMissing > QPushButton, #DlgHidden > QPushButton, -#DlgAutoDJ > QPushButton, #DlgRecording > QPushButton, #DlgAnalysis > QPushButton { margin: 2px 3px 2px 3px; @@ -1338,7 +1377,6 @@ WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } #DlgMissing > QPushButton:!enabled, #DlgHidden > QPushButton:!enabled, -#DlgAutoDJ > QPushButton:!enabled, #DlgRecording > QPushButton:!enabled, #DlgAnalysis > QPushButton:!enabled { color: #666666; diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 71ed9602062..fd1711f2886 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -482,6 +482,16 @@ background-color: transparent; } + WBaseLibrary QTabWidget QTreeView, #DlgAutoDJ QScrollArea { + background-color: #191919; + border: none; + } + + WBaseLibrary QTabWidget::pane { + background-color: #191919; + border: 1px solid #646464; + } + QScrollArea QPushButton { border: 1px solid black; background-color: #aab2b7; diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index f89f6bb013b..b4ad11814f5 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -104,6 +104,8 @@ void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId) { //qDebug() << "AutoDJFeature::bindPaneWidget" << pLibraryWidget; + + WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection, false); @@ -126,21 +128,23 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter*) { qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; - QSplitter* pContainer = new QSplitter(pSidebarWidget); + QTabWidget* pContainer = new QTabWidget(pSidebarWidget); + //QSplitter* pContainer = new QSplitter(pSidebarWidget); WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); pSidebar->setModel(&m_childModel); - pContainer->addWidget(pSidebar); - pContainer->adjustSize(); + pContainer->addTab(pSidebar, tr("Controls")); + //pContainer->addWidget(pSidebar); + //pContainer->adjustSize(); - QScrollArea* pArea = new QScrollArea(pContainer); - m_pAutoDJView = new DlgAutoDJ(pArea, m_pLibrary, m_pAutoDJProcessor); - pArea->setWidget(m_pAutoDJView); - pArea->setWidgetResizable(true); - pArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - pArea->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - pContainer->addWidget(pArea); + + m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); + //pArea->setWidgetResizable(true); + //pArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + //pArea->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + //pContainer->addWidget(pArea); + pContainer->addTab(m_pAutoDJView, tr("Drop target")); connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); @@ -168,7 +172,7 @@ TreeItemModel* AutoDJFeature::getChildModel() { } void AutoDJFeature::activate() { - //qDebug() << "AutoDJFeature::activate()"; + qDebug() << "AutoDJFeature::activate()"; m_pAutoDJView->setFocusedPane(m_featureFocus); m_pAutoDJView->onShow(); emit(switchToView(m_sAutoDJViewName)); diff --git a/src/library/autodj/dlgautodj.ui b/src/library/autodj/dlgautodj.ui index 29501650c57..b5e4847bf81 100644 --- a/src/library/autodj/dlgautodj.ui +++ b/src/library/autodj/dlgautodj.ui @@ -6,159 +6,174 @@ 0 0 - 560 + 507 399 Auto DJ - + + + 0 + - - - Turn Auto DJ on or off. + + + + 0 + 0 + - - Enable Auto DJ + + Qt::ScrollBarAlwaysOff - + true + + + + 0 + 0 + 505 + 397 + + + + + + + Turn Auto DJ on or off. + + + Enable Auto DJ + + + true + + + + + + + + + + + + + + + + Seconds + + + sec. + + + + + + + + 0 + 0 + + + + Determines the duration of the transition. + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + -9 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Trigger the transition to the next track. + + + Fade Now + + + + + + + Skip the next track in the Auto DJ playlist. + + + Skip Track + + + false + + + + + + + Add a random track from track sources (crates) or Library to the Auto DJ playlist. + + + Add Random + + + + + + + Shuffle the content of the Auto DJ playlist. + + + Shuffle + + + false + + + + + + + Qt::Vertical + + + + 20 + 7 + + + + + + - - - - - - - - - - - - - Seconds - - - sec. - - - - - - - - 0 - 0 - - - - Determines the duration of the transition. - - - false - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - -9 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Trigger the transition to the next track. - - - Fade Now - - - - - - - Skip the next track in the Auto DJ playlist. - - - Skip Track - - - false - - - - - - - Add a random track from track sources (crates) or Library to the Auto DJ playlist. - - - Add Random - - - - - - - Shuffle the content of the Auto DJ playlist. - - - Shuffle - - - false - - - - - - - Qt::Vertical - - - - 20 - 7 - - - - - pushButtonAutoDJ - pushButtonShuffle - pushButtonSkipNext - pushButtonAddRandom - pushButtonFadeNow - pushButtonAutoDJ - pushButtonShuffle - pushButtonSkipNext - pushButtonAddRandom - pushButtonFadeNow - pushButtonAutoDJ - pushButtonShuffle - pushButtonSkipNext - pushButtonAddRandom - pushButtonFadeNow - labelSelectionInfo diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 3463c302d3a..9a850461e33 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -45,7 +45,7 @@ void WBaseLibrary::setShowFocus(int sFocus) { void WBaseLibrary::switchToView(const QString& name) { QMutexLocker lock(&m_mutex); - qDebug() << "WBaseLibrary::switchToView" << name; + //qDebug() << "WBaseLibrary::switchToView" << name; QWidget* widget = m_viewMap.value(name, nullptr); if (widget != nullptr && currentWidget() != widget) { //qDebug() << "WBaseLibrary::setCurrentWidget" << name; From 9d01eec48460a8aaecb5a1dcb350a8a13dfbb8e5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 19 Jun 2016 23:15:49 +0200 Subject: [PATCH 159/552] Add style to LateNight and remove commented coded --- res/skins/LateNight/style.qss | 20 +++++++------------- src/library/autodj/autodjfeature.cpp | 13 ++----------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index d9066b9ee6b..e8c24600a05 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1203,7 +1203,7 @@ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); } -#LibrarySidebarExpanded QScrollArea QAbstractButton { +#LibrarySidebarExpanded QScrollArea QPushButton { padding: 3px !important; } @@ -1211,8 +1211,8 @@ color: #666666; } -#LibrarySidebarButtons QAbstractButton, -#LibrarySidebarExpanded QAbstractButton { +#LibrarySidebarButtons QToolButton, +#LibrarySidebarExpanded QPushButton { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border: none; @@ -1220,8 +1220,8 @@ background-color: #191919; } -#LibrarySidebarButtons QAbstractButton:hover, -#LibrarySidebarExpanded QAbstractButton:hover { +#LibrarySidebarButtons QToolButton:hover, +#LibrarySidebarExpanded QPushButton:hover { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border: 1px solid #585858; @@ -1362,8 +1362,8 @@ QLabel, QRadioButton { background: transparent; color: #cfb32c; } /* Additional space for QRadionButtons and QLabels */ WBaseLibrary QRadioButton, WBaseLibrary QLabel { margin: 9px 3px 6px 3px; } -/* Additional space for the first QRadionButton in the row */ -WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } +/* Additional space for the first QRadionButton in the row +WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } */ /* Additional space for the QPushButtons */ #DlgMissing > QPushButton, @@ -1382,12 +1382,6 @@ WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } color: #666666; } -/* Additional space for the first QPushButton in the row */ -#DlgMissing > QPushButton#btnPurge, -#DlgHidden > QPushButton#btnUnhide, -#DlgRecording > QPushButton#pushButtonRecording, -#DlgAnalysis > QPushButton#pushButtonAnalyze { margin: 9px 12px 6px 3px; } - /* Spacing between treeview and searchbar */ QTreeView { margin: 10px 0px 0px 0px; } diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index b4ad11814f5..d30cef58635 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -129,22 +129,13 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; QTabWidget* pContainer = new QTabWidget(pSidebarWidget); - //QSplitter* pContainer = new QSplitter(pSidebarWidget); WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); pSidebar->setModel(&m_childModel); - pContainer->addTab(pSidebar, tr("Controls")); - - //pContainer->addWidget(pSidebar); - //pContainer->adjustSize(); - + pContainer->addTab(pSidebar, tr("Drop target")); m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); - //pArea->setWidgetResizable(true); - //pArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - //pArea->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - //pContainer->addWidget(pArea); - pContainer->addTab(m_pAutoDJView, tr("Drop target")); + pContainer->addTab(m_pAutoDJView, tr("controls")); connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); From e762337235ba9d45d112b5871bc1cd03bd1dbbfe Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 19 Jun 2016 23:40:38 +0200 Subject: [PATCH 160/552] Added QSS in LateNight and Deere skins --- res/skins/Deere/style.qss | 61 ++++++++++++++++++++++++++++++++--- res/skins/LateNight/style.qss | 9 +++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index d123b91970c..e23700570bb 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -167,6 +167,57 @@ WBaseLibrary[showFocus="1"] { margin-right: 13px; } +#LibraryCoverArtSplitter QTabWidget { + border: none; +} + +#LibraryCoverArtSplitter QTabWidget::pane { + border: 1px solid #1A1A1A; +} + +#LibraryCoverArtSplitter QTabWidget QTreeView, #DlgAutoDJ QScrollArea { + margin: 0; + border: none; +} + +#DlgAutoDJ QLabel { + margin: 2px 4px 2px 4px; +} + +#LibraryCoverArtSplitter QTabBar::tab { + padding: 4px; + border: none; + color: #cfb32c; + background-color: #191919; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + + color: #D2D2D2; + background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, + stop: 0 #4B4B4B, + stop: 1 #4B4B4B); + border: 0px solid #4B4B4B; + outline: none; +} + +#LibraryCoverArtSplitter QTabBar::tab:hover { + border-top: 0px solid #5F5F5F; + border-right: 0px solid #5F5F5F; + border-left: 0px solid #5F5F5F; + color: #D2D2D2; + background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, + stop: 0 #5F5F5F, + stop: 1 #5F5F5F); +} + +#LibraryCoverArtSplitter QTabBar::tab:selected { + color: #FDFDFD; + background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, + stop: 0 #006596, + stop: 1 #006596); + border: 0px solid #006596; +} + /* button in library "Preview" column */ QPushButton#LibraryPreviewButton { width: 23px; @@ -360,10 +411,10 @@ WButtonBar QAbstractButton { Style them just as the other regular buttons */ #DlgMissing > QPushButton, #DlgHidden > QPushButton, -#DlgAutoDJ > QPushButton, +#DlgAutoDJ QPushButton, #DlgRecording > QPushButton, #DlgAnalysis > QPushButton { - margin: 3px 3px 3px 3px; + margin: 2px 3px 2px 3px; padding: 2px; color: #D2D2D2; background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, @@ -376,7 +427,7 @@ WButtonBar QAbstractButton { #DlgMissing > QPushButton:!enabled, #DlgHidden > QPushButton:!enabled, -#DlgAutoDJ > QPushButton:!enabled, +#DlgAutoDJ QPushButton:!enabled, #DlgAnalysis > QPushButton:!enabled { /* buttons in "disabled" (not click-able) state. They are nearly invisible by default QT palette, so style accordingly */ @@ -391,7 +442,7 @@ WButtonBar QAbstractButton { #DlgMissing > QPushButton:hover, #DlgHidden > QPushButton:hover, -#DlgAutoDJ > QPushButton:hover, +#DlgAutoDJ QPushButton:hover, #DlgRecording > QPushButton:hover, #DlgAnalysis > QPushButton:hover { color: #D2D2D2; @@ -401,7 +452,7 @@ WButtonBar QAbstractButton { border: 0px solid #5F5F5F; } -#DlgAutoDJ > QPushButton:checked, +#DlgAutoDJ QPushButton:checked, #DlgRecording > QPushButton:checked, #DlgAnalysis > QPushButton:checked { /* checkbuttons in active state */ diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index e8c24600a05..628584c01be 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1189,14 +1189,15 @@ border: none; color: #cfb32c; background-color: #191919; - border-radius: 2px; + border-top-left-radius: 2px; + border-top-right-radius: 2px; } #LibrarySidebarExpanded QTabBar::tab:hover { - border: 1px solid #585858; + border-top: 2px solid #585858; + border-right: 2px solid #585858; + border-left: 2px solid #585858; background-color: #232323; - border-radius: 2px; - color: #cfb32c; } #LibrarySidebarExpanded QTabBar::tab:selected { From 5a7bc83c1435411ad2fb4781bc2e7ea9bc4aa0dd Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 19 Jun 2016 23:43:58 +0200 Subject: [PATCH 161/552] Fix searchbox not working in Mixxx 2.0 skin --- src/skin/legacyskinparser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index ddc960f13fb..4684647fecc 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1274,6 +1274,7 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { WSearchLineEdit* pSearchBox = new WSearchLineEdit(pContainer); pSearchBox->setup(node, *m_pContext); + m_pLibrary->bindSearchBar(pSearchBox, m_paneId); commonWidgetSetup(node, pSearchBox); pLayout->addWidget(pSearchBox); From 421cfe5adbf68338754c627f29c1e1a18804d2da Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 20 Jun 2016 14:20:40 +0200 Subject: [PATCH 162/552] Fix bug when loading a 2.0 skin from Mixxx 2.1 This only happens if a 2.1 skin was loaded before loading the 2.0 skin. Now it's solved --- src/library/library.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/library/library.cpp b/src/library/library.cpp index 368b2c51c16..e36a7529d1a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -185,6 +185,10 @@ void Library::destroyInterface() { for (LibraryPaneManager* p : m_panes) { p->deleteLater(); } + + for (LibraryFeature* f : m_features) { + f->setFeatureFocus(-1); + } m_panes.clear(); } From a2a54b3e5a51a278b4c86f6d97d0c19451ad3d69 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 24 Jun 2016 16:50:44 +0200 Subject: [PATCH 163/552] Create WBreadCrumb class --- src/widget/wbreadcrumb.cpp | 19 +++++++++++++++++++ src/widget/wbreadcrumb.h | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/widget/wbreadcrumb.cpp create mode 100644 src/widget/wbreadcrumb.h diff --git a/src/widget/wbreadcrumb.cpp b/src/widget/wbreadcrumb.cpp new file mode 100644 index 00000000000..9956d9feae6 --- /dev/null +++ b/src/widget/wbreadcrumb.cpp @@ -0,0 +1,19 @@ +/* + * WBreadCrumb.cpp + * + * Created on: Jun 24, 2016 + * Author: joan + */ + +#include + + +WBreadCrumb::WBreadCrumb(QWidget* parent) + : QLabel(parent) { + + +} + +void WBreadCrumb::switchToView(TreeItem *pTree) { + +} diff --git a/src/widget/wbreadcrumb.h b/src/widget/wbreadcrumb.h new file mode 100644 index 00000000000..1ea34276086 --- /dev/null +++ b/src/widget/wbreadcrumb.h @@ -0,0 +1,19 @@ +#ifndef SRC_WIDGET_WBREADCRUMB_H_ +#define SRC_WIDGET_WBREADCRUMB_H_ + +#include +#include "library/treeitem.h" + +class WBreadCrumb: public QLabel { + Q_OBJECT + + public: + + WBreadCrumb(QWidget* parent = nullptr); + + public slots: + + void switchToView(TreeItem* pTree); +}; + +#endif /* SRC_WIDGET_WBREADCRUMB_H_ */ From 491227627b1db9d04e0b3b48120dd9dae7f61a78 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 24 Jun 2016 16:51:07 +0200 Subject: [PATCH 164/552] Fix wrong height in LateNight --- res/skins/LateNight/style.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 628584c01be..1550d08809f 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1384,7 +1384,7 @@ WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } } /* Spacing between treeview and searchbar */ -QTreeView { margin: 10px 0px 0px 0px; } +QTreeView { margin: 0px 0px 0px 0px; } /* triangle for closed/opened branches in treeview */ QTreeView { show-decoration-selected: 0; background-color: #151515; } /* Suppresses that selected sidebar items branch indicator shows wrong color when out of focus ; lp:880588 */ From 223da472b1500a8971a63610fc30c9d6e3273f06 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 24 Jun 2016 20:28:46 +0200 Subject: [PATCH 165/552] Add support from dropping targets from table to table --- src/widget/wtracktableview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index b3e8c581674..efb6ae86fcd 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1029,7 +1029,7 @@ void WTrackTableView::dragEnterEvent(QDragEnterEvent * event) { return; } } else if (DragAndDropHelper::dragEnterAccept(*event->mimeData(), - "library", true, true)) { + "", true, true)) { event->acceptProposedAction(); return; } From 61e1d44119aa388ae5a4a9f352c489e635759230 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 25 Jun 2016 20:53:01 +0200 Subject: [PATCH 166/552] Add focus change with Tab key --- res/skins/LateNight/style.qss | 22 +++++++++++++++++----- src/library/library.h | 1 - src/library/librarypanemanager.cpp | 2 ++ src/mixxx.cpp | 1 - src/widget/wbaselibrary.cpp | 11 ++++++++++- src/widget/wbaselibrary.h | 11 +++++++++-- src/widget/wbuttonbar.cpp | 4 ++++ 7 files changed, 42 insertions(+), 10 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 1550d08809f..0adde6399ae 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1158,9 +1158,7 @@ #LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #0f0f0f; - margin-right: 11px; - - + margin-right: 11px; } #LibrarySidebarExpanded QWidget { @@ -1200,6 +1198,13 @@ background-color: #232323; } +#LibrarySidebarExpanded QTabBar::tab:focus { + border-top: 2px solid #8E5C00; + border-right: 2px solid #8E5C00; + border-left: 2px solid #8E5C00; + background-color: #232323; +} + #LibrarySidebarExpanded QTabBar::tab:selected { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); } @@ -1231,6 +1236,13 @@ color: #cfb32c; } +#LibrarySidebarButtons:focus, +#LibrarySidebarButtons QToolButton:focus, +#LibrarySidebarExpanded > QWidget:focus, +#LibrarySidebarExpanded QAbstractScrollArea > QWidget:focus { + border: 1px solid #8E5C00; +} + #LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { border: 1px solid #585858; /*font: 15px/18px;*/ @@ -1409,12 +1421,12 @@ QTreeView::item:selected { color: #cfb32c; } -WBaseLibrary[showFocus="0"] { +WLibrary[showFocus="0"] { padding: 1px 0 0 0; border: none; } -WBaseLibrary[showFocus="1"] { +WLibrary[showFocus="1"] { padding: 1px 0 0 0; border-top: 1px solid #FF7100 !important; } \ No newline at end of file diff --git a/src/library/library.h b/src/library/library.h index 1c4400bfa05..2b029612c28 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -23,7 +23,6 @@ #include "library/librarysidebarexpandedmanager.h" #include "widget/wtracktableview.h" -#include "widget/wlibrary.h" #include "widget/wfeatureclickbutton.h" class LibraryPaneManager; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 157a233386c..146fe162d04 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -25,6 +25,8 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* libraryWidget, connect(this, SIGNAL(switchToView(const QString&)), m_pPaneWidget, SLOT(switchToView(const QString&))); + connect(m_pPaneWidget, SIGNAL(focused()), + this, SIGNAL(focused())); WLibrary* lib = qobject_cast(m_pPaneWidget); if (lib == nullptr) { diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 9199da4e36c..cf9a3ba7074 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -34,7 +34,6 @@ #include "effects/native/nativebackend.h" #include "library/coverartcache.h" #include "library/library.h" -#include "library/librarypanemanager.h" #include "library/library_preferences.h" #include "controllers/controllermanager.h" #include "controllers/keyboard/keyboardeventfilter.h" diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 9a850461e33..9e002830204 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -19,6 +19,7 @@ bool WBaseLibrary::registerView(QString name, QWidget* view) { return false; } + view->installEventFilter(this); int index = addWidget(view); setCurrentIndex(index); m_currentViewName = name; @@ -37,7 +38,7 @@ int WBaseLibrary::getShowFocus() { void WBaseLibrary::setShowFocus(int sFocus) { //qDebug() << "WBaseLibrary::setShowFocus" << sFocus << this; m_showFocus = sFocus; - + style()->unpolish(this); style()->polish(this); update(); @@ -54,6 +55,14 @@ void WBaseLibrary::switchToView(const QString& name) { } } +bool WBaseLibrary::eventFilter(QObject*, QEvent* pEvent) { + if (pEvent->type() == QEvent::FocusIn) { + //qDebug() << "WBaseLibrary::eventFilter FocusIn"; + emit(focused()); + } + return false; +} + bool WBaseLibrary::event(QEvent* pEvent) { if (pEvent->type() == QEvent::ToolTip) { updateTooltip(); diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index e57faeaaf2e..103766ee6d3 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -21,14 +21,21 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget int getShowFocus(); + // Sets the widget to the focused state, it's not the same as Qt focus void setShowFocus(int sFocus); - + + signals: + + void focused(); + public slots: virtual void switchToView(const QString& name); protected: - + + bool eventFilter(QObject*, QEvent* pEvent); + bool event(QEvent* pEvent) override; QMap m_viewMap; diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index bac1c20f511..09269612875 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -1,3 +1,5 @@ +#include + #include "wbuttonbar.h" #include "library/libraryfeature.h" @@ -8,12 +10,14 @@ WButtonBar::WButtonBar(QWidget* parent) m_pLayout->setContentsMargins(0,0,0,0); m_pLayout->setSpacing(0); setLayout(m_pLayout); + setFocusPolicy(Qt::NoFocus); } WFeatureClickButton* WButtonBar::addButton(LibraryFeature* pFeature) { WFeatureClickButton* button = new WFeatureClickButton(pFeature, this); button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); + //button->setFocusPolicy(Qt::NoFocus); m_pLayout->addWidget(button); return button; From 794bc58986fdc4ced8efdb816f1a2bf5363d14f3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 26 Jun 2016 00:13:33 +0200 Subject: [PATCH 167/552] Add LibraryFeatureFactory --- build/depends.py | 1 + src/library/libraryfeaturefactory.cpp | 28 +++++++++++++++++ src/library/libraryfeaturefactory.h | 45 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/library/libraryfeaturefactory.cpp create mode 100644 src/library/libraryfeaturefactory.h diff --git a/build/depends.py b/build/depends.py index e34400778a0..8350c33d3a5 100644 --- a/build/depends.py +++ b/build/depends.py @@ -848,6 +848,7 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", + "library/libraryfeaturefactory.cpp", "library/analysisfeature.cpp", "library/autodj/autodjfeature.cpp", "library/autodj/autodjprocessor.cpp", diff --git a/src/library/libraryfeaturefactory.cpp b/src/library/libraryfeaturefactory.cpp new file mode 100644 index 00000000000..99ffd571f7c --- /dev/null +++ b/src/library/libraryfeaturefactory.cpp @@ -0,0 +1,28 @@ +/* + * LibraryFeatureFactory.cpp + * + * Created on: Jun 25, 2016 + * Author: joan + */ + +#include +#include + +LibraryFeatureFactory::LibraryFeatureFactory() { + // TODO Auto-generated constructor stub + +} + +LibraryFeatureFactory::~LibraryFeatureFactory() { + // TODO Auto-generated destructor stub +} + +void LibraryFeatureFactory::registerF(const QString& name, + Creator* pCreator) { + getTable()[name] = pCreator; +} + +QHash LibraryFeatureFactory::getTable() { + static QHash table; + return table; +} diff --git a/src/library/libraryfeaturefactory.h b/src/library/libraryfeaturefactory.h new file mode 100644 index 00000000000..258ea42ab21 --- /dev/null +++ b/src/library/libraryfeaturefactory.h @@ -0,0 +1,45 @@ +/* + * LibraryFeatureFactory.h + * + * Created on: Jun 25, 2016 + * Author: joan + */ + +#ifndef SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ +#define SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ +#include +#include + +class LibraryFeature; + +/** + * To use this we trust in the compiler initialization of static + */ +#define REGISTER_F(featureName) \ + private: \ + static LibraryFeatureCreator creator; + + +class Creator { + virtual ~Creator() = 0; + virtual LibraryFeature* create() = 0; +}; + +template +class LibraryFeatureCreator : Creator { + LibraryFeature* create() { + return new T; + } +}; + +class LibraryFeatureFactory { +public: + LibraryFeatureFactory(); + ~LibraryFeatureFactory(); + + static void registerF(const QString& name, Creator* pCreator); + + static QHash getTable(); +}; + +#endif /* SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ */ From a2f504a6772ff008ef68b199a2b94b445cf13c6e Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 26 Jun 2016 00:19:12 +0200 Subject: [PATCH 168/552] Added creator to factory --- src/library/libraryfeaturefactory.cpp | 7 +++++++ src/library/libraryfeaturefactory.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/library/libraryfeaturefactory.cpp b/src/library/libraryfeaturefactory.cpp index 99ffd571f7c..3c2c0b812f9 100644 --- a/src/library/libraryfeaturefactory.cpp +++ b/src/library/libraryfeaturefactory.cpp @@ -26,3 +26,10 @@ QHash LibraryFeatureFactory::getTable() { static QHash table; return table; } + +LibraryFeature* LibraryFeatureFactory::create(const QString& name) { + if (getTable().contains(name)) { + return getTable()[name]->create(); + } + return nullptr; +} diff --git a/src/library/libraryfeaturefactory.h b/src/library/libraryfeaturefactory.h index 258ea42ab21..316613418fc 100644 --- a/src/library/libraryfeaturefactory.h +++ b/src/library/libraryfeaturefactory.h @@ -40,6 +40,8 @@ class LibraryFeatureFactory { static void registerF(const QString& name, Creator* pCreator); static QHash getTable(); + + static LibraryFeature* create(const QString& name); }; #endif /* SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ */ From be71edb35bd7b9b71b2fef43905928f0d169773e Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 27 Jun 2016 19:30:29 +0200 Subject: [PATCH 169/552] Add new function to WBreadCrumb --- src/widget/wbreadcrumb.cpp | 6 +++++- src/widget/wbreadcrumb.h | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/widget/wbreadcrumb.cpp b/src/widget/wbreadcrumb.cpp index 9956d9feae6..927ae8d04c9 100644 --- a/src/widget/wbreadcrumb.cpp +++ b/src/widget/wbreadcrumb.cpp @@ -5,7 +5,7 @@ * Author: joan */ -#include +#include WBreadCrumb::WBreadCrumb(QWidget* parent) @@ -17,3 +17,7 @@ WBreadCrumb::WBreadCrumb(QWidget* parent) void WBreadCrumb::switchToView(TreeItem *pTree) { } + +QString WBreadCrumb::getData(TreeItem* pTree) { + QString text = pTree->data().toString(); +} diff --git a/src/widget/wbreadcrumb.h b/src/widget/wbreadcrumb.h index 1ea34276086..183c0ab0b64 100644 --- a/src/widget/wbreadcrumb.h +++ b/src/widget/wbreadcrumb.h @@ -13,7 +13,11 @@ class WBreadCrumb: public QLabel { public slots: - void switchToView(TreeItem* pTree); + void switchToView(TreeItem* pTree); + + private: + + QString getData(TreeItem* pTree); }; #endif /* SRC_WIDGET_WBREADCRUMB_H_ */ From db047b4c474622dc745eb011e3c4fc7c10fbbe32 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 27 Jun 2016 22:38:06 +0200 Subject: [PATCH 170/552] Fix compilation issue --- src/library/libraryfeaturefactory.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/libraryfeaturefactory.h b/src/library/libraryfeaturefactory.h index 316613418fc..8af09738c09 100644 --- a/src/library/libraryfeaturefactory.h +++ b/src/library/libraryfeaturefactory.h @@ -21,6 +21,7 @@ class LibraryFeature; class Creator { + public: virtual ~Creator() = 0; virtual LibraryFeature* create() = 0; }; From 6fa1374387a5092570f3dfbd8e431f5df9e0df22 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 00:50:39 +0200 Subject: [PATCH 171/552] Finished getData function in WBreadCrumb --- src/widget/wbreadcrumb.cpp | 15 ++++++++++++--- src/widget/wbreadcrumb.h | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/widget/wbreadcrumb.cpp b/src/widget/wbreadcrumb.cpp index 927ae8d04c9..656edbb08f2 100644 --- a/src/widget/wbreadcrumb.cpp +++ b/src/widget/wbreadcrumb.cpp @@ -14,10 +14,19 @@ WBreadCrumb::WBreadCrumb(QWidget* parent) } -void WBreadCrumb::switchToView(TreeItem *pTree) { - +void WBreadCrumb::setBreadText(TreeItem *pTree) { + QString text = getData(pTree); + setText(text); } -QString WBreadCrumb::getData(TreeItem* pTree) { +QString& WBreadCrumb::getData(TreeItem* pTree) { + // Base case + if (pTree == nullptr) { + return ""; + } + + // Recursive case QString text = pTree->data().toString(); + QString next = getData(pTree->parent()); + return (next == "" ? text : next + " > " + text); } diff --git a/src/widget/wbreadcrumb.h b/src/widget/wbreadcrumb.h index 183c0ab0b64..03c31810f72 100644 --- a/src/widget/wbreadcrumb.h +++ b/src/widget/wbreadcrumb.h @@ -13,11 +13,11 @@ class WBreadCrumb: public QLabel { public slots: - void switchToView(TreeItem* pTree); + void setBreadText(TreeItem* pTree); private: - QString getData(TreeItem* pTree); + static QString& getData(TreeItem* pTree); }; #endif /* SRC_WIDGET_WBREADCRUMB_H_ */ From d82adaca31ba27e0eddf3ab7133928189134015e Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 00:51:25 +0200 Subject: [PATCH 172/552] Changed constructor in LibraryFeature adding the direct Library relation --- src/library/analysisfeature.cpp | 9 +-- src/library/analysisfeature.h | 5 +- src/library/autodj/autodjfeature.cpp | 7 ++- src/library/autodj/autodjfeature.h | 5 +- src/library/banshee/bansheefeature.cpp | 9 +-- src/library/banshee/bansheefeature.h | 5 +- src/library/baseexternallibraryfeature.cpp | 6 +- src/library/baseexternallibraryfeature.h | 5 +- src/library/baseplaylistfeature.cpp | 8 +-- src/library/baseplaylistfeature.h | 5 +- src/library/browse/browsefeature.cpp | 7 ++- src/library/browse/browsefeature.h | 5 +- src/library/cratefeature.cpp | 9 +-- src/library/cratefeature.h | 7 ++- src/library/itunes/itunesfeature.cpp | 7 ++- src/library/itunes/itunesfeature.h | 5 +- src/library/library.cpp | 27 +++++---- src/library/libraryfeature.cpp | 20 ++++--- src/library/libraryfeature.h | 67 +++++++++------------- src/library/mixxxlibraryfeature.cpp | 9 +-- src/library/mixxxlibraryfeature.h | 7 ++- src/library/playlistfeature.cpp | 9 +-- src/library/playlistfeature.h | 6 +- src/library/recording/recordingfeature.cpp | 6 +- src/library/recording/recordingfeature.h | 4 +- src/library/rhythmbox/rhythmboxfeature.cpp | 7 ++- src/library/rhythmbox/rhythmboxfeature.h | 5 +- src/library/setlogfeature.cpp | 7 ++- src/library/setlogfeature.h | 4 +- src/library/traktor/traktorfeature.cpp | 6 +- src/library/traktor/traktorfeature.h | 5 +- 31 files changed, 168 insertions(+), 125 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index d7968c445af..624a7523349 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -18,10 +18,11 @@ const QString AnalysisFeature::m_sAnalysisViewName = "AnalysisView"; -AnalysisFeature::AnalysisFeature(QObject* parent, - UserSettingsPointer pConfig, - TrackCollection* pTrackCollection) : - LibraryFeature(parent), +AnalysisFeature::AnalysisFeature(TrackCollection* pTrackCollection, + UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent) : + LibraryFeature(pConfig, pLibrary, parent), m_pConfig(pConfig), m_pTrackCollection(pTrackCollection), m_pAnalyzerQueue(nullptr), diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 3bbd9cbab69..b9154a2d6aa 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -23,9 +23,10 @@ class TrackCollection; class AnalysisFeature : public LibraryFeature { Q_OBJECT public: - AnalysisFeature(QObject* parent, + AnalysisFeature(TrackCollection* pTrackCollection, UserSettingsPointer pConfig, - TrackCollection* pTrackCollection); + Library* pLibrary, + QObject* parent); virtual ~AnalysisFeature(); QVariant title(); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index d30cef58635..5d69437ce6a 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -25,11 +25,12 @@ const QString AutoDJFeature::m_sAutoDJViewName = QString("Auto DJ"); static const int kMaxRetrieveAttempts = 3; -AutoDJFeature::AutoDJFeature(Library* pLibrary, - UserSettingsPointer pConfig, +AutoDJFeature::AutoDJFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, PlayerManagerInterface* pPlayerManager, TrackCollection* pTrackCollection) - : LibraryFeature(pLibrary), + : LibraryFeature(pConfig, pLibrary, parent), m_pConfig(pConfig), m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 54803c80c4b..baf8d669338 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -32,8 +32,9 @@ class AutoDJProcessor; class AutoDJFeature : public LibraryFeature { Q_OBJECT public: - AutoDJFeature(Library* pLibrary, - UserSettingsPointer pConfig, + AutoDJFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, PlayerManagerInterface* pPlayerManager, TrackCollection* pTrackCollection); virtual ~AutoDJFeature(); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 25c58faf03e..ff957f48c66 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -14,10 +14,11 @@ const QString BansheeFeature::BANSHEE_MOUNT_KEY = "mixxx.BansheeFeature.mount"; const QString BansheeFeature::m_sBansheeViewName = "BANSHEE_VIEW"; QString BansheeFeature::m_databaseFile; -BansheeFeature::BansheeFeature(QObject* parent, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig) - : BaseExternalLibraryFeature(parent, pTrackCollection), +BansheeFeature::BansheeFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : BaseExternalLibraryFeature(pConfig, pLibrary, parent, pTrackCollection), m_pTrackCollection(pTrackCollection), m_cancelImport(false) { Q_UNUSED(pConfig); diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index 7ca82073203..c7d99009328 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -20,7 +20,10 @@ class BansheePlaylistModel; class BansheeFeature : public BaseExternalLibraryFeature { Q_OBJECT public: - BansheeFeature(QObject* parent, TrackCollection* pTrackCollection, UserSettingsPointer pConfig); + BansheeFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~BansheeFeature(); static bool isSupported(); static void prepareDbPath(UserSettingsPointer pConfig); diff --git a/src/library/baseexternallibraryfeature.cpp b/src/library/baseexternallibraryfeature.cpp index 27d69ee48e3..f1f262389ed 100644 --- a/src/library/baseexternallibraryfeature.cpp +++ b/src/library/baseexternallibraryfeature.cpp @@ -4,9 +4,11 @@ #include "library/basesqltablemodel.h" -BaseExternalLibraryFeature::BaseExternalLibraryFeature(QObject* pParent, +BaseExternalLibraryFeature::BaseExternalLibraryFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* pParent, TrackCollection* pCollection) - : LibraryFeature(pParent), + : LibraryFeature(pConfig, pLibrary, pParent), m_pTrackCollection(pCollection) { m_pAddToAutoDJAction = new QAction(tr("Add to Auto DJ Queue (bottom)"), this); connect(m_pAddToAutoDJAction, SIGNAL(triggered()), diff --git a/src/library/baseexternallibraryfeature.h b/src/library/baseexternallibraryfeature.h index 7a13f5d47d2..5ebfc50037b 100644 --- a/src/library/baseexternallibraryfeature.h +++ b/src/library/baseexternallibraryfeature.h @@ -12,7 +12,10 @@ class TrackCollection; class BaseExternalLibraryFeature : public LibraryFeature { Q_OBJECT public: - BaseExternalLibraryFeature(QObject* pParent, TrackCollection* pCollection); + BaseExternalLibraryFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* pParent, + TrackCollection* pCollection); virtual ~BaseExternalLibraryFeature(); public slots: diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 63828dafe03..0b31d4e6d5f 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -19,11 +19,12 @@ #include "widget/wlibrarytextbrowser.h" #include "util/assert.h" -BasePlaylistFeature::BasePlaylistFeature(QObject* parent, - UserSettingsPointer pConfig, +BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, QString rootViewName) - : LibraryFeature(pConfig, parent), + : LibraryFeature(pConfig, pLibrary, parent), m_pTrackCollection(pTrackCollection), m_playlistDao(pTrackCollection->getPlaylistDAO()), m_trackDao(pTrackCollection->getTrackDAO()), @@ -92,7 +93,6 @@ BasePlaylistFeature::BasePlaylistFeature(QObject* parent, connect(&m_playlistDao, SIGNAL(lockChanged(int)), this, SLOT(slotPlaylistTableChanged(int))); - Library* pLibrary = static_cast(parent); connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), this, SLOT(slotTrackSelected(TrackPointer))); connect(pLibrary, SIGNAL(switchToView(const QString&)), diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 47d5a343755..cb2c45bbb52 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -25,8 +25,9 @@ class TreeItem; class BasePlaylistFeature : public LibraryFeature { Q_OBJECT public: - BasePlaylistFeature(QObject* parent, - UserSettingsPointer pConfig, + BasePlaylistFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, QString rootViewName); virtual ~BasePlaylistFeature(); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 4813ed6c83d..586ea0ca800 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -24,11 +24,12 @@ const QString kQuickLinksSeparator = "-+-"; const QString BrowseFeature::m_sBrowseViewName = QString("BROWSEHOME"); -BrowseFeature::BrowseFeature(QObject* parent, - UserSettingsPointer pConfig, +BrowseFeature::BrowseFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) - : LibraryFeature(parent), + : LibraryFeature(pConfig, pLibrary, parent), m_pConfig(pConfig), m_browseModel(this, pTrackCollection, pRecordingManager), m_proxyModel(&m_browseModel), diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 6f119a5eb5d..d378d79ea82 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -27,8 +27,9 @@ class TrackCollection; class BrowseFeature : public LibraryFeature { Q_OBJECT public: - BrowseFeature(QObject* parent, - UserSettingsPointer pConfig, + BrowseFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRec); virtual ~BrowseFeature(); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 6d9042bcf6e..933396f196b 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -27,10 +27,11 @@ const QString CrateFeature::m_sCrateViewName = QString("CRATEHOME"); -CrateFeature::CrateFeature(Library* pLibrary, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig) - : LibraryFeature(pConfig), +CrateFeature::CrateFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : LibraryFeature(pConfig, pLibrary, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_crateTableModel(this, pTrackCollection) { diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 67fabca006c..a5e62f5927b 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -24,9 +24,10 @@ class TrackCollection; class CrateFeature : public LibraryFeature { Q_OBJECT public: - CrateFeature(Library* pLibrary, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig); + CrateFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~CrateFeature(); QVariant title(); diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 293b9636e02..5ec777ca294 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -29,8 +29,11 @@ QString localhost_token() { #endif } -ITunesFeature::ITunesFeature(QObject* parent, TrackCollection* pTrackCollection) - : BaseExternalLibraryFeature(parent, pTrackCollection), +ITunesFeature::ITunesFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : BaseExternalLibraryFeature(pConfig, pLibrary, parent, pTrackCollection), m_pTrackCollection(pTrackCollection), m_cancelImport(false) { QString tableName = "itunes_library"; diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index da157b1506e..1f493bf54a6 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -21,7 +21,10 @@ class BaseExternalPlaylistModel; class ITunesFeature : public BaseExternalLibraryFeature { Q_OBJECT public: - ITunesFeature(QObject* parent, TrackCollection* pTrackCollection); + ITunesFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~ITunesFeature(); static bool isSupported(); diff --git a/src/library/library.cpp b/src/library/library.cpp index e36a7529d1a..c4e5a80a0a3 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -210,6 +210,9 @@ void Library::addFeature(LibraryFeature* feature) { m_featuresMap.insert(feature->getViewName(), feature); m_pSidebarModel->addLibraryFeature(feature); + + // TODO(jmigual): this should be removed and add a direct interaction + // between the LibraryFeature and the Library connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), this, SLOT(slotShowTrackModel(QAbstractItemModel*))); connect(feature, SIGNAL(switchToView(const QString&)), @@ -495,16 +498,16 @@ LibraryPaneManager *Library::getFocusedPane() { } void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { - m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); + m_pMixxxLibraryFeature = new MixxxLibraryFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pMixxxLibraryFeature); - addFeature(new AutoDJFeature(this, pConfig, pPlayerManager, m_pTrackCollection)); - m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, m_pConfig); + addFeature(new AutoDJFeature(pConfig, this, this, pPlayerManager, m_pTrackCollection)); + m_pPlaylistFeature = new PlaylistFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pPlaylistFeature); - m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, m_pConfig); + m_pCrateFeature = new CrateFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pCrateFeature); BrowseFeature* browseFeature = new BrowseFeature( - this, pConfig, m_pTrackCollection, m_pRecordingManager); + pConfig, this, this, m_pTrackCollection, m_pRecordingManager); connect(browseFeature, SIGNAL(scanLibrary()), &m_scanner, SLOT(scan())); connect(&m_scanner, SIGNAL(scanStarted()), @@ -513,9 +516,9 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface browseFeature, SLOT(slotLibraryScanFinished())); addFeature(browseFeature); - addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); - addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); - m_pAnalysisFeature = new AnalysisFeature(this, pConfig, m_pTrackCollection); + addFeature(new RecordingFeature(pConfig, this, this, m_pTrackCollection, m_pRecordingManager)); + addFeature(new SetlogFeature(pConfig, this, this, m_pTrackCollection)); + m_pAnalysisFeature = new AnalysisFeature(m_pTrackCollection, pConfig, this, this);//this, pConfig, m_pTrackCollection); connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), m_pAnalysisFeature, SLOT(analyzeTracks(QList))); connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), @@ -526,22 +529,22 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface //mouse or keyboard if you're using MIDI control and you scroll through them...) if (RhythmboxFeature::isSupported() && pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { - addFeature(new RhythmboxFeature(this, m_pTrackCollection)); + addFeature(new RhythmboxFeature(pConfig, this, this, m_pTrackCollection)); } if (pConfig->getValueString(ConfigKey("[Library]","ShowBansheeLibrary"),"1").toInt()) { BansheeFeature::prepareDbPath(pConfig); if (BansheeFeature::isSupported()) { - addFeature(new BansheeFeature(this, m_pTrackCollection, pConfig)); + addFeature(new BansheeFeature(pConfig, this, this, m_pTrackCollection)); } } if (ITunesFeature::isSupported() && pConfig->getValueString(ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()) { - addFeature(new ITunesFeature(this, m_pTrackCollection)); + addFeature(new ITunesFeature(pConfig, this, this, m_pTrackCollection)); } if (TraktorFeature::isSupported() && pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { - addFeature(new TraktorFeature(this, m_pTrackCollection)); + addFeature(new TraktorFeature(pConfig, this, this, m_pTrackCollection)); } } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 891e7dd7bf7..fb725cc787f 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -1,20 +1,26 @@ // libraryfeature.cpp // Created 8/17/2009 by RJ Ryan (rryan@mit.edu) +#include +#include +#include +#include +#include +#include +#include +#include + #include "library/libraryfeature.h" // KEEP THIS cpp file to tell scons that moc should be called on the class!!! // The reason for this is that LibraryFeature uses slots/signals and for this // to work the code has to be precompiles by moc -LibraryFeature::LibraryFeature(QObject *parent) - : QObject(parent), - m_featureFocus(-1) { - -} - -LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, QObject* parent) +LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent) : QObject(parent), m_pConfig(pConfig), + m_pLibrary(pLibrary), m_featureFocus(-1) { } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 14edcfdef35..430659791cb 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -4,17 +4,8 @@ #ifndef LIBRARYFEATURE_H #define LIBRARYFEATURE_H -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include #include "track/track.h" #include "treeitemmodel.h" @@ -27,15 +18,18 @@ class TrackModel; class WLibrarySidebar; class WLibrary; class KeyboardEventFilter; +class Library; // pure virtual (abstract) class to provide an interface for libraryfeatures class LibraryFeature : public QObject { Q_OBJECT public: - LibraryFeature(QObject* parent = NULL); + // The parent does not necessary be the Library LibraryFeature(UserSettingsPointer pConfig, - QObject* parent = NULL); + Library* pLibrary, + QObject* parent = nullptr); + virtual ~LibraryFeature(); virtual QVariant title() = 0; @@ -45,25 +39,20 @@ class LibraryFeature : public QObject { // different feature virtual QString getViewName() = 0; - virtual bool dropAccept(QList urls, QObject* pSource) { - Q_UNUSED(urls); - Q_UNUSED(pSource); + virtual bool dropAccept(QList /* urls */, + QObject* /* pSource */) { return false; } - virtual bool dropAcceptChild(const QModelIndex& index, - QList urls, QObject* pSource) { - Q_UNUSED(index); - Q_UNUSED(urls); - Q_UNUSED(pSource); + virtual bool dropAcceptChild(const QModelIndex& /* index */, + QList /* urls */, + QObject* /* pSource */) { return false; } - virtual bool dragMoveAccept(QUrl url) { - Q_UNUSED(url); + virtual bool dragMoveAccept(QUrl /* url */) { return false; } - virtual bool dragMoveAcceptChild(const QModelIndex& index, QUrl url) { - Q_UNUSED(index); - Q_UNUSED(url); + virtual bool dragMoveAcceptChild(const QModelIndex& /* index */, + QUrl /* url */) { return false; } @@ -74,7 +63,7 @@ class LibraryFeature : public QObject { int /* paneId */) { } - // Reimplement this to register custem views with the library widget, + // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane virtual void bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter*); @@ -91,6 +80,7 @@ class LibraryFeature : public QObject { inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } UserSettingsPointer m_pConfig; + Library* m_pLibrary; int m_featureFocus; @@ -98,45 +88,42 @@ class LibraryFeature : public QObject { // called when you single click on the root item virtual void activate() = 0; // called when you single click on a child item, e.g., a concrete playlist or crate - virtual void activateChild(const QModelIndex& index) { - Q_UNUSED(index); + virtual void activateChild(const QModelIndex&) { } // called when you right click on the root item - virtual void onRightClick(const QPoint& globalPos) { - Q_UNUSED(globalPos); + virtual void onRightClick(const QPoint&) { } // called when you right click on a child item, e.g., a concrete playlist or crate - virtual void onRightClickChild(const QPoint& globalPos, QModelIndex index) { - Q_UNUSED(globalPos); - Q_UNUSED(index); + virtual void onRightClickChild(const QPoint& /* globalPos */, + QModelIndex /* index */) { } // Only implement this, if using incremental or lazy childmodels, see BrowseFeature. // This method is executed whenever you **double** click child items - virtual void onLazyChildExpandation(const QModelIndex& index) { - Q_UNUSED(index); + virtual void onLazyChildExpandation(const QModelIndex&) { } + signals: void showTrackModel(QAbstractItemModel* model); // The difference between switchToView and switchToViewChild is that the // second will never change the sidebar Expanded view, it's usefull when // selecting an item from the sidebar Expanded view - void switchToView(const QString& view); - void switchToViewChild(const QString& view); + void switchToView(const QString&); + void switchToViewChild(const QString&); - void loadTrack(TrackPointer pTrack); + void loadTrack(TrackPointer); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); void restoreSearch(const QString&); // emit this signal before you parse a large music collection, e.g., iTunes, Traktor. // The second arg indicates if the feature should be "selected" when loading starts void featureIsLoading(LibraryFeature*, bool selectFeature); // emit this signal if the foreign music collection has been imported/parsed. - void featureLoadingFinished(LibraryFeature*s); + void featureLoadingFinished(LibraryFeature*); // emit this signal to select pFeature void featureSelect(LibraryFeature* pFeature, const QModelIndex& index); // emit this signal to enable/disable the cover art widget void enableCoverArtDisplay(bool); - void trackSelected(TrackPointer pTrack); + void trackSelected(TrackPointer); private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index f5090ac566a..76c023e9a7e 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -22,10 +22,11 @@ const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = "MixxxLibraryFeature"; -MixxxLibraryFeature::MixxxLibraryFeature(Library* pLibrary, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig) - : LibraryFeature(pLibrary), +MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : LibraryFeature(pConfig, pLibrary, parent), kMissingTitle(tr("Missing Tracks")), kHiddenTitle(tr("Hidden Tracks")), kLibraryTitle(tr("Library")), diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index ee69473cd30..4a7ed5d4ecb 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -29,9 +29,10 @@ class TrackCollection; class MixxxLibraryFeature : public LibraryFeature { Q_OBJECT public: - MixxxLibraryFeature(Library* pLibrary, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig); + MixxxLibraryFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~MixxxLibraryFeature(); QVariant title(); diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index baa5b27cd29..ff790165fb1 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -18,10 +18,11 @@ #include "util/dnd.h" #include "util/time.h" -PlaylistFeature::PlaylistFeature(QObject* parent, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig) - : BasePlaylistFeature(parent, pConfig, pTrackCollection, +PlaylistFeature::PlaylistFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, "PLAYLISTHOME") { m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, "mixxx.db.model.playlist"); diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 488c947939f..0e16f1539fe 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -20,8 +20,10 @@ class TreeItem; class PlaylistFeature : public BasePlaylistFeature { Q_OBJECT public: - PlaylistFeature(QObject* parent, TrackCollection* pTrackCollection, - UserSettingsPointer pConfig); + PlaylistFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~PlaylistFeature(); QVariant title(); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 89c61dae7c8..82a3590f531 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -12,11 +12,13 @@ const QString RecordingFeature::m_sRecordingViewName = QString("Recording"); -RecordingFeature::RecordingFeature(Library* pLibrary, +RecordingFeature::RecordingFeature( UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) - : LibraryFeature(pLibrary), + : LibraryFeature(pConfig, pLibrary, parent), m_pConfig(pConfig), m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 6aaafba6f68..2a1759059db 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -20,8 +20,10 @@ class TrackCollection; class RecordingFeature : public LibraryFeature { Q_OBJECT public: - RecordingFeature(Library* parent, + RecordingFeature( UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager); virtual ~RecordingFeature(); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index ebf95ad0fc1..081595a1081 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -12,8 +12,11 @@ const QString RhythmboxFeature::m_sRhythmBoxViewName = QString("RHYTHMBOX_VIEW"); -RhythmboxFeature::RhythmboxFeature(QObject* parent, TrackCollection* pTrackCollection) - : BaseExternalLibraryFeature(parent, pTrackCollection), +RhythmboxFeature::RhythmboxFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : BaseExternalLibraryFeature(pConfig, pLibrary, parent, pTrackCollection), m_pTrackCollection(pTrackCollection), m_cancelImport(false) { QString tableName = "rhythmbox_library"; diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index ec3ffd03a36..e142f516f2c 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -21,7 +21,10 @@ class BaseExternalPlaylistModel; class RhythmboxFeature : public BaseExternalLibraryFeature { Q_OBJECT public: - RhythmboxFeature(QObject* parent, TrackCollection*); + RhythmboxFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~RhythmboxFeature(); static bool isSupported(); diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index ff6039fe97e..b627f1b1d9a 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -11,10 +11,11 @@ #include "mixer/playerinfo.h" #include "mixer/playermanager.h" -SetlogFeature::SetlogFeature(QObject* parent, - UserSettingsPointer pConfig, +SetlogFeature::SetlogFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection) - : BasePlaylistFeature(parent, pConfig, pTrackCollection, "SETLOGHOME"), + : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, "SETLOGHOME"), m_playlistId(-1) { m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, "mixxx.db.model.setlog", diff --git a/src/library/setlogfeature.h b/src/library/setlogfeature.h index 2115076ac64..a5abeae18f8 100644 --- a/src/library/setlogfeature.h +++ b/src/library/setlogfeature.h @@ -16,7 +16,9 @@ class TreeItem; class SetlogFeature : public BasePlaylistFeature { Q_OBJECT public: - SetlogFeature(QObject* parent, UserSettingsPointer pConfig, + SetlogFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection); virtual ~SetlogFeature(); diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index c00d40d37d6..3a7ee10526f 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -52,8 +52,10 @@ bool TraktorPlaylistModel::isColumnHiddenByDefault(int column) { return BaseSqlTableModel::isColumnHiddenByDefault(column); } -TraktorFeature::TraktorFeature(QObject* parent, TrackCollection* pTrackCollection) - : BaseExternalLibraryFeature(parent, pTrackCollection), +TraktorFeature::TraktorFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, TrackCollection* pTrackCollection) + : BaseExternalLibraryFeature(pConfig, pLibrary, parent, pTrackCollection), m_pTrackCollection(pTrackCollection), m_cancelImport(false) { QString tableName = "traktor_library"; diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index 24f223f7bae..6dd0ce22aec 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -38,7 +38,10 @@ class TraktorPlaylistModel : public BaseExternalPlaylistModel { class TraktorFeature : public BaseExternalLibraryFeature { Q_OBJECT public: - TraktorFeature(QObject* parent, TrackCollection*); + TraktorFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); virtual ~TraktorFeature(); QVariant title(); From f16706698d5e215a1425b23a751792438e9e6757 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 10:44:54 +0200 Subject: [PATCH 173/552] Remove includes to avoid recompiling unnecessary code --- src/library/autodj/autodjfeature.cpp | 3 ++- src/library/libraryfeature.cpp | 4 +++- src/library/libraryfeature.h | 7 +++---- src/library/treeitem.h | 3 ++- src/widget/wfeatureclickbutton.h | 1 + 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 5d69437ce6a..b578c028c16 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -12,12 +12,13 @@ #include "library/library.h" #include "library/parser.h" -#include "mixer/playermanager.h" #include "library/autodj/autodjprocessor.h" #include "library/trackcollection.h" #include "library/autodj/dlgautodj.h" #include "library/treeitem.h" +#include "mixer/playermanager.h" #include "widget/wlibrary.h" +#include "widget/wlibrarysidebar.h" #include "controllers/keyboard/keyboardeventfilter.h" #include "sources/soundsourceproxy.h" #include "util/dnd.h" diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index fb725cc787f..588b3b2891d 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -11,10 +11,12 @@ #include #include "library/libraryfeature.h" +#include "widget/wbaselibrary.h" +#include "widget/wlibrarysidebar.h" // KEEP THIS cpp file to tell scons that moc should be called on the class!!! // The reason for this is that LibraryFeature uses slots/signals and for this -// to work the code has to be precompiles by moc +// to work the code has to be precompiled by moc LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent) diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 430659791cb..db70b6e95f4 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -6,16 +6,15 @@ #include #include +#include #include "track/track.h" #include "treeitemmodel.h" #include "library/coverartcache.h" #include "library/dao/trackdao.h" -#include "widget/wlibrary.h" -#include "widget/wlibrarysidebar.h" class TrackModel; -class WLibrarySidebar; +class WBaseLibrary; class WLibrary; class KeyboardEventFilter; class Library; @@ -106,7 +105,7 @@ class LibraryFeature : public QObject { void showTrackModel(QAbstractItemModel* model); // The difference between switchToView and switchToViewChild is that the - // second will never change the sidebar Expanded view, it's usefull when + // second will never change the sidebar Expanded view, it's useful when // selecting an item from the sidebar Expanded view void switchToView(const QString&); void switchToViewChild(const QString&); diff --git a/src/library/treeitem.h b/src/library/treeitem.h index d56c38cc243..a2e3f596071 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "library/libraryfeature.h" @@ -22,7 +23,7 @@ class TreeItem { void appendChild(TreeItem *child); /** remove a child item at the given index **/ void removeChild(int index); - /** returns the tree item at position 'row' in the childlist **/ + /** returns the tree item at position 'row' in the child list **/ TreeItem *child(int row); /** returns the number of childs of this tree item **/ int childCount() const; diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index 4043b22a941..ca1e3e7fd6b 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -4,6 +4,7 @@ #include #include #include +#include class WFeatureClickButton : public QToolButton { From 5705b355f5dcf777d6c1168279f4470c13d9d087 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 21:20:49 +0200 Subject: [PATCH 174/552] Create WLibraryStack class It can be added to the WLibrary class as it inherits the LibraryView class --- src/widget/wlibrarystack.cpp | 68 ++++++++++++++++++++++++++++++++++++ src/widget/wlibrarystack.h | 34 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/widget/wlibrarystack.cpp create mode 100644 src/widget/wlibrarystack.h diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp new file mode 100644 index 00000000000..456ecc48be9 --- /dev/null +++ b/src/widget/wlibrarystack.cpp @@ -0,0 +1,68 @@ +#include + +#include "widget/wlibrarystack.h" + +WLibraryStack::WLibraryStack(QWidget* parent) + : QStackedWidget(parent) { + // TODO Auto-generated constructor stub + +} + +WLibraryStack::~WLibraryStack() { + // TODO Auto-generated destructor stub +} + +int WLibraryStack::addWidget(QWidget* w) { + checkAndWarning(); + return QStackedWidget::addWidget(w); +} + +int WLibraryStack::insertWidget(int index, QWidget* w) { + checkAndWarning(); + return QStackedWidget::insertWidget(index, w); +} + +void WLibraryStack::onShow() { + +} + +void WLibraryStack::onSearch(const QString& text) { + LibraryView* pView = dynamic_cast(currentWidget()); + + if (pView) { + pView->onSearch(text); + } +} + +void WLibraryStack::loadSelectedTrack() { + LibraryView* pView = dynamic_cast(currentWidget()); + + if (pView) { + pView->loadSelectedTrack(); + } +} + +void WLibraryStack::slotSendToAutoDJ() { + LibraryView* pView = dynamic_cast(currentWidget()); + + if (pView) { + pView->slotSendToAutoDJ(); + } +} + +void WLibraryStack::slotSendToAutoDJTop() { + LibraryView* pView = dynamic_cast(currentWidget()); + + if (pView) { + pView->slotSendToAutoDJTop(); + } +} + +bool WLibraryStack::checkAndWarning() { + if (!dynamic_cast(w)) { + qDebug() << "WARNING: Attempted to register a view with WLibraryStack" + << "that does not implement the LibraryView interface."; + return false; + } + return true; +} diff --git a/src/widget/wlibrarystack.h b/src/widget/wlibrarystack.h new file mode 100644 index 00000000000..c02b990887c --- /dev/null +++ b/src/widget/wlibrarystack.h @@ -0,0 +1,34 @@ +#ifndef WLIBRARYSTACK_H +#define WLIBRARYSTACK_H + +#include + +#include "library/libraryview.h" + +/* This is a stacked widget that contains LibraryViews inside to, it can be + * added to the WLibrary and allows compatibility + */ + +class WLibraryStack : public QStackedWidget, public LibraryView { + Q_OBJECT + + public: + WLibraryStack(QWidget* parent = nullptr); + ~WLibraryStack(); + + int addWidget(QWidget* w); + int insertWidget(int index, QWidget *w); + + void onShow(); + void onSearch(const QString& text); + + void loadSelectedTrack(); + void slotSendToAutoDJ(); + void slotSendToAutoDJTop(); + + private: + + bool checkAndWarning(); +}; + +#endif /* WLIBRARYSTACK_H */ From 47e115c952d921c7364cd313a0e5149a27ea696a Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 21:21:31 +0200 Subject: [PATCH 175/552] Move Mixxx Library buttons to the SideBarExpanded --- src/library/dlghidden.cpp | 73 +++++++--------- src/library/dlghidden.h | 14 +-- src/library/dlghidden.ui | 127 +++++++++------------------- src/library/dlgmissing.cpp | 69 ++++++--------- src/library/dlgmissing.h | 7 +- src/library/dlgmissing.ui | 97 ++++++--------------- src/library/mixxxlibraryfeature.cpp | 50 ++++++++++- src/library/mixxxlibraryfeature.h | 15 +++- 8 files changed, 199 insertions(+), 253 deletions(-) diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 9cddafb9912..3f72daf5ec5 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -6,54 +6,23 @@ #include "util/assert.h" DlgHidden::DlgHidden(QWidget* parent, UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, + TrackCollection* pTrackCollection, KeyboardEventFilter* pKeyboard) : QWidget(parent), Ui::DlgHidden(), m_pTrackTableView( new WTrackTableView(this, pConfig, pTrackCollection, false)) { setupUi(this); - m_pTrackTableView->installEventFilter(pKeyboard); - - // Install our own trackTable - QBoxLayout* box = dynamic_cast(layout()); - DEBUG_ASSERT_AND_HANDLE(box) { //Assumes the form layout is a QVBox/QHBoxLayout! - } else { - box->removeWidget(m_pTrackTablePlaceholder); - m_pTrackTablePlaceholder->hide(); - box->insertWidget(1, m_pTrackTableView); - } + + connect(btnPurge, SIGNAL(clicked()), this, SLOT(clicked())); + connect(btnSelect, SIGNAL(clicked()), this, SLOT(selectAll())); m_pHiddenTableModel = new HiddenTableModel(this, pTrackCollection); - m_pTrackTableView->loadTrackModel(m_pHiddenTableModel); - - connect(btnUnhide, SIGNAL(clicked()), - m_pTrackTableView, SLOT(slotUnhide())); - connect(btnUnhide, SIGNAL(clicked()), - this, SLOT(clicked())); - connect(btnPurge, SIGNAL(clicked()), - m_pTrackTableView, SLOT(slotPurge())); - connect(btnPurge, SIGNAL(clicked()), - this, SLOT(clicked())); - connect(btnSelect, SIGNAL(clicked()), - this, SLOT(selectAll())); - connect(m_pTrackTableView->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - - connect(m_pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), - m_pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), - m_pTrackTableView, SLOT(setTrackTableRowHeight(int))); } DlgHidden::~DlgHidden() { // Delete m_pTrackTableView before the table model. This is because the // table view saves the header state using the model. - delete m_pTrackTableView; delete m_pHiddenTableModel; } @@ -67,13 +36,37 @@ void DlgHidden::onSearch(const QString& text) { m_pHiddenTableModel->search(text); } +void DlgHidden::setTrackTable(Library* pLibrary, WTrackTableView *pTrackTableView, int paneId) { + connect(btnUnhide, SIGNAL(clicked()), + pTrackTableView, SLOT(slotUnhide())); + connect(btnUnhide, SIGNAL(clicked()), + this, SLOT(clicked())); + connect(btnPurge, SIGNAL(clicked()), + pTrackTableView, SLOT(slotPurge())); + connect(pTrackTableView->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + pTrackTableView->loadTrackModel(m_pHiddenTableModel); + + m_trackTableView[paneId] = pTrackTableView; +} + void DlgHidden::clicked() { // all marked tracks are gone now anyway onShow(); } void DlgHidden::selectAll() { - m_pTrackTableView->selectAll(); + if (m_trackTableView.contains(m_focusedPane)) { + m_trackTableView[m_focusedPane]->selectAll(); + } } void DlgHidden::activateButtons(bool enable) { @@ -86,11 +79,3 @@ void DlgHidden::selectionChanged(const QItemSelection &selected, Q_UNUSED(deselected); activateButtons(!selected.indexes().isEmpty()); } - -void DlgHidden::setTrackTableFont(const QFont& font) { - m_pTrackTableView->setTrackTableFont(font); -} - -void DlgHidden::setTrackTableRowHeight(int rowHeight) { - m_pTrackTableView->setTrackTableRowHeight(rowHeight); -} diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index 6b78d85f1fc..eb95026679d 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -15,28 +15,30 @@ class QItemSelection; class DlgHidden : public QWidget, public Ui::DlgHidden, public LibraryView { Q_OBJECT public: - DlgHidden(QWidget* parent, UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, + DlgHidden(QWidget* parent, UserSettingsPointer pConfig, TrackCollection* pTrackCollection, KeyboardEventFilter* pKeyboard); virtual ~DlgHidden(); void onShow(); void onSearch(const QString& text); + void setTrackTable(Library* pLibrary, WTrackTableView* pTrackTableView, int paneId); + inline void setFocusedPane(int focusedPane) { + m_focusedPane = focusedPane; + } public slots: void clicked(); void selectAll(); - void selectionChanged(const QItemSelection&, const QItemSelection&); - void setTrackTableFont(const QFont& font); - void setTrackTableRowHeight(int rowHeight); + void selectionChanged(const QItemSelection&, const QItemSelection&); signals: void trackSelected(TrackPointer pTrack); private: void activateButtons(bool enable); - WTrackTableView* m_pTrackTableView; HiddenTableModel* m_pHiddenTableModel; + QHash m_trackTableView; + int m_focusedPane; }; #endif //DLGHIDDEN_H diff --git a/src/library/dlghidden.ui b/src/library/dlghidden.ui index d80de64e421..2b96be8becc 100644 --- a/src/library/dlghidden.ui +++ b/src/library/dlghidden.ui @@ -14,103 +14,60 @@ Hidden Tracks - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - 0 + + + Selects all tracks in the table below. - - 0 + + Select All - - 0 + + + + + + Purge selected tracks from the library. - - 0 + + Purge - - 0 + + false - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Selects all tracks in the table below. - - - Select All - - - - - - - Purge selected tracks from the library. - - - Purge - - - false - - - - - - - Unhide selected tracks from the library. - - - Unhide - - - Ctrl+S - - - false - - - - + - - - true + + + Unhide selected tracks from the library. + + + Unhide + + + Ctrl+S + + + false + + + + Qt::Vertical + + + + 20 + 285 + + + + - - - + diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 3f5918bfb3e..f43e2810dcc 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -11,44 +11,16 @@ DlgMissing::DlgMissing(QWidget* parent, UserSettingsPointer pConfig, Ui::DlgMissing(), m_pTrackTableView( new WTrackTableView(this, pConfig, pTrackCollection, false)) { - setupUi(this); - m_pTrackTableView->installEventFilter(pKeyboard); - - // Install our own trackTable - QBoxLayout* box = dynamic_cast(layout()); - DEBUG_ASSERT_AND_HANDLE(box) { //Assumes the form layout is a QVBox/QHBoxLayout! - } else { - box->removeWidget(m_pTrackTablePlaceholder); - m_pTrackTablePlaceholder->hide(); - box->insertWidget(1, m_pTrackTableView); - } - + setupUi(this); m_pMissingTableModel = new MissingTableModel(this, pTrackCollection); - m_pTrackTableView->loadTrackModel(m_pMissingTableModel); - - connect(btnPurge, SIGNAL(clicked()), - m_pTrackTableView, SLOT(slotPurge())); - connect(btnPurge, SIGNAL(clicked()), - this, SLOT(clicked())); - connect(btnSelect, SIGNAL(clicked()), - this, SLOT(selectAll())); - connect(m_pTrackTableView->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), - m_pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), - m_pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - connect(m_pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); + + connect(btnPurge, SIGNAL(clicked()), this, SLOT(clicked())); + connect(btnSelect, SIGNAL(clicked()), this, SLOT(selectAll())); } DlgMissing::~DlgMissing() { // Delete m_pTrackTableView before the table model. This is because the // table view saves the header state using the model. - delete m_pTrackTableView; delete m_pMissingTableModel; } @@ -66,8 +38,29 @@ void DlgMissing::onSearch(const QString& text) { m_pMissingTableModel->search(text); } -void DlgMissing::selectAll() { - m_pTrackTableView->selectAll(); +void DlgMissing::setTrackTable(WTrackTableView* pTrackTableView, int paneId) { + connect(btnPurge, SIGNAL(clicked()), + pTrackTableView, SLOT(slotPurge())); + connect(pTrackTableView->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + + pTrackTableView->loadTrackModel(m_pMissingTableModel); + m_trackTableView[paneId] = pTrackTableView; +} + +void DlgMissing::selectAll() { + if (m_trackTableView.contains(m_focusedPane)) { + m_trackTableView[m_focusedPane]->selectAll(); + } } void DlgMissing::activateButtons(bool enable) { @@ -79,11 +72,3 @@ void DlgMissing::selectionChanged(const QItemSelection &selected, Q_UNUSED(deselected); activateButtons(!selected.indexes().isEmpty()); } - -void DlgMissing::setTrackTableFont(const QFont& font) { - m_pTrackTableView->setTrackTableFont(font); -} - -void DlgMissing::setTrackTableRowHeight(int rowHeight) { - m_pTrackTableView->setTrackTableRowHeight(rowHeight); -} diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index fe287e8e8ef..c871b058db6 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -21,6 +21,10 @@ class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { void onShow(); void onSearch(const QString& text); + void setTrackTable(WTrackTableView* pTrackTableView, int paneId); + inline void setFocusedPane(int focusedPane) { + m_focusedPane = focusedPane; + } public slots: void clicked(); @@ -34,8 +38,9 @@ class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { private: void activateButtons(bool enable); - WTrackTableView* m_pTrackTableView; MissingTableModel* m_pMissingTableModel; + QHash m_trackTableView; + int m_focusedPane; }; #endif //DLGMISSING_H diff --git a/src/library/dlgmissing.ui b/src/library/dlgmissing.ui index 8db680a895c..bc3a8805537 100644 --- a/src/library/dlgmissing.ui +++ b/src/library/dlgmissing.ui @@ -14,87 +14,44 @@ Missing Tracks - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - 0 + + + Selects all tracks in the table below. - - 0 + + Select All - - 0 + + + + + + Purge selected tracks from the library. - - 0 + + Purge - - 0 + + false - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Selects all tracks in the table below. - - - Select All - - - - - - - Purge selected tracks from the library. - - - Purge - - - false - - - - + - - - true + + + Qt::Vertical - + + + 20 + 316 + + + - - - + diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 76c023e9a7e..5bccb64deca 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -13,12 +13,13 @@ #include "library/hiddentablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" +#include "library/dlghidden.h" +#include "library/dlgmissing.h" #include "treeitem.h" #include "sources/soundsourceproxy.h" #include "widget/wlibrary.h" +#include "widget/wlibrarystack.h" #include "util/dnd.h" -#include "library/dlghidden.h" -#include "library/dlgmissing.h" const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = "MixxxLibraryFeature"; @@ -146,6 +147,46 @@ void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, this, SIGNAL(trackSelected(TrackPointer))); } +QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + WLibraryStack* pStack = new WLibraryStack(nullptr); + + WTrackTableView* pHiddenTable = + new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); + pHiddenTable->installEventFilter(pKeyboard); + m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); + + if (m_pHiddenView) { + m_pHiddenView->setTrackTable(m_pLibrary, pHiddenTable, paneId); + } else { + m_hiddenPane[paneId] = pHiddenTable; + } + + WTrackTableView* pMissingTable = + new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); + pMissingTable->installEventFilter(pKeyboard); + m_missingPane[paneId] = pMissingTable; + m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); + + return pStack; +} + +void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, + KeyboardEventFilter*, + int paneId) { + m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, + m_pTrackCollection, pKeyboard); + pLibraryWidget->registerView(kHiddenTitle, m_pHiddenView); + connect(m_pHiddenView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + + m_pMissingView = new DlgMissing(pLibraryWidget, m_pConfig, m_pLibrary, + m_pTrackCollection, pKeyboard); + pLibraryWidget->registerView(kMissingTitle, m_pMissingView); + connect(m_pMissingView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); +} + QVariant MixxxLibraryFeature::title() { return kLibraryTitle; } @@ -171,7 +212,10 @@ void MixxxLibraryFeature::refreshLibraryModels() { } void MixxxLibraryFeature::activate() { - qDebug() << "MixxxLibraryFeature::activate()"; + //qDebug() << "MixxxLibraryFeature::activate()"; + m_pHiddenView->setFocusedPane(m_featureFocus); + + emit(switchToView(m_sMixxxLibraryViewName)); emit(showTrackModel(m_pLibraryTableModel)); emit(enableCoverArtDisplay(true)); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 4a7ed5d4ecb..0882b383d8f 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "library/libraryfeature.h" #include "library/dao/trackdao.h" @@ -25,6 +26,7 @@ class Library; class BaseTrackCache; class LibraryTableModel; class TrackCollection; +class WTrackTableView; class MixxxLibraryFeature : public LibraryFeature { Q_OBJECT @@ -42,6 +44,10 @@ class MixxxLibraryFeature : public LibraryFeature { TreeItemModel* getChildModel(); void bindPaneWidget(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard, int); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); + void bindSidebarWidget(WBaseLibrary* pLibraryWidget, + KeyboardEventFilter*, + int paneId); inline QString getViewName() { return m_sMixxxLibraryViewName; @@ -56,11 +62,16 @@ class MixxxLibraryFeature : public LibraryFeature { const QString kMissingTitle; const QString kHiddenTitle; const QString kLibraryTitle; + QPointer m_pHiddenView; + QPointer m_pMissingView; + QHash m_hiddenPaneId; + QHash m_missingPaneId; + QHash m_hiddenPane; + QHash m_missingPane; + Library* m_pLibrary; QSharedPointer m_pBaseTrackCache; LibraryTableModel* m_pLibraryTableModel; - DlgMissing* m_pMissingView; - DlgHidden* m_pHiddenView; TreeItemModel m_childModel; TrackDAO& m_trackDao; UserSettingsPointer m_pConfig; From 9dfc1b9e7e5c6fdce4eba5b2ecbe756d677165f0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 21:21:49 +0200 Subject: [PATCH 176/552] Begin adding new Library direct Mapping --- build/depends.py | 1 + src/library/analysisfeature.cpp | 16 ++++++++++++++++ src/library/analysisfeature.h | 2 ++ src/library/autodj/autodjfeature.cpp | 21 ++++++++++++++++++++- src/library/autodj/autodjfeature.h | 2 +- src/library/autodj/dlgautodj.cpp | 4 ++-- src/library/autodj/dlgautodj.h | 4 ++-- src/library/baseplaylistfeature.cpp | 14 ++++++++++++-- src/library/baseplaylistfeature.h | 5 +++-- src/library/browse/browsefeature.cpp | 9 +++++++-- src/library/browse/browsefeature.h | 4 ++-- src/library/library.cpp | 4 ++++ src/library/library.h | 1 + src/library/libraryfeature.h | 6 ++++++ src/library/librarypanemanager.cpp | 8 ++++---- src/library/librarypanemanager.h | 5 +++-- 16 files changed, 86 insertions(+), 20 deletions(-) diff --git a/build/depends.py b/build/depends.py index 8350c33d3a5..1b5e0611737 100644 --- a/build/depends.py +++ b/build/depends.py @@ -814,6 +814,7 @@ def sources(self, build): "widget/wmainmenubar.cpp", "widget/wbuttonbar.cpp", "widget/wfeatureclickbutton.cpp", + "widget/wlibrarystack.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 624a7523349..67451405d93 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -78,6 +78,22 @@ void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, libraryWidget->registerView(m_sAnalysisViewName, pTable); } +QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + + WAnalysisLibraryTableView* pTable = new WAnalysisLibraryTableView(nullptr, + m_pConfig, + m_pTrackCollection); + pTable->installEventFilter(pKeyboard); + + if (m_pAnalysisView) { + m_pAnalysisView->setAnalysisTableView(pTable, paneId); + } else { + m_analysisTables[paneId] = pTable; + } + return pTable; +} + void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, KeyboardEventFilter* pKeyboard) { diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index b9154a2d6aa..61d6bbad94b 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -39,9 +39,11 @@ class AnalysisFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*pKeyboard, int paneId); + QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary* libraryWidget, KeyboardEventFilter*pKeyboard); + TreeItemModel* getChildModel(); void refreshLibraryModels(); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index b578c028c16..61f39da55fd 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -126,6 +126,25 @@ void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, } } +QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { + WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, + m_pConfig, m_pTrackCollection, false); + + pTrackTableView->installEventFilter(pKeyboard); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(const QFont&)), + pTrackTableView, SLOT(setTrackTableFont(const QFont&))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + if (m_pAutoDJView) { + m_pAutoDJView->setTrackTableView(pTrackTableView, paneId); + } else { + m_trackTables[paneId] = pTrackTableView; + } + return pTrackTableView; +} + void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter*) { qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; @@ -165,7 +184,7 @@ TreeItemModel* AutoDJFeature::getChildModel() { } void AutoDJFeature::activate() { - qDebug() << "AutoDJFeature::activate()"; + //qDebug() << "AutoDJFeature::activate()"; m_pAutoDJView->setFocusedPane(m_featureFocus); m_pAutoDJView->onShow(); emit(switchToView(m_sAutoDJViewName)); diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index baf8d669338..b4489d35f53 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -47,6 +47,7 @@ class AutoDJFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter*pKeyboard, int paneId); + QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter*); TreeItemModel* getChildModel(); @@ -69,7 +70,6 @@ class AutoDJFeature : public LibraryFeature { const static QString m_sAutoDJViewName; TreeItemModel m_childModel; QPointer m_pAutoDJView; - //QList m_trackTables; QHash m_trackTables; // Initialize the list of crates loaded into the auto-DJ queue. diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 18ed0d0ff5b..6d8c612c103 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -61,10 +61,10 @@ void DlgAutoDJ::onShow() { m_pAutoDJTableModel->select(); } -void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView, int pane) { +void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView, int paneId) { pTrackTableView->loadTrackModel(m_pAutoDJTableModel); - m_trackTables[pane] = pTrackTableView; + m_trackTables[paneId] = pTrackTableView; connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index b1199f76efc..ee6a84e36c3 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -24,7 +24,7 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { virtual ~DlgAutoDJ(); void onShow(); - void setTrackTableView(WTrackTableView* pTrackTableView, int pane); + void setTrackTableView(WTrackTableView* pTrackTableView, int paneId); void setFocusedPane(int focusedPane); public slots: @@ -50,7 +50,7 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { int m_focusedPane; - QMap m_trackTables; + QHash m_trackTables; }; #endif //DLGAUTODJ_H diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 0b31d4e6d5f..72c90951dc5 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -595,8 +595,8 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { } void BasePlaylistFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int) { - Q_UNUSED(keyboard); + KeyboardEventFilter* , + int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); edit->setHtml(getRootViewHtml()); edit->setOpenLinks(false); @@ -605,6 +605,16 @@ void BasePlaylistFeature::bindPaneWidget(WLibrary* libraryWidget, libraryWidget->registerView(m_rootViewName, edit); } +QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter*, + int) { + WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); + edit->setHtml(getRootViewHtml()); + edit->setOpenLinks(false); + connect(edit, SIGNAL(anchorClicked(const QUrl)), + this, SLOT(htmlLinkClicked(const QUrl))); + return edit; +} + void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) { if (QString(link.path()) == "create") { slotCreatePlaylist(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index cb2c45bbb52..084d0e8fd86 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -34,8 +34,9 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int); + void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*, int); + + QWidget* createPaneWidget(KeyboardEventFilter*, int); QString getViewName() { return m_rootViewName; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 586ea0ca800..6268f44cbad 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -215,13 +215,18 @@ TreeItemModel* BrowseFeature::getChildModel() { } void BrowseFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int) { - Q_UNUSED(keyboard); + KeyboardEventFilter*, + int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); edit->setHtml(getRootViewHtml()); libraryWidget->registerView(m_sBrowseViewName, edit); } +QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter*, int) { + WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); + edit->setHtml(getRootViewHtml()); +} + void BrowseFeature::activate() { emit(switchToView(m_sBrowseViewName)); emit(restoreSearch(QString())); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index d378d79ea82..1808a862d7d 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,8 +38,8 @@ class BrowseFeature : public LibraryFeature { QIcon getIcon(); virtual QString getViewName(); - void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int); + void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*, int); + QWidget* createPaneWidget(KeyboardEventFilter*, int); TreeItemModel* getChildModel(); diff --git a/src/library/library.cpp b/src/library/library.cpp index c4e5a80a0a3..daa6379a05f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -556,3 +556,7 @@ void Library::handleFocus() { } } } + +void Library::slotSwitchToView(LibraryFeature* pFeature) { + +} diff --git a/src/library/library.h b/src/library/library.h index 2b029612c28..e9023897439 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -92,6 +92,7 @@ class Library : public QObject { void slotHoverFeature(const QString& featureName); void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); + void slotSwitchToView(LibraryFeature* pFeature); void slotSwitchToViewChild(const QString& view); void slotSwitchToNotFocusedView(const QString& view); void slotLoadTrack(TrackPointer pTrack); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index db70b6e95f4..d96a4249a29 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -12,6 +12,7 @@ #include "treeitemmodel.h" #include "library/coverartcache.h" #include "library/dao/trackdao.h" +#include "preferences/usersettings.h" class TrackModel; class WBaseLibrary; @@ -62,6 +63,11 @@ class LibraryFeature : public QObject { int /* paneId */) { } + virtual QWidget* createPaneWidget(KeyboardEventFilter* /* keyboard */, + int /* paneId */) { + return nullptr; + } + // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane virtual void bindSidebarWidget(WBaseLibrary *pSidebarWidget, diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 146fe162d04..73d3c034645 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -1,8 +1,9 @@ #include #include "librarypanemanager.h" -#include "widget/wbuttonbar.h" #include "library/libraryfeature.h" +#include "widget/wtracktableview.h" +#include "widget/wbuttonbar.h" #include "util/assert.h" const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); @@ -17,11 +18,10 @@ LibraryPaneManager::LibraryPaneManager(int paneId, QObject* parent) LibraryPaneManager::~LibraryPaneManager() { } -void LibraryPaneManager::bindPaneWidget(WBaseLibrary* libraryWidget, +void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryPaneManager::bindLibraryWidget" << libraryWidget; - - m_pPaneWidget = libraryWidget; + m_pPaneWidget = pLibraryWidget; connect(this, SIGNAL(switchToView(const QString&)), m_pPaneWidget, SLOT(switchToView(const QString&))); diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index c8b9ee0c106..7d4b31ab31f 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -23,7 +23,7 @@ class LibraryPaneManager : public QObject { bool initialize(); // All features must be added before adding a pane - virtual void bindPaneWidget(WBaseLibrary* libraryWidget, + virtual void bindPaneWidget(WBaseLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard); void bindSearchBar(WSearchLineEdit* pSearchLine); @@ -62,13 +62,14 @@ class LibraryPaneManager : public QObject { void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); + void slotSwitchToView(LibraryFeature* pFeature); void slotRestoreSearch(const QString& text); protected: WBaseLibrary* m_pPaneWidget; - QList m_features; + QHash m_featuresWidget; private: From 97c6555851635b02659f07f9e6f29f4928b8b4d4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 23:25:17 +0200 Subject: [PATCH 177/552] Fix compilation issue in WLibraryStack --- src/widget/wlibrarystack.cpp | 7 ++++--- src/widget/wlibrarystack.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp index 456ecc48be9..b98ef4569aa 100644 --- a/src/widget/wlibrarystack.cpp +++ b/src/widget/wlibrarystack.cpp @@ -13,12 +13,13 @@ WLibraryStack::~WLibraryStack() { } int WLibraryStack::addWidget(QWidget* w) { - checkAndWarning(); + qDebug() << "WLibraryStack::addWidget" << w; + checkAndWarning(w); return QStackedWidget::addWidget(w); } int WLibraryStack::insertWidget(int index, QWidget* w) { - checkAndWarning(); + checkAndWarning(w); return QStackedWidget::insertWidget(index, w); } @@ -58,7 +59,7 @@ void WLibraryStack::slotSendToAutoDJTop() { } } -bool WLibraryStack::checkAndWarning() { +bool WLibraryStack::checkAndWarning(QWidget* w) { if (!dynamic_cast(w)) { qDebug() << "WARNING: Attempted to register a view with WLibraryStack" << "that does not implement the LibraryView interface."; diff --git a/src/widget/wlibrarystack.h b/src/widget/wlibrarystack.h index c02b990887c..d37a1d62ecf 100644 --- a/src/widget/wlibrarystack.h +++ b/src/widget/wlibrarystack.h @@ -28,7 +28,7 @@ class WLibraryStack : public QStackedWidget, public LibraryView { private: - bool checkAndWarning(); + bool checkAndWarning(QWidget *w); }; #endif /* WLIBRARYSTACK_H */ From df8c8b40074b1a1b101a50342cab0d460811e6ee Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 28 Jun 2016 23:25:50 +0200 Subject: [PATCH 178/552] Finish moving Mixxx Library controls to sidebar --- src/library/dlghidden.cpp | 16 +--- src/library/dlghidden.h | 6 +- src/library/dlgmissing.cpp | 15 ++-- src/library/dlgmissing.h | 14 ++-- src/library/librarypanemanager.cpp | 4 + src/library/mixxxlibraryfeature.cpp | 122 ++++++++++++++++++++-------- src/library/mixxxlibraryfeature.h | 27 +++--- 7 files changed, 126 insertions(+), 78 deletions(-) diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 3f72daf5ec5..6d999e69e00 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -5,13 +5,10 @@ #include "widget/wtracktableview.h" #include "util/assert.h" -DlgHidden::DlgHidden(QWidget* parent, UserSettingsPointer pConfig, - TrackCollection* pTrackCollection, - KeyboardEventFilter* pKeyboard) +DlgHidden::DlgHidden(QWidget* parent, TrackCollection* pTrackCollection) : QWidget(parent), Ui::DlgHidden(), - m_pTrackTableView( - new WTrackTableView(this, pConfig, pTrackCollection, false)) { + m_focusedPane(-1) { setupUi(this); connect(btnPurge, SIGNAL(clicked()), this, SLOT(clicked())); @@ -32,10 +29,6 @@ void DlgHidden::onShow() { activateButtons(false); } -void DlgHidden::onSearch(const QString& text) { - m_pHiddenTableModel->search(text); -} - void DlgHidden::setTrackTable(Library* pLibrary, WTrackTableView *pTrackTableView, int paneId) { connect(btnUnhide, SIGNAL(clicked()), pTrackTableView, SLOT(slotUnhide())); @@ -74,8 +67,7 @@ void DlgHidden::activateButtons(bool enable) { btnUnhide->setEnabled(enable); } -void DlgHidden::selectionChanged(const QItemSelection &selected, - const QItemSelection &deselected) { - Q_UNUSED(deselected); +void DlgHidden::selectionChanged(const QItemSelection& selected, + const QItemSelection&) { activateButtons(!selected.indexes().isEmpty()); } diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index eb95026679d..f7da5b31606 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -12,15 +12,13 @@ class WTrackTableView; class HiddenTableModel; class QItemSelection; -class DlgHidden : public QWidget, public Ui::DlgHidden, public LibraryView { +class DlgHidden : public QWidget, public Ui::DlgHidden { Q_OBJECT public: - DlgHidden(QWidget* parent, UserSettingsPointer pConfig, TrackCollection* pTrackCollection, - KeyboardEventFilter* pKeyboard); + DlgHidden(QWidget* parent, TrackCollection *pTrackCollection); virtual ~DlgHidden(); void onShow(); - void onSearch(const QString& text); void setTrackTable(Library* pLibrary, WTrackTableView* pTrackTableView, int paneId); inline void setFocusedPane(int focusedPane) { m_focusedPane = focusedPane; diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index f43e2810dcc..1426a6c4101 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -4,13 +4,10 @@ #include "widget/wtracktableview.h" #include "util/assert.h" -DlgMissing::DlgMissing(QWidget* parent, UserSettingsPointer pConfig, - Library* pLibrary, - TrackCollection* pTrackCollection, KeyboardEventFilter* pKeyboard) +DlgMissing::DlgMissing(QWidget* parent, TrackCollection *pTrackCollection) : QWidget(parent), Ui::DlgMissing(), - m_pTrackTableView( - new WTrackTableView(this, pConfig, pTrackCollection, false)) { + m_focusedPane(-1) { setupUi(this); m_pMissingTableModel = new MissingTableModel(this, pTrackCollection); @@ -34,11 +31,9 @@ void DlgMissing::clicked() { onShow(); } -void DlgMissing::onSearch(const QString& text) { - m_pMissingTableModel->search(text); -} - -void DlgMissing::setTrackTable(WTrackTableView* pTrackTableView, int paneId) { +void DlgMissing::setTrackTable(Library* pLibrary, + WTrackTableView* pTrackTableView, + int paneId) { connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); connect(pTrackTableView->selectionModel(), diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index c871b058db6..2de7738e518 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -11,17 +11,16 @@ class WTrackTableView; class MissingTableModel; -class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { +class DlgMissing : public QWidget, public Ui::DlgMissing { Q_OBJECT public: - DlgMissing(QWidget* parent, UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, - KeyboardEventFilter* pKeyboard); + DlgMissing(QWidget* parent, TrackCollection* pTrackCollection); virtual ~DlgMissing(); void onShow(); - void onSearch(const QString& text); - void setTrackTable(WTrackTableView* pTrackTableView, int paneId); + void setTrackTable(Library *pLibrary, + WTrackTableView* pTrackTableView, + int paneId); inline void setFocusedPane(int focusedPane) { m_focusedPane = focusedPane; } @@ -30,14 +29,13 @@ class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { void clicked(); void selectAll(); void selectionChanged(const QItemSelection&, const QItemSelection&); - void setTrackTableFont(const QFont& font); - void setTrackTableRowHeight(int rowHeight); signals: void trackSelected(TrackPointer pTrack); private: void activateButtons(bool enable); + MissingTableModel* m_pMissingTableModel; QHash m_trackTableView; int m_focusedPane; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 73d3c034645..0fa45c2543b 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -97,6 +97,10 @@ void LibraryPaneManager::slotSwitchToView(const QString& view) { m_pPaneWidget->setFocus(); } +void LibraryPaneManager::slotSwitchToView(LibraryFeature *pFeature) { + +} + void LibraryPaneManager::slotRestoreSearch(const QString& text) { emit(restoreSearch(text)); } diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 5bccb64deca..b6605aaeb97 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -19,6 +19,7 @@ #include "sources/soundsourceproxy.h" #include "widget/wlibrary.h" #include "widget/wlibrarystack.h" +#include "widget/wlibrarysidebar.h" #include "util/dnd.h" const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = "MixxxLibraryFeature"; @@ -28,14 +29,12 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, QObject* parent, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, parent), - kMissingTitle(tr("Missing Tracks")), - kHiddenTitle(tr("Hidden Tracks")), kLibraryTitle(tr("Library")), - m_pLibrary(pLibrary), - m_pMissingView(NULL), - m_pHiddenView(NULL), + kHiddenTitle(tr("Hidden Tracks")), + kMissingTitle(tr("Missing Tracks")), + m_pHiddenView(nullptr), + m_pMissingView(nullptr), m_trackDao(pTrackCollection->getTrackDAO()), - m_pConfig(pConfig), m_pTrackCollection(pTrackCollection) { QStringList columns; columns << "library." + LIBRARYTABLE_ID @@ -133,23 +132,39 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { } void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, int) { - m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, - m_pTrackCollection, pKeyboard); - pLibraryWidget->registerView(kHiddenTitle, m_pHiddenView); - connect(m_pHiddenView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - - m_pMissingView = new DlgMissing(pLibraryWidget, m_pConfig, m_pLibrary, - m_pTrackCollection, pKeyboard); - pLibraryWidget->registerView(kMissingTitle, m_pMissingView); - connect(m_pMissingView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); + KeyboardEventFilter* pKeyboard, + int paneId) { + WLibraryStack* pStack = new WLibraryStack(pLibraryWidget); + m_pPaneStack = pStack; + + WTrackTableView* pHiddenTable = + new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); + pHiddenTable->installEventFilter(pKeyboard); + m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); + + if (m_pHiddenView) { + m_pHiddenView->setTrackTable(m_pLibrary, pHiddenTable, paneId); + } else { + m_hiddenPane[paneId] = pHiddenTable; + } + + WTrackTableView* pMissingTable = + new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); + pMissingTable->installEventFilter(pKeyboard); + m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); + + if (m_pMissingView) { + m_pMissingView->setTrackTable(m_pLibrary, pMissingTable, paneId); + } else { + m_missingPane[paneId] = pMissingTable; + } + pLibraryWidget->registerView(m_sMixxxLibraryViewName, pStack); } QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WLibraryStack* pStack = new WLibraryStack(nullptr); + m_pPaneStack = pStack; WTrackTableView* pHiddenTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); @@ -165,26 +180,67 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, WTrackTableView* pMissingTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); pMissingTable->installEventFilter(pKeyboard); - m_missingPane[paneId] = pMissingTable; - m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); + m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); + + if (m_pMissingView) { + m_pMissingView->setTrackTable(m_pLibrary, pMissingTable, paneId); + } else { + m_missingPane[paneId] = pMissingTable; + } return pStack; } void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, - KeyboardEventFilter*, - int paneId) { - m_pHiddenView = new DlgHidden(pLibraryWidget, m_pConfig, m_pLibrary, - m_pTrackCollection, pKeyboard); - pLibraryWidget->registerView(kHiddenTitle, m_pHiddenView); + KeyboardEventFilter*) { + QTabWidget* pTab = new QTabWidget(pLibraryWidget); + + // Create tree + WLibrarySidebar* pSidebar = new WLibrarySidebar(pTab); + pSidebar->setModel(&m_childModel); + + // Tree connections + connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), + this, SLOT(activateChild(const QModelIndex&))); + connect(pSidebar, SIGNAL(doubleClicked(const QModelIndex&)), + this, SLOT(onLazyChildExpandation(const QModelIndex&))); + connect(pSidebar, SIGNAL(rightClicked(const QPoint&, const QModelIndex&)), + this, SLOT(onRightClickChild(const QPoint&, const QModelIndex&))); + connect(pSidebar, SIGNAL(expanded(const QModelIndex&)), + this, SLOT(onLazyChildExpandation(const QModelIndex&))); + + pTab->addTab(pSidebar, tr("Tree")); + + // Create tabs + QStackedWidget* pStack = new QStackedWidget(pTab); + m_pExpandedStack = pStack; + + // Create Hidden View controls + m_pHiddenView = new DlgHidden(pLibraryWidget, m_pTrackCollection); + m_hiddenExpandedId = pStack->addWidget(m_pHiddenView); connect(m_pHiddenView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); + + // Add Track tables to Hidden view + for (auto it = m_hiddenPane.begin(); it != m_hiddenPane.end(); ++it) { + m_pHiddenView->setTrackTable(m_pLibrary, it.value(), it.key()); + } + m_hiddenPane.clear(); - m_pMissingView = new DlgMissing(pLibraryWidget, m_pConfig, m_pLibrary, - m_pTrackCollection, pKeyboard); - pLibraryWidget->registerView(kMissingTitle, m_pMissingView); + // Create Missing View controls + m_pMissingView = new DlgMissing(pLibraryWidget, m_pTrackCollection); + m_missingExpandedId = pStack->addWidget(m_pMissingView); connect(m_pMissingView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); + + // Add Track tables to Missing view + for (auto it = m_missingPane.begin(); it != m_missingPane.end(); ++it) { + m_pMissingView->setTrackTable(m_pLibrary, it.value(), it.key()); + } + m_missingPane.clear(); + + pTab->addTab(pStack, tr("Controls")); + pLibraryWidget->registerView(m_sMixxxLibraryViewName, pTab); } QVariant MixxxLibraryFeature::title() { @@ -214,7 +270,7 @@ void MixxxLibraryFeature::refreshLibraryModels() { void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; m_pHiddenView->setFocusedPane(m_featureFocus); - + m_pMissingView->setFocusedPane(m_featureFocus); emit(switchToView(m_sMixxxLibraryViewName)); emit(showTrackModel(m_pLibraryTableModel)); @@ -225,11 +281,11 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); if (itemName == m_sMixxxLibraryViewName) { activate(); - return; + } else if (itemName == kHiddenTitle) { + + } else if (itemName == kMissingTitle) { + } - - emit(switchToView(itemName)); - emit(enableCoverArtDisplay(true)); } bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 0882b383d8f..754fd9e99fa 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -10,9 +10,9 @@ #include #include #include -#include #include -#include +#include +#include #include #include "library/libraryfeature.h" @@ -43,11 +43,10 @@ class MixxxLibraryFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); void bindPaneWidget(WLibrary* pLibrary, - KeyboardEventFilter* pKeyboard, int); + KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary* pLibraryWidget, - KeyboardEventFilter*, - int paneId); + KeyboardEventFilter*); inline QString getViewName() { return m_sMixxxLibraryViewName; @@ -59,22 +58,28 @@ class MixxxLibraryFeature : public LibraryFeature { void refreshLibraryModels(); private: - const QString kMissingTitle; - const QString kHiddenTitle; const QString kLibraryTitle; + const QString kHiddenTitle; + const QString kMissingTitle; QPointer m_pHiddenView; QPointer m_pMissingView; - QHash m_hiddenPaneId; - QHash m_missingPaneId; QHash m_hiddenPane; QHash m_missingPane; - Library* m_pLibrary; + // This is needed to select the correct widget in the 2 size widget stack + // for the hidden and missing widgets. + QHash m_hiddenPaneId; + QHash m_missingPaneId; + int m_hiddenExpandedId; + int m_missingExpandedId; + + QStackedWidget* m_pPaneStack; + QStackedWidget* m_pExpandedStack; + QSharedPointer m_pBaseTrackCache; LibraryTableModel* m_pLibraryTableModel; TreeItemModel m_childModel; TrackDAO& m_trackDao; - UserSettingsPointer m_pConfig; TrackCollection* m_pTrackCollection; static const QString m_sMixxxLibraryViewName; }; From 864461718c40515543f4e89703b2f9ec09386bbb Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 08:47:27 +0200 Subject: [PATCH 179/552] Fixed some bugs in Mixx Library controls --- src/library/mixxxlibraryfeature.cpp | 23 ++++++++++++++--------- src/library/mixxxlibraryfeature.h | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index b6605aaeb97..1987fda66bd 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -135,7 +135,7 @@ void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId) { WLibraryStack* pStack = new WLibraryStack(pLibraryWidget); - m_pPaneStack = pStack; + m_paneStack[paneId] = pStack; WTrackTableView* pHiddenTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); @@ -164,7 +164,7 @@ void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WLibraryStack* pStack = new WLibraryStack(nullptr); - m_pPaneStack = pStack; + m_paneStack[paneId] = pStack; WTrackTableView* pHiddenTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); @@ -212,12 +212,11 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, pTab->addTab(pSidebar, tr("Tree")); // Create tabs - QStackedWidget* pStack = new QStackedWidget(pTab); - m_pExpandedStack = pStack; + m_pExpandedStack = new QStackedWidget(pTab); // Create Hidden View controls m_pHiddenView = new DlgHidden(pLibraryWidget, m_pTrackCollection); - m_hiddenExpandedId = pStack->addWidget(m_pHiddenView); + m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); connect(m_pHiddenView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); @@ -229,7 +228,7 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, // Create Missing View controls m_pMissingView = new DlgMissing(pLibraryWidget, m_pTrackCollection); - m_missingExpandedId = pStack->addWidget(m_pMissingView); + m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); connect(m_pMissingView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); @@ -239,7 +238,7 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, } m_missingPane.clear(); - pTab->addTab(pStack, tr("Controls")); + pTab->addTab(m_pExpandedStack, tr("Controls")); pLibraryWidget->registerView(m_sMixxxLibraryViewName, pTab); } @@ -282,9 +281,15 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { if (itemName == m_sMixxxLibraryViewName) { activate(); } else if (itemName == kHiddenTitle) { - + m_paneStack[m_featureFocus]->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); + m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); + emit(switchToView(m_sMixxxLibraryViewName)); + emit(enableCoverArtDisplay(true)); } else if (itemName == kMissingTitle) { - + m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); + m_pExpandedStack->setCurrentIndex(m_missingExpandedId); + emit(switchToView(m_sMixxxLibraryViewName)); + emit(enableCoverArtDisplay(true)); } } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 754fd9e99fa..1ebcc3a2e44 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -73,7 +73,7 @@ class MixxxLibraryFeature : public LibraryFeature { int m_hiddenExpandedId; int m_missingExpandedId; - QStackedWidget* m_pPaneStack; + QHash m_paneStack; QStackedWidget* m_pExpandedStack; QSharedPointer m_pBaseTrackCache; From 1823a2b4fc7d06efe281a4555dc4dea42817f8bb Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 10:39:03 +0200 Subject: [PATCH 180/552] Add slotSwitchToVie with feature pointer --- src/library/library.cpp | 17 +++++++++++++---- src/library/librarypanemanager.cpp | 11 ++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index daa6379a05f..cc002b9928f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -251,6 +251,19 @@ void Library::slotSwitchToView(const QString& view) { emit(switchToView(view)); } +void Library::slotSwitchToView(LibraryFeature* pFeature) { + m_pSidebarExpanded->slotSwitchToView(pFeature); + + WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); + // Only change the current pane if it's not shown already + if (pWLibrary->getCurrentViewName() != pFeature->getViewName()) { + m_panes[m_focusedPane]->slotSwitchToView(pFeature); + } + + handleFocus(); +} + + void Library::slotSwitchToViewChild(const QString &view) { //qDebug() << "Library::slotSwitchToViewChild"; m_panes[m_focusedPane]->slotSwitchToView(view); @@ -556,7 +569,3 @@ void Library::handleFocus() { } } } - -void Library::slotSwitchToView(LibraryFeature* pFeature) { - -} diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 0fa45c2543b..f3ce020032e 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -34,6 +34,10 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, } for (LibraryFeature* f : m_features) { f->bindPaneWidget(lib, pKeyboard, m_paneId); + + //QWidget* pPane = f->createPaneWidget(pKeyboard, m_paneId); + //pPane->setParent(lib); + //lib->registerView(f->getViewName(), pPane); } } @@ -97,8 +101,13 @@ void LibraryPaneManager::slotSwitchToView(const QString& view) { m_pPaneWidget->setFocus(); } -void LibraryPaneManager::slotSwitchToView(LibraryFeature *pFeature) { +void LibraryPaneManager::slotSwitchToView(LibraryFeature* pFeature) { + if (!m_featuresWidget.contains(pFeature)) { + return; + } + int widgetId = m_featuresWidget[pFeature]; + m_pPaneWidget->setCurrentIndex(widgetId); } void LibraryPaneManager::slotRestoreSearch(const QString& text) { From 9e63ff0dfd01e734a60b247d8bc1162e88dc4d5a Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 10:55:31 +0200 Subject: [PATCH 181/552] Fix Recording feature not working properly --- src/library/libraryfeature.h | 2 + src/library/recording/dlgrecording.cpp | 70 +++--------------- src/library/recording/dlgrecording.h | 31 +++----- src/library/recording/dlgrecording.ui | 78 ++++---------------- src/library/recording/recordingfeature.cpp | 82 +++++++++++++++------- src/library/recording/recordingfeature.h | 18 ++--- 6 files changed, 98 insertions(+), 183 deletions(-) diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index d96a4249a29..2d45280dbba 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -58,6 +58,8 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget // at the right pane. + // TODO(jmigual): This function should be removed and replaced by the + // createPaneWidget function virtual void bindPaneWidget(WLibrary* /* libraryWidget */, KeyboardEventFilter* /* keyboard */, int /* paneId */) { diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index 019a4c32b18..68c8f721895 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -8,11 +8,9 @@ #include "widget/wtracktableview.h" #include "util/assert.h" -DlgRecording::DlgRecording(QWidget* parent, UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, - RecordingManager* pRecordingManager, KeyboardEventFilter* pKeyboard) +DlgRecording::DlgRecording(QWidget* parent, TrackCollection* pTrackCollection, + RecordingManager* pRecordingManager) : QWidget(parent), - m_pConfig(pConfig), m_pTrackCollection(pTrackCollection), m_browseModel(this, m_pTrackCollection, pRecordingManager), m_proxyModel(&m_browseModel), @@ -20,17 +18,6 @@ DlgRecording::DlgRecording(QWidget* parent, UserSettingsPointer pConfig, m_durationRecordedStr("--:--"), m_pRecordingManager(pRecordingManager) { setupUi(this); - m_pTrackTableView = new WTrackTableView(this, pConfig, m_pTrackCollection, false); // No sorting - m_pTrackTableView->installEventFilter(pKeyboard); - - connect(m_pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(m_pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); - connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), - m_pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), - m_pTrackTableView, SLOT(setTrackTableRowHeight(int))); connect(m_pRecordingManager, SIGNAL(isRecording(bool)), this, SLOT(slotRecordingEnabled(bool))); @@ -39,21 +26,12 @@ DlgRecording::DlgRecording(QWidget* parent, UserSettingsPointer pConfig, connect(m_pRecordingManager, SIGNAL(durationRecorded(QString)), this, SLOT(slotDurationRecorded(QString))); - QBoxLayout* box = dynamic_cast(layout()); - DEBUG_ASSERT_AND_HANDLE(box) { //Assumes the form layout is a QVBox/QHBoxLayout! - } else { - box->removeWidget(m_pTrackTablePlaceholder); - m_pTrackTablePlaceholder->hide(); - box->insertWidget(1, m_pTrackTableView); - } - m_recordingDir = m_pRecordingManager->getRecordingDir(); m_proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); m_proxyModel.setSortCaseSensitivity(Qt::CaseInsensitive); m_browseModel.setPath(m_recordingDir); - m_pTrackTableView->loadTrackModel(&m_proxyModel); connect(pushButtonRecording, SIGNAL(toggled(bool)), this, SLOT(toggleRecording(bool))); @@ -69,36 +47,16 @@ void DlgRecording::onShow() { m_browseModel.setPath(m_recordingDir); } -void DlgRecording::refreshBrowseModel() { - m_browseModel.setPath(m_recordingDir); -} - -void DlgRecording::onSearch(const QString& text) { - m_proxyModel.search(text); -} - -void DlgRecording::slotRestoreSearch() { - emit(restoreSearch(currentSearch())); -} - -void DlgRecording::loadSelectedTrack() { - m_pTrackTableView->loadSelectedTrack(); -} - -void DlgRecording::slotSendToAutoDJ() { - m_pTrackTableView->slotSendToAutoDJ(); -} - -void DlgRecording::slotSendToAutoDJTop() { - m_pTrackTableView->slotSendToAutoDJTop(); -} - -void DlgRecording::loadSelectedTrackToGroup(QString group, bool play) { - m_pTrackTableView->loadSelectedTrackToGroup(group, play); +void DlgRecording::setTrackTable(WTrackTableView* pTrackTableView) { + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), + this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); + pTrackTableView->loadTrackModel(&m_proxyModel); } -void DlgRecording::moveSelection(int delta) { - m_pTrackTableView->moveSelection(delta); +void DlgRecording::refreshBrowseModel() { + m_browseModel.setPath(m_recordingDir); } void DlgRecording::toggleRecording(bool toggle) { @@ -149,11 +107,3 @@ void DlgRecording::refreshLabel() { .arg(m_durationRecordedStr); label->setText(text); } - -void DlgRecording::setTrackTableFont(const QFont& font) { - m_pTrackTableView->setTrackTableFont(font); -} - -void DlgRecording::setTrackTableRowHeight(int rowHeight) { - m_pTrackTableView->setTrackTableRowHeight(rowHeight); -} diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index 0f8db1f42ad..5a2788b9794 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -16,47 +16,32 @@ class PlaylistTableModel; class QSqlTableModel; class WTrackTableView; -class DlgRecording : public QWidget, public Ui::DlgRecording, public virtual LibraryView { +class DlgRecording : public QWidget, public Ui::DlgRecording { Q_OBJECT public: - DlgRecording(QWidget *parent, UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, - RecordingManager* pRecManager, KeyboardEventFilter* pKeyboard); + DlgRecording(QWidget *parent, TrackCollection* pTrackCollection, + RecordingManager* pRecManager); virtual ~DlgRecording(); - virtual void onSearch(const QString& text); virtual void onShow(); - virtual void loadSelectedTrack(); - virtual void slotSendToAutoDJ(); - virtual void slotSendToAutoDJTop(); - virtual void loadSelectedTrackToGroup(QString group, bool play); - virtual void moveSelection(int delta); - inline const QString currentSearch() { return m_proxyModel.currentSearch(); } + void setTrackTable(WTrackTableView* pTrackTableView); public slots: void toggleRecording(bool toggle); void slotRecordingEnabled(bool); void slotBytesRecorded(long); void refreshBrowseModel(); - void slotRestoreSearch(); void slotDurationRecorded(QString durationRecorded); - void setTrackTableFont(const QFont& font); - void setTrackTableRowHeight(int rowHeight); - - signals: - void loadTrack(TrackPointer tio); - void loadTrackToPlayer(TrackPointer tio, QString group, bool play); - void restoreSearch(QString search); - + private: - UserSettingsPointer m_pConfig; + void refreshLabel(); + TrackCollection* m_pTrackCollection; - WTrackTableView* m_pTrackTableView; BrowseTableModel m_browseModel; ProxyTrackModel m_proxyModel; QString m_recordingDir; + QHash m_TrackTableView; - void refreshLabel(); QString m_bytesRecordedStr; QString m_durationRecordedStr; diff --git a/src/library/recording/dlgrecording.ui b/src/library/recording/dlgrecording.ui index b9420593637..e1ae5c4b0d8 100644 --- a/src/library/recording/dlgrecording.ui +++ b/src/library/recording/dlgrecording.ui @@ -6,81 +6,27 @@ 0 0 - 582 - 399 + 186 + 43 Recordings - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + - - - 0 + + + Status: - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Status: - - - - - - - Start Recording - - - true - - - - + - - + + + Start Recording + + true diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 82a3590f531..5178a5ddce4 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -12,17 +12,15 @@ const QString RecordingFeature::m_sRecordingViewName = QString("Recording"); -RecordingFeature::RecordingFeature( - UserSettingsPointer pConfig, +RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) : LibraryFeature(pConfig, pLibrary, parent), - m_pConfig(pConfig), - m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), - m_pRecordingManager(pRecordingManager) { + m_pRecordingManager(pRecordingManager), + m_pRecordingView(nullptr) { } RecordingFeature::~RecordingFeature() { @@ -41,34 +39,66 @@ TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter *keyboard, int) { - //The view will be deleted by LibraryWidget - DlgRecording* pRecordingView = new DlgRecording(pLibraryWidget, - m_pConfig, - m_pLibrary, - m_pTrackCollection, - m_pRecordingManager, - keyboard); + KeyboardEventFilter *pKeyboard, int) { + + WTrackTableView* pTrackTableView = + new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection, false); // No sorting + pTrackTableView->installEventFilter(pKeyboard); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), + this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); + + pLibraryWidget->registerView(m_sRecordingViewName, pTrackTableView); + + if (m_pRecordingView) { + m_pRecordingView->setTrackTable(pTrackTableView); + } +} - pRecordingView->installEventFilter(keyboard); - pLibraryWidget->registerView(m_sRecordingViewName, pRecordingView); - connect(pRecordingView, SIGNAL(loadTrack(TrackPointer)), +QWidget *RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { + WTrackTableView* pTrackTableView = + new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); // No sorting + pTrackTableView->installEventFilter(pKeyboard); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); - connect(pRecordingView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); + connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), + this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); + + if (m_pRecordingView) { + m_pRecordingView->setTrackTable(pTrackTableView); + } + + return pTrackTableView; +} + +void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, + KeyboardEventFilter* pKeyboard) { + m_pRecordingView = new DlgRecording(nullptr, + m_pTrackCollection, + m_pRecordingManager); + m_pRecordingView->installEventFilter(pKeyboard); + connect(this, SIGNAL(refreshBrowseModel()), - pRecordingView, SLOT(refreshBrowseModel())); - connect(this, SIGNAL(requestRestoreSearch()), - pRecordingView, SLOT(slotRestoreSearch())); - connect(pRecordingView, SIGNAL(restoreSearch(QString)), - this, SIGNAL(restoreSearch(QString))); + m_pRecordingView, SLOT(refreshBrowseModel())); + pBaseLibrary->registerView(m_sRecordingViewName, m_pRecordingView); } void RecordingFeature::activate() { - emit(refreshBrowseModel()); + m_pRecordingView->refreshBrowseModel(); emit(switchToView(m_sRecordingViewName)); - // Ask the view to emit a restoreSearch signal. - emit(requestRestoreSearch()); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 2a1759059db..bb906edfe55 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -14,14 +14,14 @@ #include "library/proxytrackmodel.h" #include "recording/recordingmanager.h" -class Library; class TrackCollection; +class WTrackTableView; +class DlgRecording; class RecordingFeature : public LibraryFeature { Q_OBJECT public: - RecordingFeature( - UserSettingsPointer pConfig, + RecordingFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection, @@ -32,10 +32,13 @@ class RecordingFeature : public LibraryFeature { QIcon getIcon(); void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int); + KeyboardEventFilter* pKeyboard, int); + QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); inline QString getViewName() { return m_sRecordingViewName; } + void bindSidebarWidget(WBaseLibrary* pBaseLibrary, + KeyboardEventFilter* pKeyboard); TreeItemModel* getChildModel(); @@ -44,16 +47,15 @@ class RecordingFeature : public LibraryFeature { signals: void setRootIndex(const QModelIndex&); - void requestRestoreSearch(); - void refreshBrowseModel(); private: - UserSettingsPointer m_pConfig; - Library* m_pLibrary; TrackCollection* m_pTrackCollection; FolderTreeModel m_childModel; const static QString m_sRecordingViewName; RecordingManager* m_pRecordingManager; + + QHash m_trackTables; + QPointer m_pRecordingView; }; #endif From 345ea5b55fcee9b8db7baedbe50e465fba90b423 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 12:08:48 +0200 Subject: [PATCH 182/552] Fix some CSS issues with Library in LateNight --- res/skins/LateNight/style.qss | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 0adde6399ae..b4492a2745a 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1209,16 +1209,11 @@ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); } -#LibrarySidebarExpanded QScrollArea QPushButton { - padding: 3px !important; -} - #LibrarySidebarExpanded QWidget:!enabled { color: #666666; } -#LibrarySidebarButtons QToolButton, -#LibrarySidebarExpanded QPushButton { +#LibrarySidebarButtons QToolButton { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border: none; @@ -1226,10 +1221,17 @@ background-color: #191919; } +#LibrarySidebarExpanded QPushButton { + margin: 2px 3px 2px 3px; + padding: 4px 6px; + min-width: 65px; + border: none; + color: #cfb32c; + background-color: #191919; +} + #LibrarySidebarButtons QToolButton:hover, #LibrarySidebarExpanded QPushButton:hover { - margin: 0px 0px 0px 0px; - padding: 0px 0px 0px 0px; border: 1px solid #585858; background-color: #232323; border-radius: 2px; @@ -1379,21 +1381,14 @@ WBaseLibrary QRadioButton, WBaseLibrary QLabel { margin: 9px 3px 6px 3px; } WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } */ /* Additional space for the QPushButtons */ -#DlgMissing > QPushButton, +/*#DlgMissing > QPushButton, #DlgHidden > QPushButton, #DlgRecording > QPushButton, #DlgAnalysis > QPushButton { margin: 2px 3px 2px 3px; padding: 4px 6px; min-width: 65px; -} - -#DlgMissing > QPushButton:!enabled, -#DlgHidden > QPushButton:!enabled, -#DlgRecording > QPushButton:!enabled, -#DlgAnalysis > QPushButton:!enabled { - color: #666666; -} +}*/ /* Spacing between treeview and searchbar */ QTreeView { margin: 0px 0px 0px 0px; } From 966ecfe2df2d5ed31de29961ec458988c79560db Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 12:09:24 +0200 Subject: [PATCH 183/552] Fix that pane was not taking in account Feature's search --- src/library/librarypanemanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index f3ce020032e..7b737ff63b7 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -58,6 +58,8 @@ void LibraryPaneManager::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; } + connect(feature, SIGNAL(restoreSearch(const QString&)), + this, SIGNAL(restoreSearch(const QString&))); m_features.append(feature); } From 6bafc5862aec6a5b8d870d80d1dbeabe815d36ab Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 12:09:41 +0200 Subject: [PATCH 184/552] Finish recording feature moving to the SidebarExpanded --- src/library/recording/dlgrecording.ui | 32 ++++++++++++++++------ src/library/recording/recordingfeature.cpp | 18 ++++++++++-- src/library/recording/recordingfeature.h | 8 +++--- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/library/recording/dlgrecording.ui b/src/library/recording/dlgrecording.ui index e1ae5c4b0d8..895adc9ac48 100644 --- a/src/library/recording/dlgrecording.ui +++ b/src/library/recording/dlgrecording.ui @@ -6,31 +6,47 @@ 0 0 - 186 - 43 + 391 + 322 Recordings - + - + - Status: + Start Recording + + + true - + - Start Recording + Status: - + true + + + + Qt::Vertical + + + + 20 + 247 + + + + diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 5178a5ddce4..53e01bc4c4d 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -38,6 +38,7 @@ QIcon RecordingFeature::getIcon() { TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } + void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter *pKeyboard, int) { @@ -59,12 +60,16 @@ void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, if (m_pRecordingView) { m_pRecordingView->setTrackTable(pTrackTableView); + } else { + m_trackTables.append(pTrackTableView); } } QWidget *RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { - WTrackTableView* pTrackTableView = - new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); // No sorting + WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, + m_pConfig, + m_pTrackCollection, + false); // No sorting pTrackTableView->installEventFilter(pKeyboard); connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), @@ -79,6 +84,8 @@ QWidget *RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) if (m_pRecordingView) { m_pRecordingView->setTrackTable(pTrackTableView); + } else { + m_trackTables.append(pTrackTableView); } return pTrackTableView; @@ -93,6 +100,12 @@ void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, connect(this, SIGNAL(refreshBrowseModel()), m_pRecordingView, SLOT(refreshBrowseModel())); + + for (WTrackTableView* pTable : m_trackTables) { + m_pRecordingView->setTrackTable(pTable); + } + m_trackTables.clear(); + pBaseLibrary->registerView(m_sRecordingViewName, m_pRecordingView); } @@ -100,5 +113,6 @@ void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, void RecordingFeature::activate() { m_pRecordingView->refreshBrowseModel(); emit(switchToView(m_sRecordingViewName)); + emit(restoreSearch("")); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index bb906edfe55..7f0f0312660 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,13 +30,13 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); + inline QString getViewName() { + return m_sRecordingViewName; + } void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard, int); QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); - inline QString getViewName() { - return m_sRecordingViewName; - } void bindSidebarWidget(WBaseLibrary* pBaseLibrary, KeyboardEventFilter* pKeyboard); @@ -54,7 +54,7 @@ class RecordingFeature : public LibraryFeature { const static QString m_sRecordingViewName; RecordingManager* m_pRecordingManager; - QHash m_trackTables; + QList m_trackTables; QPointer m_pRecordingView; }; From e9a9b9960269bd020cbdd102d300dde74dfcdbf6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 16:04:31 +0200 Subject: [PATCH 185/552] Begin of createSidebar function implementation --- src/library/libraryfeature.cpp | 35 +++++++++++++++++++++------------- src/library/libraryfeature.h | 5 +++-- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 588b3b2891d..4cd0a9cfbdb 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -30,17 +30,22 @@ LibraryFeature::~LibraryFeature() { } -void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter *) { - TreeItemModel* pTreeModel = getChildModel(); - //qDebug() << "LibraryFeature::bindSidebarWidget" << pTreeModel->rowCount(); - WLibrarySidebar* pSidebar = new WLibrarySidebar(pSidebarWidget); - pSidebarWidget->registerView(getViewName(), pSidebar); - //qDebug() << getViewName() << pTreeModel << pTreeModel->hasChildren(); - - if (pTreeModel == nullptr) { +void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, + KeyboardEventFilter* pKeyboard) { + QWidget* pSidebar = createSidebarWidget(pKeyboard); + if (pSidebar == nullptr) { return; } - + + pSidebar->setParent(pSidebarWidget); + pSidebarWidget->registerView(getViewName(), pSidebar); +} + +QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { + //qDebug() << "LibraryFeature::bindSidebarWidget"; + TreeItemModel* pTreeModel = getChildModel(); + WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); + pSidebar->installEventFilter(pKeyboard); pSidebar->setModel(pTreeModel); connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), @@ -51,6 +56,8 @@ void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEve this, SLOT(onRightClickChild(const QPoint&, const QModelIndex&))); connect(pSidebar, SIGNAL(expanded(const QModelIndex&)), this, SLOT(onLazyChildExpandation(const QModelIndex&))); + + return pSidebar; } void LibraryFeature::setFeatureFocus(int focus) { @@ -63,14 +70,16 @@ QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) { QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); QFileDialog dialogg(NULL, - tr("Import Playlist"), - lastPlaylistDirectory, - tr("Playlist Files (*.m3u *.m3u8 *.pls *.csv)")); + tr("Import Playlist"), + lastPlaylistDirectory, + tr("Playlist Files (*.m3u *.m3u8 *.pls *.csv)")); dialogg.setAcceptMode(QFileDialog::AcceptOpen); dialogg.setFileMode(mode); dialogg.setModal(true); // If the user refuses return - if (! dialogg.exec()) return QStringList(); + if (!dialogg.exec()) { + return QStringList(); + } return dialogg.selectedFiles(); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 2d45280dbba..82e3d2be2f2 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -65,7 +65,7 @@ class LibraryFeature : public QObject { int /* paneId */) { } - virtual QWidget* createPaneWidget(KeyboardEventFilter* /* keyboard */, + virtual QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int /* paneId */) { return nullptr; } @@ -73,7 +73,8 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane virtual void bindSidebarWidget(WBaseLibrary *pSidebarWidget, - KeyboardEventFilter*); + KeyboardEventFilter*pKeyboard); + virtual QWidget* createSidebarWidget(KeyboardEventFilter* /* keyboard */); virtual TreeItemModel* getChildModel() = 0; From 8f75941a9694d67c626ccf0c47047f1f74e25dff Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 16:04:49 +0200 Subject: [PATCH 186/552] Avoid passing table to DlgAnalysis --- src/library/analysisfeature.cpp | 74 ++++++++++++++++----------------- src/library/analysisfeature.h | 4 +- src/library/dlganalysis.cpp | 31 ++++---------- src/library/dlganalysis.h | 16 +++---- 4 files changed, 54 insertions(+), 71 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 67451405d93..a24133d777c 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -62,73 +62,62 @@ QIcon AnalysisFeature::getIcon() { void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard, - int paneId) { - - WAnalysisLibraryTableView* pTable = new WAnalysisLibraryTableView(libraryWidget, - m_pConfig, - m_pTrackCollection); - pTable->installEventFilter(pKeyboard); - - if (m_pAnalysisView) { - m_pAnalysisView->setAnalysisTableView(pTable, paneId); - } else { - m_analysisTables[paneId] = pTable; - } - - libraryWidget->registerView(m_sAnalysisViewName, pTable); + int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(libraryWidget); + libraryWidget->registerView(m_sAnalysisViewName, pPane); } QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WAnalysisLibraryTableView* pTable = new WAnalysisLibraryTableView(nullptr, - m_pConfig, - m_pTrackCollection); + WAnalysisLibraryTableView* pTable = + new WAnalysisLibraryTableView(nullptr, m_pConfig, m_pTrackCollection); pTable->installEventFilter(pKeyboard); - + + connect(pTable, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(pTable, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), + this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); + connect(pTable, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + + m_analysisTables[paneId] = pTable; if (m_pAnalysisView) { m_pAnalysisView->setAnalysisTableView(pTable, paneId); - } else { - m_analysisTables[paneId] = pTable; } return pTable; } void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, KeyboardEventFilter* pKeyboard) { + QWidget* pSidebar = createSidebarWidget(pKeyboard); + pSidebar->setParent(libraryWidget); + libraryWidget->registerView(m_sAnalysisViewName, pSidebar); +} + +QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { + m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); - m_pAnalysisView = new DlgAnalysis(libraryWidget, m_pTrackCollection); - connect(m_pAnalysisView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(m_pAnalysisView, SIGNAL(loadTrackToPlayer(TrackPointer,QString)), - this, SIGNAL(loadTrackToPlayer(TrackPointer,QString))); connect(m_pAnalysisView, SIGNAL(analyzeTracks(QList)), - this, SLOT(analyzeTracks(QList))); + this, SLOT(analyzeTracks(QList))); connect(m_pAnalysisView, SIGNAL(stopAnalysis()), - this, SLOT(stopAnalysis())); - - connect(m_pAnalysisView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); + this, SLOT(stopAnalysis())); connect(this, SIGNAL(analysisActive(bool)), - m_pAnalysisView, SLOT(analysisActive(bool))); + m_pAnalysisView, SLOT(analysisActive(bool))); connect(this, SIGNAL(trackAnalysisStarted(int)), - m_pAnalysisView, SLOT(trackAnalysisStarted(int))); + m_pAnalysisView, SLOT(trackAnalysisStarted(int))); m_pAnalysisView->installEventFilter(pKeyboard); - if (m_analysisTables.size() > 0) { - for (auto it = m_analysisTables.begin(); it != m_analysisTables.end(); ++it) { - m_pAnalysisView->setAnalysisTableView(it.value(), it.key()); - } - m_analysisTables.clear(); + for (auto it = m_analysisTables.begin(); it != m_analysisTables.end(); ++it) { + m_pAnalysisView->setAnalysisTableView(it.value(), it.key()); } // Let the DlgAnalysis know whether or not analysis is active. bool bAnalysisActive = m_pAnalyzerQueue != NULL; emit(analysisActive(bAnalysisActive)); - - libraryWidget->registerView(m_sAnalysisViewName, m_pAnalysisView); } TreeItemModel* AnalysisFeature::getChildModel() { @@ -213,6 +202,13 @@ void AnalysisFeature::cleanupAnalyzer() { } } +void AnalysisFeature::tableSelectionChanged(const QItemSelection&, + const QItemSelection&) { + WTrackTableView* pCurrent = m_analysisTables[m_featureFocus]; + const QModelIndexList &indexes = pCurrent->selectionModel()->selectedIndexes(); + m_pAnalysisView->setSelectedIndexes(indexes); +} + bool AnalysisFeature::dropAccept(QList urls, QObject* pSource) { Q_UNUSED(pSource); QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 61d6bbad94b..11adca9b775 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -42,7 +42,7 @@ class AnalysisFeature : public LibraryFeature { QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary* libraryWidget, KeyboardEventFilter*pKeyboard); - + QWidget* createSidebarWidget(KeyboardEventFilter* pKeyboard); TreeItemModel* getChildModel(); void refreshLibraryModels(); @@ -59,6 +59,8 @@ class AnalysisFeature : public LibraryFeature { void slotProgressUpdate(int num_left); void stopAnalysis(); void cleanupAnalyzer(); + void tableSelectionChanged(const QItemSelection&, + const QItemSelection&); private: // Sets the title of this feature to the default name, given by diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index e09e251323f..fa68bfba6c4 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -48,12 +48,6 @@ void DlgAnalysis::onShow() { m_pAnalysisLibraryTableModel->select(); } -void DlgAnalysis::tableSelectionChanged(const QItemSelection&, - const QItemSelection&) { - bool tracksSelected = m_analysisTable[m_focusedPane]->selectionModel()->hasSelection(); - pushButtonAnalyze->setEnabled(tracksSelected || m_bAnalysisActive); -} - void DlgAnalysis::selectAll() { m_analysisTable[m_focusedPane]->selectAll(); } @@ -64,8 +58,7 @@ void DlgAnalysis::analyze() { emit(stopAnalysis()); } else { QList trackIds; - QModelIndexList selectedIndexes = m_analysisTable[m_focusedPane]->selectionModel()->selectedRows(); - for (QModelIndex selectedIndex : selectedIndexes) { + for (QModelIndex selectedIndex : m_selectedIndexes) { TrackId trackId(selectedIndex.sibling( selectedIndex.row(), m_pAnalysisLibraryTableModel->fieldIndex(LIBRARYTABLE_ID)).data()); @@ -115,22 +108,14 @@ int DlgAnalysis::getNumTracks() { return m_tracksInQueue; } -void DlgAnalysis::setAnalysisTableView(WAnalysisLibraryTableView* pTable, int pane) { - m_analysisTable[pane] = pTable; - - connect(pTable, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTable, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); - - connect(pTable, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - +void DlgAnalysis::setAnalysisTableView(WAnalysisLibraryTableView* pTable) { pTable->loadTrackModel(m_pAnalysisLibraryTableModel); - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection&)), - this, - SLOT(tableSelectionChanged(const QItemSelection &, const QItemSelection&))); +} + +void DlgAnalysis::setSelectedIndexes(const QModelIndexList& selectedIndexes) { + m_selectedIndexes = selectedIndexes; + pushButtonAnalyze->setEnabled(m_selectedIndexes.size() > 0 || + m_bAnalysisActive); } void DlgAnalysis::trackAnalysisStarted(int size) { diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 116f87a4a8c..9e17f3ebf9a 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -13,8 +13,11 @@ class AnalysisLibraryTableModel; class WAnalysisLibraryTableView; class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { + Q_OBJECT + public: + DlgAnalysis(QWidget *parent, TrackCollection* pTrackCollection); virtual ~DlgAnalysis(); @@ -25,14 +28,14 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { } int getNumTracks(); - void setAnalysisTableView(WAnalysisLibraryTableView* pTable, int pane); + void setAnalysisTableView(WAnalysisLibraryTableView* pTable); inline void setFocusedPane(int pane) { m_focusedPane = pane; } + void setSelectedIndexes(const QModelIndexList& selectedIndexes); public slots: - void tableSelectionChanged(const QItemSelection&, - const QItemSelection&); + void selectAll(); void analyze(); void trackAnalysisFinished(int size); @@ -43,11 +46,9 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { void analysisActive(bool bActive); signals: - void loadTrack(TrackPointer pTrack); - void loadTrackToPlayer(TrackPointer pTrack, QString player); + void analyzeTracks(QList trackIds); void stopAnalysis(); - void trackSelected(TrackPointer pTrack); private: //Note m_pTrackTablePlaceholder is defined in the .ui file @@ -57,9 +58,8 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { AnalysisLibraryTableModel* m_pAnalysisLibraryTableModel; int m_tracksInQueue; int m_currentTrack; - int m_focusedPane; - QHash m_analysisTable; + QModelIndexList m_selectedIndexes; }; #endif //DLGTRIAGE_H From 9f40c04e50378c960d0928ab6e1cc251fa903a76 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 19:47:01 +0200 Subject: [PATCH 187/552] Fix compilation issues --- src/library/analysisfeature.cpp | 16 ++++++++-------- src/library/analysisfeature.h | 1 + src/library/browse/browsefeature.cpp | 4 +++- src/library/browse/browsefeature.h | 2 +- src/library/dlganalysis.cpp | 9 ++------- src/library/dlganalysis.h | 5 +---- src/library/libraryfeature.h | 10 +++++----- src/library/libraryview.h | 8 ++++---- 8 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index a24133d777c..57ba6127a4c 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -83,9 +83,6 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, this, SIGNAL(trackSelected(TrackPointer))); m_analysisTables[paneId] = pTable; - if (m_pAnalysisView) { - m_pAnalysisView->setAnalysisTableView(pTable, paneId); - } return pTable; } @@ -103,6 +100,8 @@ QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { this, SLOT(analyzeTracks(QList))); connect(m_pAnalysisView, SIGNAL(stopAnalysis()), this, SLOT(stopAnalysis())); + connect(m_pAnalysisView, SIGNAL(selectAll()), + this, SLOT(selectAll())); connect(this, SIGNAL(analysisActive(bool)), m_pAnalysisView, SLOT(analysisActive(bool))); @@ -111,13 +110,11 @@ QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView->installEventFilter(pKeyboard); - for (auto it = m_analysisTables.begin(); it != m_analysisTables.end(); ++it) { - m_pAnalysisView->setAnalysisTableView(it.value(), it.key()); - } - // Let the DlgAnalysis know whether or not analysis is active. bool bAnalysisActive = m_pAnalyzerQueue != NULL; emit(analysisActive(bAnalysisActive)); + + return m_pAnalysisView; } TreeItemModel* AnalysisFeature::getChildModel() { @@ -130,11 +127,14 @@ void AnalysisFeature::refreshLibraryModels() { } } +void AnalysisFeature::selectAll() { + m_analysisTables[m_featureFocus]->selectAll(); +} + void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; emit(switchToView(m_sAnalysisViewName)); if (m_pAnalysisView) { - m_pAnalysisView->setFocusedPane(m_featureFocus); emit(restoreSearch(m_pAnalysisView->currentSearch())); } emit(enableCoverArtDisplay(true)); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 11adca9b775..4b46321627a 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -52,6 +52,7 @@ class AnalysisFeature : public LibraryFeature { void trackAnalysisStarted(int size); public slots: + void selectAll(); void activate(); void analyzeTracks(QList trackIds); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 6268f44cbad..c6b63f81039 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -222,9 +222,11 @@ void BrowseFeature::bindPaneWidget(WLibrary* libraryWidget, libraryWidget->registerView(m_sBrowseViewName, edit); } -QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter*, int) { +QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); edit->setHtml(getRootViewHtml()); + edit->installEventFilter(pKeyboard); + return edit; } void BrowseFeature::activate() { diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 1808a862d7d..80357b87281 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -39,7 +39,7 @@ class BrowseFeature : public LibraryFeature { virtual QString getViewName(); void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*, int); - QWidget* createPaneWidget(KeyboardEventFilter*, int); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index fa68bfba6c4..5a1a98c633e 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -13,8 +13,7 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, m_pTrackCollection(pTrackCollection), m_bAnalysisActive(false), m_tracksInQueue(0), - m_currentTrack(0), - m_focusedPane(-1) { + m_currentTrack(0) { setupUi(this); m_songsButtonGroup.addButton(radioButtonRecentlyAdded); m_songsButtonGroup.addButton(radioButtonAllSongs); @@ -36,7 +35,7 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, this, SLOT(analyze())); connect(pushButtonSelectAll, SIGNAL(clicked()), - this, SLOT(selectAll())); + this, SIGNAL(selectAll())); } DlgAnalysis::~DlgAnalysis() { @@ -48,10 +47,6 @@ void DlgAnalysis::onShow() { m_pAnalysisLibraryTableModel->select(); } -void DlgAnalysis::selectAll() { - m_analysisTable[m_focusedPane]->selectAll(); -} - void DlgAnalysis::analyze() { //qDebug() << this << "analyze()"; if (m_bAnalysisActive) { diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 9e17f3ebf9a..8ee9a9aa9ee 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -29,14 +29,10 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { int getNumTracks(); void setAnalysisTableView(WAnalysisLibraryTableView* pTable); - inline void setFocusedPane(int pane) { - m_focusedPane = pane; - } void setSelectedIndexes(const QModelIndexList& selectedIndexes); public slots: - void selectAll(); void analyze(); void trackAnalysisFinished(int size); void trackAnalysisProgress(int progress); @@ -49,6 +45,7 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { void analyzeTracks(QList trackIds); void stopAnalysis(); + void selectAll(); private: //Note m_pTrackTablePlaceholder is defined in the .ui file diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 82e3d2be2f2..009f088bcfc 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -8,16 +8,16 @@ #include #include -#include "track/track.h" -#include "treeitemmodel.h" +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/coverartcache.h" #include "library/dao/trackdao.h" #include "preferences/usersettings.h" +#include "track/track.h" +#include "treeitemmodel.h" class TrackModel; class WBaseLibrary; class WLibrary; -class KeyboardEventFilter; class Library; // pure virtual (abstract) class to provide an interface for libraryfeatures @@ -65,7 +65,7 @@ class LibraryFeature : public QObject { int /* paneId */) { } - virtual QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, + virtual QWidget* createPaneWidget(KeyboardEventFilter* /* keyboard */, int /* paneId */) { return nullptr; } @@ -74,7 +74,7 @@ class LibraryFeature : public QObject { // at the sidebar expanded pane virtual void bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter*pKeyboard); - virtual QWidget* createSidebarWidget(KeyboardEventFilter* /* keyboard */); + virtual QWidget* createSidebarWidget(KeyboardEventFilter* pKeyboard); virtual TreeItemModel* getChildModel() = 0; diff --git a/src/library/libraryview.h b/src/library/libraryview.h index 5ae34aee2fe..5eab3c40ec4 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -11,7 +11,7 @@ class LibraryView { public: - virtual ~LibraryView() {}; + virtual ~LibraryView() {} virtual void onShow() = 0; // reimplement if LibraryView should be able to search @@ -19,10 +19,10 @@ class LibraryView { // If applicable, requests that the LibraryView load the selected // track. Does nothing otherwise. - virtual void loadSelectedTrack() {}; + virtual void loadSelectedTrack() {} - virtual void slotSendToAutoDJ() {}; - virtual void slotSendToAutoDJTop() {}; + virtual void slotSendToAutoDJ() {} + virtual void slotSendToAutoDJTop() {} // If applicable, requests that the LibraryView load the selected track to // the specified group. Does nothing otherwise. From 21a3508fec425b8b2e962fce6c9f2d1380ea4b0e Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 23:00:12 +0200 Subject: [PATCH 188/552] Fixed some connections failing and removed redundant code --- src/library/analysisfeature.cpp | 37 +++++++++++++++++++--- src/library/analysisfeature.h | 1 + src/library/dlganalysis.cpp | 17 ++++++---- src/library/dlganalysis.h | 2 ++ src/library/dlghidden.cpp | 3 +- src/library/dlgmissing.cpp | 2 +- src/library/mixxxlibraryfeature.cpp | 30 +++--------------- src/library/recording/dlgrecording.cpp | 4 --- src/library/recording/recordingfeature.cpp | 34 +++----------------- src/library/recording/recordingfeature.h | 2 +- src/widget/wbreadcrumb.cpp | 36 ++++++++++----------- src/widget/wbreadcrumb.h | 4 --- 12 files changed, 76 insertions(+), 96 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 57ba6127a4c..6648f8d79ed 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -75,13 +75,27 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, new WAnalysisLibraryTableView(nullptr, m_pConfig, m_pTrackCollection); pTable->installEventFilter(pKeyboard); + if (m_pAnalysisLibraryTableModel) { + pTable->setModel(m_pAnalysisLibraryTableModel); + + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); + } + connect(pTable, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); connect(pTable, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); connect(pTable, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); + + if (m_pAnalysisLibraryTableModel) { + pTable->setModel(m_pAnalysisLibraryTableModel); + } + m_analysisTables[paneId] = pTable; return pTable; } @@ -96,6 +110,19 @@ void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); + m_pAnalysisLibraryTableModel = new AnalysisLibraryTableModel(this, m_pTrackCollection); + + for (WAnalysisLibraryTableView* pTable : m_analysisTables) { + pTable->setModel(m_pAnalysisLibraryTableModel); + + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); + } + + m_pAnalysisView->setTableModel(m_pAnalysisLibraryTableModel); + connect(m_pAnalysisView, SIGNAL(analyzeTracks(QList)), this, SLOT(analyzeTracks(QList))); connect(m_pAnalysisView, SIGNAL(stopAnalysis()), @@ -111,8 +138,9 @@ QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView->installEventFilter(pKeyboard); // Let the DlgAnalysis know whether or not analysis is active. - bool bAnalysisActive = m_pAnalyzerQueue != NULL; + bool bAnalysisActive = m_pAnalyzerQueue != nullptr; emit(analysisActive(bAnalysisActive)); + m_pAnalysisView->onShow(); return m_pAnalysisView; } @@ -185,7 +213,7 @@ void AnalysisFeature::slotProgressUpdate(int num_left) { void AnalysisFeature::stopAnalysis() { //qDebug() << this << "stopAnalysis()"; - if (m_pAnalyzerQueue != NULL) { + if (m_pAnalyzerQueue != nullptr) { m_pAnalyzerQueue->stop(); } } @@ -193,10 +221,10 @@ void AnalysisFeature::stopAnalysis() { void AnalysisFeature::cleanupAnalyzer() { setTitleDefault(); emit(analysisActive(false)); - if (m_pAnalyzerQueue != NULL) { + if (m_pAnalyzerQueue != nullptr) { m_pAnalyzerQueue->stop(); m_pAnalyzerQueue->deleteLater(); - m_pAnalyzerQueue = NULL; + m_pAnalyzerQueue = nullptr; // Restore old BPM detection setting for preferences... m_pConfig->set(ConfigKey("[BPM]","BPMDetectionEnabled"), ConfigValue(m_iOldBpmEnabled)); } @@ -204,6 +232,7 @@ void AnalysisFeature::cleanupAnalyzer() { void AnalysisFeature::tableSelectionChanged(const QItemSelection&, const QItemSelection&) { + qDebug() << "AnalysisFeature::tableSelectionChanged" << sender(); WTrackTableView* pCurrent = m_analysisTables[m_featureFocus]; const QModelIndexList &indexes = pCurrent->selectionModel()->selectedIndexes(); m_pAnalysisView->setSelectedIndexes(indexes); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 4b46321627a..1dbf8bfd7da 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -84,6 +84,7 @@ class AnalysisFeature : public LibraryFeature { const static QString m_sAnalysisViewName; QString m_analysisTitleName; QPointer m_pAnalysisView; + QPointer m_pAnalysisLibraryTableModel; QHash m_analysisTables; }; diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index 5a1a98c633e..aaabb57fbfb 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -18,17 +18,11 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, m_songsButtonGroup.addButton(radioButtonRecentlyAdded); m_songsButtonGroup.addButton(radioButtonAllSongs); - m_pAnalysisLibraryTableModel = new AnalysisLibraryTableModel(this, pTrackCollection); - connect(radioButtonRecentlyAdded, SIGNAL(clicked()), this, SLOT(showRecentSongs())); connect(radioButtonAllSongs, SIGNAL(clicked()), this, SLOT(showAllSongs())); - // TODO(rryan): This triggers a library search before the UI has even - // started up. Accounts for 0.2% of skin creation time. Get rid of this! - radioButtonRecentlyAdded->click(); - labelProgress->setText(""); pushButtonAnalyze->setEnabled(false); connect(pushButtonAnalyze, SIGNAL(clicked()), @@ -45,6 +39,10 @@ void DlgAnalysis::onShow() { // Refresh table // There might be new tracks dropped to other views m_pAnalysisLibraryTableModel->select(); + + // TODO(rryan): This triggers a library search before the UI has even + // started up. Accounts for 0.2% of skin creation time. Get rid of this! + radioButtonRecentlyAdded->click(); } void DlgAnalysis::analyze() { @@ -67,7 +65,7 @@ void DlgAnalysis::analyze() { } void DlgAnalysis::analysisActive(bool bActive) { - qDebug() << this << "analysisActive" << bActive; + //qDebug() << this << "analysisActive" << bActive; m_bAnalysisActive = bActive; if (bActive) { pushButtonAnalyze->setEnabled(true); @@ -108,11 +106,16 @@ void DlgAnalysis::setAnalysisTableView(WAnalysisLibraryTableView* pTable) { } void DlgAnalysis::setSelectedIndexes(const QModelIndexList& selectedIndexes) { + qDebug() << "DlgAnalysis::setSelectedIndexes" << selectedIndexes; m_selectedIndexes = selectedIndexes; pushButtonAnalyze->setEnabled(m_selectedIndexes.size() > 0 || m_bAnalysisActive); } +void DlgAnalysis::setTableModel(AnalysisLibraryTableModel *pTableModel) { + m_pAnalysisLibraryTableModel = pTableModel; +} + void DlgAnalysis::trackAnalysisStarted(int size) { m_tracksInQueue = size; } diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 8ee9a9aa9ee..08dd87e2ece 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -2,6 +2,7 @@ #define DLGANALYSIS_H #include +#include #include "preferences/usersettings.h" #include "library/analysislibrarytablemodel.h" @@ -30,6 +31,7 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { void setAnalysisTableView(WAnalysisLibraryTableView* pTable); void setSelectedIndexes(const QModelIndexList& selectedIndexes); + void setTableModel(AnalysisLibraryTableModel* pTableModel); public slots: diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 6d999e69e00..d79d21f846b 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -30,6 +30,8 @@ void DlgHidden::onShow() { } void DlgHidden::setTrackTable(Library* pLibrary, WTrackTableView *pTrackTableView, int paneId) { + pTrackTableView->loadTrackModel(m_pHiddenTableModel); + connect(btnUnhide, SIGNAL(clicked()), pTrackTableView, SLOT(slotUnhide())); connect(btnUnhide, SIGNAL(clicked()), @@ -46,7 +48,6 @@ void DlgHidden::setTrackTable(Library* pLibrary, WTrackTableView *pTrackTableVie pTrackTableView, SLOT(setTrackTableFont(QFont))); connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - pTrackTableView->loadTrackModel(m_pHiddenTableModel); m_trackTableView[paneId] = pTrackTableView; } diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 1426a6c4101..bc863eb8d0e 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -34,6 +34,7 @@ void DlgMissing::clicked() { void DlgMissing::setTrackTable(Library* pLibrary, WTrackTableView* pTrackTableView, int paneId) { + pTrackTableView->loadTrackModel(m_pMissingTableModel); connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); connect(pTrackTableView->selectionModel(), @@ -48,7 +49,6 @@ void DlgMissing::setTrackTable(Library* pLibrary, connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); - pTrackTableView->loadTrackModel(m_pMissingTableModel); m_trackTableView[paneId] = pTrackTableView; } diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 1987fda66bd..d0ba3fd9ae3 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -133,32 +133,10 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, - int paneId) { - WLibraryStack* pStack = new WLibraryStack(pLibraryWidget); - m_paneStack[paneId] = pStack; - - WTrackTableView* pHiddenTable = - new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); - pHiddenTable->installEventFilter(pKeyboard); - m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); - - if (m_pHiddenView) { - m_pHiddenView->setTrackTable(m_pLibrary, pHiddenTable, paneId); - } else { - m_hiddenPane[paneId] = pHiddenTable; - } - - WTrackTableView* pMissingTable = - new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); - pMissingTable->installEventFilter(pKeyboard); - m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); - - if (m_pMissingView) { - m_pMissingView->setTrackTable(m_pLibrary, pMissingTable, paneId); - } else { - m_missingPane[paneId] = pMissingTable; - } - pLibraryWidget->registerView(m_sMixxxLibraryViewName, pStack); + int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pLibraryWidget); + pLibraryWidget->registerView(m_sMixxxLibraryViewName, pPane); } QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index 68c8f721895..a2d62467b79 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -48,10 +48,6 @@ void DlgRecording::onShow() { } void DlgRecording::setTrackTable(WTrackTableView* pTrackTableView) { - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); pTrackTableView->loadTrackModel(&m_proxyModel); } diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 53e01bc4c4d..84738185672 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -40,32 +40,13 @@ TreeItemModel* RecordingFeature::getChildModel() { } void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter *pKeyboard, int) { - - WTrackTableView* pTrackTableView = - new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection, false); // No sorting - pTrackTableView->installEventFilter(pKeyboard); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); - - pLibraryWidget->registerView(m_sRecordingViewName, pTrackTableView); - - if (m_pRecordingView) { - m_pRecordingView->setTrackTable(pTrackTableView); - } else { - m_trackTables.append(pTrackTableView); - } + KeyboardEventFilter *pKeyboard, int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pLibraryWidget); + pLibraryWidget->registerView(m_sRecordingViewName, pPane); } -QWidget *RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { +QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, @@ -77,11 +58,6 @@ QWidget *RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); - if (m_pRecordingView) { m_pRecordingView->setTrackTable(pTrackTableView); } else { diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 7f0f0312660..5cfce664e0a 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -35,7 +35,7 @@ class RecordingFeature : public LibraryFeature { } void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard, int); + KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); void bindSidebarWidget(WBaseLibrary* pBaseLibrary, KeyboardEventFilter* pKeyboard); diff --git a/src/widget/wbreadcrumb.cpp b/src/widget/wbreadcrumb.cpp index 656edbb08f2..dd889156df4 100644 --- a/src/widget/wbreadcrumb.cpp +++ b/src/widget/wbreadcrumb.cpp @@ -1,32 +1,30 @@ -/* - * WBreadCrumb.cpp - * - * Created on: Jun 24, 2016 - * Author: joan - */ +#include #include +namespace { + +QString& getPathString(TreeItem* pTree) { + // Base case + if (pTree == nullptr) { + return QString(); + } + + // Recursive case + QString text = pTree->data().toString(); + QString& next = getData(pTree->parent()); + return (next.isEmpty() ? text : next % QLatin1Literal(" > ") % text); +} + +} + WBreadCrumb::WBreadCrumb(QWidget* parent) : QLabel(parent) { - } void WBreadCrumb::setBreadText(TreeItem *pTree) { QString text = getData(pTree); setText(text); } - -QString& WBreadCrumb::getData(TreeItem* pTree) { - // Base case - if (pTree == nullptr) { - return ""; - } - - // Recursive case - QString text = pTree->data().toString(); - QString next = getData(pTree->parent()); - return (next == "" ? text : next + " > " + text); -} diff --git a/src/widget/wbreadcrumb.h b/src/widget/wbreadcrumb.h index 03c31810f72..8f121e1e828 100644 --- a/src/widget/wbreadcrumb.h +++ b/src/widget/wbreadcrumb.h @@ -14,10 +14,6 @@ class WBreadCrumb: public QLabel { public slots: void setBreadText(TreeItem* pTree); - - private: - - static QString& getData(TreeItem* pTree); }; #endif /* SRC_WIDGET_WBREADCRUMB_H_ */ From 714e15c2eb7c337d186d069530436d44cdc7ec9b Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 23:29:08 +0200 Subject: [PATCH 189/552] Remove unnecessary table from DlgHidden and DlgMissing --- src/library/dlghidden.cpp | 45 ++++------------------ src/library/dlghidden.h | 14 ++----- src/library/dlgmissing.cpp | 43 ++++----------------- src/library/dlgmissing.h | 16 ++------ src/library/mixxxlibraryfeature.cpp | 60 ++++++++++++++++++++++------- src/library/mixxxlibraryfeature.h | 6 +++ 6 files changed, 75 insertions(+), 109 deletions(-) diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index d79d21f846b..858ee2d398a 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -7,12 +7,11 @@ DlgHidden::DlgHidden(QWidget* parent, TrackCollection* pTrackCollection) : QWidget(parent), - Ui::DlgHidden(), - m_focusedPane(-1) { + Ui::DlgHidden() { setupUi(this); - connect(btnPurge, SIGNAL(clicked()), this, SLOT(clicked())); - connect(btnSelect, SIGNAL(clicked()), this, SLOT(selectAll())); + connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); + connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); m_pHiddenTableModel = new HiddenTableModel(this, pTrackCollection); } @@ -29,46 +28,18 @@ void DlgHidden::onShow() { activateButtons(false); } -void DlgHidden::setTrackTable(Library* pLibrary, WTrackTableView *pTrackTableView, int paneId) { +void DlgHidden::setTrackTable(WTrackTableView *pTrackTableView) { pTrackTableView->loadTrackModel(m_pHiddenTableModel); - connect(btnUnhide, SIGNAL(clicked()), - pTrackTableView, SLOT(slotUnhide())); - connect(btnUnhide, SIGNAL(clicked()), - this, SLOT(clicked())); - connect(btnPurge, SIGNAL(clicked()), - pTrackTableView, SLOT(slotPurge())); - connect(pTrackTableView->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - m_trackTableView[paneId] = pTrackTableView; -} - -void DlgHidden::clicked() { - // all marked tracks are gone now anyway - onShow(); + connect(btnUnhide, SIGNAL(clicked()), pTrackTableView, SLOT(slotUnhide())); + connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); } -void DlgHidden::selectAll() { - if (m_trackTableView.contains(m_focusedPane)) { - m_trackTableView[m_focusedPane]->selectAll(); - } +void DlgHidden::setSelectedIndexes(const QModelIndexList& selectedIndexes) { + activateButtons(!selectedIndexes.empty()); } void DlgHidden::activateButtons(bool enable) { btnPurge->setEnabled(enable); btnUnhide->setEnabled(enable); } - -void DlgHidden::selectionChanged(const QItemSelection& selected, - const QItemSelection&) { - activateButtons(!selected.indexes().isEmpty()); -} diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index f7da5b31606..368d2736b63 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -18,25 +18,19 @@ class DlgHidden : public QWidget, public Ui::DlgHidden { DlgHidden(QWidget* parent, TrackCollection *pTrackCollection); virtual ~DlgHidden(); - void onShow(); - void setTrackTable(Library* pLibrary, WTrackTableView* pTrackTableView, int paneId); - inline void setFocusedPane(int focusedPane) { - m_focusedPane = focusedPane; - } + void setTrackTable(WTrackTableView* pTrackTableView); + void setSelectedIndexes(const QModelIndexList& selectedIndexes); public slots: - void clicked(); - void selectAll(); - void selectionChanged(const QItemSelection&, const QItemSelection&); + void onShow(); signals: + void selectAll(); void trackSelected(TrackPointer pTrack); private: void activateButtons(bool enable); HiddenTableModel* m_pHiddenTableModel; - QHash m_trackTableView; - int m_focusedPane; }; #endif //DLGHIDDEN_H diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index bc863eb8d0e..be37d4a6713 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -6,13 +6,12 @@ DlgMissing::DlgMissing(QWidget* parent, TrackCollection *pTrackCollection) : QWidget(parent), - Ui::DlgMissing(), - m_focusedPane(-1) { + Ui::DlgMissing() { setupUi(this); m_pMissingTableModel = new MissingTableModel(this, pTrackCollection); - connect(btnPurge, SIGNAL(clicked()), this, SLOT(clicked())); - connect(btnSelect, SIGNAL(clicked()), this, SLOT(selectAll())); + connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); + connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); } DlgMissing::~DlgMissing() { @@ -26,44 +25,16 @@ void DlgMissing::onShow() { activateButtons(false); } -void DlgMissing::clicked() { - // all marked tracks are gone now anyway - onShow(); -} - -void DlgMissing::setTrackTable(Library* pLibrary, - WTrackTableView* pTrackTableView, - int paneId) { +void DlgMissing::setTrackTable(WTrackTableView* pTrackTableView) { pTrackTableView->loadTrackModel(m_pMissingTableModel); - connect(btnPurge, SIGNAL(clicked()), - pTrackTableView, SLOT(slotPurge())); - connect(pTrackTableView->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - connect(pLibrary, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - m_trackTableView[paneId] = pTrackTableView; + connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); } -void DlgMissing::selectAll() { - if (m_trackTableView.contains(m_focusedPane)) { - m_trackTableView[m_focusedPane]->selectAll(); - } +void DlgMissing::setSelectedIndexes(const QModelIndexList& selectedIndexes) { + activateButtons(!selectedIndexes.isEmpty()); } void DlgMissing::activateButtons(bool enable) { btnPurge->setEnabled(enable); } - -void DlgMissing::selectionChanged(const QItemSelection &selected, - const QItemSelection &deselected) { - Q_UNUSED(deselected); - activateButtons(!selected.indexes().isEmpty()); -} diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index 2de7738e518..8969bee8c3a 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -17,28 +17,20 @@ class DlgMissing : public QWidget, public Ui::DlgMissing { DlgMissing(QWidget* parent, TrackCollection* pTrackCollection); virtual ~DlgMissing(); - void onShow(); - void setTrackTable(Library *pLibrary, - WTrackTableView* pTrackTableView, - int paneId); - inline void setFocusedPane(int focusedPane) { - m_focusedPane = focusedPane; - } + void setTrackTable(WTrackTableView* pTrackTableView); + void setSelectedIndexes(const QModelIndexList& selectedIndexes); public slots: - void clicked(); - void selectAll(); - void selectionChanged(const QItemSelection&, const QItemSelection&); + void onShow(); signals: + void selectAll(); void trackSelected(TrackPointer pTrack); private: void activateButtons(bool enable); MissingTableModel* m_pMissingTableModel; - QHash m_trackTableView; - int m_focusedPane; }; #endif //DLGMISSING_H diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index d0ba3fd9ae3..6ce1e56eda6 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -147,10 +147,16 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, WTrackTableView* pHiddenTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); pHiddenTable->installEventFilter(pKeyboard); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pHiddenTable, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pHiddenTable, SLOT(setTrackTableRowHeight(int))); + m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); if (m_pHiddenView) { - m_pHiddenView->setTrackTable(m_pLibrary, pHiddenTable, paneId); + m_pHiddenView->setTrackTable(pHiddenTable); } else { m_hiddenPane[paneId] = pHiddenTable; } @@ -158,10 +164,16 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, WTrackTableView* pMissingTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); pMissingTable->installEventFilter(pKeyboard); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pMissingTable, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pMissingTable, SLOT(setTrackTableRowHeight(int))); + m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); if (m_pMissingView) { - m_pMissingView->setTrackTable(m_pLibrary, pMissingTable, paneId); + m_pMissingView->setTrackTable(pMissingTable); } else { m_missingPane[paneId] = pMissingTable; } @@ -195,26 +207,20 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, // Create Hidden View controls m_pHiddenView = new DlgHidden(pLibraryWidget, m_pTrackCollection); m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); - connect(m_pHiddenView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); // Add Track tables to Hidden view - for (auto it = m_hiddenPane.begin(); it != m_hiddenPane.end(); ++it) { - m_pHiddenView->setTrackTable(m_pLibrary, it.value(), it.key()); + for (WTrackTableView* pTable : m_hiddenPane) { + m_pHiddenView->setTrackTable(pTable); } - m_hiddenPane.clear(); // Create Missing View controls m_pMissingView = new DlgMissing(pLibraryWidget, m_pTrackCollection); m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); - connect(m_pMissingView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); // Add Track tables to Missing view - for (auto it = m_missingPane.begin(); it != m_missingPane.end(); ++it) { - m_pMissingView->setTrackTable(m_pLibrary, it.value(), it.key()); + for (WTrackTableView* pTable : m_missingPane) { + m_pMissingView->setTrackTable(pTable); } - m_missingPane.clear(); pTab->addTab(m_pExpandedStack, tr("Controls")); pLibraryWidget->registerView(m_sMixxxLibraryViewName, pTab); @@ -244,10 +250,34 @@ void MixxxLibraryFeature::refreshLibraryModels() { } } +void MixxxLibraryFeature::hiddenSelectionChanged(const QItemSelection&, + const QItemSelection&) { + WTrackTableView* pTable = m_hiddenPane[m_featureFocus]; + const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + m_pHiddenView->setSelectedIndexes(selection); +} + +void MixxxLibraryFeature::missingSelectionChanged(const QItemSelection&, + const QItemSelection&) { + WTrackTableView* pTable = m_missingPane[m_featureFocus]; + const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + m_pMissingView->setSelectedIndexes(selection); +} + +void MixxxLibraryFeature::selectAllHidden() { + if (m_hiddenPane.contains(m_featureFocus)) { + m_hiddenPane[m_featureFocus]->selectAll(); + } +} + +void MixxxLibraryFeature::selectAllMissing() { + if (m_missingPane.contains(m_featureFocus)) { + m_missingPane[m_featureFocus]->selectAll(); + } +} + void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; - m_pHiddenView->setFocusedPane(m_featureFocus); - m_pMissingView->setFocusedPane(m_featureFocus); emit(switchToView(m_sMixxxLibraryViewName)); emit(showTrackModel(m_pLibraryTableModel)); @@ -259,11 +289,13 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { if (itemName == m_sMixxxLibraryViewName) { activate(); } else if (itemName == kHiddenTitle) { + m_pHiddenView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); emit(switchToView(m_sMixxxLibraryViewName)); emit(enableCoverArtDisplay(true)); } else if (itemName == kMissingTitle) { + m_pMissingView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); emit(switchToView(m_sMixxxLibraryViewName)); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 1ebcc3a2e44..7e949a48cd0 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -56,6 +56,12 @@ class MixxxLibraryFeature : public LibraryFeature { void activate(); void activateChild(const QModelIndex& index); void refreshLibraryModels(); + + void hiddenSelectionChanged(const QItemSelection&, const QItemSelection&); + void missingSelectionChanged(const QItemSelection&, const QItemSelection&); + + void selectAllHidden(); + void selectAllMissing(); private: const QString kLibraryTitle; From b1c450078fe46fd706273759db54d6f5db40f9b6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 29 Jun 2016 23:38:59 +0200 Subject: [PATCH 190/552] Fixed nothing happening when selecting a track --- src/library/mixxxlibraryfeature.cpp | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 6ce1e56eda6..78b1b87daa2 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -144,6 +144,7 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, WLibraryStack* pStack = new WLibraryStack(nullptr); m_paneStack[paneId] = pStack; + // Create the hidden table WTrackTableView* pHiddenTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); pHiddenTable->installEventFilter(pKeyboard); @@ -154,13 +155,20 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, pHiddenTable, SLOT(setTrackTableRowHeight(int))); m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); + m_hiddenPane[paneId] = pHiddenTable; if (m_pHiddenView) { m_pHiddenView->setTrackTable(pHiddenTable); - } else { - m_hiddenPane[paneId] = pHiddenTable; + + connect(pHiddenTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(hiddenSelectionChanged(const QItemSelection&, + const QItemSelection&))); } + // Create the missing table WTrackTableView* pMissingTable = new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); pMissingTable->installEventFilter(pKeyboard); @@ -171,11 +179,17 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, pMissingTable, SLOT(setTrackTableRowHeight(int))); m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); + m_missingPane[paneId] = pMissingTable; if (m_pMissingView) { m_pMissingView->setTrackTable(pMissingTable); - } else { - m_missingPane[paneId] = pMissingTable; + + connect(pMissingTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(missingSelectionChanged(const QItemSelection&, + const QItemSelection&))); } return pStack; @@ -211,6 +225,13 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, // Add Track tables to Hidden view for (WTrackTableView* pTable : m_hiddenPane) { m_pHiddenView->setTrackTable(pTable); + + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(missingSelectionChanged(const QItemSelection&, + const QItemSelection&))); } // Create Missing View controls @@ -220,6 +241,13 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, // Add Track tables to Missing view for (WTrackTableView* pTable : m_missingPane) { m_pMissingView->setTrackTable(pTable); + + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(missingSelectionChanged(const QItemSelection&, + const QItemSelection&))); } pTab->addTab(m_pExpandedStack, tr("Controls")); @@ -288,12 +316,14 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); if (itemName == m_sMixxxLibraryViewName) { activate(); + } else if (itemName == kHiddenTitle) { m_pHiddenView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); emit(switchToView(m_sMixxxLibraryViewName)); emit(enableCoverArtDisplay(true)); + } else if (itemName == kMissingTitle) { m_pMissingView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); From 4e995f72606cf0b4d58a4c2927f9c0266eeabff6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 00:25:51 +0200 Subject: [PATCH 191/552] Remove track table from DlgAutoDJ --- src/library/analysisfeature.cpp | 36 ++++++---------- src/library/autodj/autodjfeature.cpp | 63 ++++++++++------------------ src/library/autodj/autodjfeature.h | 3 +- src/library/autodj/dlgautodj.cpp | 53 +++++------------------ src/library/autodj/dlgautodj.h | 12 ++---- 5 files changed, 48 insertions(+), 119 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 6648f8d79ed..ea987b1dcb9 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -70,19 +70,20 @@ void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { + if (!m_pAnalysisLibraryTableModel) { + m_pAnalysisLibraryTableModel = + new AnalysisLibraryTableModel(this, m_pTrackCollection); + } WAnalysisLibraryTableView* pTable = new WAnalysisLibraryTableView(nullptr, m_pConfig, m_pTrackCollection); pTable->installEventFilter(pKeyboard); + pTable->setModel(m_pAnalysisLibraryTableModel); - if (m_pAnalysisLibraryTableModel) { - pTable->setModel(m_pAnalysisLibraryTableModel); - - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); - } + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); connect(pTable, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); @@ -91,11 +92,6 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, connect(pTable, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); - - if (m_pAnalysisLibraryTableModel) { - pTable->setModel(m_pAnalysisLibraryTableModel); - } - m_analysisTables[paneId] = pTable; return pTable; } @@ -110,15 +106,9 @@ void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); - m_pAnalysisLibraryTableModel = new AnalysisLibraryTableModel(this, m_pTrackCollection); - - for (WAnalysisLibraryTableView* pTable : m_analysisTables) { - pTable->setModel(m_pAnalysisLibraryTableModel); - - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); + if (!m_pAnalysisLibraryTableModel) { + m_pAnalysisLibraryTableModel = + new AnalysisLibraryTableModel(this, m_pTrackCollection); } m_pAnalysisView->setTableModel(m_pAnalysisLibraryTableModel); @@ -169,7 +159,7 @@ void AnalysisFeature::activate() { } void AnalysisFeature::analyzeTracks(QList trackIds) { - if (m_pAnalyzerQueue == NULL) { + if (m_pAnalyzerQueue == nullptr) { // Save the old BPM detection prefs setting (on or off) m_iOldBpmEnabled = m_pConfig->getValueString(ConfigKey("[BPM]","BPMDetectionEnabled")).toInt(); // Force BPM detection to be on. diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 61f39da55fd..84fe6e378e1 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -32,8 +32,6 @@ AutoDJFeature::AutoDJFeature(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, parent), - m_pConfig(pConfig), - m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_playlistDao(pTrackCollection->getPlaylistDAO()), @@ -105,30 +103,14 @@ QString AutoDJFeature::getViewName() { void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId) { - //qDebug() << "AutoDJFeature::bindPaneWidget" << pLibraryWidget; - - - WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, - m_pConfig, m_pTrackCollection, false); - - pTrackTableView->installEventFilter(pKeyboard); - pLibraryWidget->registerView(m_sAutoDJViewName, pTrackTableView); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(const QFont&)), - pTrackTableView, SLOT(setTrackTableFont(const QFont&))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - if (m_pAutoDJView) { - m_pAutoDJView->setTrackTableView(pTrackTableView, paneId); - } else { - m_trackTables[paneId] = pTrackTableView; - } + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pLibraryWidget); + pLibraryWidget->registerView(m_sAutoDJViewName, pPane); } QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, - m_pConfig, m_pTrackCollection, false); + WTrackTableView* pTrackTableView = + new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); pTrackTableView->installEventFilter(pKeyboard); @@ -136,12 +118,15 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan pTrackTableView, SLOT(setTrackTableFont(const QFont&))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); + m_trackTables[paneId] = pTrackTableView; - if (m_pAutoDJView) { - m_pAutoDJView->setTrackTableView(pTrackTableView, paneId); - } else { - m_trackTables[paneId] = pTrackTableView; - } + pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); + + connect(pTrackTableView->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + return pTrackTableView; } @@ -151,19 +136,13 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, QTabWidget* pContainer = new QTabWidget(pSidebarWidget); + // Add drop target WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); pSidebar->setModel(&m_childModel); - pContainer->addTab(pSidebar, tr("Drop target")); + pContainer->addTab(pSidebar, tr("Track source")); m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); pContainer->addTab(m_pAutoDJView, tr("controls")); - - connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(m_pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); - connect(m_pAutoDJView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); // Be informed when the user wants to add another random track. connect(m_pAutoDJProcessor,SIGNAL(randomTrackRequested(int)), @@ -172,11 +151,6 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, this, SLOT(slotAddRandomTrack(bool))); pSidebarWidget->registerView(m_sAutoDJViewName, pContainer); - - for (auto it = m_trackTables.begin(); it != m_trackTables.end(); ++it) { - m_pAutoDJView->setTrackTableView(it.value(), it.key()); - } - m_trackTables.clear(); } TreeItemModel* AutoDJFeature::getChildModel() { @@ -185,7 +159,6 @@ TreeItemModel* AutoDJFeature::getChildModel() { void AutoDJFeature::activate() { //qDebug() << "AutoDJFeature::activate()"; - m_pAutoDJView->setFocusedPane(m_featureFocus); m_pAutoDJView->onShow(); emit(switchToView(m_sAutoDJViewName)); emit(restoreSearch(QString())); //Null String disables search box @@ -436,3 +409,9 @@ void AutoDJFeature::slotRandomQueue(int tracksToAdd) { tracksToAdd -= 1; } } + +void AutoDJFeature::selectionChanged(const QItemSelection&, const QItemSelection&) { + WTrackTableView* pTable = m_trackTables[m_featureFocus]; + const QModelIndexList& selectedRows = pTable->selectionModel()->selectedRows(); + m_pAutoDJView->setSelectedRows(selectedRows); +} diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index b4489d35f53..ce9b5053d31 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -59,8 +59,6 @@ class AutoDJFeature : public LibraryFeature { void onRightClickChild(const QPoint& globalPos, QModelIndex index); private: - UserSettingsPointer m_pConfig; - Library* m_pLibrary; TrackCollection* m_pTrackCollection; CrateDAO& m_crateDao; PlaylistDAO& m_playlistDao; @@ -123,6 +121,7 @@ class AutoDJFeature : public LibraryFeature { // of tracks in the playlist void slotRandomQueue(int); + void selectionChanged(const QItemSelection&, const QItemSelection&); }; diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 6d8c612c103..802d0394055 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -15,8 +15,7 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, m_pAutoDJProcessor(pProcessor), // no sorting m_pAutoDJTableModel(nullptr), - m_pLibrary(pLibrary), - m_focusedPane(-1) { + m_pLibrary(pLibrary) { setupUi(this); // We do _NOT_ take ownership of this from AutoDJProcessor. @@ -26,19 +25,14 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, connect(pushButtonShuffle, SIGNAL(clicked(bool)), this, SLOT(shufflePlaylistButton(bool))); - connect(pushButtonSkipNext, SIGNAL(clicked(bool)), this, SLOT(skipNextButton(bool))); - connect(pushButtonAddRandom, SIGNAL(clicked(bool)), this, SIGNAL(addRandomButton(bool))); - connect(pushButtonFadeNow, SIGNAL(clicked(bool)), this, SLOT(fadeNowButton(bool))); - connect(spinBoxTransition, SIGNAL(valueChanged(int)), this, SLOT(transitionSliderChanged(int))); - connect(pushButtonAutoDJ, SIGNAL(toggled(bool)), this, SLOT(toggleAutoDJButton(bool))); @@ -61,27 +55,11 @@ void DlgAutoDJ::onShow() { m_pAutoDJTableModel->select(); } -void DlgAutoDJ::setTrackTableView(WTrackTableView* pTrackTableView, int paneId) { - pTrackTableView->loadTrackModel(m_pAutoDJTableModel); - - m_trackTables[paneId] = pTrackTableView; - - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SLOT(updateSelectionInfo())); - +void DlgAutoDJ::setSelectedRows(const QModelIndexList& selectedRows) { + m_selectedRows = selectedRows; updateSelectionInfo(); } -void DlgAutoDJ::setFocusedPane(int focusedPane) { - m_focusedPane = focusedPane; -} - void DlgAutoDJ::shufflePlaylistButton(bool) { LibraryView* pView = m_pLibrary->getActiveView(); WTrackTableView* pTrackTable = dynamic_cast(pView); @@ -163,34 +141,23 @@ void DlgAutoDJ::autoDJStateChanged(AutoDJProcessor::AutoDJState state) { } void DlgAutoDJ::updateSelectionInfo() { - if (!m_trackTables.contains(m_focusedPane)) { + if (m_selectedRows.isEmpty()) { labelSelectionInfo->setText(""); labelSelectionInfo->setEnabled(false); return; } int duration = 0; - WTrackTableView* pTrackTable = m_trackTables[m_focusedPane]; - if (!pTrackTable) { - return; - } - - QModelIndexList indices = pTrackTable->selectionModel()->selectedRows(); - for (int i = 0; i < indices.size(); ++i) { - TrackPointer pTrack = m_pAutoDJTableModel->getTrack(indices.at(i)); + for (const QModelIndex& mIndex : m_selectedRows) { + TrackPointer pTrack = m_pAutoDJTableModel->getTrack(mIndex); if (pTrack) { duration += pTrack->getDuration(); } } QString label; - if (!indices.isEmpty()) { - label.append(Time::formatSeconds(duration)); - label.append(QString(" (%1)").arg(indices.size())); - labelSelectionInfo->setText(label); - labelSelectionInfo->setEnabled(true); - } else { - labelSelectionInfo->setText(""); - labelSelectionInfo->setEnabled(false); - } + label.append(Time::formatSeconds(duration)); + label.append(QString(" (%1)").arg(m_selectedRows.size())); + labelSelectionInfo->setText(label); + labelSelectionInfo->setEnabled(true); } diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index ee6a84e36c3..62a311b7929 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -24,8 +24,7 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { virtual ~DlgAutoDJ(); void onShow(); - void setTrackTableView(WTrackTableView* pTrackTableView, int paneId); - void setFocusedPane(int focusedPane); + void setSelectedRows(const QModelIndexList& selectedRows); public slots: void shufflePlaylistButton(bool buttonChecked); @@ -39,18 +38,13 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { signals: void addRandomButton(bool buttonChecked); - void loadTrack(TrackPointer tio); - void loadTrackToPlayer(TrackPointer tio, QString group, bool); - void trackSelected(TrackPointer pTrack); - + private: AutoDJProcessor* m_pAutoDJProcessor; PlaylistTableModel* m_pAutoDJTableModel; Library* m_pLibrary; - int m_focusedPane; - - QHash m_trackTables; + QModelIndexList m_selectedRows; }; #endif //DLGAUTODJ_H From e8b22a551026e07e6608382fce9ae83269f14051 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 00:26:12 +0200 Subject: [PATCH 192/552] Remove track table from Mixxx Library Feature --- src/library/dlghidden.cpp | 17 +++--- src/library/dlghidden.h | 6 +- src/library/dlgmissing.cpp | 8 ++- src/library/dlgmissing.h | 4 +- src/library/mixxxlibraryfeature.cpp | 85 +++++++++++++++-------------- src/library/mixxxlibraryfeature.h | 13 ++++- 6 files changed, 77 insertions(+), 56 deletions(-) diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 858ee2d398a..5c1b22fe68d 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -5,15 +5,15 @@ #include "widget/wtracktableview.h" #include "util/assert.h" -DlgHidden::DlgHidden(QWidget* parent, TrackCollection* pTrackCollection) +DlgHidden::DlgHidden(QWidget* parent) : QWidget(parent), Ui::DlgHidden() { setupUi(this); connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); - - m_pHiddenTableModel = new HiddenTableModel(this, pTrackCollection); + connect(btnPurge, SIGNAL(clicked()), this, SIGNAL(purge())); + connect(btnUnhide, SIGNAL(clicked()), this, SIGNAL(unhide())); } DlgHidden::~DlgHidden() { @@ -28,17 +28,14 @@ void DlgHidden::onShow() { activateButtons(false); } -void DlgHidden::setTrackTable(WTrackTableView *pTrackTableView) { - pTrackTableView->loadTrackModel(m_pHiddenTableModel); - - connect(btnUnhide, SIGNAL(clicked()), pTrackTableView, SLOT(slotUnhide())); - connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); -} - void DlgHidden::setSelectedIndexes(const QModelIndexList& selectedIndexes) { activateButtons(!selectedIndexes.empty()); } +void DlgHidden::setTableModel(HiddenTableModel* pTableModel) { + m_pHiddenTableModel = pTableModel; +} + void DlgHidden::activateButtons(bool enable) { btnPurge->setEnabled(enable); btnUnhide->setEnabled(enable); diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index 368d2736b63..0b43112e5ab 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -15,17 +15,19 @@ class QItemSelection; class DlgHidden : public QWidget, public Ui::DlgHidden { Q_OBJECT public: - DlgHidden(QWidget* parent, TrackCollection *pTrackCollection); + DlgHidden(QWidget* parent); virtual ~DlgHidden(); - void setTrackTable(WTrackTableView* pTrackTableView); void setSelectedIndexes(const QModelIndexList& selectedIndexes); + void setTableModel(HiddenTableModel* pTableModel); public slots: void onShow(); signals: void selectAll(); + void unhide(); + void purge(); void trackSelected(TrackPointer pTrack); private: diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index be37d4a6713..d1eeeda265b 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -4,13 +4,13 @@ #include "widget/wtracktableview.h" #include "util/assert.h" -DlgMissing::DlgMissing(QWidget* parent, TrackCollection *pTrackCollection) +DlgMissing::DlgMissing(QWidget* parent) : QWidget(parent), Ui::DlgMissing() { setupUi(this); - m_pMissingTableModel = new MissingTableModel(this, pTrackCollection); connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); + connect(btnPurge, SIGNAL(clicked()), this, SIGNAL(purge())); connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); } @@ -35,6 +35,10 @@ void DlgMissing::setSelectedIndexes(const QModelIndexList& selectedIndexes) { activateButtons(!selectedIndexes.isEmpty()); } +void DlgMissing::setTableModel(MissingTableModel* pTableModel) { + m_pMissingTableModel = pTableModel; +} + void DlgMissing::activateButtons(bool enable) { btnPurge->setEnabled(enable); } diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index 8969bee8c3a..c83f6c23c0a 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -14,16 +14,18 @@ class MissingTableModel; class DlgMissing : public QWidget, public Ui::DlgMissing { Q_OBJECT public: - DlgMissing(QWidget* parent, TrackCollection* pTrackCollection); + DlgMissing(QWidget* parent); virtual ~DlgMissing(); void setTrackTable(WTrackTableView* pTrackTableView); void setSelectedIndexes(const QModelIndexList& selectedIndexes); + void setTableModel(MissingTableModel* pTableModel); public slots: void onShow(); signals: + void purge(); void selectAll(); void trackSelected(TrackPointer pTrack); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 78b1b87daa2..159cc86c94f 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -156,17 +156,22 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); m_hiddenPane[paneId] = pHiddenTable; - - if (m_pHiddenView) { - m_pHiddenView->setTrackTable(pHiddenTable); - - connect(pHiddenTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), - this, - SLOT(hiddenSelectionChanged(const QItemSelection&, - const QItemSelection&))); + if (m_pHiddenTableModel.isNull()) { + m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); } + pHiddenTable->loadTrackModel(m_pHiddenTableModel); + + connect(pHiddenTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(hiddenSelectionChanged(const QItemSelection&, + const QItemSelection&))); + + connect(this, SIGNAL(unhideHidden()), + pHiddenTable, SLOT(slotUnhide())); + connect(this, SIGNAL(purgeHidden()), + pHiddenTable, SLOT(slotPurge())); // Create the missing table WTrackTableView* pMissingTable = @@ -180,16 +185,19 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); m_missingPane[paneId] = pMissingTable; + if (m_pMissingTableModel.isNull()) { + m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); + } + pMissingTable->loadTrackModel(m_pMissingTableModel); + connect(pMissingTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, + SLOT(missingSelectionChanged(const QItemSelection&, + const QItemSelection&))); if (m_pMissingView) { - m_pMissingView->setTrackTable(pMissingTable); - - connect(pMissingTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), - this, - SLOT(missingSelectionChanged(const QItemSelection&, - const QItemSelection&))); + m_pMissingView->setTrackTable(pMissingTable); } return pStack; @@ -217,37 +225,34 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, // Create tabs m_pExpandedStack = new QStackedWidget(pTab); - + // Create Hidden View controls - m_pHiddenView = new DlgHidden(pLibraryWidget, m_pTrackCollection); - m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); - - // Add Track tables to Hidden view - for (WTrackTableView* pTable : m_hiddenPane) { - m_pHiddenView->setTrackTable(pTable); - - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), - this, - SLOT(missingSelectionChanged(const QItemSelection&, - const QItemSelection&))); + if (m_pHiddenTableModel.isNull()) { + m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); } + m_pHiddenView = new DlgHidden(pLibraryWidget); + m_pHiddenView->setTableModel(m_pHiddenTableModel); + connect(m_pHiddenView, SIGNAL(unhide()), + this, SIGNAL(unhideHidden())); + connect(m_pHiddenView, SIGNAL(purge()), + this, SIGNAL(purgeHidden())); + + m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); // Create Missing View controls - m_pMissingView = new DlgMissing(pLibraryWidget, m_pTrackCollection); + if (m_pMissingTableModel.isNull()) { + m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); + } + m_pMissingView = new DlgMissing(pLibraryWidget); + m_pMissingView->setTableModel(m_pMissingTableModel); + connect(m_pMissingView, SIGNAL(purge()), + this, SIGNAL(purgeMissing())); + m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); // Add Track tables to Missing view for (WTrackTableView* pTable : m_missingPane) { m_pMissingView->setTrackTable(pTable); - - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), - this, - SLOT(missingSelectionChanged(const QItemSelection&, - const QItemSelection&))); } pTab->addTab(m_pExpandedStack, tr("Controls")); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 7e949a48cd0..9801990aa4a 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -27,10 +27,12 @@ class BaseTrackCache; class LibraryTableModel; class TrackCollection; class WTrackTableView; +class HiddenTableModel; +class MissingTableModel; class MixxxLibraryFeature : public LibraryFeature { Q_OBJECT - public: + public: MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -62,6 +64,12 @@ class MixxxLibraryFeature : public LibraryFeature { void selectAllHidden(); void selectAllMissing(); + + + signals: + void unhideHidden(); + void purgeHidden(); + void purgeMissing(); private: const QString kLibraryTitle; @@ -79,6 +87,9 @@ class MixxxLibraryFeature : public LibraryFeature { int m_hiddenExpandedId; int m_missingExpandedId; + QPointer m_pHiddenTableModel; + QPointer m_pMissingTableModel; + QHash m_paneStack; QStackedWidget* m_pExpandedStack; From 8cf3dcf718fbcc4d301749ead5b57d68fcdb4624 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 00:33:03 +0200 Subject: [PATCH 193/552] Remove unnecessary function calls --- src/library/dlgmissing.cpp | 6 ---- src/library/dlgmissing.h | 1 - src/library/mixxxlibraryfeature.cpp | 56 +++++++++++++---------------- src/library/mixxxlibraryfeature.h | 5 +-- 4 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index d1eeeda265b..2dcc9c94687 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -25,12 +25,6 @@ void DlgMissing::onShow() { activateButtons(false); } -void DlgMissing::setTrackTable(WTrackTableView* pTrackTableView) { - pTrackTableView->loadTrackModel(m_pMissingTableModel); - - connect(btnPurge, SIGNAL(clicked()), pTrackTableView, SLOT(slotPurge())); -} - void DlgMissing::setSelectedIndexes(const QModelIndexList& selectedIndexes) { activateButtons(!selectedIndexes.isEmpty()); } diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index c83f6c23c0a..b71719b6808 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -17,7 +17,6 @@ class DlgMissing : public QWidget, public Ui::DlgMissing { DlgMissing(QWidget* parent); virtual ~DlgMissing(); - void setTrackTable(WTrackTableView* pTrackTableView); void setSelectedIndexes(const QModelIndexList& selectedIndexes); void setTableModel(MissingTableModel* pTableModel); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 159cc86c94f..4e7ca7ba55b 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -156,22 +156,19 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); m_hiddenPane[paneId] = pHiddenTable; + if (m_pHiddenTableModel.isNull()) { m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); } pHiddenTable->loadTrackModel(m_pHiddenTableModel); connect(pHiddenTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, - SLOT(hiddenSelectionChanged(const QItemSelection&, - const QItemSelection&))); + SLOT(hiddenSelectionChanged(const QItemSelection&, const QItemSelection&))); - connect(this, SIGNAL(unhideHidden()), - pHiddenTable, SLOT(slotUnhide())); - connect(this, SIGNAL(purgeHidden()), - pHiddenTable, SLOT(slotPurge())); + connect(this, SIGNAL(unhideHidden()), pHiddenTable, SLOT(slotUnhide())); + connect(this, SIGNAL(purgeHidden()), pHiddenTable, SLOT(slotPurge())); // Create the missing table WTrackTableView* pMissingTable = @@ -185,27 +182,29 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); m_missingPane[paneId] = pMissingTable; + if (m_pMissingTableModel.isNull()) { m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); } pMissingTable->loadTrackModel(m_pMissingTableModel); connect(pMissingTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, - const QItemSelection&)), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, - SLOT(missingSelectionChanged(const QItemSelection&, - const QItemSelection&))); - if (m_pMissingView) { - m_pMissingView->setTrackTable(pMissingTable); - } + SLOT(missingSelectionChanged(const QItemSelection&, const QItemSelection&))); return pStack; } -void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, - KeyboardEventFilter*) { - QTabWidget* pTab = new QTabWidget(pLibraryWidget); +void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, + KeyboardEventFilter*pKeyboard) { + QWidget* pSidebar = createSidebarWidget(pKeyboard); + pSidebar->setParent(pSidebarWidget); + pLibraryWidget->registerView(m_sMixxxLibraryViewName, pSidebar); +} + +QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { + QTabWidget* pTab = new QTabWidget(nullptr); // Create tree WLibrarySidebar* pSidebar = new WLibrarySidebar(pTab); @@ -220,7 +219,6 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, this, SLOT(onRightClickChild(const QPoint&, const QModelIndex&))); connect(pSidebar, SIGNAL(expanded(const QModelIndex&)), this, SLOT(onLazyChildExpandation(const QModelIndex&))); - pTab->addTab(pSidebar, tr("Tree")); // Create tabs @@ -232,10 +230,10 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, } m_pHiddenView = new DlgHidden(pLibraryWidget); m_pHiddenView->setTableModel(m_pHiddenTableModel); - connect(m_pHiddenView, SIGNAL(unhide()), - this, SIGNAL(unhideHidden())); - connect(m_pHiddenView, SIGNAL(purge()), - this, SIGNAL(purgeHidden())); + m_pHiddenView->installEventFilter(pKeyboard); + + connect(m_pHiddenView, SIGNAL(unhide()), this, SIGNAL(unhideHidden())); + connect(m_pHiddenView, SIGNAL(purge()), this, SIGNAL(purgeHidden())); m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); @@ -245,18 +243,14 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pLibraryWidget, } m_pMissingView = new DlgMissing(pLibraryWidget); m_pMissingView->setTableModel(m_pMissingTableModel); - connect(m_pMissingView, SIGNAL(purge()), - this, SIGNAL(purgeMissing())); + m_pMissingView->installEventFilter(pKeyboard); - m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); + connect(m_pMissingView, SIGNAL(purge()), this, SIGNAL(purgeMissing())); - // Add Track tables to Missing view - for (WTrackTableView* pTable : m_missingPane) { - m_pMissingView->setTrackTable(pTable); - } + m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); pTab->addTab(m_pExpandedStack, tr("Controls")); - pLibraryWidget->registerView(m_sMixxxLibraryViewName, pTab); + return pTab; } QVariant MixxxLibraryFeature::title() { diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 9801990aa4a..ddbecec63f8 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -47,8 +47,9 @@ class MixxxLibraryFeature : public LibraryFeature { void bindPaneWidget(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); - void bindSidebarWidget(WBaseLibrary* pLibraryWidget, - KeyboardEventFilter*); + + void bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter* pKeyboard); + QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); inline QString getViewName() { return m_sMixxxLibraryViewName; From 5b5727d2e8c696a52611f5df34082c77c8d9aea9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 09:41:31 +0200 Subject: [PATCH 194/552] Fixed potential source of errors with m_featureFocus Also avoided double hash lookups --- src/library/analysisfeature.cpp | 15 +++++++++++---- src/library/autodj/autodjfeature.cpp | 8 ++++++-- src/library/autodj/dlgautodj.cpp | 2 +- src/library/autodj/dlgautodj.h | 2 ++ src/library/dlganalysis.cpp | 24 ++++++------------------ src/library/dlganalysis.h | 6 ++---- src/library/dlghidden.h | 1 + src/library/dlgmissing.h | 1 + src/library/mixxxlibraryfeature.cpp | 25 +++++++++++++++++-------- 9 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index ea987b1dcb9..db783e6fa7a 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -146,7 +146,10 @@ void AnalysisFeature::refreshLibraryModels() { } void AnalysisFeature::selectAll() { - m_analysisTables[m_featureFocus]->selectAll(); + auto it = m_analysisTables.find(m_featureFocus); + if (it != m_analysisTables.end()) { + (*it)->selectAll(); + } } void AnalysisFeature::activate() { @@ -222,9 +225,13 @@ void AnalysisFeature::cleanupAnalyzer() { void AnalysisFeature::tableSelectionChanged(const QItemSelection&, const QItemSelection&) { - qDebug() << "AnalysisFeature::tableSelectionChanged" << sender(); - WTrackTableView* pCurrent = m_analysisTables[m_featureFocus]; - const QModelIndexList &indexes = pCurrent->selectionModel()->selectedIndexes(); + //qDebug() << "AnalysisFeature::tableSelectionChanged" << sender(); + auto it = m_analysisTables.find(m_featureFocus); + if (it == m_analysisTables.end()) { + return; + } + + const QModelIndexList &indexes = (*it)->selectionModel()->selectedIndexes(); m_pAnalysisView->setSelectedIndexes(indexes); } diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 84fe6e378e1..a4efa70847f 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -411,7 +411,11 @@ void AutoDJFeature::slotRandomQueue(int tracksToAdd) { } void AutoDJFeature::selectionChanged(const QItemSelection&, const QItemSelection&) { - WTrackTableView* pTable = m_trackTables[m_featureFocus]; - const QModelIndexList& selectedRows = pTable->selectionModel()->selectedRows(); + auto it = m_trackTables.find(m_featureFocus); + if (it == m_trackTables.end()) { + return; + } + + const QModelIndexList& selectedRows = (*it)->selectionModel()->selectedRows(); m_pAutoDJView->setSelectedRows(selectedRows); } diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 802d0394055..5a5bc87ed63 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -48,7 +48,7 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, } DlgAutoDJ::~DlgAutoDJ() { - qDebug() << "~DlgAutoDJ()"; + //qDebug() << "~DlgAutoDJ()"; } void DlgAutoDJ::onShow() { diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index 62a311b7929..c1cac4d1581 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -24,6 +24,8 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { virtual ~DlgAutoDJ(); void onShow(); + + // These seleced rows are always from the focused pane void setSelectedRows(const QModelIndexList& selectedRows); public slots: diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index aaabb57fbfb..4264c911f7b 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -18,11 +18,6 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, m_songsButtonGroup.addButton(radioButtonRecentlyAdded); m_songsButtonGroup.addButton(radioButtonAllSongs); - connect(radioButtonRecentlyAdded, SIGNAL(clicked()), - this, SLOT(showRecentSongs())); - connect(radioButtonAllSongs, SIGNAL(clicked()), - this, SLOT(showAllSongs())); - labelProgress->setText(""); pushButtonAnalyze->setEnabled(false); connect(pushButtonAnalyze, SIGNAL(clicked()), @@ -101,12 +96,8 @@ int DlgAnalysis::getNumTracks() { return m_tracksInQueue; } -void DlgAnalysis::setAnalysisTableView(WAnalysisLibraryTableView* pTable) { - pTable->loadTrackModel(m_pAnalysisLibraryTableModel); -} - void DlgAnalysis::setSelectedIndexes(const QModelIndexList& selectedIndexes) { - qDebug() << "DlgAnalysis::setSelectedIndexes" << selectedIndexes; + //qDebug() << "DlgAnalysis::setSelectedIndexes" << selectedIndexes; m_selectedIndexes = selectedIndexes; pushButtonAnalyze->setEnabled(m_selectedIndexes.size() > 0 || m_bAnalysisActive); @@ -114,16 +105,13 @@ void DlgAnalysis::setSelectedIndexes(const QModelIndexList& selectedIndexes) { void DlgAnalysis::setTableModel(AnalysisLibraryTableModel *pTableModel) { m_pAnalysisLibraryTableModel = pTableModel; + + connect(radioButtonRecentlyAdded, SIGNAL(clicked()), + m_pAnalysisLibraryTableModel, SLOT(showRecentSongs())); + connect(radioButtonAllSongs, SIGNAL(clicked()), + m_pAnalysisLibraryTableModel, SLOT(showAllSongs())); } void DlgAnalysis::trackAnalysisStarted(int size) { m_tracksInQueue = size; } - -void DlgAnalysis::showRecentSongs() { - m_pAnalysisLibraryTableModel->showRecentSongs(); -} - -void DlgAnalysis::showAllSongs() { - m_pAnalysisLibraryTableModel->showAllSongs(); -} diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 08dd87e2ece..a6d629369f4 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -20,7 +20,7 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { public: DlgAnalysis(QWidget *parent, - TrackCollection* pTrackCollection); + TrackCollection* pTrackCollection); virtual ~DlgAnalysis(); virtual void onShow(); @@ -29,7 +29,7 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { } int getNumTracks(); - void setAnalysisTableView(WAnalysisLibraryTableView* pTable); + // The selected indexes are always from the focused pane void setSelectedIndexes(const QModelIndexList& selectedIndexes); void setTableModel(AnalysisLibraryTableModel* pTableModel); @@ -39,8 +39,6 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { void trackAnalysisFinished(int size); void trackAnalysisProgress(int progress); void trackAnalysisStarted(int size); - void showRecentSongs(); - void showAllSongs(); void analysisActive(bool bActive); signals: diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index 0b43112e5ab..746768c9f8e 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -18,6 +18,7 @@ class DlgHidden : public QWidget, public Ui::DlgHidden { DlgHidden(QWidget* parent); virtual ~DlgHidden(); + // The indexes are always from the focused pane void setSelectedIndexes(const QModelIndexList& selectedIndexes); void setTableModel(HiddenTableModel* pTableModel); diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index b71719b6808..3a9f996aca5 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -17,6 +17,7 @@ class DlgMissing : public QWidget, public Ui::DlgMissing { DlgMissing(QWidget* parent); virtual ~DlgMissing(); + // The indexes are always from the Focused pane void setSelectedIndexes(const QModelIndexList& selectedIndexes); void setTableModel(MissingTableModel* pTableModel); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 4e7ca7ba55b..eeb97a7bad2 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -279,27 +279,36 @@ void MixxxLibraryFeature::refreshLibraryModels() { void MixxxLibraryFeature::hiddenSelectionChanged(const QItemSelection&, const QItemSelection&) { - WTrackTableView* pTable = m_hiddenPane[m_featureFocus]; - const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + auto it = m_hiddenPane.find(m_featureFocus); + if (it == m_hiddenPane.end()) { + return; + } + + const QModelIndexList& selection = (*it)->selectionModel()->selectedIndexes(); m_pHiddenView->setSelectedIndexes(selection); } void MixxxLibraryFeature::missingSelectionChanged(const QItemSelection&, const QItemSelection&) { - WTrackTableView* pTable = m_missingPane[m_featureFocus]; - const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + auto it = m_missingPane.find(m_featureFocus); + if (it == m_missingPane.end()) { + return; + } + const QModelIndexList& selection = (*it)->selectionModel()->selectedIndexes(); m_pMissingView->setSelectedIndexes(selection); } void MixxxLibraryFeature::selectAllHidden() { - if (m_hiddenPane.contains(m_featureFocus)) { - m_hiddenPane[m_featureFocus]->selectAll(); + auto it = m_hiddenPane.find(m_featureFocus); + if (it != m_hiddenPane.end()) { + (*it)->selectAll(); } } void MixxxLibraryFeature::selectAllMissing() { - if (m_missingPane.contains(m_featureFocus)) { - m_missingPane[m_featureFocus]->selectAll(); + auto it = m_missingPane.find(m_featureFocus); + if (it != m_missingPane.end()) { + (*it)->selectAll(); } } From e98dffa12b2b848cd61070b5a031d136f8b4795c Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 09:55:47 +0200 Subject: [PATCH 195/552] Remove duplicated code --- src/library/autodj/autodjfeature.cpp | 17 ++++++++++++----- src/library/autodj/autodjfeature.h | 7 +++++-- src/library/baseplaylistfeature.cpp | 17 +++++++---------- src/library/baseplaylistfeature.h | 5 ++--- src/library/browse/browsefeature.cpp | 12 ++++++------ src/library/browse/browsefeature.h | 2 +- src/library/mixxxlibraryfeature.cpp | 6 +++--- src/library/setlogfeature.cpp | 11 +++-------- src/library/setlogfeature.h | 3 --- 9 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index a4efa70847f..a707d9fe9f5 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -131,17 +131,24 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan } void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, - KeyboardEventFilter*) { - qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; - - QTabWidget* pContainer = new QTabWidget(pSidebarWidget); + KeyboardEventFilter*pKeyboard) { + //qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; + QWidget* pSidebar = createSidebarWidget(pKeyboard); + pSidebar->setParent(pSidebarWidget); + pSidebarWidget->registerView(m_sAutoDJViewName, pContainer); +} + +QWidget* AutoDJFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { + QTabWidget* pContainer = new QTabWidget(nullptr); // Add drop target WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); pSidebar->setModel(&m_childModel); + pSidebar->installEventFilter(pKeyboard); pContainer->addTab(pSidebar, tr("Track source")); m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); + m_pAutoDJView->installEventFilter(pKeyboard); pContainer->addTab(m_pAutoDJView, tr("controls")); // Be informed when the user wants to add another random track. @@ -150,7 +157,7 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, connect(m_pAutoDJView, SIGNAL(addRandomButton(bool)), this, SLOT(slotAddRandomTrack(bool))); - pSidebarWidget->registerView(m_sAutoDJViewName, pContainer); + return pContainer; } TreeItemModel* AutoDJFeature::getChildModel() { diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index ce9b5053d31..bf4ce9ded24 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -46,9 +46,12 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter*pKeyboard, int paneId); + void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); - void bindSidebarWidget(WBaseLibrary *pSidebarWidget, KeyboardEventFilter*); + + void bindSidebarWidget(WBaseLibrary *pSidebarWidget, + KeyboardEventFilter* pKeyboard); + QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); TreeItemModel* getChildModel(); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 72c90951dc5..e159cc7cfbd 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -594,18 +594,15 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { return &m_childModel; } -void BasePlaylistFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* , - int) { - WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); - edit->setHtml(getRootViewHtml()); - edit->setOpenLinks(false); - connect(edit, SIGNAL(anchorClicked(const QUrl)), - this, SLOT(htmlLinkClicked(const QUrl))); - libraryWidget->registerView(m_rootViewName, edit); +void BasePlaylistFeature::bindPaneWidget(WLibrary* pPaneWidget, + KeyboardEventFilter* pKeyboard, + int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pPaneWidget); + pPaneWidget->registerView(m_rootViewName, pPane); } -QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter*, +QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); edit->setHtml(getRootViewHtml()); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 084d0e8fd86..df63a9b8dcf 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -34,9 +34,8 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*, int); - - QWidget* createPaneWidget(KeyboardEventFilter*, int); + void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*, int paneId); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); QString getViewName() { return m_rootViewName; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index c6b63f81039..9339c62fbf1 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -214,12 +214,12 @@ TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } -void BrowseFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter*, - int) { - WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); - edit->setHtml(getRootViewHtml()); - libraryWidget->registerView(m_sBrowseViewName, edit); +void BrowseFeature::bindPaneWidget(WLibrary* pPaneWidget, + KeyboardEventFilter* pKeyboard, + int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pPaneWidget); + pPaneWidget->registerView(m_sBrowseViewName, pPaneWidget); } QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 80357b87281..d5bfd0751c7 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,7 @@ class BrowseFeature : public LibraryFeature { QIcon getIcon(); virtual QString getViewName(); - void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*, int); + void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index eeb97a7bad2..29db8761c47 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -200,7 +200,7 @@ void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter*pKeyboard) { QWidget* pSidebar = createSidebarWidget(pKeyboard); pSidebar->setParent(pSidebarWidget); - pLibraryWidget->registerView(m_sMixxxLibraryViewName, pSidebar); + pSidebarWidget->registerView(m_sMixxxLibraryViewName, pSidebar); } QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { @@ -228,7 +228,7 @@ QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard if (m_pHiddenTableModel.isNull()) { m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); } - m_pHiddenView = new DlgHidden(pLibraryWidget); + m_pHiddenView = new DlgHidden(pSidebar); m_pHiddenView->setTableModel(m_pHiddenTableModel); m_pHiddenView->installEventFilter(pKeyboard); @@ -241,7 +241,7 @@ QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard if (m_pMissingTableModel.isNull()) { m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); } - m_pMissingView = new DlgMissing(pLibraryWidget); + m_pMissingView = new DlgMissing(pSidebar); m_pMissingView->setTableModel(m_pMissingTableModel); m_pMissingView->installEventFilter(pKeyboard); diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index b627f1b1d9a..01ca2269041 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -34,6 +34,9 @@ SetlogFeature::SetlogFeature(UserSettingsPointer pConfig, TreeItem *rootItem = new TreeItem(); m_childModel.setRootItem(rootItem); constructChildModel(-1); + + connect(&PlayerInfo::instance(), SIGNAL(currentPlayingTrackChanged(TrackPointer)), + this, SLOT(slotPlayingTrackChanged(TrackPointer))); } SetlogFeature::~SetlogFeature() { @@ -54,14 +57,6 @@ QIcon SetlogFeature::getIcon() { return QIcon(":/images/library/ic_library_history.png"); } -void SetlogFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int paneId) { - BasePlaylistFeature::bindPaneWidget(libraryWidget, - keyboard, paneId); - connect(&PlayerInfo::instance(), SIGNAL(currentPlayingTrackChanged(TrackPointer)), - this, SLOT(slotPlayingTrackChanged(TrackPointer))); -} - void SetlogFeature::onRightClick(const QPoint& globalPos) { Q_UNUSED(globalPos); m_lastRightClickedIndex = QModelIndex(); diff --git a/src/library/setlogfeature.h b/src/library/setlogfeature.h index a5abeae18f8..bae6da72405 100644 --- a/src/library/setlogfeature.h +++ b/src/library/setlogfeature.h @@ -25,9 +25,6 @@ class SetlogFeature : public BasePlaylistFeature { QVariant title(); QIcon getIcon(); - virtual void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* keyboard, int paneId); - public slots: void onRightClick(const QPoint& globalPos); void onRightClickChild(const QPoint& globalPos, QModelIndex index); From 9438bda30e1af80d5674cd885ec700ddf05d15d8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:36:04 +0200 Subject: [PATCH 196/552] Renamed WBreadCrumb --- build/depends.py | 1 + src/widget/wbreadcrumb.cpp | 30 ------------------- src/widget/wlibrarybreadcrumb.cpp | 30 +++++++++++++++++++ .../{wbreadcrumb.h => wlibrarybreadcrumb.h} | 6 ++-- 4 files changed, 34 insertions(+), 33 deletions(-) delete mode 100644 src/widget/wbreadcrumb.cpp create mode 100644 src/widget/wlibrarybreadcrumb.cpp rename src/widget/{wbreadcrumb.h => wlibrarybreadcrumb.h} (60%) diff --git a/build/depends.py b/build/depends.py index 1b5e0611737..7b27f1f8b96 100644 --- a/build/depends.py +++ b/build/depends.py @@ -815,6 +815,7 @@ def sources(self, build): "widget/wbuttonbar.cpp", "widget/wfeatureclickbutton.cpp", "widget/wlibrarystack.cpp", + "widget/wlibrarybreadcrumb.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/src/widget/wbreadcrumb.cpp b/src/widget/wbreadcrumb.cpp deleted file mode 100644 index dd889156df4..00000000000 --- a/src/widget/wbreadcrumb.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include - -#include - -namespace { - -QString& getPathString(TreeItem* pTree) { - // Base case - if (pTree == nullptr) { - return QString(); - } - - // Recursive case - QString text = pTree->data().toString(); - QString& next = getData(pTree->parent()); - return (next.isEmpty() ? text : next % QLatin1Literal(" > ") % text); -} - -} - - -WBreadCrumb::WBreadCrumb(QWidget* parent) - : QLabel(parent) { - -} - -void WBreadCrumb::setBreadText(TreeItem *pTree) { - QString text = getData(pTree); - setText(text); -} diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp new file mode 100644 index 00000000000..89c8b79db88 --- /dev/null +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -0,0 +1,30 @@ +#include + +#include + +namespace { + +QString getPathString(TreeItem* pTree) { + // Base case + if (pTree == nullptr) { + return QString(); + } + + // Recursive case + QString text = pTree->data().toString(); + QString next = getPathString(pTree->parent()); + return (next.isEmpty() ? text : next % QLatin1Literal(" > ") % text); +} + +} // NAMESPACE + + +WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) + : QLabel(parent) { + setText("I'm a BreadCrumb"); +} + +void WLibraryBreadCrumb::showBreadCrumb(TreeItem *pTree) { + QString text = getPathString(pTree); + setText(text); +} diff --git a/src/widget/wbreadcrumb.h b/src/widget/wlibrarybreadcrumb.h similarity index 60% rename from src/widget/wbreadcrumb.h rename to src/widget/wlibrarybreadcrumb.h index 8f121e1e828..e794d60eb20 100644 --- a/src/widget/wbreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -4,16 +4,16 @@ #include #include "library/treeitem.h" -class WBreadCrumb: public QLabel { +class WLibraryBreadCrumb: public QLabel { Q_OBJECT public: - WBreadCrumb(QWidget* parent = nullptr); + WLibraryBreadCrumb(QWidget* parent = nullptr); public slots: - void setBreadText(TreeItem* pTree); + void showBreadCrumb(TreeItem* pTree); }; #endif /* SRC_WIDGET_WBREADCRUMB_H_ */ From 2d84b62227a0625262df836d8e3f31493d408204 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:36:36 +0200 Subject: [PATCH 197/552] Add breadcrumb to LateNight skin and fix some style issues --- res/skins/LateNight/library.xml | 6 +++ res/skins/LateNight/style.qss | 67 ++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index 84ee907fb63..aeedf94cc3d 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -58,6 +58,9 @@ 1 + + 1 + 1 @@ -69,6 +72,9 @@ 2 + + 2 + 2 diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index b4492a2745a..c2c51439d2e 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -49,19 +49,6 @@ background-color: #0f0f0f; } -#LibrarySingleton { - padding-top: 5px; - padding-bottom: 2px; -} - -#Library { - border-left: 0px solid #585858; - background-color: #0e0e0e; - padding-top: 5px; - padding-bottom: 2px; - /*border-top: 1px solid #585858;*/ -} - #DeckRowOne { qproperty-layoutAlignment: 'AlignLeft | AlignTop'; border-bottom: 1px solid #585858; @@ -1156,9 +1143,17 @@ /* Library styling is hard */ -#LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { - background-color: #0f0f0f; - margin-right: 11px; +#LibrarySingleton { + padding-top: 5px; + padding-bottom: 2px; +} + +#Library { + border-left: 0px solid #585858; + background-color: #0e0e0e; + padding-top: 5px; + padding-bottom: 2px; + /*border-top: 1px solid #585858;*/ } #LibrarySidebarExpanded QWidget { @@ -1178,7 +1173,9 @@ border: none } -#LibrarySidebarExpanded QTabWidget::pane { +#LibrarySidebarExpanded QTabWidget::pane, +#LibrarySidebarExpanded #DlgRecording, +#LibrarySidebarExpanded #DlgAnalysis { border: 1px solid #585858; } @@ -1230,14 +1227,21 @@ background-color: #191919; } -#LibrarySidebarButtons QToolButton:hover, +#LibrarySidebarButtons QToolButton:hover, #LibrarySidebarExpanded QPushButton:hover { border: 1px solid #585858; background-color: #232323; - border-radius: 2px; color: #cfb32c; } +#LibrarySidebarButtons QToolButton:hover { + border-radius: 10px; +} + +#LibrarySidebarButtons QToolButton:focus { + border-radius: 10px; +} + #LibrarySidebarButtons:focus, #LibrarySidebarButtons QToolButton:focus, #LibrarySidebarExpanded > QWidget:focus, @@ -1245,17 +1249,30 @@ border: 1px solid #8E5C00; } +#LibrarySidebarButtons WButtonBar { + background-color: #191919; + margin-right: 11px; +} + +#LibrarySidebarButtons { + margin-right: 5px; +} + #LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { border: 1px solid #585858; /*font: 15px/18px;*/ color: #cfb32c; - background-color: #0f0f0f; + background-color: #191919; alternate-background-color: #1a1a1a; selection-color: #cfb32c; selection-background-color: #725309; } +WLibraryBreadCrumb { + margin: 4px 2px; +} + /* checkbox in library "Played" column */ QTableView::indicator { width: 12px; height: 12px;} QTableView::indicator:checked { background: url(skin:/style/style_checkbox_checked.png);} @@ -1380,16 +1397,6 @@ WBaseLibrary QRadioButton, WBaseLibrary QLabel { margin: 9px 3px 6px 3px; } /* Additional space for the first QRadionButton in the row WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } */ -/* Additional space for the QPushButtons */ -/*#DlgMissing > QPushButton, -#DlgHidden > QPushButton, -#DlgRecording > QPushButton, -#DlgAnalysis > QPushButton { - margin: 2px 3px 2px 3px; - padding: 4px 6px; - min-width: 65px; -}*/ - /* Spacing between treeview and searchbar */ QTreeView { margin: 0px 0px 0px 0px; } From 15fac565ce8d577abe466755907d9c29c3f2c441 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:37:04 +0200 Subject: [PATCH 198/552] Convert dialogs from QWidgets to QFrames --- src/library/autodj/dlgautodj.cpp | 2 +- src/library/autodj/dlgautodj.h | 2 +- src/library/dlganalysis.h | 2 +- src/library/dlghidden.cpp | 2 +- src/library/dlghidden.h | 2 +- src/library/dlgmissing.cpp | 2 +- src/library/dlgmissing.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 5a5bc87ed63..3b1afcdabca 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -10,7 +10,7 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, Library* pLibrary, AutoDJProcessor* pProcessor) - : QWidget(parent), + : QFrame(parent), Ui::DlgAutoDJ(), m_pAutoDJProcessor(pProcessor), // no sorting diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index c1cac4d1581..f7ac02d6196 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -17,7 +17,7 @@ class PlaylistTableModel; class WTrackTableView; -class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ { +class DlgAutoDJ : public QFrame, public Ui::DlgAutoDJ { Q_OBJECT public: DlgAutoDJ(QWidget* parent, Library *pLibrary, AutoDJProcessor* pProcessor); diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index a6d629369f4..9cb9db57125 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -13,7 +13,7 @@ class AnalysisLibraryTableModel; class WAnalysisLibraryTableView; -class DlgAnalysis : public QWidget, public Ui::DlgAnalysis { +class DlgAnalysis : public QFrame, public Ui::DlgAnalysis { Q_OBJECT diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 5c1b22fe68d..7adcc47323d 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -6,7 +6,7 @@ #include "util/assert.h" DlgHidden::DlgHidden(QWidget* parent) - : QWidget(parent), + : QFrame(parent), Ui::DlgHidden() { setupUi(this); diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index 746768c9f8e..a084ea450e3 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -12,7 +12,7 @@ class WTrackTableView; class HiddenTableModel; class QItemSelection; -class DlgHidden : public QWidget, public Ui::DlgHidden { +class DlgHidden : public QFrame, public Ui::DlgHidden { Q_OBJECT public: DlgHidden(QWidget* parent); diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 2dcc9c94687..4eb22b2bcac 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -5,7 +5,7 @@ #include "util/assert.h" DlgMissing::DlgMissing(QWidget* parent) - : QWidget(parent), + : QFrame(parent), Ui::DlgMissing() { setupUi(this); diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index 3a9f996aca5..6438e035b36 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -11,7 +11,7 @@ class WTrackTableView; class MissingTableModel; -class DlgMissing : public QWidget, public Ui::DlgMissing { +class DlgMissing : public QFrame, public Ui::DlgMissing { Q_OBJECT public: DlgMissing(QWidget* parent); From f91a2820f68decb349bbe8ee1411d999d867f1ed Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:37:50 +0200 Subject: [PATCH 199/552] Performance improvements and allow to switch by pointer --- src/library/baseplaylistfeature.cpp | 1 + src/library/library.cpp | 63 +++++++++++++++++------------ src/library/library.h | 30 ++++++++------ src/library/librarypanemanager.cpp | 21 +++++++--- src/library/librarypanemanager.h | 7 +++- 5 files changed, 78 insertions(+), 44 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index e159cc7cfbd..80edd123ea8 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -607,6 +607,7 @@ QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); edit->setHtml(getRootViewHtml()); edit->setOpenLinks(false); + edit->installEventFilter(pKeyboard); connect(edit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); return edit; diff --git a/src/library/library.cpp b/src/library/library.cpp index cc002b9928f..81f163362ed 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -13,6 +13,7 @@ #include "library/libraryfeature.h" #include "library/librarytablemodel.h" #include "library/librarypanemanager.h" +#include "library/librarysidebarexpandedmanager.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" @@ -107,11 +108,9 @@ Library::~Library() { } void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { - if (!m_panes.contains(id)) { - createPane(id); - } - - m_panes[id]->bindSearchBar(searchLine); + // Get the value once to avoid searching again in the hash + LibraryPaneManager* pPane = getPane(id); + pPane->bindSearchBar(searchLine); } void Library::bindSidebarWidget(WButtonBar* sidebar) { @@ -148,19 +147,18 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, pLibraryWidget->registerView(m_sTrackViewName, pTrackTableView); - if (! m_panes.contains(id)) { - createPane(id); - } + // Get the value once to avoid searching again in the hash + LibraryPaneManager* pPane = getPane(id); - m_panes[id]->bindPaneWidget(pLibraryWidget, pKeyboard); + pPane->bindPaneWidget(pLibraryWidget, pKeyboard); - connect(m_panes[id], SIGNAL(showTrackModel(QAbstractItemModel*)), + connect(pPane, SIGNAL(showTrackModel(QAbstractItemModel*)), pTrackTableView, SLOT(loadTrackModel(QAbstractItemModel*))); - connect(m_panes[id], SIGNAL(searchStarting()), + connect(pPane, SIGNAL(searchStarting()), pTrackTableView, SLOT(onSearchStarting())); - connect(m_panes[id], SIGNAL(searchCleared()), + connect(pPane, SIGNAL(searchCleared()), pTrackTableView, SLOT(onSearchCleared())); - connect(m_panes[id], SIGNAL(search(const QString&)), + connect(pPane, SIGNAL(search(const QString&)), pLibraryWidget, SLOT(search(const QString&))); // Set the current font and row height on all the WTrackTableViews that were @@ -179,6 +177,12 @@ void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, m_pSidebarExpanded->bindPaneWidget(expandedPane, pKeyboard); } +void Library::bindBreadCrumb(WLibraryBreadCrumb* pBreadCrumb, int paneId) { + // Get the value once to avoid searching again in the hash + LibraryPaneManager* pPane = getPane(paneId); + pPane->setBreadCrumb(pBreadCrumb); +} + void Library::destroyInterface() { m_pSidebarExpanded->deleteLater(); @@ -251,18 +255,22 @@ void Library::slotSwitchToView(const QString& view) { emit(switchToView(view)); } -void Library::slotSwitchToView(LibraryFeature* pFeature) { - m_pSidebarExpanded->slotSwitchToView(pFeature); +void Library::slotSwitchToViewFeature(LibraryFeature* pFeature) { + m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); // Only change the current pane if it's not shown already if (pWLibrary->getCurrentViewName() != pFeature->getViewName()) { - m_panes[m_focusedPane]->slotSwitchToView(pFeature); + m_panes[m_focusedPane]->slotSwitchToViewFeature(pFeature); } handleFocus(); } +void Library::slotShowBreadCrumb(TreeItem *pTree) { + m_panes[m_focusedPane]->slotShowBreadCrumb(pTree); +} + void Library::slotSwitchToViewChild(const QString &view) { //qDebug() << "Library::slotSwitchToViewChild"; @@ -484,19 +492,21 @@ void Library::slotPaneFocused() { } -void Library::createPane(int id) { +LibraryPaneManager* Library::getPane(int id) { //qDebug() << "Library::createPane" << id; - - if (m_panes.contains(id)) { - return; + // Get the value once to avoid searching again in the hash + auto it = m_panes.find(id); + if (it != m_panes.end()) { + return *it; } - LibraryPaneManager* pane = new LibraryPaneManager(id); - pane->addFeatures(m_features); - m_panes.insert(id, pane); - connect(pane, SIGNAL(focused()), - this, SLOT(slotPaneFocused())); + LibraryPaneManager* pPane = new LibraryPaneManager(id); + pPane->addFeatures(m_features); + m_panes.insert(id, pPane); + + connect(pPane, SIGNAL(focused()), this, SLOT(slotPaneFocused())); m_focusedPane = id; + return pPane; } LibraryPaneManager *Library::getFocusedPane() { @@ -562,8 +572,11 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface } void Library::handleFocus() { + // Changes the visual focus effect, removes the existing one and adds the + // new focus m_panes[m_focusedPane]->setFocus(); for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { + // Remove the focus from not focused panes if (it.key() != m_focusedPane) { it.value()->clearFocus(); } diff --git a/src/library/library.h b/src/library/library.h index e9023897439..07e09805f9e 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -20,26 +20,28 @@ #include "library/coverartcache.h" #include "library/setlogfeature.h" #include "library/scanner/libraryscanner.h" -#include "library/librarysidebarexpandedmanager.h" #include "widget/wtracktableview.h" #include "widget/wfeatureclickbutton.h" +class CrateFeature; +class KeyboardEventFilter; class LibraryPaneManager; -class TrackModel; -class TrackCollection; -class SidebarModel; +class LibraryControl; class LibraryFeature; class LibraryTableModel; -class WLibrarySidebar; -class WLibrary; -class WSearchLineEdit; +class LibrarySidebarExpandedManager; class MixxxLibraryFeature; class PlaylistFeature; -class CrateFeature; -class LibraryControl; -class KeyboardEventFilter; class PlayerManagerInterface; +class SidebarModel; +class TrackModel; +class TrackCollection; +class WLibrary; +class WLibrarySidebar; +class WLibraryBreadCrumb; +class WButtonBar; +class WSearchLineEdit; class Library : public QObject { Q_OBJECT @@ -56,6 +58,7 @@ class Library : public QObject { KeyboardEventFilter* pKeyboard, int id); void bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard); + void bindBreadCrumb(WLibraryBreadCrumb *pBreadCrumb, int paneId); void destroyInterface(); LibraryView* getActiveView(); @@ -92,7 +95,8 @@ class Library : public QObject { void slotHoverFeature(const QString& featureName); void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); - void slotSwitchToView(LibraryFeature* pFeature); + void slotSwitchToViewFeature(LibraryFeature* pFeature); + void slotShowBreadCrumb(TreeItem* pTree); void slotSwitchToViewChild(const QString& view); void slotSwitchToNotFocusedView(const QString& view); void slotLoadTrack(TrackPointer pTrack); @@ -133,8 +137,8 @@ class Library : public QObject { private: - void createPane(int id); - + // If the pane exists returns it, otherwise it creates the pane + LibraryPaneManager *getPane(int id); LibraryPaneManager* getFocusedPane(); UserSettingsPointer m_pConfig; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 7b737ff63b7..30df2e4c79d 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -4,6 +4,7 @@ #include "library/libraryfeature.h" #include "widget/wtracktableview.h" #include "widget/wbuttonbar.h" +#include "widget/wlibrarybreadcrumb.h" #include "util/assert.h" const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); @@ -11,6 +12,7 @@ const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); LibraryPaneManager::LibraryPaneManager(int paneId, QObject* parent) : QObject(parent), m_pPaneWidget(nullptr), + m_pBreadCrumb(nullptr), m_paneId(paneId) { qApp->installEventFilter(this); } @@ -33,11 +35,12 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, return; } for (LibraryFeature* f : m_features) { - f->bindPaneWidget(lib, pKeyboard, m_paneId); + //f->bindPaneWidget(lib, pKeyboard, m_paneId); - //QWidget* pPane = f->createPaneWidget(pKeyboard, m_paneId); - //pPane->setParent(lib); - //lib->registerView(f->getViewName(), pPane); + QWidget* pPane = f->createPaneWidget(pKeyboard, m_paneId); + pPane->setParent(lib); + lib->registerView(f->getViewName(), pPane); + m_featuresWidget[f] = lib->indexOf(pPane); } } @@ -54,6 +57,10 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchLine) { pSearchLine, SLOT(restoreSearch(const QString&))); } +void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb *pBreadCrumb) { + m_pBreadCrumb = pBreadCrumb; +} + void LibraryPaneManager::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; @@ -103,7 +110,7 @@ void LibraryPaneManager::slotSwitchToView(const QString& view) { m_pPaneWidget->setFocus(); } -void LibraryPaneManager::slotSwitchToView(LibraryFeature* pFeature) { +void LibraryPaneManager::slotSwitchToViewFeature(LibraryFeature* pFeature) { if (!m_featuresWidget.contains(pFeature)) { return; } @@ -116,6 +123,10 @@ void LibraryPaneManager::slotRestoreSearch(const QString& text) { emit(restoreSearch(text)); } +void LibraryPaneManager::slotShowBreadCrumb(TreeItem *pTree) { + m_pBreadCrumb->showBreadCrumb(pTree); +} + bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (m_pPaneWidget == nullptr) { return false; diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 7d4b31ab31f..b696780c5c8 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -10,6 +10,8 @@ class LibraryFeature; class WButtonBar; +class WLibraryBreadCrumb; +class TreeItem; class LibraryPaneManager : public QObject { Q_OBJECT @@ -26,6 +28,7 @@ class LibraryPaneManager : public QObject { virtual void bindPaneWidget(WBaseLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard); void bindSearchBar(WSearchLineEdit* pSearchLine); + void setBreadCrumb(WLibraryBreadCrumb* pBreadCrumb); void addFeature(LibraryFeature* feature); void addFeatures(const QList& features); @@ -62,14 +65,16 @@ class LibraryPaneManager : public QObject { void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); - void slotSwitchToView(LibraryFeature* pFeature); + void slotSwitchToViewFeature(LibraryFeature* pFeature); void slotRestoreSearch(const QString& text); + void slotShowBreadCrumb(TreeItem* pTree); protected: WBaseLibrary* m_pPaneWidget; QList m_features; QHash m_featuresWidget; + WLibraryBreadCrumb* m_pBreadCrumb; private: From d2f0dcf2ff14db16bb4b94ec4b65c342aa9d3be3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:38:11 +0200 Subject: [PATCH 200/552] Add WLibraryBreadCrumb to LegacySkinParser --- src/skin/legacyskinparser.cpp | 29 ++++++++++++++++++++++++++--- src/skin/legacyskinparser.h | 1 + 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 4684647fecc..e7c6de85ace 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -66,6 +66,7 @@ #include "widget/wsearchlineedit.h" #include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" +#include "widget/wlibrarybreadcrumb.h" #include "widget/wbuttonbar.h" #include "widget/wskincolor.h" #include "widget/wpixmapstore.h" @@ -563,6 +564,8 @@ QList LegacySkinParser::parseNode(const QDomElement& node) { result = wrapWidget(parseLibrarySidebarExpanded(node)); } else if (nodeName == "LibraryPane") { result = wrapWidget(parseLibraryPane(node)); + } else if (nodeName == "LibraryBreadCrumb") { + result = wrapWidget(parseLibraryBreadCrumb(node)); } else if (nodeName == "Library") { result = wrapWidget(parseLibrary(node)); } else if (nodeName == "Key") { @@ -1270,13 +1273,18 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { // Must add both a SearchBox and a LibraryPane QFrame* pContainer = new QFrame(m_pParent); QVBoxLayout* pLayout = new QVBoxLayout(pContainer); - pContainer->setLayout(pLayout); + pContainer->setLayout(pLayout); WSearchLineEdit* pSearchBox = new WSearchLineEdit(pContainer); pSearchBox->setup(node, *m_pContext); m_pLibrary->bindSearchBar(pSearchBox, m_paneId); commonWidgetSetup(node, pSearchBox); pLayout->addWidget(pSearchBox); + + WLibraryBreadCrumb* pBreadCrumb = new WLibraryBreadCrumb(pContainer); + m_pLibrary->bindBreadCrumb(pBreadCrumb, m_paneId); + setupWidget(node, pBreadCrumb); + pLayout->addWidget(pBreadCrumb); WLibrary* pLibraryWidget = new WLibrary(pContainer); pLibraryWidget->installEventFilter(m_pKeyboard); @@ -1315,7 +1323,7 @@ QWidget *LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { m_pLibrary->bindSidebarExpanded(pLibrarySidebarExpanded, m_pKeyboard); pLayout->addWidget(pLibrarySidebarExpanded); - commonWidgetSetup(node, pLibrarySidebar, false); + setupWidget(node, pLibrarySidebar); commonWidgetSetup(node, pLibrarySidebarExpanded, false); return pContainer; } @@ -1330,7 +1338,6 @@ QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { m_pLibrary->bindSidebarWidget(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); - commonWidgetSetup(node, pLibrarySidebar, false); setupWidget(node, scroll); return scroll; } @@ -1344,6 +1351,22 @@ QWidget *LegacySkinParser::parseLibrarySidebarExpanded(const QDomElement &node) return pLibrarySidebarExpanded; } +QWidget* LegacySkinParser::parseLibraryBreadCrumb(const QDomElement& node) { + WLibraryBreadCrumb* pLibraryBreacrumb = new WLibraryBreadCrumb(m_pParent); + + int id = -1; + if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { + //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; + m_pLibrary->bindBreadCrumb(pLibraryBreacrumb, id); + } + else { + SKIN_WARNING(node, *m_pContext) << "No Id found"; + } + setupWidget(node, pLibraryBreacrumb); + + return pLibraryBreacrumb; +} + QWidget* LegacySkinParser::parseTableView(const QDomElement& node) { QStackedWidget* pTabWidget = new QStackedWidget(m_pParent); diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index 50fc39a78e7..a05ef2e5264 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -103,6 +103,7 @@ class LegacySkinParser : public QObject, public SkinParser { QWidget* parseLibrarySidebar(const QDomElement& node); QWidget* parseLibrarySidebarButtons(const QDomElement& node); QWidget* parseLibrarySidebarExpanded(const QDomElement& node); + QWidget* parseLibraryBreadCrumb(const QDomElement& node); QWidget* parseLibrary(const QDomElement& node); QWidget* parseBattery(const QDomElement& node); QWidget* parseCoverArt(const QDomElement& node); From 6156f026bd24aad5e842bd23bb6e84e69801cf6a Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:39:02 +0200 Subject: [PATCH 201/552] Fix some bugs with connections --- src/library/recording/dlgrecording.cpp | 2 +- src/library/recording/dlgrecording.h | 2 +- src/library/recording/recordingfeature.cpp | 3 --- src/widget/wbaselibrary.h | 1 - src/widget/wbuttonbar.cpp | 3 +-- src/widget/wbuttonbar.h | 4 ++-- 6 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index a2d62467b79..7e8eb1dc4b0 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -10,7 +10,7 @@ DlgRecording::DlgRecording(QWidget* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) - : QWidget(parent), + : QFrame(parent), m_pTrackCollection(pTrackCollection), m_browseModel(this, m_pTrackCollection, pRecordingManager), m_proxyModel(&m_browseModel), diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index 5a2788b9794..e79f7b81a0d 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -16,7 +16,7 @@ class PlaylistTableModel; class QSqlTableModel; class WTrackTableView; -class DlgRecording : public QWidget, public Ui::DlgRecording { +class DlgRecording : public QFrame, public Ui::DlgRecording { Q_OBJECT public: DlgRecording(QWidget *parent, TrackCollection* pTrackCollection, diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 84738185672..1862ccd0212 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -74,9 +74,6 @@ void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, m_pRecordingManager); m_pRecordingView->installEventFilter(pKeyboard); - connect(this, SIGNAL(refreshBrowseModel()), - m_pRecordingView, SLOT(refreshBrowseModel())); - for (WTrackTableView* pTable : m_trackTables) { m_pRecordingView->setTrackTable(pTable); } diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 103766ee6d3..0c793dc488e 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -35,7 +35,6 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget protected: bool eventFilter(QObject*, QEvent* pEvent); - bool event(QEvent* pEvent) override; QMap m_viewMap; diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 09269612875..24a38d9c46e 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -4,7 +4,7 @@ #include "library/libraryfeature.h" WButtonBar::WButtonBar(QWidget* parent) - : WWidget(parent) { + : QFrame(parent) { m_pLayout = new QVBoxLayout(this); m_pLayout->setContentsMargins(0,0,0,0); @@ -17,7 +17,6 @@ WFeatureClickButton* WButtonBar::addButton(LibraryFeature* pFeature) { WFeatureClickButton* button = new WFeatureClickButton(pFeature, this); button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - //button->setFocusPolicy(Qt::NoFocus); m_pLayout->addWidget(button); return button; diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index e06dafb213a..35c5908357d 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -5,11 +5,11 @@ #include #include #include +#include -#include "widget/wwidget.h" #include "widget/wfeatureclickbutton.h" -class WButtonBar : public WWidget +class WButtonBar : public QFrame { Q_OBJECT public: From 7c549fa364c28a247aae473622450034da9f26cf Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:39:36 +0200 Subject: [PATCH 202/552] Fix bug in browseFeature and begin experimenting breadcrumb --- src/library/analysisfeature.cpp | 6 +++++- src/library/autodj/autodjfeature.cpp | 2 +- src/library/browse/browsefeature.cpp | 2 +- src/library/dlganalysis.cpp | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index db783e6fa7a..3463fcb4ca8 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -8,6 +8,7 @@ #include "library/librarytablemodel.h" #include "library/trackcollection.h" #include "library/dlganalysis.h" +#include "library/library.h" #include "widget/wlibrary.h" #include "widget/wanalysislibrarytableview.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -154,7 +155,10 @@ void AnalysisFeature::selectAll() { void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; - emit(switchToView(m_sAnalysisViewName)); + //m_pLibrary->switchToView(m_sAnalysisViewName); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + if (m_pAnalysisView) { emit(restoreSearch(m_pAnalysisView->currentSearch())); } diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index a707d9fe9f5..25268e0dbc8 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -135,7 +135,7 @@ void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, //qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; QWidget* pSidebar = createSidebarWidget(pKeyboard); pSidebar->setParent(pSidebarWidget); - pSidebarWidget->registerView(m_sAutoDJViewName, pContainer); + pSidebarWidget->registerView(m_sAutoDJViewName, pSidebar); } QWidget* AutoDJFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 9339c62fbf1..4dd851f7a40 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -219,7 +219,7 @@ void BrowseFeature::bindPaneWidget(WLibrary* pPaneWidget, int paneId) { QWidget* pPane = createPaneWidget(pKeyboard, paneId); pPane->setParent(pPaneWidget); - pPaneWidget->registerView(m_sBrowseViewName, pPaneWidget); + pPaneWidget->registerView(m_sBrowseViewName, pPane); } QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index 4264c911f7b..983a76935f9 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -9,7 +9,7 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, TrackCollection* pTrackCollection) - : QWidget(parent), + : QFrame(parent), m_pTrackCollection(pTrackCollection), m_bAnalysisActive(false), m_tracksInQueue(0), From 4fd784f24fa80bc0fca84504c4f8c1335c8a119e Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 13:47:01 +0200 Subject: [PATCH 203/552] Fix segmentation fault and remove unnecessary inheritance --- src/library/librarypanemanager.cpp | 3 +++ src/widget/wlibrarysidebar.h | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 30df2e4c79d..8d79c995acf 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -38,6 +38,9 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, //f->bindPaneWidget(lib, pKeyboard, m_paneId); QWidget* pPane = f->createPaneWidget(pKeyboard, m_paneId); + if (pPane == nullptr) { + continue; + } pPane->setParent(lib); lib->registerView(f->getViewName(), pPane); m_featuresWidget[f] = lib->indexOf(pPane); diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index 91779778c1c..07ce7691592 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -15,12 +15,10 @@ #include "widget/wbasewidget.h" #include "library/libraryview.h" -class WLibrarySidebar : public QTreeView, public WBaseWidget, public LibraryView { +class WLibrarySidebar : public QTreeView, public WBaseWidget { Q_OBJECT public: explicit WLibrarySidebar(QWidget* parent = nullptr); - - void onShow() override {} void contextMenuEvent(QContextMenuEvent * event) override; void dragMoveEvent(QDragMoveEvent * event) override; From 68ebe852136c73207c78fa5d79ee4711a7688708 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 16:34:38 +0200 Subject: [PATCH 204/552] Rename SetLogFeature to HistoryFeature --- build/depends.py | 2 +- .../{setlogfeature.cpp => historyfeature.cpp} | 32 +++++++++---------- .../{setlogfeature.h => historyfeature.h} | 6 ++-- src/library/library.cpp | 4 +-- src/library/library.h | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) rename src/library/{setlogfeature.cpp => historyfeature.cpp} (93%) rename src/library/{setlogfeature.h => historyfeature.h} (90%) diff --git a/build/depends.py b/build/depends.py index 7b27f1f8b96..0405ebd0f0b 100644 --- a/build/depends.py +++ b/build/depends.py @@ -858,7 +858,7 @@ def sources(self, build): "library/mixxxlibraryfeature.cpp", "library/baseplaylistfeature.cpp", "library/playlistfeature.cpp", - "library/setlogfeature.cpp", + "library/historyfeature.cpp", "library/autodj/dlgautodj.cpp", "library/dlganalysis.cpp", "library/dlgcoverartfullsize.cpp", diff --git a/src/library/setlogfeature.cpp b/src/library/historyfeature.cpp similarity index 93% rename from src/library/setlogfeature.cpp rename to src/library/historyfeature.cpp index 01ca2269041..5393080e16d 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/historyfeature.cpp @@ -2,7 +2,7 @@ #include #include -#include "library/setlogfeature.h" +#include "library/historyfeature.h" #include "control/controlobject.h" #include "library/playlisttablemodel.h" @@ -11,7 +11,7 @@ #include "mixer/playerinfo.h" #include "mixer/playermanager.h" -SetlogFeature::SetlogFeature(UserSettingsPointer pConfig, +HistoryFeature::HistoryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) @@ -39,7 +39,7 @@ SetlogFeature::SetlogFeature(UserSettingsPointer pConfig, this, SLOT(slotPlayingTrackChanged(TrackPointer))); } -SetlogFeature::~SetlogFeature() { +HistoryFeature::~HistoryFeature() { // If the history playlist we created doesn't have any tracks in it then // delete it so we don't end up with tons of empty playlists. This is mostly // for developers since they regularly open Mixxx without loading a track. @@ -49,15 +49,15 @@ SetlogFeature::~SetlogFeature() { } } -QVariant SetlogFeature::title() { +QVariant HistoryFeature::title() { return tr("History"); } -QIcon SetlogFeature::getIcon() { +QIcon HistoryFeature::getIcon() { return QIcon(":/images/library/ic_library_history.png"); } -void SetlogFeature::onRightClick(const QPoint& globalPos) { +void HistoryFeature::onRightClick(const QPoint& globalPos) { Q_UNUSED(globalPos); m_lastRightClickedIndex = QModelIndex(); @@ -68,7 +68,7 @@ void SetlogFeature::onRightClick(const QPoint& globalPos) { // menu.exec(globalPos); } -void SetlogFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { +void HistoryFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { //Save the model index so we can get it in the action slots... m_lastRightClickedIndex = index; QString playlistName = index.data().toString(); @@ -109,7 +109,7 @@ void SetlogFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index } -void SetlogFeature::buildPlaylistList() { +void HistoryFeature::buildPlaylistList() { m_playlistList.clear(); // Setup the sidebar playlist model QSqlTableModel playlistTableModel(this, m_pTrackCollection->getDatabase()); @@ -134,7 +134,7 @@ void SetlogFeature::buildPlaylistList() { } } -void SetlogFeature::decorateChild(TreeItem* item, int playlist_id) { +void HistoryFeature::decorateChild(TreeItem* item, int playlist_id) { if (playlist_id == m_playlistId) { item->setIcon(QIcon(":/images/library/ic_library_history_current.png")); } else if (m_playlistDao.isPlaylistLocked(playlist_id)) { @@ -144,7 +144,7 @@ void SetlogFeature::decorateChild(TreeItem* item, int playlist_id) { } } -void SetlogFeature::slotGetNewPlaylist() { +void HistoryFeature::slotGetNewPlaylist() { //qDebug() << "slotGetNewPlaylist() succesfully triggered !"; // create a new playlist for today @@ -173,7 +173,7 @@ void SetlogFeature::slotGetNewPlaylist() { emit(showTrackModel(m_pPlaylistTableModel)); } -void SetlogFeature::slotJoinWithPrevious() { +void HistoryFeature::slotJoinWithPrevious() { //qDebug() << "slotJoinWithPrevious() row:" << m_lastRightClickedIndex.data(); if (m_lastRightClickedIndex.isValid()) { @@ -225,7 +225,7 @@ void SetlogFeature::slotJoinWithPrevious() { } } -void SetlogFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) { +void HistoryFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) { if (!currentPlayingTrack) { return; } @@ -271,7 +271,7 @@ void SetlogFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) { } } -void SetlogFeature::slotPlaylistTableChanged(int playlistId) { +void HistoryFeature::slotPlaylistTableChanged(int playlistId) { if (!m_pPlaylistTableModel) { return; } @@ -285,7 +285,7 @@ void SetlogFeature::slotPlaylistTableChanged(int playlistId) { } } -void SetlogFeature::slotPlaylistContentChanged(int playlistId) { +void HistoryFeature::slotPlaylistContentChanged(int playlistId) { if (!m_pPlaylistTableModel) { return; } @@ -298,7 +298,7 @@ void SetlogFeature::slotPlaylistContentChanged(int playlistId) { } } -void SetlogFeature::slotPlaylistTableRenamed(int playlistId, +void HistoryFeature::slotPlaylistTableRenamed(int playlistId, QString /* a_strName */) { if (!m_pPlaylistTableModel) { return; @@ -316,7 +316,7 @@ void SetlogFeature::slotPlaylistTableRenamed(int playlistId, } } -QString SetlogFeature::getRootViewHtml() const { +QString HistoryFeature::getRootViewHtml() const { QString playlistsTitle = tr("History"); QString playlistsSummary = tr("The history section automatically keeps a list of tracks you play in your DJ sets."); QString playlistsSummary2 = tr("This is handy for remembering what worked in your DJ sets, posting set-lists, or reporting your plays to licensing organizations."); diff --git a/src/library/setlogfeature.h b/src/library/historyfeature.h similarity index 90% rename from src/library/setlogfeature.h rename to src/library/historyfeature.h index bae6da72405..024dc3f16f4 100644 --- a/src/library/setlogfeature.h +++ b/src/library/historyfeature.h @@ -13,14 +13,14 @@ class TrackCollection; class TreeItem; -class SetlogFeature : public BasePlaylistFeature { +class HistoryFeature : public BasePlaylistFeature { Q_OBJECT public: - SetlogFeature(UserSettingsPointer pConfig, + HistoryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection); - virtual ~SetlogFeature(); + virtual ~HistoryFeature(); QVariant title(); QIcon getIcon(); diff --git a/src/library/library.cpp b/src/library/library.cpp index 81f163362ed..5f9687c2c51 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -28,7 +28,7 @@ #include "library/playlistfeature.h" #include "library/traktor/traktorfeature.h" #include "library/librarycontrol.h" -#include "library/setlogfeature.h" +#include "library/historyfeature.h" #include "util/sandbox.h" #include "util/assert.h" @@ -540,7 +540,7 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(browseFeature); addFeature(new RecordingFeature(pConfig, this, this, m_pTrackCollection, m_pRecordingManager)); - addFeature(new SetlogFeature(pConfig, this, this, m_pTrackCollection)); + addFeature(new HistoryFeature(pConfig, this, this, m_pTrackCollection)); m_pAnalysisFeature = new AnalysisFeature(m_pTrackCollection, pConfig, this, this);//this, pConfig, m_pTrackCollection); connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), m_pAnalysisFeature, SLOT(analyzeTracks(QList))); diff --git a/src/library/library.h b/src/library/library.h index 07e09805f9e..396f65578d5 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -18,7 +18,7 @@ #include "recording/recordingmanager.h" #include "analysisfeature.h" #include "library/coverartcache.h" -#include "library/setlogfeature.h" +#include "library/historyfeature.h" #include "library/scanner/libraryscanner.h" #include "widget/wtracktableview.h" From 467d620b660e46a044169b58412df368c833170c Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 16:35:41 +0200 Subject: [PATCH 205/552] Add breadcrumb to analysis, and basePlaylist feature --- src/library/analysisfeature.cpp | 3 +++ src/library/baseplaylistfeature.cpp | 6 +++++- src/library/librarysidebarexpandedmanager.cpp | 14 +++++++++++--- src/library/librarysidebarexpandedmanager.h | 2 +- src/library/treeitem.cpp | 4 ++-- src/widget/wlibrarybreadcrumb.cpp | 6 +++--- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 3463fcb4ca8..0834ac23d19 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -9,6 +9,7 @@ #include "library/trackcollection.h" #include "library/dlganalysis.h" #include "library/library.h" +#include "library/treeitem.h" #include "widget/wlibrary.h" #include "widget/wanalysislibrarytableview.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -30,6 +31,8 @@ AnalysisFeature::AnalysisFeature(TrackCollection* pTrackCollection, m_iOldBpmEnabled(0), m_analysisTitleName(tr("Analyze")), m_pAnalysisView(nullptr){ + + m_childModel.setRootItem(new TreeItem("$root", "$root", this, nullptr)); setTitleDefault(); } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 80edd123ea8..8e64c6cf6bb 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -132,7 +132,10 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { void BasePlaylistFeature::activate() { m_featureFocus = -1; - emit(switchToView(m_rootViewName)); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + + //emit(switchToView(m_rootViewName)); emit(restoreSearch(QString())); // Null String disables search box emit(enableCoverArtDisplay(true)); } @@ -628,6 +631,7 @@ void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) { */ QModelIndex BasePlaylistFeature::constructChildModel(int selected_id) { buildPlaylistList(); + m_childModel.setRootItem(new TreeItem("$root", "$root", this, nullptr)); QList data_list; int selected_row = -1; // Access the invisible root item diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 089342dbd20..8686d8ca9a5 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -6,16 +6,24 @@ LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) } -void LibrarySidebarExpandedManager::bindPaneWidget(WBaseLibrary* libraryWidget, +void LibrarySidebarExpandedManager::bindPaneWidget(WBaseLibrary* sidebarWidget, KeyboardEventFilter* pKeyboard) { - m_pPaneWidget = libraryWidget; + m_pPaneWidget = sidebarWidget; connect(this, SIGNAL(switchToView(const QString&)), m_pPaneWidget, SLOT(switchToView(const QString&))); for (LibraryFeature* f : m_features) { - f->bindSidebarWidget(m_pPaneWidget, pKeyboard); + //f->bindSidebarWidget(m_pPaneWidget, pKeyboard); + + QWidget* pPane = f->createSidebarWidget(pKeyboard); + if (pPane == nullptr) { + continue; + } + pPane->setParent(sidebarWidget); + sidebarWidget->registerView(f->getViewName(), pPane); + m_featuresWidget[f] = sidebarWidget->indexOf(pPane); } } diff --git a/src/library/librarysidebarexpandedmanager.h b/src/library/librarysidebarexpandedmanager.h index 0f1a659f75e..559cf5a4017 100644 --- a/src/library/librarysidebarexpandedmanager.h +++ b/src/library/librarysidebarexpandedmanager.h @@ -7,7 +7,7 @@ class LibrarySidebarExpandedManager : public LibraryPaneManager public: LibrarySidebarExpandedManager(QObject* parent = nullptr); - void bindPaneWidget(WBaseLibrary* libraryWidget, + void bindPaneWidget(WBaseLibrary* sidebarWidget, KeyboardEventFilter* pKeyboard) override; }; diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 2985373fcb9..2675b4532bf 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -41,8 +41,8 @@ TreeItem::TreeItem(const QString &data, const QString &data_path, TreeItem::TreeItem() { m_data = "$root"; m_dataPath = "$root"; - m_parentItem = NULL; - m_feature = NULL; + m_parentItem = nullptr; + m_feature = nullptr; m_bold = false; } diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 89c8b79db88..82b23eee717 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -6,14 +6,14 @@ namespace { QString getPathString(TreeItem* pTree) { // Base case - if (pTree == nullptr) { - return QString(); + if (pTree->parent() == nullptr) { + return pTree->getFeature()->title().toString(); } // Recursive case QString text = pTree->data().toString(); QString next = getPathString(pTree->parent()); - return (next.isEmpty() ? text : next % QLatin1Literal(" > ") % text); + return next % QLatin1Literal(" > ") % text; } } // NAMESPACE From d0487cbfa98a0af9e16adbd77a62726673f9c7a8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 16:58:02 +0200 Subject: [PATCH 206/552] Add BreadCrumb to AutoDJ and fix CoverArt --- src/library/autodj/autodjfeature.cpp | 15 +++++++++++++-- src/library/treeitem.cpp | 10 +++++++--- src/library/treeitem.h | 4 +++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 25268e0dbc8..8d13bb4c78d 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -57,6 +57,8 @@ AutoDJFeature::AutoDJFeature(UserSettingsPointer pConfig, // Create the "Crates" tree-item under the root item. TreeItem* root = m_childModel.getItem(QModelIndex()); + root->setLibraryFeature(this); + m_pCratesTreeItem = new TreeItem(tr("Crates"), "", this, root); m_pCratesTreeItem->setIcon(QIcon(":/images/library/ic_library_crates.png")); root->appendChild(m_pCratesTreeItem); @@ -118,6 +120,12 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan pTrackTableView, SLOT(setTrackTableFont(const QFont&))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + m_pLibrary, SIGNAL(trackSelected(TrackPointer))); + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + this, SLOT(prova())); + m_trackTables[paneId] = pTrackTableView; pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); @@ -167,8 +175,11 @@ TreeItemModel* AutoDJFeature::getChildModel() { void AutoDJFeature::activate() { //qDebug() << "AutoDJFeature::activate()"; m_pAutoDJView->onShow(); - emit(switchToView(m_sAutoDJViewName)); - emit(restoreSearch(QString())); //Null String disables search box + + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotRestoreSearch(QString()); //Null String disables search box + emit(enableCoverArtDisplay(true)); } diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 2675b4532bf..dc4575579e0 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -34,7 +34,7 @@ TreeItem::TreeItem(const QString &data, const QString &data_path, m_data = data; m_dataPath = data_path; m_parentItem = parent; - m_feature = feature; + m_pFeature = feature; m_bold = false; } @@ -42,7 +42,7 @@ TreeItem::TreeItem() { m_data = "$root"; m_dataPath = "$root"; m_parentItem = nullptr; - m_feature = nullptr; + m_pFeature = nullptr; m_bold = false; } @@ -95,7 +95,11 @@ int TreeItem::row() const { } LibraryFeature* TreeItem::getFeature() { - return m_feature; + return m_pFeature; +} + +void TreeItem::setLibraryFeature(LibraryFeature *pFeature) { + m_pFeature = pFeature; } bool TreeItem::insertChildren(QList &data, int position, int count) { diff --git a/src/library/treeitem.h b/src/library/treeitem.h index a2e3f596071..6b7be0594a6 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -49,6 +49,8 @@ class TreeItem { bool isFolder() const; /* Returns the Library feature object to which an item belongs to */ LibraryFeature* getFeature(); + + void setLibraryFeature(LibraryFeature* pFeature); void setBold(bool bold) { m_bold = bold; @@ -65,7 +67,7 @@ class TreeItem { QList m_childItems; QString m_dataPath; QString m_data; - LibraryFeature* m_feature; + LibraryFeature* m_pFeature; bool m_bold; TreeItem *m_parentItem; From 1d5674471ea1954653ccb047f796e29d5e45db0a Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 19:03:46 +0200 Subject: [PATCH 207/552] Fixed many crashes [Not building] --- src/library/autodj/autodjfeature.cpp | 2 -- src/library/baseplaylistfeature.cpp | 7 +++- src/library/cratefeature.cpp | 37 +++++++++++++++------- src/library/cratefeature.h | 3 +- src/library/libraryfeature.cpp | 27 ++++++++++++---- src/library/mixxxlibraryfeature.cpp | 15 ++++++--- src/library/recording/dlgrecording.cpp | 8 ++--- src/library/recording/dlgrecording.h | 7 ++-- src/library/recording/recordingfeature.cpp | 33 +++++++++++++++---- src/library/recording/recordingfeature.h | 7 ++++ src/widget/wlibrarybreadcrumb.cpp | 7 ++-- 11 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 8d13bb4c78d..94ebaa94d53 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -123,8 +123,6 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), m_pLibrary, SIGNAL(trackSelected(TrackPointer))); - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SLOT(prova())); m_trackTables[paneId] = pTrackTableView; diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 8e64c6cf6bb..5a1da4eb60c 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -145,7 +145,12 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { int playlistId = playlistIdFromIndex(index); if (playlistId != -1 && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); - emit(showTrackModel(m_pPlaylistTableModel)); + m_pLibrary->slotShowTrackModel(m_pPlaylistTableModel); + TreeItem* pTree = static_cast (index.internalPointer()); + if (pTree) { + m_pLibrary->slotShowBreadCrumb(pTree); + } + emit(enableCoverArtDisplay(true)); } } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 933396f196b..d829d2ee83d 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -97,8 +97,9 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, this, SLOT(slotCrateTableChanged(int))); // construct child model - TreeItem *rootItem = new TreeItem(); - m_childModel.setRootItem(rootItem); + TreeItem *pRootItem = new TreeItem(); + pRootItem->setLibraryFeature(this); + m_childModel.setRootItem(pRootItem); constructChildModel(-1); connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), @@ -130,7 +131,7 @@ QIcon CrateFeature::getIcon() { int CrateFeature::crateIdFromIndex(QModelIndex index) { TreeItem* item = static_cast(index.internalPointer()); - if (item == NULL) { + if (item == nullptr) { return -1; } @@ -188,14 +189,20 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { } void CrateFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* keyboard, int) { - Q_UNUSED(keyboard); - WLibraryTextBrowser* edit = new WLibraryTextBrowser(pLibraryWidget); - edit->setHtml(getRootViewHtml()); - edit->setOpenLinks(false); - connect(edit, SIGNAL(anchorClicked(const QUrl)), + KeyboardEventFilter* pKeyboard, int paneId) { + QWidget* pPane = createPaneWidget(pKeyboard, paneId); + pPane->setParent(pLibraryWidget); + pLibraryWidget->registerView(m_sCrateViewName, pPane); +} + +QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, int) { + WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(nullptr); + pEdit->setHtml(getRootViewHtml()); + pEdit->setOpenLinks(false); + pEdit->installEventFilter(pKeyboard); + connect(pEdit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); - pLibraryWidget->registerView(m_sCrateViewName, edit); + return pEdit; } TreeItemModel* CrateFeature::getChildModel() { @@ -204,20 +211,26 @@ TreeItemModel* CrateFeature::getChildModel() { void CrateFeature::activate() { m_featureFocus = -1; + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + emit(switchToView(m_sCrateViewName)); emit(restoreSearch(QString())); //disable search on crate home emit(enableCoverArtDisplay(true)); } void CrateFeature::activateChild(const QModelIndex& index) { - if (!index.isValid()) + if (!index.isValid()) { return; + } int crateId = crateIdFromIndex(index); if (crateId == -1) { return; } m_crateTableModel.setTableModel(crateId); - emit(showTrackModel(&m_crateTableModel)); + + m_pLibrary->slotShowTrackModel(&m_crateTableModel); + m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index a5e62f5927b..153304d6257 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -44,7 +44,8 @@ class CrateFeature : public LibraryFeature { bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); void bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* keyboard, int); + KeyboardEventFilter* pKeyboard, int paneId); + QWidget *createPaneWidget(KeyboardEventFilter* pKeyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 4cd0a9cfbdb..99437fbbba4 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -1,14 +1,17 @@ // libraryfeature.cpp // Created 8/17/2009 by RJ Ryan (rryan@mit.edu) -#include -#include -#include -#include +#include #include -#include #include +#include +#include +#include #include +#include +#include +#include + #include "library/libraryfeature.h" #include "widget/wbaselibrary.h" @@ -43,8 +46,17 @@ void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryFeature::bindSidebarWidget"; + QFrame* pContainer = new QFrame(nullptr); + pContainer->setContentsMargins(0,0,0,0); + + QVBoxLayout* pLayout = new QVBoxLayout(pContainer); + pContainer->setLayout(pLayout); + + QLabel* pTitle = new QLabel(title().toString(), pContainer); + pLayout->addWidget(pTitle); + TreeItemModel* pTreeModel = getChildModel(); - WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); + WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); pSidebar->installEventFilter(pKeyboard); pSidebar->setModel(pTreeModel); @@ -56,8 +68,9 @@ QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { this, SLOT(onRightClickChild(const QPoint&, const QModelIndex&))); connect(pSidebar, SIGNAL(expanded(const QModelIndex&)), this, SLOT(onLazyChildExpandation(const QModelIndex&))); + pLayout->addWidget(pSidebar); - return pSidebar; + return pContainer; } void LibraryFeature::setFeatureFocus(int focus) { diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 29db8761c47..91e14828139 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -113,6 +113,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection, "mixxx.db.model.library"); TreeItem* pRootItem = new TreeItem(); + pRootItem->setLibraryFeature(this); + TreeItem* pLibraryChildItem = new TreeItem(kLibraryTitle, m_sMixxxLibraryViewName, this, pRootItem); pLibraryChildItem->setIcon(getIcon()); @@ -315,13 +317,16 @@ void MixxxLibraryFeature::selectAllMissing() { void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; - emit(switchToView(m_sMixxxLibraryViewName)); - emit(showTrackModel(m_pLibraryTableModel)); + m_pLibrary->slotShowTrackModel(m_pLibraryTableModel); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + emit(enableCoverArtDisplay(true)); } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); + TreeItem* pTree = static_cast (index.internalPointer()); + if (itemName == m_sMixxxLibraryViewName) { activate(); @@ -329,14 +334,16 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pHiddenView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); - emit(switchToView(m_sMixxxLibraryViewName)); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } else if (itemName == kMissingTitle) { m_pMissingView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); - emit(switchToView(m_sMixxxLibraryViewName)); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } } diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index 7e8eb1dc4b0..8df597cec42 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -12,8 +12,8 @@ DlgRecording::DlgRecording(QWidget* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) : QFrame(parent), m_pTrackCollection(pTrackCollection), - m_browseModel(this, m_pTrackCollection, pRecordingManager), - m_proxyModel(&m_browseModel), + m_pBrowseModel(nullptr), + m_pProxyModel(nullptr), m_bytesRecordedStr("--"), m_durationRecordedStr("--:--"), m_pRecordingManager(pRecordingManager) { @@ -47,10 +47,6 @@ void DlgRecording::onShow() { m_browseModel.setPath(m_recordingDir); } -void DlgRecording::setTrackTable(WTrackTableView* pTrackTableView) { - pTrackTableView->loadTrackModel(&m_proxyModel); -} - void DlgRecording::refreshBrowseModel() { m_browseModel.setPath(m_recordingDir); } diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index e79f7b81a0d..6b30c1f4bd6 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -24,7 +24,8 @@ class DlgRecording : public QFrame, public Ui::DlgRecording { virtual ~DlgRecording(); virtual void onShow(); - void setTrackTable(WTrackTableView* pTrackTableView); + void setProxyTrackModel(ProxyTrackModel* pProxyModel); + void setBrowseTableModel(BrowseTableModel* pBrowseModel); public slots: void toggleRecording(bool toggle); @@ -37,8 +38,8 @@ class DlgRecording : public QFrame, public Ui::DlgRecording { void refreshLabel(); TrackCollection* m_pTrackCollection; - BrowseTableModel m_browseModel; - ProxyTrackModel m_proxyModel; + BrowseTableModel m_pBrowseModel; + ProxyTrackModel m_pProxyModel; QString m_recordingDir; QHash m_TrackTableView; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 1862ccd0212..fab0d021c01 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -57,6 +57,7 @@ QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) pTrackTableView, SLOT(setTrackTableFont(QFont))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); + pTrackTableView->loadTrackModel(m_pProxyModel); if (m_pRecordingView) { m_pRecordingView->setTrackTable(pTrackTableView); @@ -69,17 +70,21 @@ QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, KeyboardEventFilter* pKeyboard) { + + QWidget* pSidebar = createSidebarWidget(pKeyboard); + pSidebar->setParent(pBaseLibrary); + pBaseLibrary->registerView(m_sRecordingViewName, m_pRecordingView); +} + +QWidget *RecordingFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { m_pRecordingView = new DlgRecording(nullptr, m_pTrackCollection, m_pRecordingManager); m_pRecordingView->installEventFilter(pKeyboard); + m_pRecordingView->setBrowseTableModel(getBrowseTableModel()); + m_pRecordingView->setProxyTrackModel(getProxyTrackModel()); - for (WTrackTableView* pTable : m_trackTables) { - m_pRecordingView->setTrackTable(pTable); - } - m_trackTables.clear(); - - pBaseLibrary->registerView(m_sRecordingViewName, m_pRecordingView); + return m_pRecordingView; } @@ -89,3 +94,19 @@ void RecordingFeature::activate() { emit(restoreSearch("")); emit(enableCoverArtDisplay(false)); } + +BrowseTableModel* RecordingFeature::getBrowseTableModel() { + if (!m_pBrowseModel) { + m_pBrowseModel = new BrowseTableModel(this, m_pTrackCollection, m_pRecordingManager); + } + + return m_pBrowseModel; +} + +ProxyTrackModel* RecordingFeature::getProxyTrackModel() { + if (!m_pProxyModel) { + m_pProxyModel = new ProxyTrackModel(getBrowseTableModel()); + } + + return m_pProxyModel; +} diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 5cfce664e0a..3a754bcd002 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -39,6 +39,7 @@ class RecordingFeature : public LibraryFeature { QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); void bindSidebarWidget(WBaseLibrary* pBaseLibrary, KeyboardEventFilter* pKeyboard); + QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); TreeItemModel* getChildModel(); @@ -49,6 +50,10 @@ class RecordingFeature : public LibraryFeature { void setRootIndex(const QModelIndex&); private: + + BrowseTableModel* getBrowseTableModel(); + ProxyTrackModel* getProxyTrackModel(); + TrackCollection* m_pTrackCollection; FolderTreeModel m_childModel; const static QString m_sRecordingViewName; @@ -56,6 +61,8 @@ class RecordingFeature : public LibraryFeature { QList m_trackTables; QPointer m_pRecordingView; + BrowseTableModel* m_pBrowseModel; + ProxyTrackModel* m_pProxyModel; }; #endif diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 82b23eee717..4969c96deb8 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -4,9 +4,12 @@ namespace { -QString getPathString(TreeItem* pTree) { +QString getPathString(TreeItem* pTree) { // Base case - if (pTree->parent() == nullptr) { + if (pTree == nullptr) { + return QString(); + } + else if (pTree->parent() == nullptr) { return pTree->getFeature()->title().toString(); } From 68d32cd5e3466eb79d7c1cd46928c896f6cd3106 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 21:19:03 +0200 Subject: [PATCH 208/552] Fixed WBaseLibrary not changing some times --- src/widget/wbaselibrary.cpp | 6 ++++++ src/widget/wbaselibrary.h | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 9e002830204..2f23c92e7c6 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -55,6 +55,12 @@ void WBaseLibrary::switchToView(const QString& name) { } } +void WBaseLibrary::setCurrentIndex(int index) { + QWidget* pWidget = widget(index); + m_currentViewName = m_viewMap.key(pWidget); + QStackedWidget::setCurrentIndex(index); +} + bool WBaseLibrary::eventFilter(QObject*, QEvent* pEvent) { if (pEvent->type() == QEvent::FocusIn) { //qDebug() << "WBaseLibrary::eventFilter FocusIn"; diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 0c793dc488e..9985d0ae3a6 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -2,7 +2,7 @@ #define WLIBRARYSIDEBAREXPANDED_H #include #include -#include +#include #include "widget/wbasewidget.h" @@ -31,13 +31,15 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget public slots: virtual void switchToView(const QString& name); + + void setCurrentIndex(int index); protected: bool eventFilter(QObject*, QEvent* pEvent); bool event(QEvent* pEvent) override; - QMap m_viewMap; + QHash m_viewMap; private: From 3d4c23c5627c6dd714ed38bcf44902aa324f9ab2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 21:19:44 +0200 Subject: [PATCH 209/552] Fixed RecordingFeature segmentation fault --- src/library/recording/dlgrecording.cpp | 23 ++++++++++++++-------- src/library/recording/dlgrecording.h | 5 ++--- src/library/recording/recordingfeature.cpp | 17 +++++++--------- src/library/recording/recordingfeature.h | 1 - 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index 8df597cec42..77c22d42d94 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -28,11 +28,6 @@ DlgRecording::DlgRecording(QWidget* parent, TrackCollection* pTrackCollection, m_recordingDir = m_pRecordingManager->getRecordingDir(); - m_proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); - m_proxyModel.setSortCaseSensitivity(Qt::CaseInsensitive); - - m_browseModel.setPath(m_recordingDir); - connect(pushButtonRecording, SIGNAL(toggled(bool)), this, SLOT(toggleRecording(bool))); label->setText(""); @@ -44,11 +39,23 @@ DlgRecording::~DlgRecording() { void DlgRecording::onShow() { m_recordingDir = m_pRecordingManager->getRecordingDir(); - m_browseModel.setPath(m_recordingDir); + m_pBrowseModel->setPath(m_recordingDir); +} + +void DlgRecording::setProxyTrackModel(ProxyTrackModel* pProxyModel) { + m_pProxyModel = pProxyModel; + + m_pProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); +} + +void DlgRecording::setBrowseTableModel(BrowseTableModel* pBrowseModel) { + m_pBrowseModel = pBrowseModel; + m_pBrowseModel->setPath(m_recordingDir); } void DlgRecording::refreshBrowseModel() { - m_browseModel.setPath(m_recordingDir); + m_pBrowseModel->setPath(m_recordingDir); } void DlgRecording::toggleRecording(bool toggle) { @@ -75,7 +82,7 @@ void DlgRecording::slotRecordingEnabled(bool isRecording) { label->setEnabled(false); } //This will update the recorded track table view - m_browseModel.setPath(m_recordingDir); + m_pBrowseModel->setPath(m_recordingDir); } // gets number of recorded bytes and update label diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index 6b30c1f4bd6..cd9c1c05d78 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -38,10 +38,9 @@ class DlgRecording : public QFrame, public Ui::DlgRecording { void refreshLabel(); TrackCollection* m_pTrackCollection; - BrowseTableModel m_pBrowseModel; - ProxyTrackModel m_pProxyModel; + BrowseTableModel* m_pBrowseModel; + ProxyTrackModel* m_pProxyModel; QString m_recordingDir; - QHash m_TrackTableView; QString m_bytesRecordedStr; QString m_durationRecordedStr; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index fab0d021c01..e2d50396b96 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -20,7 +20,9 @@ RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, : LibraryFeature(pConfig, pLibrary, parent), m_pTrackCollection(pTrackCollection), m_pRecordingManager(pRecordingManager), - m_pRecordingView(nullptr) { + m_pRecordingView(nullptr), + m_pBrowseModel(nullptr), + m_pProxyModel(nullptr) { } RecordingFeature::~RecordingFeature() { @@ -57,13 +59,7 @@ QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) pTrackTableView, SLOT(setTrackTableFont(QFont))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - pTrackTableView->loadTrackModel(m_pProxyModel); - - if (m_pRecordingView) { - m_pRecordingView->setTrackTable(pTrackTableView); - } else { - m_trackTables.append(pTrackTableView); - } + pTrackTableView->loadTrackModel(getProxyTrackModel()); return pTrackTableView; } @@ -90,8 +86,9 @@ QWidget *RecordingFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { void RecordingFeature::activate() { m_pRecordingView->refreshBrowseModel(); - emit(switchToView(m_sRecordingViewName)); - emit(restoreSearch("")); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotRestoreSearch(""); + emit(enableCoverArtDisplay(false)); } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 3a754bcd002..b3a93a734ed 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -59,7 +59,6 @@ class RecordingFeature : public LibraryFeature { const static QString m_sRecordingViewName; RecordingManager* m_pRecordingManager; - QList m_trackTables; QPointer m_pRecordingView; BrowseTableModel* m_pBrowseModel; ProxyTrackModel* m_pProxyModel; From d249226366613661b18e3e2b33712b35ebfccb52 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 21:49:23 +0200 Subject: [PATCH 210/552] Fix minor bugs --- src/library/libraryfeature.h | 2 +- src/library/mixxxlibraryfeature.cpp | 2 ++ src/widget/wlibrarybreadcrumb.cpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 009f088bcfc..895c850a9b0 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -22,7 +22,7 @@ class Library; // pure virtual (abstract) class to provide an interface for libraryfeatures class LibraryFeature : public QObject { - Q_OBJECT + Q_OBJECT public: // The parent does not necessary be the Library diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 91e14828139..15ac6be76c8 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -317,6 +317,8 @@ void MixxxLibraryFeature::selectAllMissing() { void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; + // To change the sidebar + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowTrackModel(m_pLibraryTableModel); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 4969c96deb8..4e1343e83d9 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -6,7 +6,7 @@ namespace { QString getPathString(TreeItem* pTree) { // Base case - if (pTree == nullptr) { + if (pTree == nullptr || pTree->getFeature() == nullptr) { return QString(); } else if (pTree->parent() == nullptr) { From f562227d26d5bd9ee2b832d1a6d1fd5a78c3bf85 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 21:49:35 +0200 Subject: [PATCH 211/552] Add bread crumb to more features --- src/library/banshee/bansheefeature.cpp | 19 ++++++++----- src/library/browse/browsefeature.cpp | 33 +++++++++++++--------- src/library/itunes/itunesfeature.cpp | 12 ++++++-- src/library/rhythmbox/rhythmboxfeature.cpp | 16 +++++++---- src/library/traktor/traktorfeature.cpp | 17 +++++++---- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index ff957f48c66..c28799b3fb6 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -8,6 +8,7 @@ #include "library/dao/settingsdao.h" #include "library/baseexternalplaylistmodel.h" #include "library/banshee/bansheeplaylistmodel.h" +#include "library/library.h" const QString BansheeFeature::BANSHEE_MOUNT_KEY = "mixxx.BansheeFeature.mount"; @@ -97,7 +98,8 @@ void BansheeFeature::activate() { m_isActivated = true; - TreeItem* playlist_root = new TreeItem(); + TreeItem* playlistRoot = new TreeItem(); + playlistRoot->setLibraryFeature(this); QList list = m_connection.getPlaylists(); @@ -105,12 +107,12 @@ void BansheeFeature::activate() { foreach (playlist, list) { qDebug() << playlist.name; // append the playlist to the child model - TreeItem *item = new TreeItem(playlist.name, playlist.playlistId, this, playlist_root); - playlist_root->appendChild(item); + TreeItem *item = new TreeItem(playlist.name, playlist.playlistId, this, playlistRoot); + playlistRoot->appendChild(item); } - if (playlist_root) { - m_childModel.setRootItem(playlist_root); + if (playlistRoot) { + m_childModel.setRootItem(playlistRoot); if (m_isActivated) { activate(); } @@ -123,7 +125,9 @@ void BansheeFeature::activate() { } m_pBansheePlaylistModel->setTableModel(0); // Gets the master playlist - emit(showTrackModel(m_pBansheePlaylistModel)); + + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel); emit(enableCoverArtDisplay(false)); } @@ -135,7 +139,8 @@ void BansheeFeature::activateChild(const QModelIndex& index) { if (playlistID > 0) { qDebug() << "Activating " << item->data().toString(); m_pBansheePlaylistModel->setTableModel(playlistID); - emit(showTrackModel(m_pBansheePlaylistModel)); + m_pLibrary->slotShowBreadCrumb(item); + m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel); emit(enableCoverArtDisplay(false)); } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 4dd851f7a40..708d29b655a 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -1,24 +1,26 @@ // browsefeature.cpp // Created 9/8/2009 by RJ Ryan (rryan@mit.edu) -#include -#include +#include +#include #include -#include #include -#include -#include #include #include +#include +#include +#include -#include "track/track.h" -#include "library/treeitem.h" +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/browse/browsefeature.h" +#include "library/library.h" #include "library/trackcollection.h" -#include "widget/wlibrarytextbrowser.h" -#include "widget/wlibrary.h" -#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/treeitem.h" +#include "track/track.h" #include "util/sandbox.h" +#include "widget/wlibrary.h" +#include "widget/wlibrarytextbrowser.h" + const QString kQuickLinksSeparator = "-+-"; @@ -58,6 +60,7 @@ BrowseFeature::BrowseFeature(UserSettingsPointer pConfig, // The invisible root item of the child model TreeItem* rootItem = new TreeItem(); + rootItem->setLibraryFeature(this); m_pQuickLinkItem = new TreeItem(tr("Quick Links"), QUICK_LINK_NODE, this, rootItem); rootItem->appendChild(m_pQuickLinkItem); @@ -230,8 +233,10 @@ QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { } void BrowseFeature::activate() { - emit(switchToView(m_sBrowseViewName)); - emit(restoreSearch(QString())); + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotRestoreSearch(QString()); + emit(enableCoverArtDisplay(false)); } @@ -260,7 +265,9 @@ void BrowseFeature::activateChild(const QModelIndex& index) { } m_browseModel.setPath(dir); } - emit(showTrackModel(&m_proxyModel)); + m_pLibrary->slotShowBreadCrumb(item); + m_pLibrary->slotShowTrackModel(&m_proxyModel); + emit(enableCoverArtDisplay(false)); } diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 5ec777ca294..572ae05ca6b 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -14,6 +14,7 @@ #include "library/dao/settingsdao.h" #include "library/baseexternaltrackmodel.h" #include "library/baseexternalplaylistmodel.h" +#include "library/library.h" #include "library/queryutil.h" #include "util/lcs.h" #include "util/sandbox.h" @@ -151,7 +152,8 @@ void ITunesFeature::activate(bool forceReload) { NULL, tr("Select your iTunes library"), QDir::homePath(), "*.xml"); QFileInfo dbFile(m_dbfile); if (m_dbfile.isEmpty() || !dbFile.exists()) { - emit(showTrackModel(m_pITunesTrackModel)); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotShowTrackModel(m_pITunesTrackModel); return; } @@ -181,7 +183,8 @@ void ITunesFeature::activate(bool forceReload) { emit (featureIsLoading(this, true)); } - emit(showTrackModel(m_pITunesTrackModel)); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotShowTrackModel(m_pITunesTrackModel); emit(enableCoverArtDisplay(false)); } @@ -190,7 +193,9 @@ void ITunesFeature::activateChild(const QModelIndex& index) { QString playlist = index.data().toString(); qDebug() << "Activating " << playlist; m_pITunesPlaylistModel->setPlaylist(playlist); - emit(showTrackModel(m_pITunesPlaylistModel)); + + m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + m_pLibrary->slotShowTrackModel(m_pITunesPlaylistModel); emit(enableCoverArtDisplay(false)); } @@ -743,6 +748,7 @@ void ITunesFeature::clearTable(QString table_name) { void ITunesFeature::onTrackCollectionLoaded() { TreeItem* root = m_future.result(); + root->setLibraryFeature(this); if (root) { m_childModel.setRootItem(root); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 081595a1081..83538ae062f 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -7,8 +7,9 @@ #include "library/baseexternaltrackmodel.h" #include "library/baseexternalplaylistmodel.h" -#include "library/treeitem.h" +#include "library/library.h" #include "library/queryutil.h" +#include "library/treeitem.h" const QString RhythmboxFeature::m_sRhythmBoxViewName = QString("RHYTHMBOX_VIEW"); @@ -113,7 +114,7 @@ TreeItemModel* RhythmboxFeature::getChildModel() { } void RhythmboxFeature::activate() { - qDebug() << "RhythmboxFeature::activate()"; + //qDebug() << "RhythmboxFeature::activate()"; if (!m_isActivated) { m_isActivated = true; @@ -132,8 +133,10 @@ void RhythmboxFeature::activate() { //calls a slot in the sidebar model such that 'Rhythmbox (isLoading)' is displayed. emit (featureIsLoading(this, true)); } - emit(switchToView(m_sRhythmBoxViewName)); - emit(showTrackModel(m_pRhythmboxTrackModel)); + + m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); } @@ -142,7 +145,9 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { QString playlist = index.data().toString(); qDebug() << "Activating " << playlist; m_pRhythmboxPlaylistModel->setPlaylist(playlist); - emit(showTrackModel(m_pRhythmboxPlaylistModel)); + + m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + m_pLibrary->slotShowTrackModel(m_pRhythmboxPlaylistModel); emit(enableCoverArtDisplay(false)); } @@ -441,6 +446,7 @@ void RhythmboxFeature::clearTable(QString table_name) { void RhythmboxFeature::onTrackCollectionLoaded() { TreeItem* root = m_track_future.result(); + root->setLibraryFeature(this); if (root) { m_childModel.setRootItem(root); diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 3a7ee10526f..fe8f2b3b371 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -10,6 +10,7 @@ #include "library/traktor/traktorfeature.h" +#include "library/library.h" #include "library/librarytablemodel.h" #include "library/missingtablemodel.h" #include "library/queryutil.h" @@ -143,7 +144,7 @@ void TraktorFeature::refreshLibraryModels() { } void TraktorFeature::activate() { - qDebug() << "TraktorFeature::activate()"; + //qDebug() << "TraktorFeature::activate()"; if (!m_isActivated) { m_isActivated = true; @@ -164,8 +165,9 @@ void TraktorFeature::activate() { //calls a slot in the sidebar model such that 'iTunes (isLoading)' is displayed. emit (featureIsLoading(this, true)); } - - emit(showTrackModel(m_pTraktorTableModel)); + + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotShowTrackModel(m_pTraktorTableModel); emit(enableCoverArtDisplay(false)); } @@ -179,7 +181,8 @@ void TraktorFeature::activateChild(const QModelIndex& index) { if (item->isPlaylist()) { qDebug() << "Activate Traktor Playlist: " << item->dataPath().toString(); m_pTraktorPlaylistModel->setPlaylist(item->dataPath().toString()); - emit(showTrackModel(m_pTraktorPlaylistModel)); + m_pLibrary->slotShowBreadCrumb(item); + m_pLibrary->slotShowTrackModel(m_pTraktorPlaylistModel); emit(enableCoverArtDisplay(false)); } } @@ -610,17 +613,19 @@ QString TraktorFeature::getTraktorMusicDatabase() { void TraktorFeature::onTrackCollectionLoaded() { TreeItem* root = m_future.result(); + root->setLibraryFeature(this); if (root) { m_childModel.setRootItem(root); // Tell the traktor track source that it should re-build its index. m_trackSource->buildIndex(); //m_pTraktorTableModel->select(); - emit(showTrackModel(m_pTraktorTableModel)); + m_pLibrary->slotShowBreadCrumb(root); + m_pLibrary->slotShowTrackModel(m_pTraktorTableModel); qDebug() << "Traktor library loaded successfully"; } else { QMessageBox::warning( - NULL, + nullptr, tr("Error Loading Traktor Library"), tr("There was an error loading your Traktor library. Some of " "your Traktor tracks or playlists may not have loaded.")); From 1c31e738d8f12e9e00479e346558e1f23fb52403 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 23:33:36 +0200 Subject: [PATCH 212/552] Remove SwitchToView remains and finish recording breadcrumb --- src/library/baseplaylistfeature.cpp | 1 - src/library/browse/browsefeature.cpp | 2 +- src/library/cratefeature.cpp | 5 +---- src/library/library.cpp | 18 ++++++------------ src/library/library.h | 3 --- src/library/libraryfeature.h | 5 ----- src/library/librarypanemanager.cpp | 4 ++-- src/library/librarypanemanager.h | 1 - src/library/recording/recordingfeature.cpp | 5 +++++ 9 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 5a1da4eb60c..1fddf5f578b 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -135,7 +135,6 @@ void BasePlaylistFeature::activate() { m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - //emit(switchToView(m_rootViewName)); emit(restoreSearch(QString())); // Null String disables search box emit(enableCoverArtDisplay(true)); } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 708d29b655a..296ab8037b2 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -268,7 +268,7 @@ void BrowseFeature::activateChild(const QModelIndex& index) { m_pLibrary->slotShowBreadCrumb(item); m_pLibrary->slotShowTrackModel(&m_proxyModel); - emit(enableCoverArtDisplay(false)); + emit(enableCoverArtDisplay(true)); } void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index d829d2ee83d..b3a67b7e70b 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -104,8 +104,6 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), this, SLOT(slotTrackSelected(TrackPointer))); - connect(pLibrary, SIGNAL(switchToView(const QString&)), - this, SLOT(slotResetSelectedTrack())); } CrateFeature::~CrateFeature() { @@ -213,9 +211,8 @@ void CrateFeature::activate() { m_featureFocus = -1; m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home - emit(switchToView(m_sCrateViewName)); - emit(restoreSearch(QString())); //disable search on crate home emit(enableCoverArtDisplay(true)); } diff --git a/src/library/library.cpp b/src/library/library.cpp index 5f9687c2c51..9ab43dc745a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -149,7 +149,6 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, // Get the value once to avoid searching again in the hash LibraryPaneManager* pPane = getPane(id); - pPane->bindPaneWidget(pLibraryWidget, pKeyboard); connect(pPane, SIGNAL(showTrackModel(QAbstractItemModel*)), @@ -221,8 +220,6 @@ void Library::addFeature(LibraryFeature* feature) { this, SLOT(slotShowTrackModel(QAbstractItemModel*))); connect(feature, SIGNAL(switchToView(const QString&)), this, SLOT(slotSwitchToView(const QString&))); - connect(feature, SIGNAL(switchToViewChild(const QString&)), - this, SLOT(slotSwitchToViewChild(const QString&))); connect(feature, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), @@ -251,8 +248,6 @@ void Library::slotSwitchToView(const QString& view) { } handleFocus(); - - emit(switchToView(view)); } void Library::slotSwitchToViewFeature(LibraryFeature* pFeature) { @@ -271,12 +266,6 @@ void Library::slotShowBreadCrumb(TreeItem *pTree) { m_panes[m_focusedPane]->slotShowBreadCrumb(pTree); } - -void Library::slotSwitchToViewChild(const QString &view) { - //qDebug() << "Library::slotSwitchToViewChild"; - m_panes[m_focusedPane]->slotSwitchToView(view); -} - void Library::slotSwitchToNotFocusedView(const QString &view) { // Search for the view not being shown already @@ -337,7 +326,7 @@ void Library::onSkinLoadFinished() { // Assign a feature to show on each pane unless there are more panes // than features while (itP != m_panes.end() && itF != m_features.end()) { - qDebug() << (*itF)->getViewName() << itP.key(); + //qDebug() << (*itF)->getViewName() << itP.key(); m_focusedPane = itP.key(); (*itF)->setFeatureFocus(itP.key()); @@ -346,6 +335,11 @@ void Library::onSkinLoadFinished() { ++itP; ++itF; } + + // The first pane always shows the Mixxx Library feature on start + m_focusedPane = m_panes.begin().key(); + (*m_features.begin())->setFeatureFocus(m_focusedPane); + (*m_features.begin())->activate(); } else { qDebug() << "Library::onSkinLoadFinished No Panes loaded!"; diff --git a/src/library/library.h b/src/library/library.h index 396f65578d5..7282fcefb37 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -97,7 +97,6 @@ class Library : public QObject { void slotSwitchToView(const QString& view); void slotSwitchToViewFeature(LibraryFeature* pFeature); void slotShowBreadCrumb(TreeItem* pTree); - void slotSwitchToViewChild(const QString& view); void slotSwitchToNotFocusedView(const QString& view); void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); @@ -132,8 +131,6 @@ class Library : public QObject { // Emitted when a library scan starts and finishes. void scanStarted(); void scanFinished(); - - void switchToView(const QString&); private: diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 895c850a9b0..ad1e6939182 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -112,12 +112,7 @@ class LibraryFeature : public QObject { signals: void showTrackModel(QAbstractItemModel* model); - - // The difference between switchToView and switchToViewChild is that the - // second will never change the sidebar Expanded view, it's useful when - // selecting an item from the sidebar Expanded view void switchToView(const QString&); - void switchToViewChild(const QString&); void loadTrack(TrackPointer); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 8d79c995acf..de80e89a1de 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -103,13 +103,13 @@ void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { return; } emit(showTrackModel(model)); - emit(switchToView(m_sTrackViewName)); + m_pPaneWidget->switchToView(m_sTrackViewName); emit(restoreSearch(trackModel->currentSearch())); } void LibraryPaneManager::slotSwitchToView(const QString& view) { //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; - emit(switchToView(view)); + m_pPaneWidget->switchToView(view); m_pPaneWidget->setFocus(); } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index b696780c5c8..e0c372302ff 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -54,7 +54,6 @@ class LibraryPaneManager : public QObject { void focused(); void showTrackModel(QAbstractItemModel* model); - void switchToView(const QString&); void restoreSearch(const QString&); void search(const QString& text); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index e2d50396b96..1a3fae590ab 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -23,6 +23,10 @@ RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, m_pRecordingView(nullptr), m_pBrowseModel(nullptr), m_pProxyModel(nullptr) { + + TreeItem* pRoot = new TreeItem(); + pRoot->setLibraryFeature(this); + m_childModel.setRootItem(pRoot); } RecordingFeature::~RecordingFeature() { @@ -87,6 +91,7 @@ QWidget *RecordingFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { void RecordingFeature::activate() { m_pRecordingView->refreshBrowseModel(); m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(""); emit(enableCoverArtDisplay(false)); From e54810f84242088d7f2057ae1162469839f9c526 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 30 Jun 2016 23:49:39 +0200 Subject: [PATCH 213/552] Add BreadCrumb to Deere skin --- res/skins/Deere/library.xml | 8 ++++++++ res/skins/Deere/style.qss | 14 ++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index c300a41bdff..341ec2ab9c9 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -176,6 +176,10 @@ 1 + + LibraryBreadCrumb + 1 + 1 @@ -189,6 +193,10 @@ 2 + + LibraryBreadCrumb + 2 + 2 diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index e23700570bb..25c505586a5 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -167,6 +167,12 @@ WBaseLibrary[showFocus="1"] { margin-right: 13px; } +#LibraryBreadCrumb { + margin: 4px 4px; + font-size: 12px; + color: #FFFFFF; +} + #LibraryCoverArtSplitter QTabWidget { border: none; } @@ -381,14 +387,6 @@ WBaseLibrary QSpinBox:editable { color:#d2d2d2; } -/* Extra declaration for QRadionButton otherwise it shows up with wrong colors in Linux with Gnome */ -WBaseLibrary QLabel, WBaseLibrary QRadioButton { - /* same as QTreeview */ - color: #d2d2d2; - font-size: 10px; - margin: 9px 10px 6px 0px; -} - WBaseLibrary QRadioButton::indicator { margin: 0px 5px 0px 2px; width: 18px; From 3c439e9bd182b35a2025a1da0a0f72cb729c501b Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 00:34:43 +0200 Subject: [PATCH 214/552] Fix some style issues in Deere skin --- res/skins/Deere/library.xml | 2 + res/skins/Deere/style.qss | 86 +++++++++++----------------------- src/library/libraryfeature.cpp | 2 + 3 files changed, 32 insertions(+), 58 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index 341ec2ab9c9..e572a467fd6 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -26,6 +26,7 @@ [Library],show_library + min,me LibrarySidebarButtons @@ -152,6 +153,7 @@ 0,0 + LibrarySidebarExpanded diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 25c505586a5..723787bd92c 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -162,15 +162,21 @@ WBaseLibrary[showFocus="1"] { image: url(:/images/library/ic_library_unchecked.png); } +#LibrarySidebarButtons { + margin-top: 5px; +} + #LibrarySidebarButtons, #LibrarySidebarButtons WButtonBar { background-color: #222222; margin-right: 13px; } -#LibraryBreadCrumb { +#LibraryBreadCrumb, +WBaseLibrary QLabel { margin: 4px 4px; font-size: 12px; - color: #FFFFFF; + font-weight: bold; + color: #B3B3B3; } #LibraryCoverArtSplitter QTabWidget { @@ -181,13 +187,14 @@ WBaseLibrary[showFocus="1"] { border: 1px solid #1A1A1A; } -#LibraryCoverArtSplitter QTabWidget QTreeView, #DlgAutoDJ QScrollArea { +#LibraryCoverArtSplitter QTabWidget QTreeView, #DlgAutoDJ { margin: 0; border: none; } -#DlgAutoDJ QLabel { - margin: 2px 4px 2px 4px; +#DlgAutoDJ #scrollAreaWidgetContents { + background-color: #222222; + border: none; } #LibraryCoverArtSplitter QTabBar::tab { @@ -211,16 +218,12 @@ WBaseLibrary[showFocus="1"] { border-right: 0px solid #5F5F5F; border-left: 0px solid #5F5F5F; color: #D2D2D2; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #5F5F5F, - stop: 1 #5F5F5F); + background-color: #5F5F5F; } #LibraryCoverArtSplitter QTabBar::tab:selected { color: #FDFDFD; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #006596, - stop: 1 #006596); + background-color: #006596; border: 0px solid #006596; } @@ -407,52 +410,32 @@ WButtonBar QAbstractButton { /* buttons in library (in hierarchical order of appearance) Style them just as the other regular buttons */ -#DlgMissing > QPushButton, -#DlgHidden > QPushButton, -#DlgAutoDJ QPushButton, -#DlgRecording > QPushButton, -#DlgAnalysis > QPushButton { +WBaseLibrary QPushButton { margin: 2px 3px 2px 3px; padding: 2px; color: #D2D2D2; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #4B4B4B, - stop: 1 #4B4B4B); + + background-color: #4B4B4B; border: 1px solid #4B4B4B; border-radius: 2px; outline: none; } -#DlgMissing > QPushButton:!enabled, -#DlgHidden > QPushButton:!enabled, -#DlgAutoDJ QPushButton:!enabled, -#DlgAnalysis > QPushButton:!enabled { +WBaseLibrary QPushButton:!enabled { /* buttons in "disabled" (not click-able) state. They are nearly invisible by default QT palette, so style accordingly */ color: #808080; /* Default #A3A3A3 -90L HSL*/ - background-color: qlineargradient(spread:pad, - x1:0, y1:0, x2:1, y2:0, - stop:0 rgba(95, 95, 95, 127), - stop:1 rgba(95, 95, 95, 127)); - /* 50% #5F5F5F = RGBA#5F5F5F7F */ + background-color: rgba(95, 95, 95, 127); border: 0px solid #5F5F5F; } -#DlgMissing > QPushButton:hover, -#DlgHidden > QPushButton:hover, -#DlgAutoDJ QPushButton:hover, -#DlgRecording > QPushButton:hover, -#DlgAnalysis > QPushButton:hover { +WBaseLibrary QPushButton:hover { color: #D2D2D2; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #5F5F5F, - stop: 1 #5F5F5F); + background-color: #5F5F5F; border: 0px solid #5F5F5F; } -#DlgAutoDJ QPushButton:checked, -#DlgRecording > QPushButton:checked, -#DlgAnalysis > QPushButton:checked { +WBaseLibrary QPushButton:checked { /* checkbuttons in active state */ color: #FDFDFD; background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, @@ -461,9 +444,7 @@ WButtonBar QAbstractButton { border: 0px solid #006596; } -#DlgAutoDJ > QPushButton:checked:hover, -#DlgRecording > QPushButton:checked:hover, -#DlgAnalysis > QPushButton:checked:hover { +WBaseLibrary QPushButton:checked:hover { /* checkbuttons hovered over in "active" state */ color: #FDFDFD; background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, @@ -472,10 +453,7 @@ WButtonBar QAbstractButton { border: 0px solid #0080BE; } -#DlgMissing > QPushButton:pressed, -#DlgHidden > QPushButton:pressed, -#DlgAutoDJ > QPushButton:pressed, -#DlgAnalysis > QPushButton:pressed { +WBaseLibrary QPushButton:pressed { /* pushbuttons in "down" state */ color: #FDFDFD; background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, @@ -484,13 +462,6 @@ WButtonBar QAbstractButton { border: 0px solid #006596; } -/* Additional space for the first and the last QPushButton in the row */ -#DlgMissing > QPushButton#btnPurge, -#DlgHidden > QPushButton#btnUnhide, -#DlgRecording > QPushButton#pushButtonRecording { - margin: 9px 12px 6px 3px; -} - /* Scroll bars */ QScrollBar:horizontal { border-top: 1px solid #141414; @@ -543,10 +514,6 @@ QScrollArea { background-color: #222222; } -WBaseLibrary QWidget { - background-color: #222222; -} - /******************************************************************************* ** END LIBRARY ***************************************************************** @@ -611,10 +578,13 @@ WBaseLibrary QWidget { WWidget, QLabel { font-family: "Open Sans"; - font-size: 8px; text-transform: uppercase; } +WWidget { + font-size: 8px; +} + /* Start spacing for Deck overview row (small waveform, option grid) */ #OptionGrid { background-color: #333333; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 99437fbbba4..588b915a410 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -50,6 +50,8 @@ QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { pContainer->setContentsMargins(0,0,0,0); QVBoxLayout* pLayout = new QVBoxLayout(pContainer); + pLayout->setContentsMargins(0,0,0,0); + pLayout->setSpacing(0); pContainer->setLayout(pLayout); QLabel* pTitle = new QLabel(title().toString(), pContainer); From 88662eeb55ef6939abdea258a38e210844021af4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 11:07:39 +0200 Subject: [PATCH 215/552] Fixed issue with focus change --- src/library/banshee/bansheefeature.cpp | 2 ++ src/library/baseplaylistfeature.cpp | 8 +++----- src/library/browse/browsefeature.cpp | 2 ++ src/library/cratefeature.cpp | 2 +- src/library/itunes/itunesfeature.cpp | 1 + src/library/library.cpp | 3 +++ src/library/rhythmbox/rhythmboxfeature.cpp | 3 ++- src/library/traktor/traktorfeature.cpp | 2 ++ 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index c28799b3fb6..605e25835d8 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -139,6 +139,8 @@ void BansheeFeature::activateChild(const QModelIndex& index) { if (playlistID > 0) { qDebug() << "Activating " << item->data().toString(); m_pBansheePlaylistModel->setTableModel(playlistID); + + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(item); m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel); emit(enableCoverArtDisplay(false)); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 1fddf5f578b..ea0a19b70c5 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -131,7 +131,6 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { } void BasePlaylistFeature::activate() { - m_featureFocus = -1; m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); @@ -144,11 +143,10 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { int playlistId = playlistIdFromIndex(index); if (playlistId != -1 && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); + + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowTrackModel(m_pPlaylistTableModel); - TreeItem* pTree = static_cast (index.internalPointer()); - if (pTree) { - m_pLibrary->slotShowBreadCrumb(pTree); - } + m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 296ab8037b2..a0cda0ec870 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -265,6 +265,8 @@ void BrowseFeature::activateChild(const QModelIndex& index) { } m_browseModel.setPath(dir); } + + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(item); m_pLibrary->slotShowTrackModel(&m_proxyModel); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index b3a67b7e70b..9cd007db28a 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -208,7 +208,6 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { - m_featureFocus = -1; m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home @@ -226,6 +225,7 @@ void CrateFeature::activateChild(const QModelIndex& index) { } m_crateTableModel.setTableModel(crateId); + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowTrackModel(&m_crateTableModel); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 572ae05ca6b..b1803ae3a51 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -194,6 +194,7 @@ void ITunesFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pITunesPlaylistModel->setPlaylist(playlist); + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); m_pLibrary->slotShowTrackModel(m_pITunesPlaylistModel); emit(enableCoverArtDisplay(false)); diff --git a/src/library/library.cpp b/src/library/library.cpp index 9ab43dc745a..97543937bac 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -252,6 +252,9 @@ void Library::slotSwitchToView(const QString& view) { void Library::slotSwitchToViewFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + if (pFeature->getFeatureFocus() >= 0) { + m_focusedPane = pFeature->getFeatureFocus(); + } WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); // Only change the current pane if it's not shown already diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 83538ae062f..299d2ffdef2 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -135,8 +135,8 @@ void RhythmboxFeature::activate() { } m_pLibrary->slotSwitchToViewFeature(this); - m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel); emit(enableCoverArtDisplay(false)); } @@ -146,6 +146,7 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pRhythmboxPlaylistModel->setPlaylist(playlist); + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); m_pLibrary->slotShowTrackModel(m_pRhythmboxPlaylistModel); emit(enableCoverArtDisplay(false)); diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index fe8f2b3b371..11a732f0086 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -181,6 +181,8 @@ void TraktorFeature::activateChild(const QModelIndex& index) { if (item->isPlaylist()) { qDebug() << "Activate Traktor Playlist: " << item->dataPath().toString(); m_pTraktorPlaylistModel->setPlaylist(item->dataPath().toString()); + + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(item); m_pLibrary->slotShowTrackModel(m_pTraktorPlaylistModel); emit(enableCoverArtDisplay(false)); From 1c9ef3624e8958cac6253271e63d68108b7f9e5b Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 11:13:13 +0200 Subject: [PATCH 216/552] Added focus change coments and a new function --- src/library/library.cpp | 22 +++++++--------------- src/library/library.h | 10 +++++++++- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 97543937bac..1712fa77ff0 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -252,9 +252,7 @@ void Library::slotSwitchToView(const QString& view) { void Library::slotSwitchToViewFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); - if (pFeature->getFeatureFocus() >= 0) { - m_focusedPane = pFeature->getFeatureFocus(); - } + slotUpdateFocus(pFeature); WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); // Only change the current pane if it's not shown already @@ -269,18 +267,6 @@ void Library::slotShowBreadCrumb(TreeItem *pTree) { m_panes[m_focusedPane]->slotShowBreadCrumb(pTree); } -void Library::slotSwitchToNotFocusedView(const QString &view) { - - // Search for the view not being shown already - for (LibraryPaneManager* p : m_panes) { - if (p->getPaneWidget()->getCurrentViewName() == view) { - return; - } - } - - m_panes[m_focusedPane]->slotSwitchToView(view); -} - void Library::slotLoadTrack(TrackPointer pTrack) { emit(loadTrack(pTrack)); } @@ -488,6 +474,12 @@ void Library::slotPaneFocused() { //qDebug() << "Library::slotPaneFocused" << m_focusedPane; } +void Library::slotUpdateFocus(LibraryFeature *pFeature) { + if (pFeature->getFeatureFocus() >= 0) { + m_focusedPane = pFeature->getFeatureFocus(); + } +} + LibraryPaneManager* Library::getPane(int id) { //qDebug() << "Library::createPane" << id; diff --git a/src/library/library.h b/src/library/library.h index 7282fcefb37..fa490098bc4 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -93,11 +93,16 @@ class Library : public QObject { public slots: void slotActivateFeature(const QString& featureName); void slotHoverFeature(const QString& featureName); + + // It uses the current focus, it needs to be updated before calling it void slotShowTrackModel(QAbstractItemModel* model); + + // It uses the current focus, avoid using this function void slotSwitchToView(const QString& view); + + // Updates the focus from the feature before changing the view void slotSwitchToViewFeature(LibraryFeature* pFeature); void slotShowBreadCrumb(TreeItem* pTree); - void slotSwitchToNotFocusedView(const QString& view); void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); void slotLoadLocationToPlayer(QString location, QString group); @@ -112,6 +117,9 @@ class Library : public QObject { void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); void slotPaneFocused(); + + // Updates with the focus feature + void slotUpdateFocus(LibraryFeature* pFeature); void scan() { m_scanner.scan(); From 7f5053ad1492690bdcdab319962eb5213577b3ca Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 11:30:59 +0200 Subject: [PATCH 217/552] Last tweaks in trackModelChange --- src/library/banshee/bansheefeature.cpp | 3 +-- src/library/baseplaylistfeature.cpp | 3 +-- src/library/browse/browsefeature.cpp | 3 +-- src/library/cratefeature.cpp | 3 +-- src/library/itunes/itunesfeature.cpp | 5 ++--- src/library/library.cpp | 9 +++++++-- src/library/library.h | 4 ++++ src/library/mixxxlibraryfeature.cpp | 3 +-- src/library/rhythmbox/rhythmboxfeature.cpp | 6 ++---- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 605e25835d8..516696a9433 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -140,9 +140,8 @@ void BansheeFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << item->data().toString(); m_pBansheePlaylistModel->setTableModel(playlistID); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel, this); m_pLibrary->slotShowBreadCrumb(item); - m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel); emit(enableCoverArtDisplay(false)); } } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index ea0a19b70c5..e2342e98e33 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -144,8 +144,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { if (playlistId != -1 && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); - m_pLibrary->slotSwitchToViewFeature(this); - m_pLibrary->slotShowTrackModel(m_pPlaylistTableModel); + m_pLibrary->slotShowTrackModel(m_pPlaylistTableModel, this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index a0cda0ec870..6cd53f4ec50 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -266,9 +266,8 @@ void BrowseFeature::activateChild(const QModelIndex& index) { m_browseModel.setPath(dir); } - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(&m_proxyModel, this); m_pLibrary->slotShowBreadCrumb(item); - m_pLibrary->slotShowTrackModel(&m_proxyModel); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 9cd007db28a..abedb800c33 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -225,8 +225,7 @@ void CrateFeature::activateChild(const QModelIndex& index) { } m_crateTableModel.setTableModel(crateId); - m_pLibrary->slotSwitchToViewFeature(this); - m_pLibrary->slotShowTrackModel(&m_crateTableModel); + m_pLibrary->slotShowTrackModel(&m_crateTableModel, this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index b1803ae3a51..27fd6399b32 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -183,8 +183,8 @@ void ITunesFeature::activate(bool forceReload) { emit (featureIsLoading(this, true)); } + m_pLibrary->slotShowTrackModel(m_pITunesTrackModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotShowTrackModel(m_pITunesTrackModel); emit(enableCoverArtDisplay(false)); } @@ -194,9 +194,8 @@ void ITunesFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pITunesPlaylistModel->setPlaylist(playlist); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(m_pITunesPlaylistModel, this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); - m_pLibrary->slotShowTrackModel(m_pITunesPlaylistModel); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/library.cpp b/src/library/library.cpp index 1712fa77ff0..1a3f7c7f76a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -127,7 +127,7 @@ void Library::bindSidebarWidget(WButtonBar* sidebar) { } void Library::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, int id) { + KeyboardEventFilter* pKeyboard, int id) { WTrackTableView* pTrackTableView = new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); pTrackTableView->installEventFilter(pKeyboard); @@ -237,6 +237,11 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { m_panes[m_focusedPane]->slotShowTrackModel(model); } +void Library::slotShowTrackModel(QAbstractItemModel *model, LibraryFeature *pFeature) { + slotUpdateFocus(pFeature); + slotShowTrackModel(model); +} + void Library::slotSwitchToView(const QString& view) { //qDebug() << "Library::slotSwitchToView" << view; m_pSidebarExpanded->slotSwitchToView(view); @@ -328,7 +333,7 @@ void Library::onSkinLoadFinished() { // The first pane always shows the Mixxx Library feature on start m_focusedPane = m_panes.begin().key(); (*m_features.begin())->setFeatureFocus(m_focusedPane); - (*m_features.begin())->activate(); + slotActivateFeature((*m_features.begin())->getViewName()); } else { qDebug() << "Library::onSkinLoadFinished No Panes loaded!"; diff --git a/src/library/library.h b/src/library/library.h index fa490098bc4..7cdbc9a2aa7 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -95,8 +95,12 @@ class Library : public QObject { void slotHoverFeature(const QString& featureName); // It uses the current focus, it needs to be updated before calling it + // avoid this function void slotShowTrackModel(QAbstractItemModel* model); + // Updates the focus from the feature before changing the view + void slotShowTrackModel(QAbstractItemModel *model, LibraryFeature* pFeature); + // It uses the current focus, avoid using this function void slotSwitchToView(const QString& view); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 15ac6be76c8..fe5a4271e12 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -318,8 +318,7 @@ void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; // To change the sidebar - m_pLibrary->slotSwitchToViewFeature(this); - m_pLibrary->slotShowTrackModel(m_pLibraryTableModel); + m_pLibrary->slotShowTrackModel(m_pLibraryTableModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(true)); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 299d2ffdef2..e528f6a28e2 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -134,9 +134,8 @@ void RhythmboxFeature::activate() { emit (featureIsLoading(this, true)); } - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel); emit(enableCoverArtDisplay(false)); } @@ -146,9 +145,8 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pRhythmboxPlaylistModel->setPlaylist(playlist); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotShowTrackModel(m_pRhythmboxPlaylistModel, this); m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); - m_pLibrary->slotShowTrackModel(m_pRhythmboxPlaylistModel); emit(enableCoverArtDisplay(false)); } From 86433f69ebfbc3bbae5c8d8f127f553e1068774e Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 17:58:38 +0200 Subject: [PATCH 218/552] Fixed many nullpointer issues and fixed not overriding some methods --- src/library/analysisfeature.cpp | 7 +++- src/library/analysisfeature.h | 7 +--- src/library/autodj/autodjfeature.cpp | 18 +++++++- src/library/autodj/autodjfeature.h | 4 +- src/library/banshee/bansheefeature.h | 2 +- src/library/baseplaylistfeature.cpp | 4 ++ src/library/baseplaylistfeature.h | 5 +-- src/library/browse/browsefeature.cpp | 1 - src/library/browse/browsefeature.h | 3 +- src/library/cratefeature.h | 5 +-- src/library/itunes/itunesfeature.h | 2 +- src/library/librarypanemanager.cpp | 20 ++++++++- src/library/librarypanemanager.h | 4 +- src/library/mixxxlibraryfeature.cpp | 48 ++++++++++++++++++---- src/library/mixxxlibraryfeature.h | 16 ++++---- src/library/recording/recordingfeature.cpp | 12 +++++- src/library/recording/recordingfeature.h | 8 ++-- src/library/rhythmbox/rhythmboxfeature.cpp | 4 ++ src/library/rhythmbox/rhythmboxfeature.h | 4 +- src/library/traktor/traktorfeature.h | 2 +- 20 files changed, 123 insertions(+), 53 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 0834ac23d19..8ea78f03b0c 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -25,7 +25,6 @@ AnalysisFeature::AnalysisFeature(TrackCollection* pTrackCollection, Library* pLibrary, QObject* parent) : LibraryFeature(pConfig, pLibrary, parent), - m_pConfig(pConfig), m_pTrackCollection(pTrackCollection), m_pAnalyzerQueue(nullptr), m_iOldBpmEnabled(0), @@ -64,6 +63,10 @@ QIcon AnalysisFeature::getIcon() { return QIcon(":/images/library/ic_library_prepare.png"); } +QString AnalysisFeature::getViewName() { + return m_sAnalysisViewName; +} + void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard, int paneId) { @@ -151,7 +154,7 @@ void AnalysisFeature::refreshLibraryModels() { void AnalysisFeature::selectAll() { auto it = m_analysisTables.find(m_featureFocus); - if (it != m_analysisTables.end()) { + if (it != m_analysisTables.end() && !it->isNull()) { (*it)->selectAll(); } } diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 1dbf8bfd7da..cd30b869033 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -31,9 +31,7 @@ class AnalysisFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - inline QString getViewName() { - return m_sAnalysisViewName; - } + QString getViewName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -73,7 +71,6 @@ class AnalysisFeature : public LibraryFeature { // tracks in the job void setTitleProgress(int trackNum, int totalNum); - UserSettingsPointer m_pConfig; TrackCollection* m_pTrackCollection; AnalyzerQueue* m_pAnalyzerQueue; // Used to temporarily enable BPM detection in the prefs before we analyse @@ -85,7 +82,7 @@ class AnalysisFeature : public LibraryFeature { QString m_analysisTitleName; QPointer m_pAnalysisView; QPointer m_pAnalysisLibraryTableModel; - QHash m_analysisTables; + QHash > m_analysisTables; }; diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 94ebaa94d53..3a87452d987 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -172,6 +172,10 @@ TreeItemModel* AutoDJFeature::getChildModel() { void AutoDJFeature::activate() { //qDebug() << "AutoDJFeature::activate()"; + DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull()) { + return; + } + m_pAutoDJView->onShow(); m_pLibrary->slotSwitchToViewFeature(this); @@ -314,6 +318,10 @@ void AutoDJFeature::slotAddRandomTrack(bool) { TrackPointer addedTrack = (m_pTrackCollection->getTrackDAO()).getTrack(trackId); if(addedTrack->exists()) { playlistDao.appendTrackToPlaylist(trackId, m_iAutoDJPlaylistId); + DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull()) { + return; + } + m_pAutoDJView->onShow(); return; } else { @@ -334,6 +342,10 @@ void AutoDJFeature::slotAddRandomTrack(bool) { if(addedTrack->exists()) { if(!addedTrack->getPlayCounter().isPlayed()) { playlistDao.appendTrackToPlaylist(trackId, m_iAutoDJPlaylistId); + DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull()) { + return; + } + m_pAutoDJView->onShow(); return; } @@ -427,8 +439,12 @@ void AutoDJFeature::slotRandomQueue(int tracksToAdd) { } void AutoDJFeature::selectionChanged(const QItemSelection&, const QItemSelection&) { + DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull()) { + return; + } + auto it = m_trackTables.find(m_featureFocus); - if (it == m_trackTables.end()) { + if (it == m_trackTables.end() || it->isNull()) { return; } diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index bf4ce9ded24..727c3a7a87f 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -41,7 +41,7 @@ class AutoDJFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - virtual QString getViewName(); + QString getViewName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -71,7 +71,7 @@ class AutoDJFeature : public LibraryFeature { const static QString m_sAutoDJViewName; TreeItemModel m_childModel; QPointer m_pAutoDJView; - QHash m_trackTables; + QHash > m_trackTables; // Initialize the list of crates loaded into the auto-DJ queue. void constructCrateChildModel(); diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index c7d99009328..ce61ea61c84 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -30,7 +30,7 @@ class BansheeFeature : public BaseExternalLibraryFeature { virtual QVariant title(); virtual QIcon getIcon(); - virtual QString getViewName(); + QString getViewName() override; virtual TreeItemModel* getChildModel(); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index e2342e98e33..743115f2b7d 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -617,6 +617,10 @@ QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, return edit; } +QString BasePlaylistFeature::getViewName() { + return m_rootViewName; +} + void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) { if (QString(link.path()) == "create") { slotCreatePlaylist(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index df63a9b8dcf..25cb9155ad4 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -36,10 +36,7 @@ class BasePlaylistFeature : public LibraryFeature { void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); - - QString getViewName() { - return m_rootViewName; - } + QString getViewName() override; signals: void showPage(const QUrl& page); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 6cd53f4ec50..77133a914c6 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -32,7 +32,6 @@ BrowseFeature::BrowseFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) : LibraryFeature(pConfig, pLibrary, parent), - m_pConfig(pConfig), m_browseModel(this, pTrackCollection, pRecordingManager), m_proxyModel(&m_browseModel), m_pTrackCollection(pTrackCollection), diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index d5bfd0751c7..aad4bb8eb6f 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -36,7 +36,7 @@ class BrowseFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - virtual QString getViewName(); + QString getViewName() override; void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); @@ -66,7 +66,6 @@ class BrowseFeature : public LibraryFeature { void saveQuickLinks(); void loadQuickLinks(); - UserSettingsPointer m_pConfig; BrowseTableModel m_browseModel; ProxyTrackModel m_proxyModel; TrackCollection* m_pTrackCollection; diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 153304d6257..167cb84be83 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -32,10 +32,8 @@ class CrateFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); + QString getViewName() override; - inline QString getViewName() { return m_sCrateViewName; } - - inline bool hasSearch() { return false; } void onSearch(QString&) {} bool dragMoveAccept(QUrl url); @@ -111,7 +109,6 @@ class CrateFeature : public LibraryFeature { TreeItemModel m_childModel; TrackPointer m_pSelectedTrack; QSet m_cratesSelectedTrackIsIn; - UserSettingsPointer m_pConfig; const static QString m_sCrateViewName; }; diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index 1f493bf54a6..071293e0da7 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -30,7 +30,7 @@ class ITunesFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - virtual QString getViewName(); + QString getViewName() override; TreeItemModel* getChildModel(); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index de80e89a1de..74511c3c612 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -88,6 +88,10 @@ void LibraryPaneManager::setFocusedFeature(const QString& featureName) { void LibraryPaneManager::setFocus() { //qDebug() << "LibraryPaneManager::setFocus"; + DEBUG_ASSERT_AND_HANDLE(m_pPaneWidget) { + return; + } + m_pPaneWidget->setProperty("showFocus", 1); } @@ -99,7 +103,7 @@ void LibraryPaneManager::clearFocus() { void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { //qDebug() << "LibraryPaneManager::slotShowTrackModel" << model; TrackModel* trackModel = dynamic_cast(model); - DEBUG_ASSERT_AND_HANDLE(trackModel) { + DEBUG_ASSERT_AND_HANDLE(trackModel && !m_pPaneWidget.isNull()) { return; } emit(showTrackModel(model)); @@ -109,6 +113,10 @@ void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { void LibraryPaneManager::slotSwitchToView(const QString& view) { //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; + DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { + return; + } + m_pPaneWidget->switchToView(view); m_pPaneWidget->setFocus(); } @@ -118,6 +126,10 @@ void LibraryPaneManager::slotSwitchToViewFeature(LibraryFeature* pFeature) { return; } + DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { + return; + } + int widgetId = m_featuresWidget[pFeature]; m_pPaneWidget->setCurrentIndex(widgetId); } @@ -127,11 +139,15 @@ void LibraryPaneManager::slotRestoreSearch(const QString& text) { } void LibraryPaneManager::slotShowBreadCrumb(TreeItem *pTree) { + DEBUG_ASSERT_AND_HANDLE(!m_pBreadCrumb.isNull()) { + return; + } + m_pBreadCrumb->showBreadCrumb(pTree); } bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { - if (m_pPaneWidget == nullptr) { + if (m_pPaneWidget.isNull()) { return false; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index e0c372302ff..3930981b69d 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -70,10 +70,10 @@ class LibraryPaneManager : public QObject { protected: - WBaseLibrary* m_pPaneWidget; + QPointer m_pPaneWidget; QList m_features; QHash m_featuresWidget; - WLibraryBreadCrumb* m_pBreadCrumb; + QPointer m_pBreadCrumb; private: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index fe5a4271e12..417725b8edb 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -34,6 +34,11 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, kMissingTitle(tr("Missing Tracks")), m_pHiddenView(nullptr), m_pMissingView(nullptr), + m_hiddenPaneId(-1), + m_missingPaneId(-1), + m_pHiddenTableModel(nullptr), + m_pMissingTableModel(nullptr), + m_pExpandedStack(nullptr), m_trackDao(pTrackCollection->getTrackDAO()), m_pTrackCollection(pTrackCollection) { QStringList columns; @@ -263,6 +268,10 @@ QIcon MixxxLibraryFeature::getIcon() { return QIcon(":/images/library/ic_library_library.png"); } +QString MixxxLibraryFeature::getViewName() { + return m_sMixxxLibraryViewName; +} + TreeItemModel* MixxxLibraryFeature::getChildModel() { return &m_childModel; } @@ -271,10 +280,10 @@ void MixxxLibraryFeature::refreshLibraryModels() { if (m_pLibraryTableModel) { m_pLibraryTableModel->select(); } - if (m_pMissingView) { + if (!m_pMissingView.isNull()) { m_pMissingView->onShow(); } - if (m_pHiddenView) { + if (!m_pHiddenView.isNull()) { m_pHiddenView->onShow(); } } @@ -282,7 +291,11 @@ void MixxxLibraryFeature::refreshLibraryModels() { void MixxxLibraryFeature::hiddenSelectionChanged(const QItemSelection&, const QItemSelection&) { auto it = m_hiddenPane.find(m_featureFocus); - if (it == m_hiddenPane.end()) { + if (it == m_hiddenPane.end() || it->isNull()) { + return; + } + + DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull()) { return; } @@ -293,23 +306,28 @@ void MixxxLibraryFeature::hiddenSelectionChanged(const QItemSelection&, void MixxxLibraryFeature::missingSelectionChanged(const QItemSelection&, const QItemSelection&) { auto it = m_missingPane.find(m_featureFocus); - if (it == m_missingPane.end()) { + if (it == m_missingPane.end() || it->isNull()) { return; } + + DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull()) { + return; + } + const QModelIndexList& selection = (*it)->selectionModel()->selectedIndexes(); m_pMissingView->setSelectedIndexes(selection); } void MixxxLibraryFeature::selectAllHidden() { auto it = m_hiddenPane.find(m_featureFocus); - if (it != m_hiddenPane.end()) { + if (it != m_hiddenPane.end() && !it->isNull()) { (*it)->selectAll(); } } void MixxxLibraryFeature::selectAllMissing() { auto it = m_missingPane.find(m_featureFocus); - if (it != m_missingPane.end()) { + if (it != m_missingPane.end() && !it->isNull()) { (*it)->selectAll(); } } @@ -332,14 +350,30 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { activate(); } else if (itemName == kHiddenTitle) { + auto it = m_paneStack.find(m_featureFocus); + DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull() && + !m_pExpandedStack.isNull() && + it != m_paneStack.end() && + !it->isNull()) { + return; + } + m_pHiddenView->onShow(); - m_paneStack[m_featureFocus]->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); + (*it)->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } else if (itemName == kMissingTitle) { + auto it = m_paneStack.find(m_featureFocus); + DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull() && + !m_pExpandedStack.isNull() && + it != m_paneStack.end() && + !it->isNull()) { + return; + } + m_pMissingView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index ddbecec63f8..0b6a168e9fb 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -41,6 +41,8 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); + QString getViewName() override; + bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); @@ -50,10 +52,6 @@ class MixxxLibraryFeature : public LibraryFeature { void bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter* pKeyboard); QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); - - inline QString getViewName() { - return m_sMixxxLibraryViewName; - } public slots: void activate(); @@ -78,21 +76,23 @@ class MixxxLibraryFeature : public LibraryFeature { const QString kMissingTitle; QPointer m_pHiddenView; QPointer m_pMissingView; - QHash m_hiddenPane; - QHash m_missingPane; + QHash > m_hiddenPane; + QHash > m_missingPane; // This is needed to select the correct widget in the 2 size widget stack // for the hidden and missing widgets. QHash m_hiddenPaneId; QHash m_missingPaneId; + + // SidebarExpanded pane's ids int m_hiddenExpandedId; int m_missingExpandedId; QPointer m_pHiddenTableModel; QPointer m_pMissingTableModel; - QHash m_paneStack; - QStackedWidget* m_pExpandedStack; + QHash > m_paneStack; + QPointer m_pExpandedStack; QSharedPointer m_pBaseTrackCache; LibraryTableModel* m_pLibraryTableModel; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 1a3fae590ab..0f80892a42e 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -41,6 +41,10 @@ QIcon RecordingFeature::getIcon() { return QIcon(":/images/library/ic_library_recordings.png"); } +QString RecordingFeature::getViewName() { + return m_sRecordingViewName; +} + TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } @@ -89,6 +93,10 @@ QWidget *RecordingFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { void RecordingFeature::activate() { + DEBUG_ASSERT_AND_HANDLE(!m_pRecordingView.isNull()) { + return; + } + m_pRecordingView->refreshBrowseModel(); m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); @@ -98,7 +106,7 @@ void RecordingFeature::activate() { } BrowseTableModel* RecordingFeature::getBrowseTableModel() { - if (!m_pBrowseModel) { + if (m_pBrowseModel.isNull()) { m_pBrowseModel = new BrowseTableModel(this, m_pTrackCollection, m_pRecordingManager); } @@ -106,7 +114,7 @@ BrowseTableModel* RecordingFeature::getBrowseTableModel() { } ProxyTrackModel* RecordingFeature::getProxyTrackModel() { - if (!m_pProxyModel) { + if (m_pProxyModel.isNull()) { m_pProxyModel = new ProxyTrackModel(getBrowseTableModel()); } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index b3a93a734ed..bfce846efc8 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,9 +30,7 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - inline QString getViewName() { - return m_sRecordingViewName; - } + QString getViewName() override; void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard, int paneId); @@ -60,8 +58,8 @@ class RecordingFeature : public LibraryFeature { RecordingManager* m_pRecordingManager; QPointer m_pRecordingView; - BrowseTableModel* m_pBrowseModel; - ProxyTrackModel* m_pProxyModel; + QPointer m_pBrowseModel; + QPointer m_pProxyModel; }; #endif diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index e528f6a28e2..aaddfaa79f5 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -109,6 +109,10 @@ QIcon RhythmboxFeature::getIcon() { return QIcon(":/images/library/ic_library_rhythmbox.png"); } +QString RhythmboxFeature::getViewName() { + return m_sRhythmBoxViewName; +} + TreeItemModel* RhythmboxFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index e142f516f2c..f337be1a680 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -30,9 +30,7 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - inline QString getViewName() { - return m_sRhythmBoxViewName; - } + QString getViewName() override; TreeItemModel* getChildModel(); // processes the music collection diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index 6dd0ce22aec..ffd7c7ecee6 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -46,7 +46,7 @@ class TraktorFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - virtual QString getViewName(); + QString getViewName() override; static bool isSupported(); TreeItemModel* getChildModel(); From 47421f069a913e22024de099c6a49a01f33f2a6e Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:14:30 +0200 Subject: [PATCH 219/552] Fixed build not working --- src/library/mixxxlibraryfeature.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 417725b8edb..6f70c2cd8e3 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -34,8 +34,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, kMissingTitle(tr("Missing Tracks")), m_pHiddenView(nullptr), m_pMissingView(nullptr), - m_hiddenPaneId(-1), - m_missingPaneId(-1), + m_hiddenExpandedId(-1), + m_missingExpandedId(-1), m_pHiddenTableModel(nullptr), m_pMissingTableModel(nullptr), m_pExpandedStack(nullptr), From a1f251a0c1b09e391f770c5ee1f19b2079be7f0c Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:15:11 +0200 Subject: [PATCH 220/552] Fixed not building --- src/library/mixxxlibraryfeature.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 6f70c2cd8e3..417725b8edb 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -34,8 +34,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, kMissingTitle(tr("Missing Tracks")), m_pHiddenView(nullptr), m_pMissingView(nullptr), - m_hiddenExpandedId(-1), - m_missingExpandedId(-1), + m_hiddenPaneId(-1), + m_missingPaneId(-1), m_pHiddenTableModel(nullptr), m_pMissingTableModel(nullptr), m_pExpandedStack(nullptr), From fc037046f5f4b988e5474e0f2d078e76ca8a9625 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:17:42 +0200 Subject: [PATCH 221/552] Fixed not building --- src/library/cratefeature.cpp | 4 ++++ src/library/mixxxlibraryfeature.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index abedb800c33..00bc2c30b4a 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -127,6 +127,10 @@ QIcon CrateFeature::getIcon() { return QIcon(":/images/library/ic_library_crates.png"); } +QString CrateFeature::getViewName() { + return m_sCrateViewName; +} + int CrateFeature::crateIdFromIndex(QModelIndex index) { TreeItem* item = static_cast(index.internalPointer()); if (item == nullptr) { diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 417725b8edb..6f70c2cd8e3 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -34,8 +34,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, kMissingTitle(tr("Missing Tracks")), m_pHiddenView(nullptr), m_pMissingView(nullptr), - m_hiddenPaneId(-1), - m_missingPaneId(-1), + m_hiddenExpandedId(-1), + m_missingExpandedId(-1), m_pHiddenTableModel(nullptr), m_pMissingTableModel(nullptr), m_pExpandedStack(nullptr), From c3a5c9f3618b5f827b92e1fe19f4ea750665f31e Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:29:20 +0200 Subject: [PATCH 222/552] Remove Bind Pane from LibraryFeature --- src/library/analysisfeature.cpp | 8 -------- src/library/analysisfeature.h | 3 +-- src/library/autodj/autodjfeature.cpp | 8 -------- src/library/autodj/autodjfeature.h | 1 - src/library/baseplaylistfeature.cpp | 8 -------- src/library/baseplaylistfeature.h | 1 - src/library/browse/browsefeature.cpp | 8 -------- src/library/browse/browsefeature.h | 1 - src/library/cratefeature.cpp | 7 ------- src/library/cratefeature.h | 2 -- src/library/libraryfeature.h | 9 +-------- src/library/mixxxlibraryfeature.cpp | 8 -------- src/library/mixxxlibraryfeature.h | 3 +-- src/library/recording/recordingfeature.cpp | 7 ------- src/library/recording/recordingfeature.h | 2 -- src/skin/legacyskinparser.cpp | 2 -- 16 files changed, 3 insertions(+), 75 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 8ea78f03b0c..f832f60ce0b 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -67,14 +67,6 @@ QString AnalysisFeature::getViewName() { return m_sAnalysisViewName; } -void AnalysisFeature::bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard, - int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(libraryWidget); - libraryWidget->registerView(m_sAnalysisViewName, pPane); -} - QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { if (!m_pAnalysisLibraryTableModel) { diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index cd30b869033..b52b6e3b588 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -35,8 +35,7 @@ class AnalysisFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter*pKeyboard, - int paneId); + QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary* libraryWidget, KeyboardEventFilter*pKeyboard); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 3a87452d987..d04884cfe92 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -102,14 +102,6 @@ QString AutoDJFeature::getViewName() { return m_sAutoDJViewName; } -void AutoDJFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, - int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pLibraryWidget); - pLibraryWidget->registerView(m_sAutoDJViewName, pPane); -} - QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 727c3a7a87f..a360008dd8c 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -46,7 +46,6 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - void bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary *pSidebarWidget, diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 743115f2b7d..fc7b1dde8ab 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -598,14 +598,6 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { return &m_childModel; } -void BasePlaylistFeature::bindPaneWidget(WLibrary* pPaneWidget, - KeyboardEventFilter* pKeyboard, - int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pPaneWidget); - pPaneWidget->registerView(m_rootViewName, pPane); -} - QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 25cb9155ad4..26e056fe079 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -34,7 +34,6 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); QString getViewName() override; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 77133a914c6..08c1cd1c94d 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -216,14 +216,6 @@ TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } -void BrowseFeature::bindPaneWidget(WLibrary* pPaneWidget, - KeyboardEventFilter* pKeyboard, - int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pPaneWidget); - pPaneWidget->registerView(m_sBrowseViewName, pPane); -} - QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); edit->setHtml(getRootViewHtml()); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index aad4bb8eb6f..8c423b755e6 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,6 @@ class BrowseFeature : public LibraryFeature { QIcon getIcon(); QString getViewName() override; - void bindPaneWidget(WLibrary* pPaneWidget, KeyboardEventFilter*pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 00bc2c30b4a..178dd0e232b 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -190,13 +190,6 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { return !locked && formatSupported; } -void CrateFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pLibraryWidget); - pLibraryWidget->registerView(m_sCrateViewName, pPane); -} - QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, int) { WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(nullptr); pEdit->setHtml(getRootViewHtml()); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 167cb84be83..09c16b6e8e8 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -41,8 +41,6 @@ class CrateFeature : public LibraryFeature { QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); - void bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, int paneId); QWidget *createPaneWidget(KeyboardEventFilter* pKeyboard, int); TreeItemModel* getChildModel(); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index ad1e6939182..cd24cded0a3 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -55,16 +55,9 @@ class LibraryFeature : public QObject { QUrl /* url */) { return false; } - + // Reimplement this to register custom views with the library widget // at the right pane. - // TODO(jmigual): This function should be removed and replaced by the - // createPaneWidget function - virtual void bindPaneWidget(WLibrary* /* libraryWidget */, - KeyboardEventFilter* /* keyboard */, - int /* paneId */) { - } - virtual QWidget* createPaneWidget(KeyboardEventFilter* /* keyboard */, int /* paneId */) { return nullptr; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 6f70c2cd8e3..3bf03be912b 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -138,14 +138,6 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { delete m_pLibraryTableModel; } -void MixxxLibraryFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, - int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pLibraryWidget); - pLibraryWidget->registerView(m_sMixxxLibraryViewName, pPane); -} - QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WLibraryStack* pStack = new WLibraryStack(nullptr); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 0b6a168e9fb..a6c503cf3b6 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -46,8 +46,7 @@ class MixxxLibraryFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); - void bindPaneWidget(WLibrary* pLibrary, - KeyboardEventFilter* pKeyboard, int paneId); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); void bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter* pKeyboard); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 0f80892a42e..ad193fc19ff 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -49,13 +49,6 @@ TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } -void RecordingFeature::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter *pKeyboard, int paneId) { - QWidget* pPane = createPaneWidget(pKeyboard, paneId); - pPane->setParent(pLibraryWidget); - pLibraryWidget->registerView(m_sRecordingViewName, pPane); -} - QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index bfce846efc8..7f87489f201 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -32,8 +32,6 @@ class RecordingFeature : public LibraryFeature { QIcon getIcon(); QString getViewName() override; - void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard, int paneId); QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); void bindSidebarWidget(WBaseLibrary* pBaseLibrary, KeyboardEventFilter* pKeyboard); diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index e7c6de85ace..76db23eefe6 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1175,8 +1175,6 @@ QWidget* LegacySkinParser::parseCoverArt(const QDomElement& node) { // If no group was provided, hook the widget up to the Library. if (channel.isEmpty()) { // Connect cover art signals to the library - connect(m_pLibrary, SIGNAL(switchToView(const QString&)), - pCoverArt, SLOT(slotReset())); connect(m_pLibrary, SIGNAL(enableCoverArtDisplay(bool)), pCoverArt, SLOT(slotEnable(bool))); connect(m_pLibrary, SIGNAL(trackSelected(TrackPointer)), From 05845c84b73606a4a68601ebaf8c7db522e72933 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:35:46 +0200 Subject: [PATCH 223/552] Fix minor issues with libraryPaneManager connections and RhythmBox --- src/library/librarypanemanager.cpp | 4 +--- src/library/rhythmbox/rhythmboxfeature.cpp | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 74511c3c612..6e70902e848 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -24,9 +24,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryPaneManager::bindLibraryWidget" << libraryWidget; m_pPaneWidget = pLibraryWidget; - - connect(this, SIGNAL(switchToView(const QString&)), - m_pPaneWidget, SLOT(switchToView(const QString&))); + connect(m_pPaneWidget, SIGNAL(focused()), this, SIGNAL(focused())); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index aaddfaa79f5..5fa65c49ea5 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,6 +138,7 @@ void RhythmboxFeature::activate() { emit (featureIsLoading(this, true)); } + m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); @@ -162,12 +163,12 @@ TreeItem* RhythmboxFeature::importMusicCollection() { if (!db.exists()) { db.setFileName(QDir::homePath() + "/.local/share/rhythmbox/rhythmdb.xml"); if (!db.exists()) { - return NULL; + return nullptr; } } if (!db.open(QIODevice::ReadOnly | QIODevice::Text)) - return NULL; + return nullptr; //Delete all table entries of Traktor feature ScopedTransaction transaction(m_database); From fe1386172746891674644f303c8ff6efe4e156c5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 1 Jul 2016 18:43:30 +0200 Subject: [PATCH 224/552] Removed bindSidebarWidget function --- src/library/analysisfeature.cpp | 7 ------- src/library/analysisfeature.h | 2 -- src/library/autodj/autodjfeature.cpp | 8 -------- src/library/autodj/autodjfeature.h | 3 --- src/library/banshee/bansheefeature.cpp | 2 +- src/library/library.cpp | 2 ++ src/library/libraryfeature.cpp | 11 ----------- src/library/libraryfeature.h | 2 -- src/library/mixxxlibraryfeature.cpp | 7 ------- src/library/mixxxlibraryfeature.h | 2 -- src/library/recording/recordingfeature.cpp | 8 -------- src/library/recording/recordingfeature.h | 2 -- src/library/rhythmbox/rhythmboxfeature.cpp | 1 - src/library/traktor/traktorfeature.cpp | 2 +- 14 files changed, 4 insertions(+), 55 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index f832f60ce0b..37f58ec13cc 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -95,13 +95,6 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, return pTable; } -void AnalysisFeature::bindSidebarWidget(WBaseLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard) { - QWidget* pSidebar = createSidebarWidget(pKeyboard); - pSidebar->setParent(libraryWidget); - libraryWidget->registerView(m_sAnalysisViewName, pSidebar); -} - QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index b52b6e3b588..bc89908b82c 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -37,8 +37,6 @@ class AnalysisFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); - void bindSidebarWidget(WBaseLibrary* libraryWidget, - KeyboardEventFilter*pKeyboard); QWidget* createSidebarWidget(KeyboardEventFilter* pKeyboard); TreeItemModel* getChildModel(); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index d04884cfe92..ec2afd0c36a 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -128,14 +128,6 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan return pTrackTableView; } -void AutoDJFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, - KeyboardEventFilter*pKeyboard) { - //qDebug() << "AutoDJFeature::bindSidebarWidget" << pSidebarWidget; - QWidget* pSidebar = createSidebarWidget(pKeyboard); - pSidebar->setParent(pSidebarWidget); - pSidebarWidget->registerView(m_sAutoDJViewName, pSidebar); -} - QWidget* AutoDJFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { QTabWidget* pContainer = new QTabWidget(nullptr); diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index a360008dd8c..9ba96cb2d77 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -47,9 +47,6 @@ class AutoDJFeature : public LibraryFeature { bool dragMoveAccept(QUrl url); QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); - - void bindSidebarWidget(WBaseLibrary *pSidebarWidget, - KeyboardEventFilter* pKeyboard); QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); TreeItemModel* getChildModel(); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 516696a9433..3dd290f201c 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -126,8 +126,8 @@ void BansheeFeature::activate() { m_pBansheePlaylistModel->setTableModel(0); // Gets the master playlist + m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/library.cpp b/src/library/library.cpp index 1a3f7c7f76a..15a79a92cd9 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -238,6 +238,8 @@ void Library::slotShowTrackModel(QAbstractItemModel* model) { } void Library::slotShowTrackModel(QAbstractItemModel *model, LibraryFeature *pFeature) { + m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + slotUpdateFocus(pFeature); slotShowTrackModel(model); } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 588b915a410..808ce6eb6fd 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -33,17 +33,6 @@ LibraryFeature::~LibraryFeature() { } -void LibraryFeature::bindSidebarWidget(WBaseLibrary *pSidebarWidget, - KeyboardEventFilter* pKeyboard) { - QWidget* pSidebar = createSidebarWidget(pKeyboard); - if (pSidebar == nullptr) { - return; - } - - pSidebar->setParent(pSidebarWidget); - pSidebarWidget->registerView(getViewName(), pSidebar); -} - QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryFeature::bindSidebarWidget"; QFrame* pContainer = new QFrame(nullptr); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index cd24cded0a3..ca8adb52d8b 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -65,8 +65,6 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane - virtual void bindSidebarWidget(WBaseLibrary *pSidebarWidget, - KeyboardEventFilter*pKeyboard); virtual QWidget* createSidebarWidget(KeyboardEventFilter* pKeyboard); virtual TreeItemModel* getChildModel() = 0; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 3bf03be912b..7ac0a4de545 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -195,13 +195,6 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, return pStack; } -void MixxxLibraryFeature::bindSidebarWidget(WBaseLibrary* pSidebarWidget, - KeyboardEventFilter*pKeyboard) { - QWidget* pSidebar = createSidebarWidget(pKeyboard); - pSidebar->setParent(pSidebarWidget); - pSidebarWidget->registerView(m_sMixxxLibraryViewName, pSidebar); -} - QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { QTabWidget* pTab = new QTabWidget(nullptr); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index a6c503cf3b6..fcc13d40ada 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -48,8 +48,6 @@ class MixxxLibraryFeature : public LibraryFeature { TreeItemModel* getChildModel(); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); - - void bindSidebarWidget(WBaseLibrary* pSidebarWidget, KeyboardEventFilter* pKeyboard); QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); public slots: diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index ad193fc19ff..370d595dda9 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -65,14 +65,6 @@ QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) return pTrackTableView; } -void RecordingFeature::bindSidebarWidget(WBaseLibrary* pBaseLibrary, - KeyboardEventFilter* pKeyboard) { - - QWidget* pSidebar = createSidebarWidget(pKeyboard); - pSidebar->setParent(pBaseLibrary); - pBaseLibrary->registerView(m_sRecordingViewName, m_pRecordingView); -} - QWidget *RecordingFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { m_pRecordingView = new DlgRecording(nullptr, m_pTrackCollection, diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 7f87489f201..dfceabceb6f 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -33,8 +33,6 @@ class RecordingFeature : public LibraryFeature { QString getViewName() override; QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); - void bindSidebarWidget(WBaseLibrary* pBaseLibrary, - KeyboardEventFilter* pKeyboard); QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); TreeItemModel* getChildModel(); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 5fa65c49ea5..364315dc0f2 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,7 +138,6 @@ void RhythmboxFeature::activate() { emit (featureIsLoading(this, true)); } - m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 11a732f0086..c7924a60277 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -166,8 +166,8 @@ void TraktorFeature::activate() { emit (featureIsLoading(this, true)); } + m_pLibrary->slotShowTrackModel(m_pTraktorTableModel, this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotShowTrackModel(m_pTraktorTableModel); emit(enableCoverArtDisplay(false)); } From 951c690abffab50dcd83b880ff8147842c18bcc1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 09:52:22 +0200 Subject: [PATCH 225/552] Remove unnecessary signals and added more QPointers --- src/library/analysisfeature.cpp | 39 +++++++++++++-------------------- src/library/analysisfeature.h | 2 ++ src/library/dlganalysis.cpp | 20 +++++++++-------- src/library/dlganalysis.h | 9 +++----- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 37f58ec13cc..9775aead741 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -68,22 +68,16 @@ QString AnalysisFeature::getViewName() { } QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, - int paneId) { - if (!m_pAnalysisLibraryTableModel) { - m_pAnalysisLibraryTableModel = - new AnalysisLibraryTableModel(this, m_pTrackCollection); - } - + int paneId) { WAnalysisLibraryTableView* pTable = new WAnalysisLibraryTableView(nullptr, m_pConfig, m_pTrackCollection); pTable->installEventFilter(pKeyboard); - pTable->setModel(m_pAnalysisLibraryTableModel); + pTable->loadTrackModel(getAnalysisTableModel()); connect(pTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); - connect(pTable, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); connect(pTable, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), @@ -98,20 +92,8 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); - if (!m_pAnalysisLibraryTableModel) { - m_pAnalysisLibraryTableModel = - new AnalysisLibraryTableModel(this, m_pTrackCollection); - } - - m_pAnalysisView->setTableModel(m_pAnalysisLibraryTableModel); + m_pAnalysisView->setTableModel(getAnalysisTableModel()); - connect(m_pAnalysisView, SIGNAL(analyzeTracks(QList)), - this, SLOT(analyzeTracks(QList))); - connect(m_pAnalysisView, SIGNAL(stopAnalysis()), - this, SLOT(stopAnalysis())); - connect(m_pAnalysisView, SIGNAL(selectAll()), - this, SLOT(selectAll())); - connect(this, SIGNAL(analysisActive(bool)), m_pAnalysisView, SLOT(analysisActive(bool))); connect(this, SIGNAL(trackAnalysisStarted(int)), @@ -132,7 +114,7 @@ TreeItemModel* AnalysisFeature::getChildModel() { } void AnalysisFeature::refreshLibraryModels() { - if (m_pAnalysisView) { + if (!m_pAnalysisView.isNull()) { m_pAnalysisView->onShow(); } } @@ -150,7 +132,7 @@ void AnalysisFeature::activate() { m_pLibrary->slotSwitchToViewFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - if (m_pAnalysisView) { + if (!m_pAnalysisView.isNull()) { emit(restoreSearch(m_pAnalysisView->currentSearch())); } emit(enableCoverArtDisplay(true)); @@ -222,7 +204,7 @@ void AnalysisFeature::tableSelectionChanged(const QItemSelection&, const QItemSelection&) { //qDebug() << "AnalysisFeature::tableSelectionChanged" << sender(); auto it = m_analysisTables.find(m_featureFocus); - if (it == m_analysisTables.end()) { + if (it == m_analysisTables.end() || it->isNull()) { return; } @@ -242,3 +224,12 @@ bool AnalysisFeature::dropAccept(QList urls, QObject* pSource) { bool AnalysisFeature::dragMoveAccept(QUrl url) { return SoundSourceProxy::isUrlSupported(url); } + +AnalysisLibraryTableModel* AnalysisFeature::getAnalysisTableModel() { + if (m_pAnalysisLibraryTableModel.isNull()) { + m_pAnalysisLibraryTableModel = + new AnalysisLibraryTableModel(this, m_pTrackCollection); + } + + return m_pAnalysisLibraryTableModel; +} diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index bc89908b82c..33920539722 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -67,6 +67,8 @@ class AnalysisFeature : public LibraryFeature { // where x is the current track being analyzed and y is the total number of // tracks in the job void setTitleProgress(int trackNum, int totalNum); + + AnalysisLibraryTableModel* getAnalysisTableModel(); TrackCollection* m_pTrackCollection; AnalyzerQueue* m_pAnalyzerQueue; diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index 983a76935f9..e552827aaad 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -1,17 +1,19 @@ #include -#include "widget/wwidget.h" -#include "widget/wskincolor.h" -#include "widget/wanalysislibrarytableview.h" -#include "library/trackcollection.h" +#include "library/analysisfeature.h" #include "library/dlganalysis.h" +#include "library/trackcollection.h" #include "util/assert.h" +#include "widget/wanalysislibrarytableview.h" +#include "widget/wskincolor.h" +#include "widget/wwidget.h" -DlgAnalysis::DlgAnalysis(QWidget* parent, +DlgAnalysis::DlgAnalysis(QWidget* parent, AnalysisFeature *pAnalysis, TrackCollection* pTrackCollection) : QFrame(parent), m_pTrackCollection(pTrackCollection), m_bAnalysisActive(false), + m_pAnalysis(pAnalysis), m_tracksInQueue(0), m_currentTrack(0) { setupUi(this); @@ -24,7 +26,7 @@ DlgAnalysis::DlgAnalysis(QWidget* parent, this, SLOT(analyze())); connect(pushButtonSelectAll, SIGNAL(clicked()), - this, SIGNAL(selectAll())); + m_pAnalysis, SLOT(selectAll())); } DlgAnalysis::~DlgAnalysis() { @@ -43,7 +45,7 @@ void DlgAnalysis::onShow() { void DlgAnalysis::analyze() { //qDebug() << this << "analyze()"; if (m_bAnalysisActive) { - emit(stopAnalysis()); + m_pAnalysis->stopAnalysis(); } else { QList trackIds; for (QModelIndex selectedIndex : m_selectedIndexes) { @@ -55,7 +57,7 @@ void DlgAnalysis::analyze() { } } m_currentTrack = 1; - emit(analyzeTracks(trackIds)); + m_pAnalysis->analyzeTracks(trackIds); } } @@ -75,7 +77,7 @@ void DlgAnalysis::analysisActive(bool bActive) { // slot void DlgAnalysis::trackAnalysisFinished(int size) { - qDebug() << "Analysis finished" << size << "tracks left"; + //qDebug() << "Analysis finished" << size << "tracks left"; if (size > 0) { m_currentTrack = m_tracksInQueue - size + 1; } diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 9cb9db57125..9a83b0491ef 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -12,6 +12,7 @@ class AnalysisLibraryTableModel; class WAnalysisLibraryTableView; +class AnalysisFeature; class DlgAnalysis : public QFrame, public Ui::DlgAnalysis { @@ -20,6 +21,7 @@ class DlgAnalysis : public QFrame, public Ui::DlgAnalysis { public: DlgAnalysis(QWidget *parent, + AnalysisFeature* pAnalysis, TrackCollection* pTrackCollection); virtual ~DlgAnalysis(); @@ -40,19 +42,14 @@ class DlgAnalysis : public QFrame, public Ui::DlgAnalysis { void trackAnalysisProgress(int progress); void trackAnalysisStarted(int size); void analysisActive(bool bActive); - - signals: - void analyzeTracks(QList trackIds); - void stopAnalysis(); - void selectAll(); - private: //Note m_pTrackTablePlaceholder is defined in the .ui file TrackCollection* m_pTrackCollection; bool m_bAnalysisActive; QButtonGroup m_songsButtonGroup; AnalysisLibraryTableModel* m_pAnalysisLibraryTableModel; + AnalysisFeature* m_pAnalysis; int m_tracksInQueue; int m_currentTrack; From ecbc51652f4a833adf8679efe786af8ee5537b0a Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 10:21:44 +0200 Subject: [PATCH 226/552] Rename getViewName() and remove switchToView --- src/library/analysisfeature.cpp | 6 +-- src/library/analysisfeature.h | 4 +- src/library/autodj/autodjfeature.cpp | 4 +- src/library/autodj/autodjfeature.h | 2 +- src/library/banshee/bansheefeature.cpp | 2 +- src/library/banshee/bansheefeature.h | 2 +- src/library/baseplaylistfeature.cpp | 4 +- src/library/baseplaylistfeature.h | 2 +- src/library/browse/browsefeature.cpp | 4 +- src/library/browse/browsefeature.h | 2 +- src/library/cratefeature.cpp | 4 +- src/library/cratefeature.h | 2 +- src/library/itunes/itunesfeature.cpp | 2 +- src/library/itunes/itunesfeature.h | 2 +- src/library/library.cpp | 48 ++++++------------- src/library/library.h | 10 ++-- src/library/libraryfeature.h | 3 +- src/library/librarypanemanager.cpp | 18 +++++-- src/library/librarypanemanager.h | 12 ++--- src/library/librarysidebarexpandedmanager.cpp | 10 +--- src/library/mixxxlibraryfeature.cpp | 6 +-- src/library/mixxxlibraryfeature.h | 2 +- src/library/recording/recordingfeature.cpp | 4 +- src/library/recording/recordingfeature.h | 2 +- src/library/rhythmbox/rhythmboxfeature.cpp | 2 +- src/library/rhythmbox/rhythmboxfeature.h | 2 +- src/library/traktor/traktorfeature.cpp | 4 +- src/library/traktor/traktorfeature.h | 2 +- src/widget/wfeatureclickbutton.cpp | 23 ++++----- src/widget/wfeatureclickbutton.h | 17 ++----- 30 files changed, 88 insertions(+), 119 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 9775aead741..edce582da9a 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -63,7 +63,7 @@ QIcon AnalysisFeature::getIcon() { return QIcon(":/images/library/ic_library_prepare.png"); } -QString AnalysisFeature::getViewName() { +QString AnalysisFeature::getFeatureName() { return m_sAnalysisViewName; } @@ -90,7 +90,7 @@ QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, } QWidget* AnalysisFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { - m_pAnalysisView = new DlgAnalysis(nullptr, m_pTrackCollection); + m_pAnalysisView = new DlgAnalysis(nullptr, this, m_pTrackCollection); m_pAnalysisView->setTableModel(getAnalysisTableModel()); @@ -129,7 +129,7 @@ void AnalysisFeature::selectAll() { void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; //m_pLibrary->switchToView(m_sAnalysisViewName); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); if (!m_pAnalysisView.isNull()) { diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 33920539722..6d8e04f7dc4 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -31,7 +31,7 @@ class AnalysisFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -41,6 +41,7 @@ class AnalysisFeature : public LibraryFeature { TreeItemModel* getChildModel(); void refreshLibraryModels(); + void stopAnalysis(); signals: void analysisActive(bool bActive); @@ -53,7 +54,6 @@ class AnalysisFeature : public LibraryFeature { private slots: void slotProgressUpdate(int num_left); - void stopAnalysis(); void cleanupAnalyzer(); void tableSelectionChanged(const QItemSelection&, const QItemSelection&); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index ec2afd0c36a..97f168d42a4 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -98,7 +98,7 @@ QIcon AutoDJFeature::getIcon() { return QIcon(":/images/library/ic_library_autodj.png"); } -QString AutoDJFeature::getViewName() { +QString AutoDJFeature::getFeatureName() { return m_sAutoDJViewName; } @@ -162,7 +162,7 @@ void AutoDJFeature::activate() { m_pAutoDJView->onShow(); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //Null String disables search box diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 9ba96cb2d77..02861d0bf10 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -41,7 +41,7 @@ class AutoDJFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 3dd290f201c..2bebedfaab9 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -63,7 +63,7 @@ QIcon BansheeFeature::getIcon() { return QIcon(":/images/library/ic_library_banshee.png"); } -QString BansheeFeature::getViewName() { +QString BansheeFeature::getFeatureName() { return m_sBansheeViewName; } diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index ce61ea61c84..47ea34552f2 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -30,7 +30,7 @@ class BansheeFeature : public BaseExternalLibraryFeature { virtual QVariant title(); virtual QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; virtual TreeItemModel* getChildModel(); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index fc7b1dde8ab..af74a8d8925 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -131,7 +131,7 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { } void BasePlaylistFeature::activate() { - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); emit(restoreSearch(QString())); // Null String disables search box @@ -609,7 +609,7 @@ QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, return edit; } -QString BasePlaylistFeature::getViewName() { +QString BasePlaylistFeature::getFeatureName() { return m_rootViewName; } diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 26e056fe079..bb6a4676146 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -35,7 +35,7 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); - QString getViewName() override; + QString getFeatureName() override; signals: void showPage(const QUrl& page); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 08c1cd1c94d..34ee4af7bef 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -208,7 +208,7 @@ QIcon BrowseFeature::getIcon() { return QIcon(":/images/library/ic_library_browse.png"); } -QString BrowseFeature::getViewName() { +QString BrowseFeature::getFeatureName() { return m_sBrowseViewName; } @@ -224,7 +224,7 @@ QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { } void BrowseFeature::activate() { - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 8c423b755e6..7e33c6bc5d4 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -36,7 +36,7 @@ class BrowseFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 178dd0e232b..d47a0e3a027 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -127,7 +127,7 @@ QIcon CrateFeature::getIcon() { return QIcon(":/images/library/ic_library_crates.png"); } -QString CrateFeature::getViewName() { +QString CrateFeature::getFeatureName() { return m_sCrateViewName; } @@ -205,7 +205,7 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 09c16b6e8e8..a2e4a4664dc 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -32,7 +32,7 @@ class CrateFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; void onSearch(QString&) {} diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 27fd6399b32..814908640d7 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -117,7 +117,7 @@ QIcon ITunesFeature::getIcon() { return QIcon(":/images/library/ic_library_itunes.png"); } -QString ITunesFeature::getViewName() { +QString ITunesFeature::getFeatureName() { return m_sItunesView; } diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index 071293e0da7..ced6a301adf 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -30,7 +30,7 @@ class ITunesFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; TreeItemModel* getChildModel(); diff --git a/src/library/library.cpp b/src/library/library.cpp index 15a79a92cd9..6283d6c5a97 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -117,10 +117,10 @@ void Library::bindSidebarWidget(WButtonBar* sidebar) { for (LibraryFeature* f : m_features) { WFeatureClickButton* button = sidebar->addButton(f); - connect(button, SIGNAL(clicked(const QString&)), - this, SLOT(slotActivateFeature(const QString&))); - connect(button, SIGNAL(hoverShow(const QString&)), - this, SLOT(slotHoverFeature(const QString&))); + connect(button, SIGNAL(clicked(LibraryFeature*)), + this, SLOT(slotActivateFeature(LibraryFeature*))); + connect(button, SIGNAL(hoverShow(LibraryFeature*)), + this, SLOT(slotHoverFeature(LibraryFeature*))); connect(button, SIGNAL(rightClicked(const QPoint&)), f, SLOT(onRightClick(const QPoint&))); } @@ -210,7 +210,7 @@ void Library::addFeature(LibraryFeature* feature) { return; } m_features.append(feature); - m_featuresMap.insert(feature->getViewName(), feature); + m_featuresMap.insert(feature->getFeatureName(), feature); m_pSidebarModel->addLibraryFeature(feature); @@ -218,8 +218,6 @@ void Library::addFeature(LibraryFeature* feature) { // between the LibraryFeature and the Library connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), this, SLOT(slotShowTrackModel(QAbstractItemModel*))); - connect(feature, SIGNAL(switchToView(const QString&)), - this, SLOT(slotSwitchToView(const QString&))); connect(feature, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), @@ -244,26 +242,13 @@ void Library::slotShowTrackModel(QAbstractItemModel *model, LibraryFeature *pFea slotShowTrackModel(model); } -void Library::slotSwitchToView(const QString& view) { - //qDebug() << "Library::slotSwitchToView" << view; - m_pSidebarExpanded->slotSwitchToView(view); - - WBaseLibrary* wLibrary = m_panes[m_focusedPane]->getPaneWidget(); - // Only change the current pane if it's not shown already - if (wLibrary->getCurrentViewName() != view) { - m_panes[m_focusedPane]->slotSwitchToView(view); - } - - handleFocus(); -} - -void Library::slotSwitchToViewFeature(LibraryFeature* pFeature) { +void Library::slotSwitchToFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); slotUpdateFocus(pFeature); WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); // Only change the current pane if it's not shown already - if (pWLibrary->getCurrentViewName() != pFeature->getViewName()) { + if (pWLibrary->getCurrentViewName() != pFeature->getFeatureName()) { m_panes[m_focusedPane]->slotSwitchToViewFeature(pFeature); } @@ -335,7 +320,7 @@ void Library::onSkinLoadFinished() { // The first pane always shows the Mixxx Library feature on start m_focusedPane = m_panes.begin().key(); (*m_features.begin())->setFeatureFocus(m_focusedPane); - slotActivateFeature((*m_features.begin())->getViewName()); + slotActivateFeature(*m_features.begin()); } else { qDebug() << "Library::onSkinLoadFinished No Panes loaded!"; @@ -416,12 +401,10 @@ QStringList Library::getDirs() { return m_pTrackCollection->getDirectoryDAO().getDirs(); } -void Library::slotActivateFeature(const QString &featureName) { - LibraryFeature* pFeature = m_featuresMap[featureName]; - +void Library::slotActivateFeature(LibraryFeature *pFeature) { // The feature is being shown currently in the focused pane - if (m_panes[m_focusedPane]->getFocusedFeature() == featureName) { - m_pSidebarExpanded->slotSwitchToView(featureName); + if (m_panes[m_focusedPane]->getFocusedFeature() == pFeature) { + m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); return; } @@ -436,22 +419,21 @@ void Library::slotActivateFeature(const QString &featureName) { } else { // The feature is shown in some pane m_focusedPane = pFeature->getFeatureFocus(); - m_pSidebarExpanded->slotSwitchToView(featureName); + m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); handleFocus(); return; } - m_panes[m_focusedPane]->setFocusedFeature(featureName); + m_panes[m_focusedPane]->setFocusedFeature(pFeature); pFeature->setFeatureFocus(m_focusedPane); pFeature->activate(); handleFocus(); } -void Library::slotHoverFeature(const QString &featureName) { +void Library::slotHoverFeature(LibraryFeature *pFeature) { // This function only changes the sidebar expanded to allow dropping items // directly in some features sidebar panes - - m_pSidebarExpanded->slotSwitchToView(featureName); + m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); } void Library::slotSetTrackTableFont(const QFont& font) { diff --git a/src/library/library.h b/src/library/library.h index 7cdbc9a2aa7..a5a2aa84b6f 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -91,8 +91,9 @@ class Library : public QObject { static const int kDefaultRowHeightPx; public slots: - void slotActivateFeature(const QString& featureName); - void slotHoverFeature(const QString& featureName); + + void slotActivateFeature(LibraryFeature* pFeature); + void slotHoverFeature(LibraryFeature* pFeature); // It uses the current focus, it needs to be updated before calling it // avoid this function @@ -101,11 +102,8 @@ class Library : public QObject { // Updates the focus from the feature before changing the view void slotShowTrackModel(QAbstractItemModel *model, LibraryFeature* pFeature); - // It uses the current focus, avoid using this function - void slotSwitchToView(const QString& view); - // Updates the focus from the feature before changing the view - void slotSwitchToViewFeature(LibraryFeature* pFeature); + void slotSwitchToFeature(LibraryFeature* pFeature); void slotShowBreadCrumb(TreeItem* pTree); void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index ca8adb52d8b..114e19969bf 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -37,7 +37,7 @@ class LibraryFeature : public QObject { // Must be a unique name for each feature, it must be a unique name for each // different feature - virtual QString getViewName() = 0; + virtual QString getFeatureName() = 0; virtual bool dropAccept(QList /* urls */, QObject* /* pSource */) { @@ -103,7 +103,6 @@ class LibraryFeature : public QObject { signals: void showTrackModel(QAbstractItemModel* model); - void switchToView(const QString&); void loadTrack(TrackPointer); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 6e70902e848..5c73bcc73ab 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -40,7 +40,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, continue; } pPane->setParent(lib); - lib->registerView(f->getViewName(), pPane); + lib->registerView(f->getFeatureName(), pPane); m_featuresWidget[f] = lib->indexOf(pPane); } } @@ -80,8 +80,20 @@ WBaseLibrary* LibraryPaneManager::getPaneWidget() { return m_pPaneWidget; } -void LibraryPaneManager::setFocusedFeature(const QString& featureName) { - m_focusedFeature = featureName; +void LibraryPaneManager::setFocusedFeatureName(const QString& featureName) { + m_focusedFeatureName = featureName; +} + +const QString& LibraryPaneManager::getFocusedFeatureName() const { + return m_focusedFeatureName; +} + +void LibraryPaneManager::setFocusedFeature(LibraryFeature* pFeature) { + m_pFocusedFeature = pFeature; +} + +LibraryFeature *LibraryPaneManager::getFocusedFeature() const { + return m_pFocusedFeature; } void LibraryPaneManager::setFocus() { diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 3930981b69d..c6703f15f0d 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -34,12 +34,9 @@ class LibraryPaneManager : public QObject { void addFeatures(const QList& features); WBaseLibrary* getPaneWidget(); - - void setFocusedFeature(const QString& featureName); - - QString getFocusedFeature() { - return m_focusedFeature; - } + + void setFocusedFeature(LibraryFeature* pFeature); + LibraryFeature* getFocusedFeature() const; void setFocus(); @@ -79,7 +76,8 @@ class LibraryPaneManager : public QObject { const static QString m_sTrackViewName; - QString m_focusedFeature; + QString m_focusedFeatureName; + LibraryFeature* m_pFocusedFeature; int m_paneId; diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 8686d8ca9a5..054c7a3e407 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -8,21 +8,15 @@ LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) void LibrarySidebarExpandedManager::bindPaneWidget(WBaseLibrary* sidebarWidget, KeyboardEventFilter* pKeyboard) { - m_pPaneWidget = sidebarWidget; - connect(this, SIGNAL(switchToView(const QString&)), - m_pPaneWidget, SLOT(switchToView(const QString&))); - - for (LibraryFeature* f : m_features) { - //f->bindSidebarWidget(m_pPaneWidget, pKeyboard); - + for (LibraryFeature* f : m_features) { QWidget* pPane = f->createSidebarWidget(pKeyboard); if (pPane == nullptr) { continue; } pPane->setParent(sidebarWidget); - sidebarWidget->registerView(f->getViewName(), pPane); + sidebarWidget->registerView(f->getFeatureName(), pPane); m_featuresWidget[f] = sidebarWidget->indexOf(pPane); } } diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 7ac0a4de545..ffd8a4ec8d1 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -253,7 +253,7 @@ QIcon MixxxLibraryFeature::getIcon() { return QIcon(":/images/library/ic_library_library.png"); } -QString MixxxLibraryFeature::getViewName() { +QString MixxxLibraryFeature::getFeatureName() { return m_sMixxxLibraryViewName; } @@ -346,7 +346,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pHiddenView->onShow(); (*it)->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); @@ -362,7 +362,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pMissingView->onShow(); m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index fcc13d40ada..98a177f138b 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -41,7 +41,7 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 370d595dda9..10bfcf0f6dc 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -41,7 +41,7 @@ QIcon RecordingFeature::getIcon() { return QIcon(":/images/library/ic_library_recordings.png"); } -QString RecordingFeature::getViewName() { +QString RecordingFeature::getFeatureName() { return m_sRecordingViewName; } @@ -83,7 +83,7 @@ void RecordingFeature::activate() { } m_pRecordingView->refreshBrowseModel(); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(""); diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index dfceabceb6f..64d274c2ae3 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,7 +30,7 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int); QWidget* createSidebarWidget(KeyboardEventFilter *pKeyboard); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 364315dc0f2..efd6bb98036 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -109,7 +109,7 @@ QIcon RhythmboxFeature::getIcon() { return QIcon(":/images/library/ic_library_rhythmbox.png"); } -QString RhythmboxFeature::getViewName() { +QString RhythmboxFeature::getFeatureName() { return m_sRhythmBoxViewName; } diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index f337be1a680..4653fe51dcc 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -30,7 +30,7 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; TreeItemModel* getChildModel(); // processes the music collection diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index c7924a60277..4fdfc71c2d2 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -128,7 +128,7 @@ QIcon TraktorFeature::getIcon() { return QIcon(":/images/library/ic_library_traktor.png"); } -QString TraktorFeature::getViewName() { +QString TraktorFeature::getFeatureName() { return m_sTraktorViewName; } @@ -182,7 +182,7 @@ void TraktorFeature::activateChild(const QModelIndex& index) { qDebug() << "Activate Traktor Playlist: " << item->dataPath().toString(); m_pTraktorPlaylistModel->setPlaylist(item->dataPath().toString()); - m_pLibrary->slotSwitchToViewFeature(this); + m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(item); m_pLibrary->slotShowTrackModel(m_pTraktorPlaylistModel); emit(enableCoverArtDisplay(false)); diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index ffd7c7ecee6..6c7b26a89b1 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -46,7 +46,7 @@ class TraktorFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getViewName() override; + QString getFeatureName() override; static bool isSupported(); TreeItemModel* getChildModel(); diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index 83678be505b..fd32a9491ac 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -3,25 +3,20 @@ const int WFeatureClickButton::kHoverTime = 250; // milliseconds -WFeatureClickButton::WFeatureClickButton(LibraryFeature* feature, QWidget* parent) +WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* parent) : QToolButton(parent), - m_feature(feature) { - DEBUG_ASSERT_AND_HANDLE(feature != nullptr) { + m_pFeature(pFeature) { + DEBUG_ASSERT_AND_HANDLE(pFeature != nullptr) { return; } - setIcon(m_feature->getIcon()); - setText(m_feature->title().toString()); - m_data = m_feature->getViewName(); + setIcon(m_pFeature->getIcon()); + setText(m_pFeature->title().toString()); connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); setAcceptDrops(true); } -void WFeatureClickButton::setData(const QString& data) { - m_data = data; -} - void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::RightButton) { emit(rightClicked(event->globalPos())); @@ -35,7 +30,7 @@ void WFeatureClickButton::dragEnterEvent(QDragEnterEvent* event) { event->ignore(); return; } - if (m_feature->dragMoveAccept(event->mimeData()->urls().first())) { + if (m_pFeature->dragMoveAccept(event->mimeData()->urls().first())) { event->acceptProposedAction(); m_hoverTimer.start(kHoverTime, this); } @@ -52,7 +47,7 @@ void WFeatureClickButton::dropEvent(QDropEvent* event) { return; } - if (m_feature->dropAccept(event->mimeData()->urls(), event->source())) { + if (m_pFeature->dropAccept(event->mimeData()->urls(), event->source())) { event->acceptProposedAction(); } } @@ -62,10 +57,10 @@ void WFeatureClickButton::timerEvent(QTimerEvent* event) { QToolButton::timerEvent(event); return; } - emit(hoverShow(m_data)); + emit(hoverShow(m_pFeature)); } void WFeatureClickButton::slotClicked() { - emit(clicked(m_data)); + emit(clicked(m_pFeature)); } diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index ca1e3e7fd6b..110e8984661 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -11,27 +11,21 @@ class WFeatureClickButton : public QToolButton Q_OBJECT public: - WFeatureClickButton(LibraryFeature* feature = nullptr, + WFeatureClickButton(LibraryFeature* pFeature = nullptr, QWidget* parent = nullptr); - void setData(const QString& data); - signals: - void clicked(const QString& view); - + void clicked(LibraryFeature*); void rightClicked(const QPoint&); - - void hoverShow(const QString& feature); + void hoverShow(LibraryFeature*); protected: void mousePressEvent(QMouseEvent* event); void dragEnterEvent(QDragEnterEvent* event); - void dragLeaveEvent(QDragLeaveEvent*); - void dropEvent(QDropEvent* event); void timerEvent(QTimerEvent* event); @@ -44,10 +38,7 @@ private slots: static const int kHoverTime; - QString m_data; - - LibraryFeature* m_feature; - + LibraryFeature* m_pFeature; QBasicTimer m_hoverTimer; }; From adf86dbe32cfdf5b163492e0f66228b7262bd674 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 10:27:05 +0200 Subject: [PATCH 227/552] Fixed compilation issue --- src/library/librarypanemanager.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 5c73bcc73ab..cb09899967b 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -80,14 +80,6 @@ WBaseLibrary* LibraryPaneManager::getPaneWidget() { return m_pPaneWidget; } -void LibraryPaneManager::setFocusedFeatureName(const QString& featureName) { - m_focusedFeatureName = featureName; -} - -const QString& LibraryPaneManager::getFocusedFeatureName() const { - return m_focusedFeatureName; -} - void LibraryPaneManager::setFocusedFeature(LibraryFeature* pFeature) { m_pFocusedFeature = pFeature; } From 3a0a3b7e55e58a3766bfae4cd348f63f340a5446 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 10:30:24 +0200 Subject: [PATCH 228/552] Rename misspeled name --- src/library/libraryfeature.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 808ce6eb6fd..a2d83136705 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -73,17 +73,17 @@ QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) { ConfigKey("[Library]", "LastImportExportPlaylistDirectory"), QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); - QFileDialog dialogg(NULL, - tr("Import Playlist"), - lastPlaylistDirectory, - tr("Playlist Files (*.m3u *.m3u8 *.pls *.csv)")); - dialogg.setAcceptMode(QFileDialog::AcceptOpen); - dialogg.setFileMode(mode); - dialogg.setModal(true); + QFileDialog dialog(nullptr, + tr("Import Playlist"), + lastPlaylistDirectory, + tr("Playlist Files (*.m3u *.m3u8 *.pls *.csv)")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(mode); + dialog.setModal(true); // If the user refuses return - if (!dialogg.exec()) { + if (!dialog.exec()) { return QStringList(); } - return dialogg.selectedFiles(); + return dialog.selectedFiles(); } From 45a630623bb3a6ecb8303645bd2e26ccf8dd9121 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 10:36:57 +0200 Subject: [PATCH 229/552] Remove factory --- src/library/libraryfeaturefactory.cpp | 35 ------------------- src/library/libraryfeaturefactory.h | 48 --------------------------- 2 files changed, 83 deletions(-) delete mode 100644 src/library/libraryfeaturefactory.cpp delete mode 100644 src/library/libraryfeaturefactory.h diff --git a/src/library/libraryfeaturefactory.cpp b/src/library/libraryfeaturefactory.cpp deleted file mode 100644 index 3c2c0b812f9..00000000000 --- a/src/library/libraryfeaturefactory.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * LibraryFeatureFactory.cpp - * - * Created on: Jun 25, 2016 - * Author: joan - */ - -#include -#include - -LibraryFeatureFactory::LibraryFeatureFactory() { - // TODO Auto-generated constructor stub - -} - -LibraryFeatureFactory::~LibraryFeatureFactory() { - // TODO Auto-generated destructor stub -} - -void LibraryFeatureFactory::registerF(const QString& name, - Creator* pCreator) { - getTable()[name] = pCreator; -} - -QHash LibraryFeatureFactory::getTable() { - static QHash table; - return table; -} - -LibraryFeature* LibraryFeatureFactory::create(const QString& name) { - if (getTable().contains(name)) { - return getTable()[name]->create(); - } - return nullptr; -} diff --git a/src/library/libraryfeaturefactory.h b/src/library/libraryfeaturefactory.h deleted file mode 100644 index 8af09738c09..00000000000 --- a/src/library/libraryfeaturefactory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * LibraryFeatureFactory.h - * - * Created on: Jun 25, 2016 - * Author: joan - */ - -#ifndef SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ -#define SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ -#include -#include - -class LibraryFeature; - -/** - * To use this we trust in the compiler initialization of static - */ -#define REGISTER_F(featureName) \ - private: \ - static LibraryFeatureCreator creator; - - -class Creator { - public: - virtual ~Creator() = 0; - virtual LibraryFeature* create() = 0; -}; - -template -class LibraryFeatureCreator : Creator { - LibraryFeature* create() { - return new T; - } -}; - -class LibraryFeatureFactory { -public: - LibraryFeatureFactory(); - ~LibraryFeatureFactory(); - - static void registerF(const QString& name, Creator* pCreator); - - static QHash getTable(); - - static LibraryFeature* create(const QString& name); -}; - -#endif /* SRC_LIBRARY_LIBRARYFEATUREFACTORY_H_ */ From a0104390d3645eaba1c7d88690cd5203d5e7d7e9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 12:06:51 +0200 Subject: [PATCH 230/552] Fixed build and added Bread Crumb to shade skin --- build/depends.py | 1 - res/skins/Shade/skin.xml | 85 ++++----- src/library/autodj/autodjfeature.cpp | 5 +- src/library/autodj/dlgautodj.ui | 275 ++++++++++++--------------- 4 files changed, 160 insertions(+), 206 deletions(-) diff --git a/build/depends.py b/build/depends.py index 0405ebd0f0b..f50939d6c3f 100644 --- a/build/depends.py +++ b/build/depends.py @@ -850,7 +850,6 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", - "library/libraryfeaturefactory.cpp", "library/analysisfeature.cpp", "library/autodj/autodjfeature.cpp", "library/autodj/autodjprocessor.cpp", diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index fd1711f2886..0179fcde6e9 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -460,21 +460,10 @@ background: transparent; color: #C1C1C1;} - - WBaseLibrary QRadioButton, WBaseLibrary QLabel { margin: 9px 3px 6px 3px; } - - - WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } - - #DlgMissing > QPushButton, - #DlgHidden > QPushButton, - #DlgAutoDJ > QPushButton, - #DlgRecording > QPushButton, - #DlgAnalysis > QPushButton { - margin: 3px 3px 3px 3px; + WBaseLibrary QPushButton { + margin: 2px 3px; padding: 3px 3px; - min-width: 65px; } WBaseLibrary QScrollArea, @@ -492,7 +481,7 @@ border: 1px solid #646464; } - QScrollArea QPushButton { + WBaseLibrary QPushButton { border: 1px solid black; background-color: #aab2b7; } @@ -527,15 +516,9 @@ border-top: 2px solid aqua; } - - /*#DlgMissing > QPushButton#btnPurge, - #DlgHidden > QPushButton#btnUnhide, - #DlgAutoDJ > QPushButton#pushButtonAutoDJ, - #DlgRecording > QPushButton#pushButtonRecording, - #DlgAnalysis > QPushButton#pushButtonAnalyze { margin: 9px 12px 6px 3px; }*/ - - - /*#DlgAutoDJ > QPushButton#pushButtonShuffle { margin: 9px 3px 6px 12px; } */ + WLibraryBreadCrumb { + margin: 2px 4px; + } QTreeView { margin: 0px 0px 0px 5px; } @@ -777,38 +760,32 @@ - - e,me - 1,e - 0,0 + + horizontal - - horizontal + + LibrarySidebarButtons + + + vertical + 8,2 - - LibrarySidebarButtons - - - vertical - - - LibrarySidebarExpanded - - - - 16,16 - me,me - - [Library],show_coverart - visible - - - - + + LibrarySidebarExpanded + + + + 30,30 + me,me + + [Library],show_coverart + visible + + - + - + @@ -817,6 +794,9 @@ 1 + + 1 + 1 @@ -828,6 +808,9 @@ 2 + + 2 + 2 diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 97f168d42a4..3465e55c7d4 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -139,7 +139,10 @@ QWidget* AutoDJFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); m_pAutoDJView->installEventFilter(pKeyboard); - pContainer->addTab(m_pAutoDJView, tr("controls")); + QScrollArea* pScroll = new QScrollArea(pContainer); + pScroll->setWidget(m_pAutoDJView); + pScroll->setWidgetResizable(true); + pContainer->addTab(pScroll, tr("controls")); // Be informed when the user wants to add another random track. connect(m_pAutoDJProcessor,SIGNAL(randomTrackRequested(int)), diff --git a/src/library/autodj/dlgautodj.ui b/src/library/autodj/dlgautodj.ui index b5e4847bf81..b8c2bb67a1c 100644 --- a/src/library/autodj/dlgautodj.ui +++ b/src/library/autodj/dlgautodj.ui @@ -13,166 +13,135 @@ Auto DJ - - - 0 - + - - - - 0 - 0 - + + + + + Seconds + + + sec. + + + + + + + + 0 + 0 + + + + Determines the duration of the transition. + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + -9 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Turn Auto DJ on or off. - - Qt::ScrollBarAlwaysOff + + Enable Auto DJ - + true - - - - 0 - 0 - 505 - 397 - - - - - - - Turn Auto DJ on or off. - - - Enable Auto DJ - - - true - - - - - - - - - - - - - - - - Seconds - - - sec. - - - - - - - - 0 - 0 - - - - Determines the duration of the transition. - - - false - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - -9 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Trigger the transition to the next track. - - - Fade Now - - - - - - - Skip the next track in the Auto DJ playlist. - - - Skip Track - - - false - - - - - - - Add a random track from track sources (crates) or Library to the Auto DJ playlist. - - - Add Random - - - - - - - Shuffle the content of the Auto DJ playlist. - - - Shuffle - - - false - - - - - - - Qt::Vertical - - - - 20 - 7 - - - - - - + + + + + + + + + + + Trigger the transition to the next track. + + + Fade Now + + + + + + + Skip the next track in the Auto DJ playlist. + + + Skip Track + + + false + + + + + + + Add a random track from track sources (crates) or Library to the Auto DJ playlist. + + + Add Random + + + + + + + Shuffle the content of the Auto DJ playlist. + + + Shuffle + + + false + + + + + + + Qt::Vertical + + + + 20 + 172 + + + + From deba0ed6d7f7d5ff596767a7f84f28f4aae5003d Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 12:50:35 +0200 Subject: [PATCH 231/552] Avoid moving focus to a hidden pane --- src/library/library.cpp | 38 ++++++++++++++----- src/library/library.h | 6 ++- src/library/librarypanemanager.cpp | 24 +++++++++--- src/library/librarypanemanager.h | 10 +++-- src/library/librarysidebarexpandedmanager.cpp | 5 ++- src/library/librarysidebarexpandedmanager.h | 2 +- src/widget/wbaselibrary.cpp | 13 +++++++ src/widget/wbaselibrary.h | 6 ++- src/widget/wlibrarystack.cpp | 2 +- 9 files changed, 81 insertions(+), 25 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 6283d6c5a97..e1c951a27e4 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -169,7 +169,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard) { //qDebug() << "Library::bindSidebarExpanded"; - m_pSidebarExpanded = new LibrarySidebarExpandedManager; + m_pSidebarExpanded = new LibrarySidebarExpandedManager(this); connect(m_pSidebarExpanded, SIGNAL(focused()), this, SLOT(slotPaneFocused())); m_pSidebarExpanded->addFeatures(m_features); @@ -401,15 +401,35 @@ QStringList Library::getDirs() { return m_pTrackCollection->getDirectoryDAO().getDirs(); } +void Library::paneCollapsed(int paneId) { + m_collapsedPanes.insert(paneId); + + // Automatically switch the focus to a non collapsed pane + m_panes[paneId]->clearFocus(); + + for (LibraryPaneManager* pPane : m_panes) { + if (!m_collapsedPanes.contains(pPane->getPaneId())) { + m_focusedPane = pPane->getPaneId(); + pPane->setFocus(); + break; + } + } +} + +void Library::paneUncollapsed(int paneId) { + m_collapsedPanes.remove(paneId); +} + void Library::slotActivateFeature(LibraryFeature *pFeature) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getFocusedFeature() == pFeature) { m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); return; } + int featureFocus = pFeature->getFeatureFocus(); // The feature is not focused anywhere - if (pFeature->getFeatureFocus() < 0) { + if (featureFocus < 0 || m_collapsedPanes.contains(featureFocus)) { // Remove the previous focused feature in this pane for (LibraryFeature* f : m_features) { if (f->getFeatureFocus() == m_focusedPane) { @@ -417,8 +437,8 @@ void Library::slotActivateFeature(LibraryFeature *pFeature) { } } } else { - // The feature is shown in some pane - m_focusedPane = pFeature->getFeatureFocus(); + // The feature is shown in some not collapsed pane + m_focusedPane = featureFocus; m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); handleFocus(); return; @@ -470,20 +490,20 @@ void Library::slotUpdateFocus(LibraryFeature *pFeature) { } -LibraryPaneManager* Library::getPane(int id) { +LibraryPaneManager* Library::getPane(int paneId) { //qDebug() << "Library::createPane" << id; // Get the value once to avoid searching again in the hash - auto it = m_panes.find(id); + auto it = m_panes.find(paneId); if (it != m_panes.end()) { return *it; } - LibraryPaneManager* pPane = new LibraryPaneManager(id); + LibraryPaneManager* pPane = new LibraryPaneManager(paneId, this); pPane->addFeatures(m_features); - m_panes.insert(id, pPane); + m_panes.insert(paneId, pPane); connect(pPane, SIGNAL(focused()), this, SLOT(slotPaneFocused())); - m_focusedPane = id; + m_focusedPane = paneId; return pPane; } diff --git a/src/library/library.h b/src/library/library.h index a5a2aa84b6f..0c37180dd5a 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -65,6 +65,9 @@ class Library : public QObject { void addFeature(LibraryFeature* feature); QStringList getDirs(); + + void paneCollapsed(int paneId); + void paneUncollapsed(int paneId); // TODO(rryan) Transitionary only -- the only reason this is here is so the // waveform widgets can signal to a player to load a track. This can be @@ -145,7 +148,7 @@ class Library : public QObject { private: // If the pane exists returns it, otherwise it creates the pane - LibraryPaneManager *getPane(int id); + LibraryPaneManager *getPane(int paneId); LibraryPaneManager* getFocusedPane(); UserSettingsPointer m_pConfig; @@ -167,6 +170,7 @@ class Library : public QObject { LibraryPaneManager* m_pSidebarExpanded; QList m_features; QHash m_featuresMap; + QSet m_collapsedPanes; // Can be any integer as it's used with a HashMap int m_focusedPane; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index cb09899967b..fca8b1957b0 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -1,19 +1,21 @@ #include -#include "librarypanemanager.h" #include "library/libraryfeature.h" -#include "widget/wtracktableview.h" +#include "library/library.h" +#include "library/librarypanemanager.h" +#include "util/assert.h" #include "widget/wbuttonbar.h" #include "widget/wlibrarybreadcrumb.h" -#include "util/assert.h" +#include "widget/wtracktableview.h" const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); -LibraryPaneManager::LibraryPaneManager(int paneId, QObject* parent) +LibraryPaneManager::LibraryPaneManager(int paneId, Library *pLibrary, QObject* parent) : QObject(parent), m_pPaneWidget(nullptr), m_pBreadCrumb(nullptr), - m_paneId(paneId) { + m_paneId(paneId), + m_pLibrary(pLibrary) { qApp->installEventFilter(this); } @@ -27,6 +29,10 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, connect(m_pPaneWidget, SIGNAL(focused()), this, SIGNAL(focused())); + connect(m_pPaneWidget, SIGNAL(collapsed()), + this, SLOT(slotPaneCollapsed())); + connect(m_pPaneWidget, SIGNAL(uncollapsed()), + this, SLOT(slotPaneUncollapsed())); WLibrary* lib = qobject_cast(m_pPaneWidget); if (lib == nullptr) { @@ -148,6 +154,14 @@ void LibraryPaneManager::slotShowBreadCrumb(TreeItem *pTree) { m_pBreadCrumb->showBreadCrumb(pTree); } +void LibraryPaneManager::slotPaneCollapsed() { + m_pLibrary->paneCollapsed(m_paneId); +} + +void LibraryPaneManager::slotPaneUncollapsed() { + m_pLibrary->paneUncollapsed(m_paneId); +} + bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (m_pPaneWidget.isNull()) { return false; diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index c6703f15f0d..8fd0a0de125 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -12,13 +12,14 @@ class LibraryFeature; class WButtonBar; class WLibraryBreadCrumb; class TreeItem; +class Library; class LibraryPaneManager : public QObject { Q_OBJECT public: - LibraryPaneManager(int paneId, QObject* parent = nullptr); + LibraryPaneManager(int paneId, Library* pLibrary, QObject* parent = nullptr); ~LibraryPaneManager(); @@ -64,6 +65,8 @@ class LibraryPaneManager : public QObject { void slotSwitchToViewFeature(LibraryFeature* pFeature); void slotRestoreSearch(const QString& text); void slotShowBreadCrumb(TreeItem* pTree); + void slotPaneCollapsed(); + void slotPaneUncollapsed(); protected: @@ -75,11 +78,10 @@ class LibraryPaneManager : public QObject { private: const static QString m_sTrackViewName; - - QString m_focusedFeatureName; - LibraryFeature* m_pFocusedFeature; + LibraryFeature* m_pFocusedFeature; int m_paneId; + Library* m_pLibrary; private slots: diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 054c7a3e407..9d217e5039d 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -1,8 +1,9 @@ #include "librarysidebarexpandedmanager.h" #include "library/libraryfeature.h" -LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(QObject* parent) - : LibraryPaneManager(-1, parent) { +LibrarySidebarExpandedManager::LibrarySidebarExpandedManager(Library *pLibrary, + QObject* parent) + : LibraryPaneManager(-1, pLibrary, parent) { } diff --git a/src/library/librarysidebarexpandedmanager.h b/src/library/librarysidebarexpandedmanager.h index 559cf5a4017..7a29eb9ada9 100644 --- a/src/library/librarysidebarexpandedmanager.h +++ b/src/library/librarysidebarexpandedmanager.h @@ -5,7 +5,7 @@ class LibrarySidebarExpandedManager : public LibraryPaneManager { public: - LibrarySidebarExpandedManager(QObject* parent = nullptr); + LibrarySidebarExpandedManager(Library* pLibrary, QObject* parent = nullptr); void bindPaneWidget(WBaseLibrary* sidebarWidget, KeyboardEventFilter* pKeyboard) override; diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 2f23c92e7c6..786064eee6c 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "wbaselibrary.h" @@ -77,3 +78,15 @@ bool WBaseLibrary::event(QEvent* pEvent) { return QStackedWidget::event(pEvent); } +void WBaseLibrary::resizeEvent(QResizeEvent *pEvent) { + + // Detect whether the library is collapsed to change the focus behaviour + if (pEvent->size().isEmpty()) { + m_isCollapsed = true; + emit(collapsed()); + } else if (m_isCollapsed) { + m_isCollapsed = false; + emit(uncollapsed()); + } +} + diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 9985d0ae3a6..e9ff6ffed4f 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -27,6 +27,8 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget signals: void focused(); + void collapsed(); + void uncollapsed(); public slots: @@ -38,16 +40,16 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget bool eventFilter(QObject*, QEvent* pEvent); bool event(QEvent* pEvent) override; + void resizeEvent(QResizeEvent* pEvent); QHash m_viewMap; private: QString m_currentViewName; - QMutex m_mutex; - int m_showFocus; + bool m_isCollapsed; }; #endif // WLIBRARYSIDEBAREXPANDED_H diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp index b98ef4569aa..1a7c431990a 100644 --- a/src/widget/wlibrarystack.cpp +++ b/src/widget/wlibrarystack.cpp @@ -13,7 +13,7 @@ WLibraryStack::~WLibraryStack() { } int WLibraryStack::addWidget(QWidget* w) { - qDebug() << "WLibraryStack::addWidget" << w; + //qDebug() << "WLibraryStack::addWidget" << w; checkAndWarning(w); return QStackedWidget::addWidget(w); } From 47e9ba52aaada7ff05cbabbc94bc2f8ff42b779d Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 13:34:00 +0200 Subject: [PATCH 232/552] Add new WTrackTable behaviour --- src/library/cratefeature.cpp | 46 ++++++++++++++++++++-------- src/library/cratefeature.h | 6 +++- src/library/itunes/itunesfeature.cpp | 2 +- src/library/libraryfeature.cpp | 33 ++++++++++++++++++++ src/library/libraryfeature.h | 19 +++++++----- 5 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index d47a0e3a027..d192b24e783 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -7,23 +7,24 @@ #include #include + +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/cratefeature.h" +#include "library/cratetablemodel.h" #include "library/export/trackexportwizard.h" +#include "library/parsercsv.h" #include "library/parser.h" #include "library/parserm3u.h" #include "library/parserpls.h" -#include "library/parsercsv.h" - -#include "library/cratetablemodel.h" -#include "library/trackcollection.h" #include "library/queryutil.h" -#include "widget/wlibrarytextbrowser.h" -#include "widget/wlibrary.h" -#include "controllers/keyboard/keyboardeventfilter.h" -#include "treeitem.h" +#include "library/trackcollection.h" #include "sources/soundsourceproxy.h" +#include "treeitem.h" #include "util/dnd.h" #include "util/time.h" +#include "widget/wlibrary.h" +#include "widget/wlibrarytextbrowser.h" +#include "widget/wlibrarystack.h" const QString CrateFeature::m_sCrateViewName = QString("CRATEHOME"); @@ -34,7 +35,9 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, : LibraryFeature(pConfig, pLibrary, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), - m_crateTableModel(this, pTrackCollection) { + m_crateTableModel(this, pTrackCollection), + m_idBrowse(-1), + m_idTable(-1) { m_pCreateCrateAction = new QAction(tr("Create New Crate"),this); connect(m_pCreateCrateAction, SIGNAL(triggered()), @@ -190,14 +193,24 @@ bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { return !locked && formatSupported; } -QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, int) { - WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(nullptr); +QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, + int paneId) { + WLibraryStack* pContainer = new WLibraryStack(nullptr); + m_panes[paneId] = pContainer; + + WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(pContainer); pEdit->setHtml(getRootViewHtml()); pEdit->setOpenLinks(false); pEdit->installEventFilter(pKeyboard); connect(pEdit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); - return pEdit; + + m_idBrowse = pContainer->addWidget(pEdit); + + QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); + m_idTable = pContainer->addWidget(pTable); + + return pContainer; } TreeItemModel* CrateFeature::getChildModel() { @@ -205,6 +218,13 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { + auto it = m_panes.find(m_featureFocus); + if (it == m_panes.end() || it->isNull()) { + return; + } + + (*it)->setCurrentIndex(m_idBrowse); + asda hsdflkja hfdsa m_pLibrary->slotSwitchToFeature(this); m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home @@ -232,7 +252,7 @@ void CrateFeature::activateCrate(int crateId) { QModelIndex index = indexFromCrateId(crateId); if (crateId != -1 && index.isValid()) { m_crateTableModel.setTableModel(crateId); - emit(showTrackModel(&m_crateTableModel)); + showTrackModel(&m_crateTableModel); emit(enableCoverArtDisplay(true)); // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index a2e4a4664dc..16284601f98 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -41,7 +41,7 @@ class CrateFeature : public LibraryFeature { QObject* pSource); bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); - QWidget *createPaneWidget(KeyboardEventFilter* pKeyboard, int); + QWidget *createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); TreeItemModel* getChildModel(); @@ -107,6 +107,10 @@ class CrateFeature : public LibraryFeature { TreeItemModel m_childModel; TrackPointer m_pSelectedTrack; QSet m_cratesSelectedTrackIsIn; + QHash > m_panes; + int m_idBrowse; + int m_idTable; + const static QString m_sCrateViewName; }; diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 814908640d7..26cb0e40bd4 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -756,7 +756,7 @@ void ITunesFeature::onTrackCollectionLoaded() { m_trackSource->buildIndex(); //m_pITunesTrackModel->select(); - emit(showTrackModel(m_pITunesTrackModel)); + showTrackModel(m_pITunesTrackModel); qDebug() << "Itunes library loaded: success"; } else { QMessageBox::warning( diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index a2d83136705..eda31b4d870 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -16,6 +16,7 @@ #include "library/libraryfeature.h" #include "widget/wbaselibrary.h" #include "widget/wlibrarysidebar.h" +#include "widget/wtracktableview.h" // KEEP THIS cpp file to tell scons that moc should be called on the class!!! // The reason for this is that LibraryFeature uses slots/signals and for this @@ -33,6 +34,30 @@ LibraryFeature::~LibraryFeature() { } +QWidget* LibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + WTrackTableView* pTrackTable = + new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection); + + pTrackTable->installEventFilter(pKeyboard); + + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), + this, SLOT(slotLoadTrack(TrackPointer))); + connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), + this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + + m_tables.append(pTrackTable); + + return pTrackTable; +} + QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryFeature::bindSidebarWidget"; QFrame* pContainer = new QFrame(nullptr); @@ -68,6 +93,14 @@ void LibraryFeature::setFeatureFocus(int focus) { m_featureFocus = focus; } +void LibraryFeature::showTrackModel(QAbstractItemModel *model) { + for (QPointer pTable : m_tables) { + if (!pTable.isNull()) { + pTable->loadTrackModel(model); + } + } +} + QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) { QString lastPlaylistDirectory = m_pConfig->getValueString( ConfigKey("[Library]", "LastImportExportPlaylistDirectory"), diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 114e19969bf..0a8d86f15ed 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -5,6 +5,8 @@ #define LIBRARYFEATURE_H #include +#include +#include #include #include @@ -15,10 +17,12 @@ #include "track/track.h" #include "treeitemmodel.h" +class Library; +class TrackCollection; class TrackModel; class WBaseLibrary; class WLibrary; -class Library; +class WTrackTableView; // pure virtual (abstract) class to provide an interface for libraryfeatures class LibraryFeature : public QObject { @@ -58,10 +62,7 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget // at the right pane. - virtual QWidget* createPaneWidget(KeyboardEventFilter* /* keyboard */, - int /* paneId */) { - return nullptr; - } + virtual QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane @@ -78,8 +79,12 @@ class LibraryFeature : public QObject { protected: inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + + void showTrackModel(QAbstractItemModel *model); + UserSettingsPointer m_pConfig; Library* m_pLibrary; + TrackCollection* m_pTrackCollection; int m_featureFocus; @@ -102,7 +107,6 @@ class LibraryFeature : public QObject { } signals: - void showTrackModel(QAbstractItemModel* model); void loadTrack(TrackPointer); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); @@ -120,7 +124,8 @@ class LibraryFeature : public QObject { private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); - + + QList > m_tables; }; #endif /* LIBRARYFEATURE_H */ From d53607b4e3db10ce3ea2e4ddc6dd31bc4acfbcb4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 16:31:46 +0200 Subject: [PATCH 233/552] Changed showTrackModel function [Not Building] --- src/library/analysisfeature.cpp | 6 +- src/library/autodj/autodjfeature.cpp | 4 +- src/library/banshee/bansheefeature.cpp | 8 +- src/library/baseplaylistfeature.cpp | 42 +++-- src/library/baseplaylistfeature.h | 9 +- src/library/browse/browsefeature.cpp | 36 +++-- src/library/browse/browsefeature.h | 8 +- src/library/cratefeature.cpp | 31 ++-- src/library/cratefeature.h | 4 +- src/library/historyfeature.cpp | 4 +- src/library/itunes/itunesfeature.cpp | 12 +- src/library/library.cpp | 46 +----- src/library/library.h | 30 ++-- src/library/libraryfeature.cpp | 69 ++++++--- src/library/libraryfeature.h | 15 +- src/library/librarypanemanager.cpp | 29 ++-- src/library/librarypanemanager.h | 7 +- src/library/mixxxlibraryfeature.cpp | 169 ++++++++------------- src/library/mixxxlibraryfeature.h | 25 ++- src/library/recording/recordingfeature.cpp | 4 +- src/library/rhythmbox/rhythmboxfeature.cpp | 8 +- src/library/traktor/traktorfeature.cpp | 13 +- 22 files changed, 282 insertions(+), 297 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index edce582da9a..d4802d518cc 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -129,11 +129,11 @@ void AnalysisFeature::selectAll() { void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; //m_pLibrary->switchToView(m_sAnalysisViewName); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->switchToFeature(this); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); if (!m_pAnalysisView.isNull()) { - emit(restoreSearch(m_pAnalysisView->currentSearch())); + m_pLibrary->slotRestoreSearch(m_pAnalysisView->currentSearch()); } emit(enableCoverArtDisplay(true)); } diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 3465e55c7d4..074fafe592e 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -165,8 +165,8 @@ void AutoDJFeature::activate() { m_pAutoDJView->onShow(); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->switchToFeature(this); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //Null String disables search box emit(enableCoverArtDisplay(true)); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 2bebedfaab9..f402b80923d 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -126,8 +126,8 @@ void BansheeFeature::activate() { m_pBansheePlaylistModel->setTableModel(0); // Gets the master playlist - m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel, this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(m_pBansheePlaylistModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); } @@ -140,8 +140,8 @@ void BansheeFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << item->data().toString(); m_pBansheePlaylistModel->setTableModel(playlistID); - m_pLibrary->slotShowTrackModel(m_pBansheePlaylistModel, this); - m_pLibrary->slotShowBreadCrumb(item); + showTrackModel(m_pBansheePlaylistModel); + m_pLibrary->showBreadCrumb(item); emit(enableCoverArtDisplay(false)); } } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index af74a8d8925..2318ec584a8 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -16,6 +16,7 @@ #include "library/treeitem.h" #include "controllers/keyboard/keyboardeventfilter.h" #include "widget/wlibrary.h" +#include "widget/wlibrarystack.h" #include "widget/wlibrarytextbrowser.h" #include "util/assert.h" @@ -28,7 +29,7 @@ BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, m_pTrackCollection(pTrackCollection), m_playlistDao(pTrackCollection->getPlaylistDAO()), m_trackDao(pTrackCollection->getTrackDAO()), - m_pPlaylistTableModel(NULL), + m_pPlaylistTableModel(nullptr), m_rootViewName(rootViewName) { m_pCreatePlaylistAction = new QAction(tr("Create New Playlist"),this); connect(m_pCreatePlaylistAction, SIGNAL(triggered()), @@ -131,8 +132,15 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { } void BasePlaylistFeature::activate() { - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + auto it = m_panes.find(m_featureFocus); + auto itId = m_idBrowse.find(m_featureFocus); + if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); + switchToFeature(); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(restoreSearch(QString())); // Null String disables search box emit(enableCoverArtDisplay(true)); @@ -144,8 +152,15 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { if (playlistId != -1 && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); - m_pLibrary->slotShowTrackModel(m_pPlaylistTableModel, this); - m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + auto it = m_panes.find(m_featureFocus); + auto itId = m_idTable.find(m_featureFocus); + if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); + showTrackModel(m_pPlaylistTableModel); + m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } @@ -156,7 +171,7 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { QModelIndex index = indexFromPlaylistId(playlistId); if (playlistId != -1 && index.isValid() && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); - emit(showTrackModel(m_pPlaylistTableModel)); + showTrackModel(m_pPlaylistTableModel); emit(enableCoverArtDisplay(true)); // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); @@ -599,14 +614,23 @@ TreeItemModel* BasePlaylistFeature::getChildModel() { } QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, - int) { - WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); + int paneId) { + WLibraryStack* pStack = new WLibraryStack(nullptr); + m_panes[paneId] = pStack; + + WLibraryTextBrowser* edit = new WLibraryTextBrowser(pStack); edit->setHtml(getRootViewHtml()); edit->setOpenLinks(false); edit->installEventFilter(pKeyboard); connect(edit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); - return edit; + m_idBrowse[paneId] = pStack->addWidget(edit); + + QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); + pTable->setParent(pStack); + m_idTable[paneId] = pStack->addWidget(pTable); + + return pStack; } QString BasePlaylistFeature::getFeatureName() { diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index bb6a4676146..e12b9ef5e45 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -16,11 +16,12 @@ #include "library/dao/trackdao.h" #include "track/track.h" -class WLibrary; class KeyboardEventFilter; class PlaylistTableModel; class TrackCollection; class TreeItem; +class WLibrary; +class WLibraryStack; class BasePlaylistFeature : public LibraryFeature { Q_OBJECT @@ -34,7 +35,7 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* getChildModel(); - QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); QString getFeatureName() override; signals: @@ -110,6 +111,10 @@ class BasePlaylistFeature : public LibraryFeature { QSet m_playlistsSelectedTrackIsIn; QString m_rootViewName; + + QHash > m_panes; + QHash m_idBrowse; + QHash m_idTable; }; #endif /* BASEPLAYLISTFEATURE_H */ diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 34ee4af7bef..c89927a6a49 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -19,6 +19,7 @@ #include "track/track.h" #include "util/sandbox.h" #include "widget/wlibrary.h" +#include "widget/wlibrarystack.h" #include "widget/wlibrarytextbrowser.h" @@ -216,16 +217,33 @@ TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } -QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { - WLibraryTextBrowser* edit = new WLibraryTextBrowser(nullptr); - edit->setHtml(getRootViewHtml()); - edit->installEventFilter(pKeyboard); - return edit; +QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + WLibraryStack* pStack = new WLibraryStack(nullptr); + m_panes[paneId] = pStack; + + WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(nullptr); + pEdit->setHtml(getRootViewHtml()); + pEdit->installEventFilter(pKeyboard); + m_idBrowse[paneId] = pStack->addWidget(pEdit); + + QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); + pTable->setParent(pStack); + m_idTable[paneId] = pStack->addWidget(pTable); + + return pStack; } void BrowseFeature::activate() { - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + auto it = m_panes.find(m_featureFocus); + auto itId = m_idBrowse.find(m_featureFocus); + if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); + switchToFeature(); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); emit(enableCoverArtDisplay(false)); @@ -257,8 +275,8 @@ void BrowseFeature::activateChild(const QModelIndex& index) { m_browseModel.setPath(dir); } - m_pLibrary->slotShowTrackModel(&m_proxyModel, this); - m_pLibrary->slotShowBreadCrumb(item); + showTrackModel(&m_proxyModel); + m_pLibrary->showBreadCrumb(item); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 7e33c6bc5d4..aa13c5132b9 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #define DEVICE_NODE "::mixxx_device_node::" class TrackCollection; +class WLibraryStack; class BrowseFeature : public LibraryFeature { Q_OBJECT @@ -38,7 +40,7 @@ class BrowseFeature : public LibraryFeature { QIcon getIcon(); QString getFeatureName() override; - QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int); + QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId); TreeItemModel* getChildModel(); @@ -76,6 +78,10 @@ class BrowseFeature : public LibraryFeature { TreeItem* m_pQuickLinkItem; QStringList m_quickLinkList; static const QString m_sBrowseViewName; + + QHash > m_panes; + QHash m_idBrowse; + QHash m_idTable; }; #endif // BROWSEFEATURE_H diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index d192b24e783..833c4c6e825 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -35,9 +35,7 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, : LibraryFeature(pConfig, pLibrary, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), - m_crateTableModel(this, pTrackCollection), - m_idBrowse(-1), - m_idTable(-1) { + m_crateTableModel(this, pTrackCollection) { m_pCreateCrateAction = new QAction(tr("Create New Crate"),this); connect(m_pCreateCrateAction, SIGNAL(triggered()), @@ -205,10 +203,10 @@ QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, connect(pEdit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); - m_idBrowse = pContainer->addWidget(pEdit); + m_idBrowse[paneId] = pContainer->addWidget(pEdit); QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); - m_idTable = pContainer->addWidget(pTable); + m_idTable[paneId] = pContainer->addWidget(pTable); return pContainer; } @@ -219,14 +217,15 @@ TreeItemModel* CrateFeature::getChildModel() { void CrateFeature::activate() { auto it = m_panes.find(m_featureFocus); - if (it == m_panes.end() || it->isNull()) { + auto itId = m_idBrowse.find(m_featureFocus); + if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { return; } - (*it)->setCurrentIndex(m_idBrowse); - asda hsdflkja hfdsa - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + (*it)->setCurrentIndex(*itId); + + m_pLibrary->switchToFeature(this); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home emit(enableCoverArtDisplay(true)); @@ -240,10 +239,18 @@ void CrateFeature::activateChild(const QModelIndex& index) { if (crateId == -1) { return; } + + auto it = m_panes.find(m_featureFocus); + auto itId = m_idTable.find(m_featureFocus); + if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); m_crateTableModel.setTableModel(crateId); - m_pLibrary->slotShowTrackModel(&m_crateTableModel, this); - m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + showTrackModel(&m_crateTableModel); + m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 16284601f98..aef70b16946 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -108,8 +108,8 @@ class CrateFeature : public LibraryFeature { TrackPointer m_pSelectedTrack; QSet m_cratesSelectedTrackIsIn; QHash > m_panes; - int m_idBrowse; - int m_idTable; + QHash m_idBrowse; + QHash m_idTable; const static QString m_sCrateViewName; }; diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 5393080e16d..314d3f45dc5 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -170,7 +170,7 @@ void HistoryFeature::slotGetNewPlaylist() { } slotPlaylistTableChanged(m_playlistId); // For moving selection - emit(showTrackModel(m_pPlaylistTableModel)); + showTrackModel(m_pPlaylistTableModel); } void HistoryFeature::slotJoinWithPrevious() { @@ -218,7 +218,7 @@ void HistoryFeature::slotJoinWithPrevious() { if (m_playlistDao.copyPlaylistTracks(currentPlaylistId, previousPlaylistId)) { m_playlistDao.deletePlaylist(currentPlaylistId); slotPlaylistTableChanged(previousPlaylistId); // For moving selection - emit(showTrackModel(m_pPlaylistTableModel)); + showTrackModel(m_pPlaylistTableModel); } } } diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 26cb0e40bd4..50b57d9d17a 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -152,8 +152,8 @@ void ITunesFeature::activate(bool forceReload) { NULL, tr("Select your iTunes library"), QDir::homePath(), "*.xml"); QFileInfo dbFile(m_dbfile); if (m_dbfile.isEmpty() || !dbFile.exists()) { - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotShowTrackModel(m_pITunesTrackModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(m_pITunesTrackModel); return; } @@ -183,8 +183,8 @@ void ITunesFeature::activate(bool forceReload) { emit (featureIsLoading(this, true)); } - m_pLibrary->slotShowTrackModel(m_pITunesTrackModel, this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(m_pITunesTrackModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); } @@ -194,8 +194,8 @@ void ITunesFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pITunesPlaylistModel->setPlaylist(playlist); - m_pLibrary->slotShowTrackModel(m_pITunesPlaylistModel, this); - m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + showTrackModel(m_pITunesPlaylistModel); + m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/library.cpp b/src/library/library.cpp index e1c951a27e4..2614bf21741 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -127,36 +127,12 @@ void Library::bindSidebarWidget(WButtonBar* sidebar) { } void Library::bindPaneWidget(WLibrary* pLibraryWidget, - KeyboardEventFilter* pKeyboard, int id) { - WTrackTableView* pTrackTableView = - new WTrackTableView(pLibraryWidget, m_pConfig, m_pTrackCollection); - pTrackTableView->installEventFilter(pKeyboard); - - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SLOT(slotLoadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); - - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - - connect(this, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(this, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - pLibraryWidget->registerView(m_sTrackViewName, pTrackTableView); + KeyboardEventFilter* pKeyboard, int paneId) { // Get the value once to avoid searching again in the hash - LibraryPaneManager* pPane = getPane(id); + LibraryPaneManager* pPane = getPane(paneId); pPane->bindPaneWidget(pLibraryWidget, pKeyboard); - connect(pPane, SIGNAL(showTrackModel(QAbstractItemModel*)), - pTrackTableView, SLOT(loadTrackModel(QAbstractItemModel*))); - connect(pPane, SIGNAL(searchStarting()), - pTrackTableView, SLOT(onSearchStarting())); - connect(pPane, SIGNAL(searchCleared()), - pTrackTableView, SLOT(onSearchCleared())); connect(pPane, SIGNAL(search(const QString&)), pLibraryWidget, SLOT(search(const QString&))); @@ -216,8 +192,6 @@ void Library::addFeature(LibraryFeature* feature) { // TODO(jmigual): this should be removed and add a direct interaction // between the LibraryFeature and the Library - connect(feature, SIGNAL(showTrackModel(QAbstractItemModel*)), - this, SLOT(slotShowTrackModel(QAbstractItemModel*))); connect(feature, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), @@ -230,19 +204,7 @@ void Library::addFeature(LibraryFeature* feature) { this, SIGNAL(trackSelected(TrackPointer))); } -void Library::slotShowTrackModel(QAbstractItemModel* model) { - //qDebug() << "Library::slotShowTrackModel" << m_focusedPane; - m_panes[m_focusedPane]->slotShowTrackModel(model); -} - -void Library::slotShowTrackModel(QAbstractItemModel *model, LibraryFeature *pFeature) { - m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); - - slotUpdateFocus(pFeature); - slotShowTrackModel(model); -} - -void Library::slotSwitchToFeature(LibraryFeature* pFeature) { +void Library::switchToFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); slotUpdateFocus(pFeature); @@ -255,7 +217,7 @@ void Library::slotSwitchToFeature(LibraryFeature* pFeature) { handleFocus(); } -void Library::slotShowBreadCrumb(TreeItem *pTree) { +void Library::showBreadCrumb(TreeItem *pTree) { m_panes[m_focusedPane]->slotShowBreadCrumb(pTree); } diff --git a/src/library/library.h b/src/library/library.h index 0c37180dd5a..2f10d1aeacf 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -46,6 +46,14 @@ class WSearchLineEdit; class Library : public QObject { Q_OBJECT public: + enum RemovalType { + LeaveTracksUnchanged = 0, + HideTracks, + PurgeTracks + }; + + static const int kDefaultRowHeightPx; + Library(QObject* parent, UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager, @@ -55,7 +63,7 @@ class Library : public QObject { void bindSearchBar(WSearchLineEdit* searchLine, int id); void bindSidebarWidget(WButtonBar* sidebar); void bindPaneWidget(WLibrary* libraryWidget, - KeyboardEventFilter* pKeyboard, int id); + KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard); void bindBreadCrumb(WLibraryBreadCrumb *pBreadCrumb, int paneId); @@ -84,30 +92,16 @@ class Library : public QObject { inline const QFont& getTrackTableFont() const { return m_trackTableFont; } - - enum RemovalType { - LeaveTracksUnchanged = 0, - HideTracks, - PurgeTracks - }; - - static const int kDefaultRowHeightPx; + + void switchToFeature(LibraryFeature* pFeature); + void showBreadCrumb(TreeItem* pTree); public slots: void slotActivateFeature(LibraryFeature* pFeature); void slotHoverFeature(LibraryFeature* pFeature); - // It uses the current focus, it needs to be updated before calling it - // avoid this function - void slotShowTrackModel(QAbstractItemModel* model); - - // Updates the focus from the feature before changing the view - void slotShowTrackModel(QAbstractItemModel *model, LibraryFeature* pFeature); - // Updates the focus from the feature before changing the view - void slotSwitchToFeature(LibraryFeature* pFeature); - void slotShowBreadCrumb(TreeItem* pTree); void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); void slotLoadLocationToPlayer(QString location, QString group); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index eda31b4d870..c0e211573d9 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -12,7 +12,7 @@ #include #include - +#include "library/library.h" #include "library/libraryfeature.h" #include "widget/wbaselibrary.h" #include "widget/wlibrarysidebar.h" @@ -23,10 +23,12 @@ // to work the code has to be precompiled by moc LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, + TrackCollection* pTrackCollection, QObject* parent) : QObject(parent), m_pConfig(pConfig), m_pLibrary(pLibrary), + m_pTrackCollection(pTrackCollection), m_featureFocus(-1) { } @@ -36,26 +38,7 @@ LibraryFeature::~LibraryFeature() { QWidget* LibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTable = - new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection); - - pTrackTable->installEventFilter(pKeyboard); - - connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), - this, SLOT(slotLoadTrack(TrackPointer))); - connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), - this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - m_tables.append(pTrackTable); - - return pTrackTable; + return createTableWidget(pKeyboard, paneId); } QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { @@ -93,12 +76,48 @@ void LibraryFeature::setFeatureFocus(int focus) { m_featureFocus = focus; } +WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + WTrackTableView* pTrackTableView = + new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection); + + pTrackTableView->installEventFilter(pKeyboard); + + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), + this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); + connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), + this, SIGNAL(trackSelected(TrackPointer))); + + connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), + pTrackTableView, SLOT(setTrackTableFont(QFont))); + connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), + pTrackTableView, SLOT(setTrackTableRowHeight(int))); + m_trackTables[paneId] = pTrackTableView; + + return pTrackTableView; +} + void LibraryFeature::showTrackModel(QAbstractItemModel *model) { - for (QPointer pTable : m_tables) { - if (!pTable.isNull()) { - pTable->loadTrackModel(model); - } + auto it = m_trackTables.find(m_featureFocus); + if (it == m_trackTables.end() || it->isNull()) { + return; + } + (*it)->loadTrackModel(model); + switchToFeature(); +} + +void LibraryFeature::switchToFeature() { + m_pLibrary->switchToFeature(this); +} + +WTrackTableView *LibraryFeature::getFocusedTable() { + auto it = m_trackTables.find(m_featureFocus); + if (it == m_trackTables.end() || it->isNull()) { + return nullptr; } + return *it; } QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 0a8d86f15ed..0ddb80d295a 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -5,7 +5,7 @@ #define LIBRARYFEATURE_H #include -#include +#include #include #include #include @@ -31,7 +31,7 @@ class LibraryFeature : public QObject { // The parent does not necessary be the Library LibraryFeature(UserSettingsPointer pConfig, - Library* pLibrary, + Library* pLibrary, TrackCollection *pTrackCollection, QObject* parent = nullptr); virtual ~LibraryFeature(); @@ -62,7 +62,8 @@ class LibraryFeature : public QObject { // Reimplement this to register custom views with the library widget // at the right pane. - virtual QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); + virtual QWidget *createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId); // Reimplement this to register custom views with the library widget, // at the sidebar expanded pane @@ -79,8 +80,13 @@ class LibraryFeature : public QObject { protected: inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, + int paneId); void showTrackModel(QAbstractItemModel *model); + void switchToFeature(); + + WTrackTableView* getFocusedTable(); UserSettingsPointer m_pConfig; Library* m_pLibrary; @@ -124,8 +130,7 @@ class LibraryFeature : public QObject { private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); - - QList > m_tables; + QHash > m_trackTables; }; #endif /* LIBRARYFEATURE_H */ diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index fca8b1957b0..09de0cc8d8a 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -51,17 +51,17 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, } } -void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchLine) { - pSearchLine->installEventFilter(this); +void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { + pSearchBar->installEventFilter(this); - connect(pSearchLine, SIGNAL(search(const QString&)), + connect(pSearchBar, SIGNAL(search(const QString&)), this, SIGNAL(search(const QString&))); - connect(pSearchLine, SIGNAL(searchCleared()), + connect(pSearchBar, SIGNAL(searchCleared()), this, SIGNAL(searchCleared())); - connect(pSearchLine, SIGNAL(searchStarting()), + connect(pSearchBar, SIGNAL(searchStarting()), this, SIGNAL(searchStarting())); - connect(this, SIGNAL(restoreSearch(const QString&)), - pSearchLine, SLOT(restoreSearch(const QString&))); + + m_pSearchBar = pSearchBar; } void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb *pBreadCrumb) { @@ -108,17 +108,6 @@ void LibraryPaneManager::clearFocus() { m_pPaneWidget->setProperty("showFocus", 0); } -void LibraryPaneManager::slotShowTrackModel(QAbstractItemModel* model) { - //qDebug() << "LibraryPaneManager::slotShowTrackModel" << model; - TrackModel* trackModel = dynamic_cast(model); - DEBUG_ASSERT_AND_HANDLE(trackModel && !m_pPaneWidget.isNull()) { - return; - } - emit(showTrackModel(model)); - m_pPaneWidget->switchToView(m_sTrackViewName); - emit(restoreSearch(trackModel->currentSearch())); -} - void LibraryPaneManager::slotSwitchToView(const QString& view) { //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { @@ -143,7 +132,9 @@ void LibraryPaneManager::slotSwitchToViewFeature(LibraryFeature* pFeature) { } void LibraryPaneManager::slotRestoreSearch(const QString& text) { - emit(restoreSearch(text)); + if (!m_pSearchBar.isNull()) { + m_pSearchBar->restoreSearch(text); + } } void LibraryPaneManager::slotShowBreadCrumb(TreeItem *pTree) { diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 8fd0a0de125..838bf8cfe7e 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -28,7 +28,7 @@ class LibraryPaneManager : public QObject { // All features must be added before adding a pane virtual void bindPaneWidget(WBaseLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard); - void bindSearchBar(WSearchLineEdit* pSearchLine); + void bindSearchBar(WSearchLineEdit* pSearchBar); void setBreadCrumb(WLibraryBreadCrumb* pBreadCrumb); void addFeature(LibraryFeature* feature); @@ -51,16 +51,12 @@ class LibraryPaneManager : public QObject { void focused(); - void showTrackModel(QAbstractItemModel* model); - - void restoreSearch(const QString&); void search(const QString& text); void searchCleared(); void searchStarting(); public slots: - void slotShowTrackModel(QAbstractItemModel* model); void slotSwitchToView(const QString& view); void slotSwitchToViewFeature(LibraryFeature* pFeature); void slotRestoreSearch(const QString& text); @@ -74,6 +70,7 @@ class LibraryPaneManager : public QObject { QList m_features; QHash m_featuresWidget; QPointer m_pBreadCrumb; + QPointer m_pSearchBar; private: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index ffd8a4ec8d1..46108e72989 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -36,8 +36,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, m_pMissingView(nullptr), m_hiddenExpandedId(-1), m_missingExpandedId(-1), - m_pHiddenTableModel(nullptr), - m_pMissingTableModel(nullptr), + m_pHiddenTableModel(new HiddenTableModel(this, pTrackCollection)), + m_pMissingTableModel(new MissingTableModel(this, pTrackCollection)), m_pExpandedStack(nullptr), m_trackDao(pTrackCollection->getTrackDAO()), m_pTrackCollection(pTrackCollection) { @@ -140,59 +140,20 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WLibraryStack* pStack = new WLibraryStack(nullptr); - m_paneStack[paneId] = pStack; + WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); - // Create the hidden table - WTrackTableView* pHiddenTable = - new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); - pHiddenTable->installEventFilter(pKeyboard); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), - pHiddenTable, SLOT(setTrackTableFont(QFont))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pHiddenTable, SLOT(setTrackTableRowHeight(int))); - - m_hiddenPaneId[paneId] = pStack->addWidget(pHiddenTable); - m_hiddenPane[paneId] = pHiddenTable; - - if (m_pHiddenTableModel.isNull()) { - m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); - } - pHiddenTable->loadTrackModel(m_pHiddenTableModel); + /*pHiddenTable->loadTrackModel(m_pHiddenTableModel); connect(pHiddenTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, - SLOT(hiddenSelectionChanged(const QItemSelection&, const QItemSelection&))); + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); */ - connect(this, SIGNAL(unhideHidden()), pHiddenTable, SLOT(slotUnhide())); - connect(this, SIGNAL(purgeHidden()), pHiddenTable, SLOT(slotPurge())); + connect(this, SIGNAL(unhideHidden()), pTable, SLOT(slotUnhide())); + connect(this, SIGNAL(purgeHidden()), pTable, SLOT(slotPurge())); + connect(this, SIGNAL(purgeMissing()), pTable, SLOT(slotPurge())); - // Create the missing table - WTrackTableView* pMissingTable = - new WTrackTableView(pStack, m_pConfig, m_pTrackCollection, false); - pMissingTable->installEventFilter(pKeyboard); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), - pMissingTable, SLOT(setTrackTableFont(QFont))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pMissingTable, SLOT(setTrackTableRowHeight(int))); - - m_missingPaneId[paneId] = pStack->addWidget(pMissingTable); - m_missingPane[paneId] = pMissingTable; - - if (m_pMissingTableModel.isNull()) { - m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); - } - pMissingTable->loadTrackModel(m_pMissingTableModel); - - connect(pMissingTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(missingSelectionChanged(const QItemSelection&, const QItemSelection&))); - - return pStack; + return pTable; } QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard) { @@ -217,28 +178,22 @@ QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard m_pExpandedStack = new QStackedWidget(pTab); // Create Hidden View controls - if (m_pHiddenTableModel.isNull()) { - m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); - } m_pHiddenView = new DlgHidden(pSidebar); m_pHiddenView->setTableModel(m_pHiddenTableModel); m_pHiddenView->installEventFilter(pKeyboard); connect(m_pHiddenView, SIGNAL(unhide()), this, SIGNAL(unhideHidden())); connect(m_pHiddenView, SIGNAL(purge()), this, SIGNAL(purgeHidden())); - + connect(m_pHiddenView, SIGNAL(selectAll()), this, SLOT(selectAll())); m_hiddenExpandedId = m_pExpandedStack->addWidget(m_pHiddenView); // Create Missing View controls - if (m_pMissingTableModel.isNull()) { - m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); - } m_pMissingView = new DlgMissing(pSidebar); m_pMissingView->setTableModel(m_pMissingTableModel); m_pMissingView->installEventFilter(pKeyboard); connect(m_pMissingView, SIGNAL(purge()), this, SIGNAL(purgeMissing())); - + connect(m_pMissingView, SIGNAL(selectAll()), this, SLOT(selectAll())); m_missingExpandedId = m_pExpandedStack->addWidget(m_pMissingView); pTab->addTab(m_pExpandedStack, tr("Controls")); @@ -273,56 +228,45 @@ void MixxxLibraryFeature::refreshLibraryModels() { } } -void MixxxLibraryFeature::hiddenSelectionChanged(const QItemSelection&, - const QItemSelection&) { - auto it = m_hiddenPane.find(m_featureFocus); - if (it == m_hiddenPane.end() || it->isNull()) { - return; - } - - DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull()) { +void MixxxLibraryFeature::selectionChanged(const QItemSelection&, + const QItemSelection&) { + WTrackTableView* pTable = getFocusedTable(); + if (pTable == nullptr) { return; } - const QModelIndexList& selection = (*it)->selectionModel()->selectedIndexes(); - m_pHiddenView->setSelectedIndexes(selection); -} - -void MixxxLibraryFeature::missingSelectionChanged(const QItemSelection&, - const QItemSelection&) { - auto it = m_missingPane.find(m_featureFocus); - if (it == m_missingPane.end() || it->isNull()) { + auto it = m_idPaneCurrent.find(m_featureFocus); + if (it == m_idPaneCurrent.end()) { return; } - DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull()) { - return; + const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + switch (*it) { + case Panes::Hidden: + m_pHiddenView->setSelectedIndexes(selection); + break; + case Panes::Missing: + m_pMissingView->setSelectedIndexes(selection); + break; + default: + break; } - - const QModelIndexList& selection = (*it)->selectionModel()->selectedIndexes(); - m_pMissingView->setSelectedIndexes(selection); } -void MixxxLibraryFeature::selectAllHidden() { - auto it = m_hiddenPane.find(m_featureFocus); - if (it != m_hiddenPane.end() && !it->isNull()) { - (*it)->selectAll(); +void MixxxLibraryFeature::selectAll() { + QPointer pTable = getFocusedTable(); + if (!pTable.isNull()) { + pTable->selectAll(); } } -void MixxxLibraryFeature::selectAllMissing() { - auto it = m_missingPane.find(m_featureFocus); - if (it != m_missingPane.end() && !it->isNull()) { - (*it)->selectAll(); - } -} void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; - // To change the sidebar - m_pLibrary->slotShowTrackModel(m_pLibraryTableModel, this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_idPaneCurrent[m_featureFocus] = Panes::MixxxLibrary; + showTrackModel(m_pLibraryTableModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(true)); } @@ -330,40 +274,57 @@ void MixxxLibraryFeature::activate() { void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); TreeItem* pTree = static_cast (index.internalPointer()); + QPointer pTable = getFocusedTable(); if (itemName == m_sMixxxLibraryViewName) { activate(); - } else if (itemName == kHiddenTitle) { - auto it = m_paneStack.find(m_featureFocus); + } else if (itemName == kHiddenTitle) { DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull() && - !m_pExpandedStack.isNull() && - it != m_paneStack.end() && - !it->isNull()) { + !m_pExpandedStack.isNull() && + !pTable.isNull()) { return; } + m_idPaneCurrent[m_featureFocus] = Panes::Hidden; + pTable->loadTrackModel(m_pHiddenTableModel); + + // This is the only way to get the selection signal changing the track + // models, every time the model changes the selection model changes too + // so we need to reconnect + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + m_pHiddenView->onShow(); - (*it)->setCurrentIndex(m_hiddenPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(pTree); + switchToFeature(); + m_pLibrary->showBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } else if (itemName == kMissingTitle) { - auto it = m_paneStack.find(m_featureFocus); DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull() && !m_pExpandedStack.isNull() && - it != m_paneStack.end() && - !it->isNull()) { + !pTable.isNull()) { return; } + m_idPaneCurrent[m_featureFocus] = Panes::Missing; + pTable->loadTrackModel(m_pMissingTableModel); + + // This is the only way to get the selection signal changing the track + // models, every time the model changes the selection model changes too + // so we need to reconnect + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + m_pMissingView->onShow(); - m_paneStack[m_featureFocus]->setCurrentIndex(m_missingPaneId[m_featureFocus]); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(pTree); + switchToFeature(); + m_pLibrary->showBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 98a177f138b..19576ff04e4 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -55,11 +55,9 @@ class MixxxLibraryFeature : public LibraryFeature { void activateChild(const QModelIndex& index); void refreshLibraryModels(); - void hiddenSelectionChanged(const QItemSelection&, const QItemSelection&); - void missingSelectionChanged(const QItemSelection&, const QItemSelection&); + void selectionChanged(const QItemSelection&, const QItemSelection&); - void selectAllHidden(); - void selectAllMissing(); + void selectAll(); signals: @@ -68,27 +66,26 @@ class MixxxLibraryFeature : public LibraryFeature { void purgeMissing(); private: + enum Panes { + MixxxLibrary = 1, + Hidden = 2, + Missing = 3 + }; + const QString kLibraryTitle; const QString kHiddenTitle; const QString kMissingTitle; QPointer m_pHiddenView; QPointer m_pMissingView; - QHash > m_hiddenPane; - QHash > m_missingPane; - - // This is needed to select the correct widget in the 2 size widget stack - // for the hidden and missing widgets. - QHash m_hiddenPaneId; - QHash m_missingPaneId; + QHash m_idPaneCurrent; // SidebarExpanded pane's ids int m_hiddenExpandedId; int m_missingExpandedId; - QPointer m_pHiddenTableModel; - QPointer m_pMissingTableModel; + HiddenTableModel* m_pHiddenTableModel; + MissingTableModel* m_pMissingTableModel; - QHash > m_paneStack; QPointer m_pExpandedStack; QSharedPointer m_pBaseTrackCache; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 10bfcf0f6dc..88e7b41a018 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -83,8 +83,8 @@ void RecordingFeature::activate() { } m_pRecordingView->refreshBrowseModel(); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + m_pLibrary->switchToFeature(this); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->slotRestoreSearch(""); emit(enableCoverArtDisplay(false)); diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index efd6bb98036..a5f21464d2c 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,8 +138,8 @@ void RhythmboxFeature::activate() { emit (featureIsLoading(this, true)); } - m_pLibrary->slotShowTrackModel(m_pRhythmboxTrackModel, this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(m_pRhythmboxTrackModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); } @@ -149,8 +149,8 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { qDebug() << "Activating " << playlist; m_pRhythmboxPlaylistModel->setPlaylist(playlist); - m_pLibrary->slotShowTrackModel(m_pRhythmboxPlaylistModel, this); - m_pLibrary->slotShowBreadCrumb(static_cast(index.internalPointer())); + showTrackModel(m_pRhythmboxPlaylistModel); + m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 4fdfc71c2d2..96e6dcdbf43 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -166,8 +166,8 @@ void TraktorFeature::activate() { emit (featureIsLoading(this, true)); } - m_pLibrary->slotShowTrackModel(m_pTraktorTableModel, this); - m_pLibrary->slotShowBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(m_pTraktorTableModel); + m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(false)); } @@ -182,9 +182,8 @@ void TraktorFeature::activateChild(const QModelIndex& index) { qDebug() << "Activate Traktor Playlist: " << item->dataPath().toString(); m_pTraktorPlaylistModel->setPlaylist(item->dataPath().toString()); - m_pLibrary->slotSwitchToFeature(this); - m_pLibrary->slotShowBreadCrumb(item); - m_pLibrary->slotShowTrackModel(m_pTraktorPlaylistModel); + showTrackModel(m_pTraktorPlaylistModel); + m_pLibrary->showBreadCrumb(item); emit(enableCoverArtDisplay(false)); } } @@ -622,8 +621,8 @@ void TraktorFeature::onTrackCollectionLoaded() { m_trackSource->buildIndex(); //m_pTraktorTableModel->select(); - m_pLibrary->slotShowBreadCrumb(root); - m_pLibrary->slotShowTrackModel(m_pTraktorTableModel); + showTrackModel(m_pTraktorTableModel); + m_pLibrary->showBreadCrumb(root); qDebug() << "Traktor library loaded successfully"; } else { QMessageBox::warning( From 3f3fcc3adb9eb12fe0cef0bf04c962758441a56d Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 16:39:13 +0200 Subject: [PATCH 234/552] Fixed not building --- src/library/analysisfeature.cpp | 8 +++----- src/library/analysisfeature.h | 5 ++--- src/library/autodj/autodjfeature.cpp | 2 +- src/library/baseexternallibraryfeature.cpp | 3 +-- src/library/baseexternallibraryfeature.h | 1 - src/library/baseplaylistfeature.cpp | 3 +-- src/library/baseplaylistfeature.h | 1 - src/library/browse/browsefeature.cpp | 2 +- src/library/cratefeature.cpp | 2 +- src/library/library.cpp | 2 +- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/recording/recordingfeature.cpp | 2 +- 12 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index d4802d518cc..9cccce02f30 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -20,12 +20,10 @@ const QString AnalysisFeature::m_sAnalysisViewName = "AnalysisView"; -AnalysisFeature::AnalysisFeature(TrackCollection* pTrackCollection, - UserSettingsPointer pConfig, - Library* pLibrary, +AnalysisFeature::AnalysisFeature(UserSettingsPointer pConfig, + Library* pLibrary, TrackCollection* pTrackCollection, QObject* parent) : - LibraryFeature(pConfig, pLibrary, parent), - m_pTrackCollection(pTrackCollection), + LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_pAnalyzerQueue(nullptr), m_iOldBpmEnabled(0), m_analysisTitleName(tr("Analyze")), diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 6d8e04f7dc4..092cf353b40 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -23,9 +23,9 @@ class TrackCollection; class AnalysisFeature : public LibraryFeature { Q_OBJECT public: - AnalysisFeature(TrackCollection* pTrackCollection, - UserSettingsPointer pConfig, + AnalysisFeature(UserSettingsPointer pConfig, Library* pLibrary, + TrackCollection* pTrackCollection, QObject* parent); virtual ~AnalysisFeature(); @@ -70,7 +70,6 @@ class AnalysisFeature : public LibraryFeature { AnalysisLibraryTableModel* getAnalysisTableModel(); - TrackCollection* m_pTrackCollection; AnalyzerQueue* m_pAnalyzerQueue; // Used to temporarily enable BPM detection in the prefs before we analyse int m_iOldBpmEnabled; diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 074fafe592e..248c5444578 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -31,7 +31,7 @@ AutoDJFeature::AutoDJFeature(UserSettingsPointer pConfig, QObject* parent, PlayerManagerInterface* pPlayerManager, TrackCollection* pTrackCollection) - : LibraryFeature(pConfig, pLibrary, parent), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_playlistDao(pTrackCollection->getPlaylistDAO()), diff --git a/src/library/baseexternallibraryfeature.cpp b/src/library/baseexternallibraryfeature.cpp index f1f262389ed..450a9277689 100644 --- a/src/library/baseexternallibraryfeature.cpp +++ b/src/library/baseexternallibraryfeature.cpp @@ -8,8 +8,7 @@ BaseExternalLibraryFeature::BaseExternalLibraryFeature(UserSettingsPointer pConf Library* pLibrary, QObject* pParent, TrackCollection* pCollection) - : LibraryFeature(pConfig, pLibrary, pParent), - m_pTrackCollection(pCollection) { + : LibraryFeature(pConfig, pLibrary, pCollection, pParent) { m_pAddToAutoDJAction = new QAction(tr("Add to Auto DJ Queue (bottom)"), this); connect(m_pAddToAutoDJAction, SIGNAL(triggered()), this, SLOT(slotAddToAutoDJ())); diff --git a/src/library/baseexternallibraryfeature.h b/src/library/baseexternallibraryfeature.h index 5ebfc50037b..43ce15bbbbb 100644 --- a/src/library/baseexternallibraryfeature.h +++ b/src/library/baseexternallibraryfeature.h @@ -41,7 +41,6 @@ class BaseExternalLibraryFeature : public LibraryFeature { private: void addToAutoDJ(bool bTop); - TrackCollection* m_pTrackCollection; QAction* m_pAddToAutoDJAction; QAction* m_pAddToAutoDJTopAction; QAction* m_pImportAsMixxxPlaylistAction; diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 2318ec584a8..f9766c5619b 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -25,8 +25,7 @@ BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, QObject* parent, TrackCollection* pTrackCollection, QString rootViewName) - : LibraryFeature(pConfig, pLibrary, parent), - m_pTrackCollection(pTrackCollection), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_playlistDao(pTrackCollection->getPlaylistDAO()), m_trackDao(pTrackCollection->getTrackDAO()), m_pPlaylistTableModel(nullptr), diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index e12b9ef5e45..1b7ea78068c 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -81,7 +81,6 @@ class BasePlaylistFeature : public LibraryFeature { // on failure. QModelIndex indexFromPlaylistId(int playlistId); - TrackCollection* m_pTrackCollection; PlaylistDAO &m_playlistDao; TrackDAO &m_trackDao; PlaylistTableModel* m_pPlaylistTableModel; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index c89927a6a49..ebe67535451 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -32,7 +32,7 @@ BrowseFeature::BrowseFeature(UserSettingsPointer pConfig, QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) - : LibraryFeature(pConfig, pLibrary, parent), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_browseModel(this, pTrackCollection, pRecordingManager), m_proxyModel(&m_browseModel), m_pTrackCollection(pTrackCollection), diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 833c4c6e825..c2394e49eb5 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -32,7 +32,7 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) - : LibraryFeature(pConfig, pLibrary, parent), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), m_crateTableModel(this, pTrackCollection) { diff --git a/src/library/library.cpp b/src/library/library.cpp index 2614bf21741..74d552bbe28 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -501,7 +501,7 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(browseFeature); addFeature(new RecordingFeature(pConfig, this, this, m_pTrackCollection, m_pRecordingManager)); addFeature(new HistoryFeature(pConfig, this, this, m_pTrackCollection)); - m_pAnalysisFeature = new AnalysisFeature(m_pTrackCollection, pConfig, this, this);//this, pConfig, m_pTrackCollection); + m_pAnalysisFeature = new AnalysisFeature(pConfig, this, m_pTrackCollection, this); connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), m_pAnalysisFeature, SLOT(analyzeTracks(QList))); connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 46108e72989..46792e89fe7 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -28,7 +28,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) - : LibraryFeature(pConfig, pLibrary, parent), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), kLibraryTitle(tr("Library")), kHiddenTitle(tr("Hidden Tracks")), kMissingTitle(tr("Missing Tracks")), diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 88e7b41a018..583cb27e12d 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -17,7 +17,7 @@ RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, QObject* parent, TrackCollection* pTrackCollection, RecordingManager* pRecordingManager) - : LibraryFeature(pConfig, pLibrary, parent), + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_pTrackCollection(pTrackCollection), m_pRecordingManager(pRecordingManager), m_pRecordingView(nullptr), From 4ca315a35964d585c959f4d57a80a7e378e71c38 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 2 Jul 2016 22:05:54 +0200 Subject: [PATCH 235/552] Fixed missing and hidden tables not loading --- src/library/mixxxlibraryfeature.cpp | 42 ++++++++++++++++++++--------- src/library/mixxxlibraryfeature.h | 7 +++-- src/widget/wtracktableview.cpp | 5 ++++ src/widget/wtracktableview.h | 1 + 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 46792e89fe7..a14f3eb0684 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -36,8 +36,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, m_pMissingView(nullptr), m_hiddenExpandedId(-1), m_missingExpandedId(-1), - m_pHiddenTableModel(new HiddenTableModel(this, pTrackCollection)), - m_pMissingTableModel(new MissingTableModel(this, pTrackCollection)), + m_pHiddenTableModel(nullptr), + m_pMissingTableModel(nullptr), m_pExpandedStack(nullptr), m_trackDao(pTrackCollection->getTrackDAO()), m_pTrackCollection(pTrackCollection) { @@ -142,13 +142,6 @@ QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); - /*pHiddenTable->loadTrackModel(m_pHiddenTableModel); - - connect(pHiddenTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); */ - connect(this, SIGNAL(unhideHidden()), pTable, SLOT(slotUnhide())); connect(this, SIGNAL(purgeHidden()), pTable, SLOT(slotPurge())); connect(this, SIGNAL(purgeMissing()), pTable, SLOT(slotPurge())); @@ -179,7 +172,7 @@ QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard // Create Hidden View controls m_pHiddenView = new DlgHidden(pSidebar); - m_pHiddenView->setTableModel(m_pHiddenTableModel); + m_pHiddenView->setTableModel(getHiddenTableModel()); m_pHiddenView->installEventFilter(pKeyboard); connect(m_pHiddenView, SIGNAL(unhide()), this, SIGNAL(unhideHidden())); @@ -189,7 +182,7 @@ QWidget *MixxxLibraryFeature::createSidebarWidget(KeyboardEventFilter *pKeyboard // Create Missing View controls m_pMissingView = new DlgMissing(pSidebar); - m_pMissingView->setTableModel(m_pMissingTableModel); + m_pMissingView->setTableModel(getMissingTableModel()); m_pMissingView->installEventFilter(pKeyboard); connect(m_pMissingView, SIGNAL(purge()), this, SIGNAL(purgeMissing())); @@ -265,7 +258,14 @@ void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; m_idPaneCurrent[m_featureFocus] = Panes::MixxxLibrary; + QPointer pTable = getFocusedTable(); + if (pTable.isNull()) { + return; + } + + pTable->setSortingEnabled(true); showTrackModel(m_pLibraryTableModel); + m_pLibraryTableModel->select(); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(true)); @@ -287,7 +287,8 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { } m_idPaneCurrent[m_featureFocus] = Panes::Hidden; - pTable->loadTrackModel(m_pHiddenTableModel); + pTable->setSortingEnabled(false); + pTable->loadTrackModel(getHiddenTableModel()); // This is the only way to get the selection signal changing the track // models, every time the model changes the selection model changes too @@ -311,7 +312,8 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { } m_idPaneCurrent[m_featureFocus] = Panes::Missing; - pTable->loadTrackModel(m_pMissingTableModel); + pTable->setSortingEnabled(false); + pTable->loadTrackModel(getMissingTableModel()); // This is the only way to get the selection signal changing the track // models, every time the model changes the selection model changes too @@ -345,3 +347,17 @@ bool MixxxLibraryFeature::dragMoveAccept(QUrl url) { return SoundSourceProxy::isUrlSupported(url) || Parser::isPlaylistFilenameSupported(url.toLocalFile()); } + +HiddenTableModel* MixxxLibraryFeature::getHiddenTableModel() { + if (m_pHiddenTableModel.isNull()) { + m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); + } + return m_pHiddenTableModel; +} + +MissingTableModel* MixxxLibraryFeature::getMissingTableModel() { + if (m_pMissingTableModel.isNull()) { + m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); + } + return m_pMissingTableModel; +} diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 19576ff04e4..24f63d111a2 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -72,6 +72,9 @@ class MixxxLibraryFeature : public LibraryFeature { Missing = 3 }; + HiddenTableModel* getHiddenTableModel(); + MissingTableModel* getMissingTableModel(); + const QString kLibraryTitle; const QString kHiddenTitle; const QString kMissingTitle; @@ -83,8 +86,8 @@ class MixxxLibraryFeature : public LibraryFeature { int m_hiddenExpandedId; int m_missingExpandedId; - HiddenTableModel* m_pHiddenTableModel; - MissingTableModel* m_pMissingTableModel; + QPointer m_pHiddenTableModel; + QPointer m_pMissingTableModel; QPointer m_pExpandedStack; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index efb6ae86fcd..8a6eea19917 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1283,6 +1283,11 @@ void WTrackTableView::loadSelectedTrackToGroup(QString group, bool play) { loadSelectionToGroup(group, play); } +void WTrackTableView::setSortingEnabled(bool sorting) { + m_sorting = sorting; + WLibraryTableView::setSortingEnabled(sorting); +} + void WTrackTableView::slotSendToAutoDJ() { // append to auto DJ sendToAutoDJ(false); // bTop = false diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 9bff23196f5..d503a9b37ca 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -35,6 +35,7 @@ class WTrackTableView : public WLibraryTableView { void keyPressEvent(QKeyEvent* event) override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(QString group, bool play) override; + void setSortingEnabled(bool sorting); public slots: void loadTrackModel(QAbstractItemModel* model); From 208f3597f3fe8a32a9653523d0fa3ce36ca3cab1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 3 Jul 2016 00:35:16 +0200 Subject: [PATCH 236/552] Rename slots to not being slots anymore and fix some bugs WTrackTable was not showing anything when loading a track model, now it shows the track model by default --- src/library/analysisfeature.cpp | 2 +- src/library/autodj/autodjfeature.cpp | 2 +- src/library/baseplaylistfeature.cpp | 4 +++- src/library/browse/browsefeature.cpp | 2 +- src/library/cratefeature.cpp | 3 ++- src/library/library.cpp | 6 ++---- src/library/library.h | 2 +- src/library/libraryfeature.h | 1 - src/library/librarypanemanager.cpp | 4 +--- src/library/librarypanemanager.h | 4 ++-- src/library/mixxxlibraryfeature.cpp | 4 +++- src/library/recording/recordingfeature.cpp | 2 +- src/util/dnd.h | 1 + src/widget/wfeatureclickbutton.cpp | 1 + src/widget/wtracktableview.cpp | 1 + 15 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 9cccce02f30..e5e55909b89 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -131,7 +131,7 @@ void AnalysisFeature::activate() { m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); if (!m_pAnalysisView.isNull()) { - m_pLibrary->slotRestoreSearch(m_pAnalysisView->currentSearch()); + m_pLibrary->restoreSearch(m_pAnalysisView->currentSearch()); } emit(enableCoverArtDisplay(true)); } diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 248c5444578..b547e2cde06 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -167,7 +167,7 @@ void AutoDJFeature::activate() { m_pLibrary->switchToFeature(this); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotRestoreSearch(QString()); //Null String disables search box + m_pLibrary->restoreSearch(QString()); //Null String disables search box emit(enableCoverArtDisplay(true)); } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index f9766c5619b..51aa400f931 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -141,7 +141,7 @@ void BasePlaylistFeature::activate() { switchToFeature(); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - emit(restoreSearch(QString())); // Null String disables search box + m_pLibrary->restoreSearch(QString()); // Null String disables search box emit(enableCoverArtDisplay(true)); } @@ -159,6 +159,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { (*it)->setCurrentIndex(*itId); showTrackModel(m_pPlaylistTableModel); + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); @@ -171,6 +172,7 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { if (playlistId != -1 && index.isValid() && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); showTrackModel(m_pPlaylistTableModel); + //m_pPlaylistTableModel->select(); emit(enableCoverArtDisplay(true)); // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index ebe67535451..a7fc03b0d39 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -244,7 +244,7 @@ void BrowseFeature::activate() { (*it)->setCurrentIndex(*itId); switchToFeature(); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotRestoreSearch(QString()); + m_pLibrary->restoreSearch(QString()); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index c2394e49eb5..6ecd021df54 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -226,7 +226,7 @@ void CrateFeature::activate() { m_pLibrary->switchToFeature(this); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotRestoreSearch(QString()); //disable search on crate home + m_pLibrary->restoreSearch(QString()); //disable search on crate home emit(enableCoverArtDisplay(true)); } @@ -250,6 +250,7 @@ void CrateFeature::activateChild(const QModelIndex& index) { m_crateTableModel.setTableModel(crateId); showTrackModel(&m_crateTableModel); + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/library.cpp b/src/library/library.cpp index 74d552bbe28..4f72a69cf0f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -196,8 +196,6 @@ void Library::addFeature(LibraryFeature* feature) { this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); - connect(feature, SIGNAL(restoreSearch(const QString&)), - this, SLOT(slotRestoreSearch(const QString&))); connect(feature, SIGNAL(enableCoverArtDisplay(bool)), this, SIGNAL(enableCoverArtDisplay(bool))); connect(feature, SIGNAL(trackSelected(TrackPointer)), @@ -237,12 +235,12 @@ void Library::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool pla emit(loadTrackToPlayer(pTrack, group, play)); } -void Library::slotRestoreSearch(const QString& text) { +void Library::restoreSearch(const QString& text) { LibraryPaneManager* pane = getFocusedPane(); DEBUG_ASSERT_AND_HANDLE(pane) { return; } - pane->slotRestoreSearch(text); + pane->restoreSearch(text); } void Library::slotRefreshLibraryModels() { diff --git a/src/library/library.h b/src/library/library.h index 2f10d1aeacf..099d2601311 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -95,6 +95,7 @@ class Library : public QObject { void switchToFeature(LibraryFeature* pFeature); void showBreadCrumb(TreeItem* pTree); + void restoreSearch(const QString& text); public slots: @@ -105,7 +106,6 @@ class Library : public QObject { void slotLoadTrack(TrackPointer pTrack); void slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool play); void slotLoadLocationToPlayer(QString location, QString group); - void slotRestoreSearch(const QString& text); void slotRefreshLibraryModels(); void slotCreatePlaylist(); void slotCreateCrate(); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 0ddb80d295a..e0caea2c885 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -116,7 +116,6 @@ class LibraryFeature : public QObject { void loadTrack(TrackPointer); void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); - void restoreSearch(const QString&); // emit this signal before you parse a large music collection, e.g., iTunes, Traktor. // The second arg indicates if the feature should be "selected" when loading starts void featureIsLoading(LibraryFeature*, bool selectFeature); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 09de0cc8d8a..7b97746ffdf 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -72,8 +72,6 @@ void LibraryPaneManager::addFeature(LibraryFeature* feature) { DEBUG_ASSERT_AND_HANDLE(feature) { return; } - connect(feature, SIGNAL(restoreSearch(const QString&)), - this, SIGNAL(restoreSearch(const QString&))); m_features.append(feature); } @@ -131,7 +129,7 @@ void LibraryPaneManager::slotSwitchToViewFeature(LibraryFeature* pFeature) { m_pPaneWidget->setCurrentIndex(widgetId); } -void LibraryPaneManager::slotRestoreSearch(const QString& text) { +void LibraryPaneManager::restoreSearch(const QString& text) { if (!m_pSearchBar.isNull()) { m_pSearchBar->restoreSearch(text); } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 838bf8cfe7e..ab6e4e72e3e 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -40,9 +40,10 @@ class LibraryPaneManager : public QObject { LibraryFeature* getFocusedFeature() const; void setFocus(); - void clearFocus(); + void restoreSearch(const QString& text); + inline int getPaneId() { return m_paneId; } @@ -59,7 +60,6 @@ class LibraryPaneManager : public QObject { void slotSwitchToView(const QString& view); void slotSwitchToViewFeature(LibraryFeature* pFeature); - void slotRestoreSearch(const QString& text); void slotShowBreadCrumb(TreeItem* pTree); void slotPaneCollapsed(); void slotPaneUncollapsed(); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index a14f3eb0684..ea6ec336490 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -265,7 +265,7 @@ void MixxxLibraryFeature::activate() { pTable->setSortingEnabled(true); showTrackModel(m_pLibraryTableModel); - m_pLibraryTableModel->select(); + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(true)); @@ -301,6 +301,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pHiddenView->onShow(); m_pExpandedStack->setCurrentIndex(m_hiddenExpandedId); switchToFeature(); + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); @@ -326,6 +327,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pMissingView->onShow(); m_pExpandedStack->setCurrentIndex(m_missingExpandedId); switchToFeature(); + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(pTree); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 583cb27e12d..ce65f83466b 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -85,7 +85,7 @@ void RecordingFeature::activate() { m_pRecordingView->refreshBrowseModel(); m_pLibrary->switchToFeature(this); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->slotRestoreSearch(""); + m_pLibrary->restoreSearch(""); emit(enableCoverArtDisplay(false)); } diff --git a/src/util/dnd.h b/src/util/dnd.h index 542b0ecdf6d..8cab28e375c 100644 --- a/src/util/dnd.h +++ b/src/util/dnd.h @@ -26,6 +26,7 @@ class DragAndDropHelper { bool firstOnly, bool acceptPlaylists) { QList fileLocations; + qDebug() << urls; foreach (const QUrl& url, urls) { // XXX: Possible WTF alert - Previously we thought we needed diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index fd32a9491ac..8b94eff7f14 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -41,6 +41,7 @@ void WFeatureClickButton::dragLeaveEvent(QDragLeaveEvent*) { } void WFeatureClickButton::dropEvent(QDropEvent* event) { + m_hoverTimer.stop(); event->acceptProposedAction(); if (!event->mimeData()->hasUrls() || event->source() == this) { event->ignore(); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 8a6eea19917..440bc332115 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -355,6 +355,7 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) { // target though, so my hax above may not be completely unjustified. setVisible(true); + trackModel->select(); } void WTrackTableView::createActions() { From b3f3ff823a10c44dd85ef6669c13e7ad98634f37 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 3 Jul 2016 00:39:05 +0200 Subject: [PATCH 237/552] Fix AutoDJ sidebar --- src/library/autodj/autodjfeature.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index b547e2cde06..b89297e114c 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -131,18 +131,19 @@ QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int pan QWidget* AutoDJFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { QTabWidget* pContainer = new QTabWidget(nullptr); - // Add drop target - WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); - pSidebar->setModel(&m_childModel); - pSidebar->installEventFilter(pKeyboard); - pContainer->addTab(pSidebar, tr("Track source")); - + // Add controls m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); m_pAutoDJView->installEventFilter(pKeyboard); QScrollArea* pScroll = new QScrollArea(pContainer); pScroll->setWidget(m_pAutoDJView); pScroll->setWidgetResizable(true); - pContainer->addTab(pScroll, tr("controls")); + pContainer->addTab(pScroll, tr("Controls")); + + // Add drop target + WLibrarySidebar* pSidebar = new WLibrarySidebar(pContainer); + pSidebar->setModel(&m_childModel); + pSidebar->installEventFilter(pKeyboard); + pContainer->addTab(pSidebar, tr("Track source")); // Be informed when the user wants to add another random track. connect(m_pAutoDJProcessor,SIGNAL(randomTrackRequested(int)), From c01cb0dacd2925f767025d27775f4c6629c1d281 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 3 Jul 2016 01:02:05 +0200 Subject: [PATCH 238/552] Add LibraryFeature pointer in WBaseLibrary instead of QString --- src/library/library.cpp | 20 ++++------- src/library/library.h | 11 +++--- src/library/librarypanemanager.cpp | 26 +++----------- src/library/librarypanemanager.h | 8 ++--- src/library/librarysidebarexpandedmanager.cpp | 3 +- src/widget/wbaselibrary.cpp | 34 +++++++------------ src/widget/wbaselibrary.h | 14 ++++---- src/widget/wlibrary.cpp | 23 ++++++------- src/widget/wlibrary.h | 4 +-- 9 files changed, 50 insertions(+), 93 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 4f72a69cf0f..244a9cc32ef 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -37,10 +37,6 @@ #include "controllers/keyboard/keyboardeventfilter.h" -// This is is the name which we use to register the WTrackTableView with the -// WLibrary -const QString Library::m_sTrackViewName = QString("WTrackTableView"); - // The default row height of the library. const int Library::kDefaultRowHeightPx = 20; @@ -186,7 +182,6 @@ void Library::addFeature(LibraryFeature* feature) { return; } m_features.append(feature); - m_featuresMap.insert(feature->getFeatureName(), feature); m_pSidebarModel->addLibraryFeature(feature); @@ -203,20 +198,20 @@ void Library::addFeature(LibraryFeature* feature) { } void Library::switchToFeature(LibraryFeature* pFeature) { - m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + m_pSidebarExpanded->switchToFeature(pFeature); slotUpdateFocus(pFeature); WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); // Only change the current pane if it's not shown already - if (pWLibrary->getCurrentViewName() != pFeature->getFeatureName()) { - m_panes[m_focusedPane]->slotSwitchToViewFeature(pFeature); + if (pWLibrary->getCurrentFeature() != pFeature) { + m_panes[m_focusedPane]->switchToFeature(pFeature); } handleFocus(); } void Library::showBreadCrumb(TreeItem *pTree) { - m_panes[m_focusedPane]->slotShowBreadCrumb(pTree); + m_panes[m_focusedPane]->showBreadCrumb(pTree); } void Library::slotLoadTrack(TrackPointer pTrack) { @@ -267,7 +262,6 @@ void Library::onSkinLoadFinished() { // Assign a feature to show on each pane unless there are more panes // than features while (itP != m_panes.end() && itF != m_features.end()) { - //qDebug() << (*itF)->getViewName() << itP.key(); m_focusedPane = itP.key(); (*itF)->setFeatureFocus(itP.key()); @@ -383,7 +377,7 @@ void Library::paneUncollapsed(int paneId) { void Library::slotActivateFeature(LibraryFeature *pFeature) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getFocusedFeature() == pFeature) { - m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + m_pSidebarExpanded->switchToFeature(pFeature); return; } int featureFocus = pFeature->getFeatureFocus(); @@ -399,7 +393,7 @@ void Library::slotActivateFeature(LibraryFeature *pFeature) { } else { // The feature is shown in some not collapsed pane m_focusedPane = featureFocus; - m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + m_pSidebarExpanded->switchToFeature(pFeature); handleFocus(); return; } @@ -413,7 +407,7 @@ void Library::slotActivateFeature(LibraryFeature *pFeature) { void Library::slotHoverFeature(LibraryFeature *pFeature) { // This function only changes the sidebar expanded to allow dropping items // directly in some features sidebar panes - m_pSidebarExpanded->slotSwitchToViewFeature(pFeature); + m_pSidebarExpanded->switchToFeature(pFeature); } void Library::slotSetTrackTableFont(const QFont& font) { diff --git a/src/library/library.h b/src/library/library.h index 099d2601311..bdeea24346c 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -145,11 +145,13 @@ class Library : public QObject { LibraryPaneManager *getPane(int paneId); LibraryPaneManager* getFocusedPane(); + void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); + + void handleFocus(); + UserSettingsPointer m_pConfig; SidebarModel* m_pSidebarModel; TrackCollection* m_pTrackCollection; - const static QString m_sTrackViewName; - const static QString m_sAutoDJViewName; MixxxLibraryFeature* m_pMixxxLibraryFeature; PlaylistFeature* m_pPlaylistFeature; CrateFeature* m_pCrateFeature; @@ -163,15 +165,10 @@ class Library : public QObject { QHash m_panes; LibraryPaneManager* m_pSidebarExpanded; QList m_features; - QHash m_featuresMap; QSet m_collapsedPanes; // Can be any integer as it's used with a HashMap int m_focusedPane; - - void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); - - void handleFocus(); }; #endif /* LIBRARY_H */ diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 7b97746ffdf..d0c168f9abf 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -8,8 +8,6 @@ #include "widget/wlibrarybreadcrumb.h" #include "widget/wtracktableview.h" -const QString LibraryPaneManager::m_sTrackViewName = QString("WTrackTableView"); - LibraryPaneManager::LibraryPaneManager(int paneId, Library *pLibrary, QObject* parent) : QObject(parent), m_pPaneWidget(nullptr), @@ -46,8 +44,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, continue; } pPane->setParent(lib); - lib->registerView(f->getFeatureName(), pPane); - m_featuresWidget[f] = lib->indexOf(pPane); + lib->registerView(f, pPane); } } @@ -106,27 +103,12 @@ void LibraryPaneManager::clearFocus() { m_pPaneWidget->setProperty("showFocus", 0); } -void LibraryPaneManager::slotSwitchToView(const QString& view) { - //qDebug() << "LibraryPaneManager::slotSwitchToView" << view; - DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { - return; - } - - m_pPaneWidget->switchToView(view); - m_pPaneWidget->setFocus(); -} - -void LibraryPaneManager::slotSwitchToViewFeature(LibraryFeature* pFeature) { - if (!m_featuresWidget.contains(pFeature)) { - return; - } - +void LibraryPaneManager::switchToFeature(LibraryFeature* pFeature) { DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { return; } - int widgetId = m_featuresWidget[pFeature]; - m_pPaneWidget->setCurrentIndex(widgetId); + m_pPaneWidget->switchToFeature(pFeature); } void LibraryPaneManager::restoreSearch(const QString& text) { @@ -135,7 +117,7 @@ void LibraryPaneManager::restoreSearch(const QString& text) { } } -void LibraryPaneManager::slotShowBreadCrumb(TreeItem *pTree) { +void LibraryPaneManager::showBreadCrumb(TreeItem *pTree) { DEBUG_ASSERT_AND_HANDLE(!m_pBreadCrumb.isNull()) { return; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index ab6e4e72e3e..b925acda507 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -43,6 +43,8 @@ class LibraryPaneManager : public QObject { void clearFocus(); void restoreSearch(const QString& text); + void switchToFeature(LibraryFeature* pFeature); + void showBreadCrumb(TreeItem* pTree); inline int getPaneId() { return m_paneId; @@ -58,9 +60,6 @@ class LibraryPaneManager : public QObject { public slots: - void slotSwitchToView(const QString& view); - void slotSwitchToViewFeature(LibraryFeature* pFeature); - void slotShowBreadCrumb(TreeItem* pTree); void slotPaneCollapsed(); void slotPaneUncollapsed(); @@ -68,13 +67,10 @@ class LibraryPaneManager : public QObject { QPointer m_pPaneWidget; QList m_features; - QHash m_featuresWidget; QPointer m_pBreadCrumb; QPointer m_pSearchBar; private: - - const static QString m_sTrackViewName; LibraryFeature* m_pFocusedFeature; int m_paneId; diff --git a/src/library/librarysidebarexpandedmanager.cpp b/src/library/librarysidebarexpandedmanager.cpp index 9d217e5039d..60da9906c79 100644 --- a/src/library/librarysidebarexpandedmanager.cpp +++ b/src/library/librarysidebarexpandedmanager.cpp @@ -17,8 +17,7 @@ void LibrarySidebarExpandedManager::bindPaneWidget(WBaseLibrary* sidebarWidget, continue; } pPane->setParent(sidebarWidget); - sidebarWidget->registerView(f->getFeatureName(), pPane); - m_featuresWidget[f] = sidebarWidget->indexOf(pPane); + sidebarWidget->registerView(f, pPane); } } diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 786064eee6c..92bfe51b8b9 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -4,7 +4,8 @@ #include #include -#include "wbaselibrary.h" +#include "library/libraryfeature.h" +#include "widget/wbaselibrary.h" WBaseLibrary::WBaseLibrary(QWidget* parent) : QStackedWidget(parent), @@ -14,22 +15,22 @@ WBaseLibrary::WBaseLibrary(QWidget* parent) } -bool WBaseLibrary::registerView(QString name, QWidget* view) { +bool WBaseLibrary::registerView(LibraryFeature *pFeature, QWidget *view) { QMutexLocker lock(&m_mutex); - if (m_viewMap.contains(name)) { + if (m_featureMap.contains(pFeature)) { return false; } view->installEventFilter(this); int index = addWidget(view); setCurrentIndex(index); - m_currentViewName = name; - m_viewMap[name] = view; + m_pCurrentFeature = pFeature; + m_featureMap[pFeature] = view; return true; } -QString WBaseLibrary::getCurrentViewName() { - return m_currentViewName; +LibraryFeature *WBaseLibrary::getCurrentFeature() { + return m_pCurrentFeature; } int WBaseLibrary::getShowFocus() { @@ -45,23 +46,14 @@ void WBaseLibrary::setShowFocus(int sFocus) { update(); } -void WBaseLibrary::switchToView(const QString& name) { - QMutexLocker lock(&m_mutex); - //qDebug() << "WBaseLibrary::switchToView" << name; - QWidget* widget = m_viewMap.value(name, nullptr); - if (widget != nullptr && currentWidget() != widget) { - //qDebug() << "WBaseLibrary::setCurrentWidget" << name; - m_currentViewName = name; - setCurrentWidget(widget); +void WBaseLibrary::switchToFeature(LibraryFeature *pFeature) { + auto it = m_featureMap.find(pFeature); + if (it != m_featureMap.end() && currentWidget() != (*it)) { + m_pCurrentFeature = pFeature; + setCurrentWidget(*it); } } -void WBaseLibrary::setCurrentIndex(int index) { - QWidget* pWidget = widget(index); - m_currentViewName = m_viewMap.key(pWidget); - QStackedWidget::setCurrentIndex(index); -} - bool WBaseLibrary::eventFilter(QObject*, QEvent* pEvent) { if (pEvent->type() == QEvent::FocusIn) { //qDebug() << "WBaseLibrary::eventFilter FocusIn"; diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index e9ff6ffed4f..9975aa324b7 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -6,6 +6,8 @@ #include "widget/wbasewidget.h" +class LibraryFeature; + class WBaseLibrary : public QStackedWidget, public WBaseWidget { Q_OBJECT @@ -13,9 +15,9 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget WBaseLibrary(QWidget* parent = nullptr); - virtual bool registerView(QString name, QWidget* view); + virtual bool registerView(LibraryFeature* pFeature, QWidget* view); - QString getCurrentViewName(); + LibraryFeature* getCurrentFeature(); Q_PROPERTY(int showFocus READ getShowFocus WRITE setShowFocus) @@ -32,9 +34,7 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget public slots: - virtual void switchToView(const QString& name); - - void setCurrentIndex(int index); + virtual void switchToFeature(LibraryFeature* pFeature); protected: @@ -42,11 +42,11 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget bool event(QEvent* pEvent) override; void resizeEvent(QResizeEvent* pEvent); - QHash m_viewMap; + QHash m_featureMap; private: - QString m_currentViewName; + LibraryFeature* m_pCurrentFeature; QMutex m_mutex; int m_showFocus; bool m_isCollapsed; diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrary.cpp index 2221107847b..238632a1a4d 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrary.cpp @@ -14,33 +14,30 @@ WLibrary::WLibrary(QWidget* parent) } -bool WLibrary::registerView(QString name, QWidget* view) { +bool WLibrary::registerView(LibraryFeature *pFeature, QWidget* pView) { QMutexLocker lock(&m_mutex); - //qDebug() << "WLibrary::registerView" << name; - if (dynamic_cast(view) == nullptr) { + if (pFeature == nullptr || dynamic_cast(pView) == nullptr) { qDebug() << "WARNING: Attempted to register a view with WLibrary " << "that does not implement the LibraryView interface. " << "Ignoring."; return false; } - return WBaseLibrary::registerView(name, view); + return WBaseLibrary::registerView(pFeature, pView); } -void WLibrary::switchToView(const QString& name) { +void WLibrary::switchToFeature(LibraryFeature *pFeature) { QMutexLocker lock(&m_mutex); - //qDebug() << "WLibrary::switchToView" << name; - QWidget* widget = m_viewMap.value(name, nullptr); - if (widget != nullptr) { - LibraryView * lview = dynamic_cast(widget); - if (lview == nullptr) { + auto it = m_featureMap.find(pFeature); + if (it != m_featureMap.end()) { + LibraryView* pView = dynamic_cast(*it); + if (pView == nullptr) { qDebug() << "WARNING: Attempted to register a view with WLibrary " << "that does not implement the LibraryView interface. " << "Ignoring."; return; } - - WBaseLibrary::switchToView(name); - lview->onShow(); + WBaseLibrary::switchToFeature(pFeature); + pView->onShow(); } } diff --git a/src/widget/wlibrary.h b/src/widget/wlibrary.h index 344a69520c7..7115b3933e0 100644 --- a/src/widget/wlibrary.h +++ b/src/widget/wlibrary.h @@ -26,7 +26,7 @@ class WLibrary : public WBaseLibrary { // the view and is in charge of deleting it. Returns whether or not the // registration was successful. Registered widget must implement the // LibraryView interface. - bool registerView(QString name, QWidget* view); + bool registerView(LibraryFeature* pFeature, QWidget *pView); LibraryView* getActiveView() const; @@ -34,7 +34,7 @@ class WLibrary : public WBaseLibrary { // Show the view registered with the given name. Does nothing if the current // view is the specified view, or if the name does not specify any // registered view. - void switchToView(const QString& name); + void switchToFeature(LibraryFeature* pFeature); void search(const QString&); From b0fd7c7206426a104b840a631c910f0e41784688 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 3 Jul 2016 01:12:21 +0200 Subject: [PATCH 239/552] Fix search in analysis feature --- src/library/analysisfeature.cpp | 41 +++++++++++++-------------------- src/library/analysisfeature.h | 1 - 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index e5e55909b89..0d848b9ff6e 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -4,19 +4,20 @@ #include +#include "analyzer/analyzerqueue.h" +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/analysisfeature.h" -#include "library/librarytablemodel.h" -#include "library/trackcollection.h" #include "library/dlganalysis.h" #include "library/library.h" +#include "library/librarytablemodel.h" +#include "library/trackcollection.h" #include "library/treeitem.h" -#include "widget/wlibrary.h" -#include "widget/wanalysislibrarytableview.h" -#include "controllers/keyboard/keyboardeventfilter.h" -#include "analyzer/analyzerqueue.h" #include "sources/soundsourceproxy.h" -#include "util/dnd.h" #include "util/debug.h" +#include "util/dnd.h" +#include "widget/wanalysislibrarytableview.h" +#include "widget/wlibrary.h" +#include "widget/wtracktableview.h" const QString AnalysisFeature::m_sAnalysisViewName = "AnalysisView"; @@ -66,24 +67,14 @@ QString AnalysisFeature::getFeatureName() { } QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, - int paneId) { - WAnalysisLibraryTableView* pTable = - new WAnalysisLibraryTableView(nullptr, m_pConfig, m_pTrackCollection); - pTable->installEventFilter(pKeyboard); + int paneId) { + WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); pTable->loadTrackModel(getAnalysisTableModel()); - connect(pTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(tableSelectionChanged(const QItemSelection&, const QItemSelection&))); - connect(pTable, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(pTable, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool)), - this, SIGNAL(loadTrackToPlayer(TrackPointer,QString,bool))); - connect(pTable, SIGNAL(trackSelected(TrackPointer)), - this, SIGNAL(trackSelected(TrackPointer))); - m_analysisTables[paneId] = pTable; return pTable; } @@ -118,9 +109,9 @@ void AnalysisFeature::refreshLibraryModels() { } void AnalysisFeature::selectAll() { - auto it = m_analysisTables.find(m_featureFocus); - if (it != m_analysisTables.end() && !it->isNull()) { - (*it)->selectAll(); + QPointer pTable = LibraryFeature::getFocusedTable(); + if (!pTable.isNull()) { + pTable->selectAll(); } } @@ -201,12 +192,12 @@ void AnalysisFeature::cleanupAnalyzer() { void AnalysisFeature::tableSelectionChanged(const QItemSelection&, const QItemSelection&) { //qDebug() << "AnalysisFeature::tableSelectionChanged" << sender(); - auto it = m_analysisTables.find(m_featureFocus); - if (it == m_analysisTables.end() || it->isNull()) { + QPointer pTable = LibraryFeature::getFocusedTable(); + if (pTable.isNull()) { return; } - const QModelIndexList &indexes = (*it)->selectionModel()->selectedIndexes(); + const QModelIndexList &indexes = pTable->selectionModel()->selectedIndexes(); m_pAnalysisView->setSelectedIndexes(indexes); } diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 092cf353b40..fe44fdefb2f 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -80,7 +80,6 @@ class AnalysisFeature : public LibraryFeature { QString m_analysisTitleName; QPointer m_pAnalysisView; QPointer m_pAnalysisLibraryTableModel; - QHash > m_analysisTables; }; From 3f00ce8ea9d6d824f0c853c438740a42711e8f53 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 6 Jul 2016 10:14:48 +0200 Subject: [PATCH 240/552] Fix changing playlist not working --- src/widget/wtracktableview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 8a4a8cffa82..5d5e0f965d6 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -211,8 +211,8 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) { * this will cause a small GUI freeze */ if (getTrackModel() == trackModel) { - // Re-sort the table even if the track model is the same. This triggers - // a select() if the table is dirty. + // Re-sort the table even if the track model is the same. + trackModel->select(); doSortByColumn(horizontalHeader()->sortIndicatorSection()); return; } From 21c463dd57edf237298319a1d7bea99006c35af8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 6 Jul 2016 13:07:28 +0200 Subject: [PATCH 241/552] Force travis build --- src/library/mixxxlibraryfeature.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 7312c65cca8..3e254745bd9 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -32,6 +32,7 @@ class MissingTableModel; class MixxxLibraryFeature : public LibraryFeature { Q_OBJECT + public: MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, From d376d7815fd723225ace007fbefa8527e14decfc Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 6 Jul 2016 14:18:53 +0200 Subject: [PATCH 242/552] Add multiple pane playlists view --- src/library/baseplaylistfeature.cpp | 29 ++++++++++++++++++++++++++--- src/library/baseplaylistfeature.h | 5 +++++ src/library/historyfeature.cpp | 8 +++++--- src/library/historyfeature.h | 1 + src/library/library.cpp | 29 +++++++++++++++++++---------- src/library/library.h | 3 ++- src/library/libraryfeature.cpp | 8 ++++++++ src/library/libraryfeature.h | 16 ++++++++-------- src/library/librarypanemanager.cpp | 13 +++++++------ src/library/librarypanemanager.h | 8 +++----- src/library/playlistfeature.cpp | 9 +++++---- src/library/playlistfeature.h | 1 + 12 files changed, 90 insertions(+), 40 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 51aa400f931..6b091b2b7e6 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -100,7 +100,8 @@ BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, } BasePlaylistFeature::~BasePlaylistFeature() { - delete m_pPlaylistTableModel; + qDeleteAll(m_playlistTableModel); + m_playlistTableModel.clear(); delete m_pCreatePlaylistAction; delete m_pDeletePlaylistAction; delete m_pImportPlaylistAction; @@ -130,6 +131,14 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { return playlistId; } +QPointer BasePlaylistFeature::getPlaylistTableModel(int paneId) { + auto it = m_playlistTableModel.find(paneId); + if (it == m_playlistTableModel.end() || it->isNull()) { + return constructTableModel(); + } + return *it; +} + void BasePlaylistFeature::activate() { auto it = m_panes.find(m_featureFocus); auto itId = m_idBrowse.find(m_featureFocus); @@ -143,22 +152,31 @@ void BasePlaylistFeature::activate() { m_pLibrary->restoreSearch(QString()); // Null String disables search box emit(enableCoverArtDisplay(true)); + m_featureFocus = -1; } void BasePlaylistFeature::activateChild(const QModelIndex& index) { //qDebug() << "BasePlaylistFeature::activateChild()" << index; int playlistId = playlistIdFromIndex(index); + m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); + if (playlistId != -1 && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistId); - auto it = m_panes.find(m_featureFocus); - auto itId = m_idTable.find(m_featureFocus); + auto it = m_panes.find(m_focusedPane); + auto itId = m_idTable.find(m_focusedPane); if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { return; } (*it)->setCurrentIndex(*itId); + + // Set the feature Focus for a moment to allow the LibraryFeature class + // to find the focused WTrackTable + m_featureFocus = m_focusedPane; showTrackModel(m_pPlaylistTableModel); + m_featureFocus = -1; + m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); @@ -331,6 +349,11 @@ void BasePlaylistFeature::slotCreatePlaylist() { } } +void BasePlaylistFeature::setFeatureFocus(int focus) { + m_pPlaylistTableModel = getPlaylistTableModel(focus); + LibraryFeature::setFeatureFocus(focus); +} + void BasePlaylistFeature::slotDeletePlaylist() { //qDebug() << "slotDeletePlaylist() row:" << m_lastRightClickedIndex.data(); int playlistId = playlistIdFromIndex(m_lastRightClickedIndex); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 2279052e799..18dc25a475a 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -52,6 +52,7 @@ class BasePlaylistFeature : public LibraryFeature { virtual void slotPlaylistContentChanged(int playlistId) = 0; virtual void slotPlaylistTableRenamed(int playlistId, QString a_strName) = 0; void slotCreatePlaylist(); + void setFeatureFocus(int focus); protected slots: void slotDeletePlaylist(); @@ -77,6 +78,9 @@ class BasePlaylistFeature : public LibraryFeature { virtual void addToAutoDJ(bool bTop); int playlistIdFromIndex(QModelIndex index); + QPointer getPlaylistTableModel(int paneId); + virtual PlaylistTableModel* constructTableModel() = 0; + // Get the QModelIndex of a playlist based on its id. Returns QModelIndex() // on failure. QModelIndex indexFromPlaylistId(int playlistId); @@ -84,6 +88,7 @@ class BasePlaylistFeature : public LibraryFeature { PlaylistDAO &m_playlistDao; TrackDAO &m_trackDao; PlaylistTableModel* m_pPlaylistTableModel; + QHash > m_playlistTableModel; QAction *m_pCreatePlaylistAction; QAction *m_pDeletePlaylistAction; QAction *m_pAddToAutoDJAction; diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 314d3f45dc5..cea87cee71c 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -17,9 +17,6 @@ HistoryFeature::HistoryFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, "SETLOGHOME"), m_playlistId(-1) { - m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, - "mixxx.db.model.setlog", - true); //show all tracks m_pJoinWithPreviousAction = new QAction(tr("Join with previous"), this); connect(m_pJoinWithPreviousAction, SIGNAL(triggered()), this, SLOT(slotJoinWithPrevious())); @@ -144,6 +141,11 @@ void HistoryFeature::decorateChild(TreeItem* item, int playlist_id) { } } +PlaylistTableModel* HistoryFeature::constructTableModel() { + return new PlaylistTableModel(this, m_pTrackCollection, + "mixxx.db.model.setlog", true); +} + void HistoryFeature::slotGetNewPlaylist() { //qDebug() << "slotGetNewPlaylist() succesfully triggered !"; diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index 024dc3f16f4..beeeb7376e9 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -34,6 +34,7 @@ class HistoryFeature : public BasePlaylistFeature { protected: void buildPlaylistList(); void decorateChild(TreeItem *pChild, int playlist_id); + PlaylistTableModel* constructTableModel(); private slots: void slotPlayingTrackChanged(TrackPointer currentPlayingTrack); diff --git a/src/library/library.cpp b/src/library/library.cpp index 37b7ded2436..625102aa005 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -140,8 +140,6 @@ void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard) { //qDebug() << "Library::bindSidebarExpanded"; m_pSidebarExpanded = new LibrarySidebarExpandedManager(this); - connect(m_pSidebarExpanded, SIGNAL(focused()), - this, SLOT(slotPaneFocused())); m_pSidebarExpanded->addFeatures(m_features); m_pSidebarExpanded->bindPaneWidget(expandedPane, pKeyboard); } @@ -362,6 +360,7 @@ void Library::paneCollapsed(int paneId) { for (LibraryPaneManager* pPane : m_panes) { if (!m_collapsedPanes.contains(pPane->getPaneId())) { m_focusedPane = pPane->getPaneId(); + setFocusedPane(); pPane->setFocus(); break; } @@ -374,8 +373,9 @@ void Library::paneUncollapsed(int paneId) { void Library::slotActivateFeature(LibraryFeature *pFeature) { // The feature is being shown currently in the focused pane - if (m_panes[m_focusedPane]->getFocusedFeature() == pFeature) { + if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { m_pSidebarExpanded->switchToFeature(pFeature); + handleFocus(); return; } int featureFocus = pFeature->getFeatureFocus(); @@ -391,12 +391,13 @@ void Library::slotActivateFeature(LibraryFeature *pFeature) { } else { // The feature is shown in some not collapsed pane m_focusedPane = featureFocus; + setFocusedPane(); m_pSidebarExpanded->switchToFeature(pFeature); handleFocus(); return; } - m_panes[m_focusedPane]->setFocusedFeature(pFeature); + m_panes[m_focusedPane]->setCurrentFeature(pFeature); pFeature->setFeatureFocus(m_focusedPane); pFeature->activate(); handleFocus(); @@ -418,17 +419,18 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::slotPaneFocused() { - LibraryPaneManager* pane = qobject_cast(sender()); - DEBUG_ASSERT_AND_HANDLE(pane) { +void Library::slotPaneFocused(LibraryPaneManager* pPane) { + DEBUG_ASSERT_AND_HANDLE(pPane) { return; } - if (pane != m_pSidebarExpanded) { - m_focusedPane = m_panes.key(pane, -1); + if (pPane != m_pSidebarExpanded) { + m_focusedPane = pPane->getPaneId(); + pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } + setFocusedPane(); handleFocus(); } @@ -438,6 +440,7 @@ void Library::slotPaneFocused() { void Library::slotUpdateFocus(LibraryFeature *pFeature) { if (pFeature->getFeatureFocus() >= 0) { m_focusedPane = pFeature->getFeatureFocus(); + setFocusedPane(); } } @@ -454,8 +457,8 @@ LibraryPaneManager* Library::getPane(int paneId) { pPane->addFeatures(m_features); m_panes.insert(paneId, pPane); - connect(pPane, SIGNAL(focused()), this, SLOT(slotPaneFocused())); m_focusedPane = paneId; + setFocusedPane(); return pPane; } @@ -521,6 +524,12 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface } } +void Library::setFocusedPane() { + for (LibraryFeature* pFeature : m_features) { + pFeature->setFocusedPane(m_focusedPane); + } +} + void Library::handleFocus() { // Changes the visual focus effect, removes the existing one and adds the // new focus diff --git a/src/library/library.h b/src/library/library.h index bdeea24346c..092eb42d676 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -115,7 +115,7 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - void slotPaneFocused(); + void slotPaneFocused(LibraryPaneManager *pPane); // Updates with the focus feature void slotUpdateFocus(LibraryFeature* pFeature); @@ -146,6 +146,7 @@ class Library : public QObject { LibraryPaneManager* getFocusedPane(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); + void setFocusedPane(); void handleFocus(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index f0d92a85481..202d5dda260 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -65,6 +65,14 @@ void LibraryFeature::setFeatureFocus(int focus) { m_featureFocus = focus; } +int LibraryFeature::getFeatureFocus() { + return m_featureFocus; +} + +void LibraryFeature::setFocusedPane(int paneId) { + m_focusedPane = paneId; +} + WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index fd0b0e4783f..937b70d6db0 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -72,11 +72,10 @@ class LibraryFeature : public QObject { virtual TreeItemModel* getChildModel() = 0; - void setFeatureFocus(int focus); + virtual void setFeatureFocus(int focus); + virtual int getFeatureFocus(); - int getFeatureFocus() { - return m_featureFocus; - } + virtual void setFocusedPane(int paneId); protected: inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } @@ -86,14 +85,14 @@ class LibraryFeature : public QObject { WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, int paneId); - // Override this function to create a custom inner widget for the sidebar, - // the default widget is a WLibrarySidebar widget - virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); - // Creates a WLibrarySidebar widget with the getChildModel() function as // model WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); + // Override this function to create a custom inner widget for the sidebar, + // the default widget is a WLibrarySidebar widget + virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); + void showTrackModel(QAbstractItemModel *model); void switchToFeature(); @@ -104,6 +103,7 @@ class LibraryFeature : public QObject { TrackCollection* m_pTrackCollection; int m_featureFocus; + int m_focusedPane; public slots: // called when you single click on the root item diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index d0c168f9abf..273305b4ccf 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -81,12 +81,12 @@ WBaseLibrary* LibraryPaneManager::getPaneWidget() { return m_pPaneWidget; } -void LibraryPaneManager::setFocusedFeature(LibraryFeature* pFeature) { - m_pFocusedFeature = pFeature; +void LibraryPaneManager::setCurrentFeature(LibraryFeature* pFeature) { + m_pCurrentFeature = pFeature; } -LibraryFeature *LibraryPaneManager::getFocusedFeature() const { - return m_pFocusedFeature; +LibraryFeature *LibraryPaneManager::getCurrentFeature() const { + return m_pCurrentFeature; } void LibraryPaneManager::setFocus() { @@ -104,10 +104,11 @@ void LibraryPaneManager::clearFocus() { } void LibraryPaneManager::switchToFeature(LibraryFeature* pFeature) { - DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { + DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull() && pFeature) { return; } + m_pCurrentFeature = pFeature; m_pPaneWidget->switchToFeature(pFeature); } @@ -140,7 +141,7 @@ bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (event->type() == QEvent::MouseButtonPress && m_pPaneWidget->underMouse()) { - emit(focused()); + m_pLibrary->slotPaneFocused(this); } // Since this event filter is for the entire application (to handle the diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index b925acda507..28bfb8ae9dc 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -36,8 +36,8 @@ class LibraryPaneManager : public QObject { WBaseLibrary* getPaneWidget(); - void setFocusedFeature(LibraryFeature* pFeature); - LibraryFeature* getFocusedFeature() const; + void setCurrentFeature(LibraryFeature* pFeature); + LibraryFeature* getCurrentFeature() const; void setFocus(); void clearFocus(); @@ -52,8 +52,6 @@ class LibraryPaneManager : public QObject { signals: - void focused(); - void search(const QString& text); void searchCleared(); void searchStarting(); @@ -72,7 +70,7 @@ class LibraryPaneManager : public QObject { private: - LibraryFeature* m_pFocusedFeature; + LibraryFeature* m_pCurrentFeature; int m_paneId; Library* m_pLibrary; diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 767f47dc75c..d41ef8712a3 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -24,9 +24,6 @@ PlaylistFeature::PlaylistFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, "PLAYLISTHOME") { - m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, - "mixxx.db.model.playlist"); - //construct child model TreeItem *rootItem = new TreeItem(); m_childModel.setRootItem(rootItem); @@ -48,7 +45,7 @@ void PlaylistFeature::onRightClick(const QPoint& globalPos) { m_lastRightClickedIndex = QModelIndex(); //Create the right-click menu - QMenu menu(NULL); + QMenu menu(nullptr); menu.addAction(m_pCreatePlaylistAction); menu.addSeparator(); menu.addAction(m_pCreateImportPlaylistAction); @@ -190,6 +187,10 @@ void PlaylistFeature::decorateChild(TreeItem* item, int playlist_id) { } } +PlaylistTableModel* PlaylistFeature::constructTableModel() { + return new PlaylistTableModel(this, m_pTrackCollection, "mixxx.db.model.playlist"); +} + void PlaylistFeature::slotPlaylistTableChanged(int playlistId) { if (!m_pPlaylistTableModel) { return; diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 0e16f1539fe..a049d9c0987 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -45,6 +45,7 @@ class PlaylistFeature : public BasePlaylistFeature { protected: void buildPlaylistList(); void decorateChild(TreeItem *pChild, int playlist_id); + PlaylistTableModel* constructTableModel(); private: QString getRootViewHtml() const; From 245f5fb5a850ae310d8d7f06fff097103679087a Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 6 Jul 2016 14:33:52 +0200 Subject: [PATCH 243/552] Added multipane view to crates --- src/library/baseplaylistfeature.cpp | 2 +- src/library/cratefeature.cpp | 53 +++++++++++++++++++---------- src/library/cratefeature.h | 5 ++- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 6b091b2b7e6..6be07fbc949 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -134,7 +134,7 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { QPointer BasePlaylistFeature::getPlaylistTableModel(int paneId) { auto it = m_playlistTableModel.find(paneId); if (it == m_playlistTableModel.end() || it->isNull()) { - return constructTableModel(); + it = m_playlistTableModel.insert(paneId, constructTableModel()); } return *it; } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 135e093f924..697674a218c 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -36,7 +36,7 @@ CrateFeature::CrateFeature(UserSettingsPointer pConfig, : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_pTrackCollection(pTrackCollection), m_crateDao(pTrackCollection->getCrateDAO()), - m_crateTableModel(this, pTrackCollection) { + m_pCrateTableModel(nullptr) { m_pCreateCrateAction = new QAction(tr("Create New Crate"),this); connect(m_pCreateCrateAction, SIGNAL(triggered()), @@ -228,7 +228,7 @@ void CrateFeature::activate() { m_pLibrary->switchToFeature(this); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->restoreSearch(QString()); //disable search on crate home - + m_featureFocus = -1; emit(enableCoverArtDisplay(true)); } @@ -241,16 +241,22 @@ void CrateFeature::activateChild(const QModelIndex& index) { return; } - auto it = m_panes.find(m_featureFocus); - auto itId = m_idTable.find(m_featureFocus); + m_pCrateTableModel = getTableModel(m_focusedPane); + auto it = m_panes.find(m_focusedPane); + auto itId = m_idTable.find(m_focusedPane); if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { return; } (*it)->setCurrentIndex(*itId); - m_crateTableModel.setTableModel(crateId); + m_pCrateTableModel->setTableModel(crateId); + + // Set the feature Focus for a moment to allow the LibraryFeature class + // to find the focused WTrackTable + m_featureFocus = m_focusedPane; + showTrackModel(m_pCrateTableModel); + m_featureFocus = -1; - showTrackModel(&m_crateTableModel); m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); @@ -258,10 +264,12 @@ void CrateFeature::activateChild(const QModelIndex& index) { void CrateFeature::activateCrate(int crateId) { //qDebug() << "CrateFeature::activateCrate()" << crateId; + m_pCrateTableModel = getTableModel(m_focusedPane); + QModelIndex index = indexFromCrateId(crateId); if (crateId != -1 && index.isValid()) { - m_crateTableModel.setTableModel(crateId); - showTrackModel(&m_crateTableModel); + m_pCrateTableModel->setTableModel(crateId); + showTrackModel(m_pCrateTableModel); emit(enableCoverArtDisplay(true)); // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); @@ -272,7 +280,7 @@ void CrateFeature::activateCrate(int crateId) { void CrateFeature::onRightClick(const QPoint& globalPos) { m_lastRightClickedIndex = QModelIndex(); - QMenu menu(NULL); + QMenu menu(nullptr); menu.addAction(m_pCreateCrateAction); menu.addSeparator(); menu.addAction(m_pCreateImportPlaylistAction); @@ -652,7 +660,7 @@ void CrateFeature::slotImportPlaylistFile(const QString &playlist_file) { //qDebug() << "Size of Imported Playlist: " << entries.size(); //Iterate over the List that holds URLs of playlist entires - m_crateTableModel.addTracks(QModelIndex(), entries); + m_pCrateTableModel->addTracks(QModelIndex(), entries); //delete the parser object delete playlist_parser; @@ -700,7 +708,7 @@ void CrateFeature::slotCreateImportCrate() { lastCrateId = m_crateDao.createCrate(name); if (lastCrateId != -1) { - m_crateTableModel.setTableModel(lastCrateId); + m_pCrateTableModel->setTableModel(lastCrateId); } else { QMessageBox::warning(NULL, @@ -726,7 +734,7 @@ void CrateFeature::slotAnalyzeCrate() { } void CrateFeature::slotExportPlaylist() { - int crateId = m_crateTableModel.getCrate(); + int crateId = m_pCrateTableModel->getCrate(); QString crateName = m_crateDao.crateName(crateId); qDebug() << "Export crate" << crateId << crateName; @@ -764,7 +772,7 @@ void CrateFeature::slotExportPlaylist() { // Create a new table model since the main one might have an active search. QScopedPointer pCrateTableModel( new CrateTableModel(this, m_pTrackCollection)); - pCrateTableModel->setTableModel(m_crateTableModel.getCrate()); + pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); pCrateTableModel->select(); if (file_location.endsWith(".csv", Qt::CaseInsensitive)) { @@ -776,8 +784,8 @@ void CrateFeature::slotExportPlaylist() { QList playlist_items; int rows = pCrateTableModel->rowCount(); for (int i = 0; i < rows; ++i) { - QModelIndex index = m_crateTableModel.index(i, 0); - playlist_items << m_crateTableModel.getTrackLocation(index); + QModelIndex index = m_pCrateTableModel->index(i, 0); + playlist_items << m_pCrateTableModel->getTrackLocation(index); } if (file_location.endsWith(".pls", Qt::CaseInsensitive)) { @@ -801,14 +809,14 @@ void CrateFeature::slotExportTrackFiles() { // Create a new table model since the main one might have an active search. QScopedPointer pCrateTableModel( new CrateTableModel(this, m_pTrackCollection)); - pCrateTableModel->setTableModel(m_crateTableModel.getCrate()); + pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); pCrateTableModel->select(); int rows = pCrateTableModel->rowCount(); QList trackpointers; for (int i = 0; i < rows; ++i) { - QModelIndex index = m_crateTableModel.index(i, 0); - trackpointers.push_back(m_crateTableModel.getTrack(index)); + QModelIndex index = m_pCrateTableModel->index(i, 0); + trackpointers.push_back(m_pCrateTableModel->getTrack(index)); } TrackExportWizard track_export(nullptr, m_pConfig, trackpointers); @@ -905,3 +913,12 @@ QModelIndex CrateFeature::indexFromCrateId(int crateId) { } return QModelIndex(); } + +QPointer CrateFeature::getTableModel(int paneId) { + auto it = m_crateTableModel.find(paneId); + if (it == m_crateTableModel.end() || it->isNull()) { + it = m_crateTableModel.insert(paneId, + new CrateTableModel(this, m_pTrackCollection)); + } + return *it; +} diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 39a4306bf6b..add752b426e 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -87,6 +87,8 @@ class CrateFeature : public LibraryFeature { // Get the QModelIndex of a crate based on its id. Returns QModelIndex() // on failure. QModelIndex indexFromCrateId(int crateId); + + QPointer getTableModel(int paneId); TrackCollection* m_pTrackCollection; CrateDAO& m_crateDao; @@ -102,7 +104,8 @@ class CrateFeature : public LibraryFeature { QAction *m_pExportTrackFilesAction; QAction *m_pAnalyzeCrateAction; QList > m_crateList; - CrateTableModel m_crateTableModel; + QHash > m_crateTableModel; + CrateTableModel* m_pCrateTableModel; QModelIndex m_lastRightClickedIndex; TreeItemModel m_childModel; TrackPointer m_pSelectedTrack; From 0463a111ec2bb6bc36691c79b894a4ef7e55a643 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 7 Jul 2016 09:49:27 +0200 Subject: [PATCH 244/552] Remove unnecessary featureName --- src/library/analysisfeature.cpp | 6 ------ src/library/analysisfeature.h | 2 -- src/library/autodj/autodjfeature.cpp | 5 ----- src/library/autodj/autodjfeature.h | 2 -- src/library/banshee/bansheefeature.cpp | 5 ----- src/library/banshee/bansheefeature.h | 4 +--- src/library/baseplaylistfeature.cpp | 10 ++-------- src/library/baseplaylistfeature.h | 5 +---- src/library/browse/browsefeature.cpp | 6 ------ src/library/browse/browsefeature.h | 2 -- src/library/cratefeature.cpp | 6 ------ src/library/cratefeature.h | 3 --- src/library/historyfeature.cpp | 2 +- src/library/itunes/itunesfeature.cpp | 5 ----- src/library/itunes/itunesfeature.h | 2 -- src/library/libraryfeature.h | 4 ---- src/library/mixxxlibraryfeature.cpp | 10 ++-------- src/library/mixxxlibraryfeature.h | 2 -- src/library/playlistfeature.cpp | 3 +-- src/library/recording/recordingfeature.cpp | 6 ------ src/library/recording/recordingfeature.h | 2 -- src/library/rhythmbox/rhythmboxfeature.cpp | 6 ------ src/library/rhythmbox/rhythmboxfeature.h | 3 --- src/library/traktor/traktorfeature.cpp | 6 ------ src/library/traktor/traktorfeature.h | 2 -- 25 files changed, 8 insertions(+), 101 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 5a02ce99a3e..3d0ac1ec164 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -19,8 +19,6 @@ #include "widget/wlibrary.h" #include "widget/wtracktableview.h" -const QString AnalysisFeature::m_sAnalysisViewName = "AnalysisView"; - AnalysisFeature::AnalysisFeature(UserSettingsPointer pConfig, Library* pLibrary, TrackCollection* pTrackCollection, QObject* parent) : @@ -62,10 +60,6 @@ QIcon AnalysisFeature::getIcon() { return QIcon(":/images/library/ic_library_prepare.png"); } -QString AnalysisFeature::getFeatureName() { - return m_sAnalysisViewName; -} - QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 9a7de987fdf..2516c8c9efb 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -31,7 +31,6 @@ class AnalysisFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -76,7 +75,6 @@ class AnalysisFeature : public LibraryFeature { // The title returned by title() QVariant m_Title; TreeItemModel m_childModel; - const static QString m_sAnalysisViewName; QString m_analysisTitleName; QPointer m_pAnalysisView; QPointer m_pAnalysisLibraryTableModel; diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index de2806407cf..e222477143d 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -23,7 +23,6 @@ #include "sources/soundsourceproxy.h" #include "util/dnd.h" -const QString AutoDJFeature::m_sAutoDJViewName = QString("Auto DJ"); static const int kMaxRetrieveAttempts = 3; AutoDJFeature::AutoDJFeature(UserSettingsPointer pConfig, @@ -100,10 +99,6 @@ QIcon AutoDJFeature::getIcon() { return QIcon(":/images/library/ic_library_autodj.png"); } -QString AutoDJFeature::getFeatureName() { - return m_sAutoDJViewName; -} - QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 1f330520ff8..a433ec07237 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -41,7 +41,6 @@ class AutoDJFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -64,7 +63,6 @@ class AutoDJFeature : public LibraryFeature { // The id of the AutoDJ playlist. int m_iAutoDJPlaylistId; AutoDJProcessor* m_pAutoDJProcessor; - const static QString m_sAutoDJViewName; TreeItemModel m_childModel; QPointer m_pAutoDJView; QHash > m_trackTables; diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index f402b80923d..6e90b8b67bb 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -12,7 +12,6 @@ const QString BansheeFeature::BANSHEE_MOUNT_KEY = "mixxx.BansheeFeature.mount"; -const QString BansheeFeature::m_sBansheeViewName = "BANSHEE_VIEW"; QString BansheeFeature::m_databaseFile; BansheeFeature::BansheeFeature(UserSettingsPointer pConfig, @@ -63,10 +62,6 @@ QIcon BansheeFeature::getIcon() { return QIcon(":/images/library/ic_library_banshee.png"); } -QString BansheeFeature::getFeatureName() { - return m_sBansheeViewName; -} - void BansheeFeature::activate() { //qDebug("BansheeFeature::activate()"); diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index 47ea34552f2..096a3b924cd 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -30,7 +30,6 @@ class BansheeFeature : public BaseExternalLibraryFeature { virtual QVariant title(); virtual QIcon getIcon(); - QString getFeatureName() override; virtual TreeItemModel* getChildModel(); @@ -59,8 +58,7 @@ class BansheeFeature : public BaseExternalLibraryFeature { bool m_cancelImport; static QString m_databaseFile; - - static const QString m_sBansheeViewName; + static const QString BANSHEE_MOUNT_KEY; }; diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 6be07fbc949..1b959c75e6e 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -23,13 +23,11 @@ BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, - TrackCollection* pTrackCollection, - QString rootViewName) + TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_playlistDao(pTrackCollection->getPlaylistDAO()), m_trackDao(pTrackCollection->getTrackDAO()), - m_pPlaylistTableModel(nullptr), - m_rootViewName(rootViewName) { + m_pPlaylistTableModel(nullptr) { m_pCreatePlaylistAction = new QAction(tr("Create New Playlist"),this); connect(m_pCreatePlaylistAction, SIGNAL(triggered()), this, SLOT(slotCreatePlaylist())); @@ -657,10 +655,6 @@ QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, return pStack; } -QString BasePlaylistFeature::getFeatureName() { - return m_rootViewName; -} - void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) { if (QString(link.path()) == "create") { slotCreatePlaylist(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 18dc25a475a..9f3159b07f9 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -29,14 +29,12 @@ class BasePlaylistFeature : public LibraryFeature { BasePlaylistFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, - TrackCollection* pTrackCollection, - QString rootViewName); + TrackCollection* pTrackCollection); virtual ~BasePlaylistFeature(); TreeItemModel* getChildModel(); QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId) override; - QString getFeatureName() override; signals: void showPage(const QUrl& page); @@ -114,7 +112,6 @@ class BasePlaylistFeature : public LibraryFeature { virtual QString getRootViewHtml() const = 0; QSet m_playlistsSelectedTrackIsIn; - QString m_rootViewName; QHash > m_panes; QHash m_idBrowse; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 950bafad5ac..cf8c9e586fc 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -25,8 +25,6 @@ const QString kQuickLinksSeparator = "-+-"; -const QString BrowseFeature::m_sBrowseViewName = QString("BROWSEHOME"); - BrowseFeature::BrowseFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -209,10 +207,6 @@ QIcon BrowseFeature::getIcon() { return QIcon(":/images/library/ic_library_browse.png"); } -QString BrowseFeature::getFeatureName() { - return m_sBrowseViewName; -} - TreeItemModel* BrowseFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 615475a7e99..46fdce22f4d 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,6 @@ class BrowseFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId) override; @@ -77,7 +76,6 @@ class BrowseFeature : public LibraryFeature { TreeItem* m_pLastRightClickedItem; TreeItem* m_pQuickLinkItem; QStringList m_quickLinkList; - static const QString m_sBrowseViewName; QHash > m_panes; QHash m_idBrowse; diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 697674a218c..f56d5a1452a 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -27,8 +27,6 @@ #include "widget/wlibrarytextbrowser.h" #include "widget/wlibrarystack.h" -const QString CrateFeature::m_sCrateViewName = QString("CRATEHOME"); - CrateFeature::CrateFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -129,10 +127,6 @@ QIcon CrateFeature::getIcon() { return QIcon(":/images/library/ic_library_crates.png"); } -QString CrateFeature::getFeatureName() { - return m_sCrateViewName; -} - int CrateFeature::crateIdFromIndex(QModelIndex index) { TreeItem* item = static_cast(index.internalPointer()); if (item == nullptr) { diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index add752b426e..fd5870f3ddc 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -32,7 +32,6 @@ class CrateFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; void onSearch(QString&) {} @@ -113,8 +112,6 @@ class CrateFeature : public LibraryFeature { QHash > m_panes; QHash m_idBrowse; QHash m_idTable; - - const static QString m_sCrateViewName; }; #endif /* CRATEFEATURE_H */ diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index cea87cee71c..6c8fd71e391 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -15,7 +15,7 @@ HistoryFeature::HistoryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) - : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, "SETLOGHOME"), + : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection), m_playlistId(-1) { m_pJoinWithPreviousAction = new QAction(tr("Join with previous"), this); connect(m_pJoinWithPreviousAction, SIGNAL(triggered()), diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 50b57d9d17a..0b3dac8aeaf 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -20,7 +20,6 @@ #include "util/sandbox.h" const QString ITunesFeature::ITDB_PATH_KEY = "mixxx.itunesfeature.itdbpath"; -const QString ITunesFeature::m_sItunesView = "ITUNES_VIEW"; QString localhost_token() { #if defined(__WINDOWS__) @@ -117,10 +116,6 @@ QIcon ITunesFeature::getIcon() { return QIcon(":/images/library/ic_library_itunes.png"); } -QString ITunesFeature::getFeatureName() { - return m_sItunesView; -} - void ITunesFeature::activate() { activate(false); emit(enableCoverArtDisplay(false)); diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index ced6a301adf..10818eca0f4 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -30,7 +30,6 @@ class ITunesFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; TreeItemModel* getChildModel(); @@ -72,7 +71,6 @@ class ITunesFeature : public BaseExternalLibraryFeature { QString m_dbItunesRoot; QString m_mixxxItunesRoot; - static const QString m_sItunesView; QSharedPointer m_trackSource; diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 937b70d6db0..fd8307d9ddd 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -39,10 +39,6 @@ class LibraryFeature : public QObject { virtual QVariant title() = 0; virtual QIcon getIcon() = 0; - - // Must be a unique name for each feature, it must be a unique name for each - // different feature - virtual QString getFeatureName() = 0; virtual bool dropAccept(QList /* urls */, QObject* /* pSource */) { diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 3c95594ecc3..f485bcafad1 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -22,8 +22,6 @@ #include "widget/wlibrarysidebar.h" #include "util/dnd.h" -const QString MixxxLibraryFeature::m_sMixxxLibraryViewName = "MixxxLibraryFeature"; - MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -123,7 +121,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TreeItem* pRootItem = new TreeItem(); pRootItem->setLibraryFeature(this); - TreeItem* pLibraryChildItem = new TreeItem(kLibraryTitle, m_sMixxxLibraryViewName, + TreeItem* pLibraryChildItem = new TreeItem(kLibraryTitle, kLibraryTitle, this, pRootItem); pLibraryChildItem->setIcon(getIcon()); TreeItem* pmissingChildItem = new TreeItem(kMissingTitle, kMissingTitle, @@ -194,10 +192,6 @@ QIcon MixxxLibraryFeature::getIcon() { return QIcon(":/images/library/ic_library_library.png"); } -QString MixxxLibraryFeature::getFeatureName() { - return m_sMixxxLibraryViewName; -} - TreeItemModel* MixxxLibraryFeature::getChildModel() { return &m_childModel; } @@ -270,7 +264,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { TreeItem* pTree = static_cast (index.internalPointer()); QPointer pTable = getFocusedTable(); - if (itemName == m_sMixxxLibraryViewName) { + if (itemName == kLibraryTitle) { activate(); return; } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 3e254745bd9..460e8b5a0b6 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -42,7 +42,6 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); @@ -100,7 +99,6 @@ class MixxxLibraryFeature : public LibraryFeature { TreeItemModel m_childModel; TrackDAO& m_trackDao; TrackCollection* m_pTrackCollection; - static const QString m_sMixxxLibraryViewName; }; #endif /* MIXXXLIBRARYFEATURE_H */ diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index d41ef8712a3..2d99850a8e4 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -22,8 +22,7 @@ PlaylistFeature::PlaylistFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) - : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection, - "PLAYLISTHOME") { + : BasePlaylistFeature(pConfig, pLibrary, parent, pTrackCollection) { //construct child model TreeItem *rootItem = new TreeItem(); m_childModel.setRootItem(rootItem); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 682d822c70d..7b3b369d393 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -10,8 +10,6 @@ #include "widget/wlibrary.h" #include "controllers/keyboard/keyboardeventfilter.h" -const QString RecordingFeature::m_sRecordingViewName = QString("Recording"); - RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -41,10 +39,6 @@ QIcon RecordingFeature::getIcon() { return QIcon(":/images/library/ic_library_recordings.png"); } -QString RecordingFeature::getFeatureName() { - return m_sRecordingViewName; -} - TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index adb24a4367f..01e241092a3 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,7 +30,6 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; @@ -50,7 +49,6 @@ class RecordingFeature : public LibraryFeature { TrackCollection* m_pTrackCollection; FolderTreeModel m_childModel; - const static QString m_sRecordingViewName; RecordingManager* m_pRecordingManager; QPointer m_pRecordingView; diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index a5f21464d2c..25f7f4ff626 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -11,8 +11,6 @@ #include "library/queryutil.h" #include "library/treeitem.h" -const QString RhythmboxFeature::m_sRhythmBoxViewName = QString("RHYTHMBOX_VIEW"); - RhythmboxFeature::RhythmboxFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -109,10 +107,6 @@ QIcon RhythmboxFeature::getIcon() { return QIcon(":/images/library/ic_library_rhythmbox.png"); } -QString RhythmboxFeature::getFeatureName() { - return m_sRhythmBoxViewName; -} - TreeItemModel* RhythmboxFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index 4653fe51dcc..4ea8a6601bd 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -30,7 +30,6 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; TreeItemModel* getChildModel(); // processes the music collection @@ -67,8 +66,6 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { bool m_cancelImport; QSharedPointer m_trackSource; - - static const QString m_sRhythmBoxViewName; }; #endif // RHYTHMBOXFEATURE_H diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 96e6dcdbf43..3b3b697f88e 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -18,8 +18,6 @@ #include "library/treeitem.h" #include "util/sandbox.h" -const QString TraktorFeature::m_sTraktorViewName = "TRAKTOR_VIEW"; - TraktorTrackModel::TraktorTrackModel(QObject* parent, TrackCollection* pTrackCollection, QSharedPointer trackSource) @@ -128,10 +126,6 @@ QIcon TraktorFeature::getIcon() { return QIcon(":/images/library/ic_library_traktor.png"); } -QString TraktorFeature::getFeatureName() { - return m_sTraktorViewName; -} - bool TraktorFeature::isSupported() { return (QFile::exists(getTraktorMusicDatabase())); } diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index 6c7b26a89b1..d210ae335eb 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -46,7 +46,6 @@ class TraktorFeature : public BaseExternalLibraryFeature { QVariant title(); QIcon getIcon(); - QString getFeatureName() override; static bool isSupported(); TreeItemModel* getChildModel(); @@ -82,7 +81,6 @@ class TraktorFeature : public BaseExternalLibraryFeature { QFutureWatcher m_future_watcher; QFuture m_future; QString m_title; - static const QString m_sTraktorViewName; QSharedPointer m_trackSource; }; From 5183a2e72575b39bfe7a4a8f93469217f0252e73 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 7 Jul 2016 14:36:40 +0200 Subject: [PATCH 245/552] Fixed wrong focus connection --- src/library/librarypanemanager.cpp | 6 +++++- src/library/librarypanemanager.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 273305b4ccf..34c59a93570 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -26,7 +26,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, m_pPaneWidget = pLibraryWidget; connect(m_pPaneWidget, SIGNAL(focused()), - this, SIGNAL(focused())); + this, SLOT(slotPaneFocused())); connect(m_pPaneWidget, SIGNAL(collapsed()), this, SLOT(slotPaneCollapsed())); connect(m_pPaneWidget, SIGNAL(uncollapsed()), @@ -134,6 +134,10 @@ void LibraryPaneManager::slotPaneUncollapsed() { m_pLibrary->paneUncollapsed(m_paneId); } +void LibraryPaneManager::slotPaneFocused() { + m_pLibrary->slotPaneFocused(this); +} + bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (m_pPaneWidget.isNull()) { return false; diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 28bfb8ae9dc..f5a6d412ddf 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -60,6 +60,7 @@ class LibraryPaneManager : public QObject { void slotPaneCollapsed(); void slotPaneUncollapsed(); + void slotPaneFocused(); protected: From 0f87c11f95f215900aedb6d837c4c75fbdc01677 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 7 Jul 2016 09:37:07 +0200 Subject: [PATCH 246/552] Created Maintenance Feature --- build/depends.py | 1 + res/images/library/ic_library_maintenance.png | Bin 0 -> 1630 bytes res/mixxx.qrc | 1 + src/library/maintenancefeature.cpp | 24 ++++++++++++++++++ src/library/maintenancefeature.h | 23 +++++++++++++++++ 5 files changed, 49 insertions(+) create mode 100644 res/images/library/ic_library_maintenance.png create mode 100644 src/library/maintenancefeature.cpp create mode 100644 src/library/maintenancefeature.h diff --git a/build/depends.py b/build/depends.py index 4c88c68b359..141dc809d3f 100644 --- a/build/depends.py +++ b/build/depends.py @@ -879,6 +879,7 @@ def sources(self, build): "library/dlgmissing.cpp", "library/dlgtagfetcher.cpp", "library/dlgtrackinfo.cpp", + "library/maintenancefeature.cpp", "library/browse/browsetablemodel.cpp", "library/browse/browsethread.cpp", diff --git a/res/images/library/ic_library_maintenance.png b/res/images/library/ic_library_maintenance.png new file mode 100644 index 0000000000000000000000000000000000000000..a68e4e6ff26ea7add40ddc432a3d155d247caf4f GIT binary patch literal 1630 zcmV-k2BG9~Q}`_`v`G1?x#f zK~!ko&6;b7RaF$nf9E*O_?n%jQlfG*M=Zh-?PU*pSWsvZsR<^Mryzu6jEtviALiCLzHS;TIN{eadI4;ncIiEj%`l&p1aTSUg-~qnS1Yk zthLwP>%Z38$HNg}kV9!>fA-|xywc`BzsLIa0d@clz#d>5&hQ16tK9&@SA}bM47INDo{l5e!y+OlR%?1dmC7&v^i8_jC!C2 zxF}(&79ddCw4_y_Ch12@_+G%Z!1MCg#yntG801y~Z9tDKOr2Ormk}PI78pPV)HrOP z{=fsk5}kIrt83 zj)>=|CK`ch(YBStUoi!K0lulS0t0{`406}mXD`XQIBg*@=dm!zeMj{%9#|Fzxuw8* zrA@2IFbEh0oC9oC+MLY71NQ-Ma&`~`YsBiEz*WF4K!4zIV1?4ACps%$ISvSe+(2L{ zaDPfcjshL>_X2ULb!VvDpTK0L&Gtw}&w;?E11n?&%Hbfe5!f#W|F}4T5#q%zlmmN3 zR=+QZaPm;%fc63e@8XTe>-YNbt&CxiO3 zG6RHAI)SOcT$wBhUjeU5Ow^SS{KY>H1m*zqfiWqS*a?hN+T=ZnaRM2rPFS(aQYZtTY$O0|EILD6BBp(3_ls5aaFlg+YO$A;NOSs}r;6pzQ zawAg+ADx?Bz>8Uhk29{)W}R%qV~*XI0bc@nAGjfdC(ufpO<9F6ri3_wCWmedfW=Ci zHl+e5L>*Pq#)*sExslEKnexhg=IQj3e1v8eO`&Mq z4JhCwg|faErIdZ8kkpt`2~Vu>2C&l3jgyoS7QGR;R}%Xqye}EpUdh#m0BuT}1E zlGx9XnoCw}2EG8cP`FMyqO@tZgsumMOZqxdlJe0G+vMSd%aea8TfEAe3<*xL8qp3Z zXdSS^gJDwOYP5JJsS2?hm=oRFl-iax)(`E#6BKS>;;yUxo>Eu=Y%iC( z`mr0vZIU#Hvgek|9-S`yu=^}Voj<#{Xs<{yw^rEjZ{SBOf%atoE)uq`Httc{taLVE znR{N_^_?$XVP=&T&=hVz|43?7ESxS^ggPV&RC_zkc5&;z>u9ke)LtQ$YNEH0Rw8QB zjA&V@TM{1^v;pfVyjtK(t}y|4Fd^^g5U24;MHO&#e>T&2aK zv#*k>p+Ie!Hm$(jN}FQ&^{Ft(eM+IMzDT~?2|Oc~YInVE^)o8aD$(fLgfh&>b{Vip z7=4UFMS3oU_btranslations/mixxx_uz.qm translations/mixxx_zh_CN.qm translations/mixxx_zh_TW.qm + images/library/ic_library_maintenance.png diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp new file mode 100644 index 00000000000..8d6f5dddbaf --- /dev/null +++ b/src/library/maintenancefeature.cpp @@ -0,0 +1,24 @@ +#include + +#include "maintenancefeature.h" + +MaintenanceFeature::MaintenanceFeature(UserSettingsPointer pConfig, Library* pLibrary, + TrackCollection* pTrackCollection, + QObject* parent) + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), + kMaintenanceTitle(tr("Library Maintenance")) { + +} + +QVariant MaintenanceFeature::title() { + return kMaintenanceTitle; +} + +QIcon MaintenanceFeature::getIcon() { + return QIcon(":/images/library/ic_library_maintenance.png"); +} + +void MaintenanceFeature::activate() { + switchToFeature(); +} + diff --git a/src/library/maintenancefeature.h b/src/library/maintenancefeature.h new file mode 100644 index 00000000000..73091946c87 --- /dev/null +++ b/src/library/maintenancefeature.h @@ -0,0 +1,23 @@ +#ifndef MAINTENANCEFEATURE_H +#define MAINTENANCEFEATURE_H +#include "library/libraryfeature.h" + +class MaintenanceFeature : public LibraryFeature +{ + public: + MaintenanceFeature(UserSettingsPointer pConfig, + Library* pLibrary, TrackCollection* pTrackCollection, + QObject* parent); + + QVariant title(); + QIcon getIcon(); + + public slots: + void activate(); + + private: + + QString kMaintenanceTitle; +}; + +#endif // MAINTENANCEFEATURE_H From ed1952fcf694b00efa849aceabd980751e7e1591 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 7 Jul 2016 14:34:21 +0200 Subject: [PATCH 247/552] Added new breadcrumb mode --- src/library/library.cpp | 48 +++++++++++++++++++----------- src/library/library.h | 1 + src/library/librarypanemanager.cpp | 7 +++++ src/library/librarypanemanager.h | 1 + src/widget/wlibrarybreadcrumb.cpp | 4 +++ src/widget/wlibrarybreadcrumb.h | 1 + 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 625102aa005..92fbfe02f32 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -7,30 +7,32 @@ #include #include -#include "mixer/playermanager.h" -#include "library/library.h" -#include "library/library_preferences.h" +#include "library/autodj/autodjfeature.h" +#include "library/banshee/bansheefeature.h" +#include "library/browse/browsefeature.h" +#include "library/cratefeature.h" +#include "library/historyfeature.h" +#include "library/itunes/itunesfeature.h" +#include "library/librarycontrol.h" #include "library/libraryfeature.h" -#include "library/librarytablemodel.h" +#include "library/library.h" #include "library/librarypanemanager.h" +#include "library/library_preferences.h" #include "library/librarysidebarexpandedmanager.h" +#include "library/librarytablemodel.h" +#include "library/maintenancefeature.h" +#include "library/mixxxlibraryfeature.h" +#include "library/playlistfeature.h" +#include "library/recording/recordingfeature.h" +#include "library/rhythmbox/rhythmboxfeature.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" -#include "library/browse/browsefeature.h" -#include "library/cratefeature.h" -#include "library/rhythmbox/rhythmboxfeature.h" -#include "library/banshee/bansheefeature.h" -#include "library/recording/recordingfeature.h" -#include "library/itunes/itunesfeature.h" -#include "library/mixxxlibraryfeature.h" -#include "library/autodj/autodjfeature.h" -#include "library/playlistfeature.h" #include "library/traktor/traktorfeature.h" -#include "library/librarycontrol.h" -#include "library/historyfeature.h" -#include "util/sandbox.h" +#include "mixer/playermanager.h" #include "util/assert.h" +#include "util/sandbox.h" + #include "widget/wlibrarysidebar.h" #include "widget/wbuttonbar.h" @@ -210,6 +212,10 @@ void Library::showBreadCrumb(TreeItem *pTree) { m_panes[m_focusedPane]->showBreadCrumb(pTree); } +void Library::showBreadCrumb(const QString &text) { + m_panes[m_focusedPane]->showBreadCrumb(text); +} + void Library::slotLoadTrack(TrackPointer pTrack) { emit(loadTrack(pTrack)); } @@ -478,10 +484,13 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(m_pMixxxLibraryFeature); addFeature(new AutoDJFeature(pConfig, this, this, pPlayerManager, m_pTrackCollection)); + m_pPlaylistFeature = new PlaylistFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pPlaylistFeature); + m_pCrateFeature = new CrateFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pCrateFeature); + BrowseFeature* browseFeature = new BrowseFeature( pConfig, this, this, m_pTrackCollection, m_pRecordingManager); connect(browseFeature, SIGNAL(scanLibrary()), @@ -490,16 +499,19 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface browseFeature, SLOT(slotLibraryScanStarted())); connect(&m_scanner, SIGNAL(scanFinished()), browseFeature, SLOT(slotLibraryScanFinished())); - addFeature(browseFeature); + addFeature(new RecordingFeature(pConfig, this, this, m_pTrackCollection, m_pRecordingManager)); + addFeature(new HistoryFeature(pConfig, this, this, m_pTrackCollection)); + m_pAnalysisFeature = new AnalysisFeature(pConfig, this, m_pTrackCollection, this); connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), m_pAnalysisFeature, SLOT(analyzeTracks(QList))); connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), m_pAnalysisFeature, SLOT(analyzeTracks(QList))); addFeature(m_pAnalysisFeature); + //iTunes and Rhythmbox should be last until we no longer have an obnoxious //messagebox popup when you select them. (This forces you to reach for your //mouse or keyboard if you're using MIDI control and you scroll through them...) @@ -522,6 +534,8 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { addFeature(new TraktorFeature(pConfig, this, this, m_pTrackCollection)); } + + addFeature(new MaintenanceFeature(pConfig, this, this, m_pTrackCollection)); } void Library::setFocusedPane() { diff --git a/src/library/library.h b/src/library/library.h index 092eb42d676..1fd6174b7b2 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -95,6 +95,7 @@ class Library : public QObject { void switchToFeature(LibraryFeature* pFeature); void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QString& text); void restoreSearch(const QString& text); public slots: diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 34c59a93570..bdc759649ac 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -126,6 +126,13 @@ void LibraryPaneManager::showBreadCrumb(TreeItem *pTree) { m_pBreadCrumb->showBreadCrumb(pTree); } +void LibraryPaneManager::showBreadCrumb(const QString &text) { + DEBUG_ASSERT_AND_HANDLE(!m_pBreadCrumb.isNull()) { + return; + } + m_pBreadCrumb->showBreadCrumb(text); +} + void LibraryPaneManager::slotPaneCollapsed() { m_pLibrary->paneCollapsed(m_paneId); } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index f5a6d412ddf..10e36f83fe5 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -45,6 +45,7 @@ class LibraryPaneManager : public QObject { void restoreSearch(const QString& text); void switchToFeature(LibraryFeature* pFeature); void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QString& text); inline int getPaneId() { return m_paneId; diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index d76d334b3d0..084abfe34f4 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -48,6 +48,10 @@ void WLibraryBreadCrumb::showBreadCrumb(TreeItem *pTree) { setText(getPathString(pTree)); } +void WLibraryBreadCrumb::showBreadCrumb(const QString &text) { + setText(text); +} + void WLibraryBreadCrumb::resizeEvent(QResizeEvent *pEvent) { QLabel::resizeEvent(pEvent); setText(m_longText); diff --git a/src/widget/wlibrarybreadcrumb.h b/src/widget/wlibrarybreadcrumb.h index f22fb801e3e..03c7966c588 100644 --- a/src/widget/wlibrarybreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -19,6 +19,7 @@ class WLibraryBreadCrumb : public QLabel { public slots: void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QString& text); protected: From 1e75e5b3b0673d70094fb5f7f6bab80325dc380a Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 7 Jul 2016 14:34:36 +0200 Subject: [PATCH 248/552] Finished Maintenance Feature --- src/library/libraryfeature.cpp | 14 ++- src/library/libraryfeature.h | 59 +++++----- src/library/maintenancefeature.cpp | 171 +++++++++++++++++++++++++++- src/library/maintenancefeature.h | 56 ++++++++- src/library/mixxxlibraryfeature.cpp | 165 --------------------------- src/library/mixxxlibraryfeature.h | 25 ---- src/widget/wtracktableview.cpp | 2 + 7 files changed, 264 insertions(+), 228 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 202d5dda260..b10342ce0d0 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -76,7 +76,7 @@ void LibraryFeature::setFocusedPane(int paneId) { WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = - new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection); + new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, true); pTrackTableView->installEventFilter(pKeyboard); @@ -129,6 +129,18 @@ void LibraryFeature::switchToFeature() { m_pLibrary->switchToFeature(this); } +void LibraryFeature::restoreSearch(const QString& search) { + m_pLibrary->restoreSearch(search); +} + +void LibraryFeature::showBreadCrumb(TreeItem *pTree) { + m_pLibrary->showBreadCrumb(pTree); +} + +void LibraryFeature::showBreadCrumb(const QString &text) { + m_pLibrary->showBreadCrumb(text); +} + WTrackTableView *LibraryFeature::getFocusedTable() { auto it = m_trackTables.find(m_featureFocus); if (it == m_trackTables.end() || it->isNull()) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index fd8307d9ddd..165efa4f4c2 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -73,34 +73,6 @@ class LibraryFeature : public QObject { virtual void setFocusedPane(int paneId); - protected: - inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } - inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } - - // Creates a table widget with no model - WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, - int paneId); - - // Creates a WLibrarySidebar widget with the getChildModel() function as - // model - WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); - - // Override this function to create a custom inner widget for the sidebar, - // the default widget is a WLibrarySidebar widget - virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); - - void showTrackModel(QAbstractItemModel *model); - void switchToFeature(); - - WTrackTableView* getFocusedTable(); - - UserSettingsPointer m_pConfig; - Library* m_pLibrary; - TrackCollection* m_pTrackCollection; - - int m_featureFocus; - int m_focusedPane; - public slots: // called when you single click on the root item virtual void activate() = 0; @@ -133,6 +105,37 @@ class LibraryFeature : public QObject { // emit this signal to enable/disable the cover art widget void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); + +protected: + inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } + inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + + // Creates a table widget with no model + virtual WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, + int paneId); + + // Creates a WLibrarySidebar widget with the getChildModel() function as + // model + WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); + + // Override this function to create a custom inner widget for the sidebar, + // the default widget is a WLibrarySidebar widget + virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); + + void showTrackModel(QAbstractItemModel *model); + void switchToFeature(); + void restoreSearch(const QString& search); + void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QString& text); + + WTrackTableView* getFocusedTable(); + + UserSettingsPointer m_pConfig; + Library* m_pLibrary; + TrackCollection* m_pTrackCollection; + + int m_featureFocus; + int m_focusedPane; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 8d6f5dddbaf..86ae8ac4693 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -1,12 +1,25 @@ #include +#include -#include "maintenancefeature.h" +#include "library/dlghidden.h" +#include "library/dlgmissing.h" +#include "library/hiddentablemodel.h" +#include "library/maintenancefeature.h" +#include "library/missingtablemodel.h" -MaintenanceFeature::MaintenanceFeature(UserSettingsPointer pConfig, Library* pLibrary, - TrackCollection* pTrackCollection, - QObject* parent) +#include "widget/wtracktableview.h" + +MaintenanceFeature::MaintenanceFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), - kMaintenanceTitle(tr("Library Maintenance")) { + kMaintenanceTitle(tr("Maintenance")), + kHiddenTitle(tr("Hidden Tracks")), + kMissingTitle(tr("Missing Tracks")), + m_pHiddenView(nullptr), + m_pMissingView(nullptr), + m_pTab(nullptr) { } @@ -18,7 +31,155 @@ QIcon MaintenanceFeature::getIcon() { return QIcon(":/images/library/ic_library_maintenance.png"); } +TreeItemModel* MaintenanceFeature::getChildModel() { + return nullptr; +} + void MaintenanceFeature::activate() { + DEBUG_ASSERT_AND_HANDLE(!m_pTab.isNull()) { + return; + } + + slotTabIndexChanged(m_pTab->currentIndex()); + + switchToFeature(); + emit(enableCoverArtDisplay(true)); +} + +void MaintenanceFeature::selectionChanged(const QItemSelection&, + const QItemSelection&) { + WTrackTableView* pTable = getFocusedTable(); + if (pTable == nullptr) { + return; + } + + auto it = m_idPaneCurrent.find(m_featureFocus); + if (it == m_idPaneCurrent.end()) { + return; + } + + const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); + if (*it == Pane::Hidden) { + m_pHiddenView->setSelectedIndexes(selection); + } else if (*it == Pane::Missing) { + m_pMissingView->setSelectedIndexes(selection); + } +} + +void MaintenanceFeature::selectAll() { + QPointer pTable = getFocusedTable(); + if (!pTable.isNull()) { + pTable->selectAll(); + } +} + +QWidget* MaintenanceFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { + // The inner widget is a tab with the hidden and the missing controls + m_pTab = new QTabWidget(nullptr); + m_pTab->installEventFilter(pKeyboard); + connect(m_pTab, SIGNAL(currentChanged(int)), + this, SLOT(slotTabIndexChanged(int))); + + m_pHiddenView = new DlgHidden(m_pTab); + m_pHiddenView->setTableModel(getHiddenTableModel()); + m_pHiddenView->installEventFilter(pKeyboard); + connect(m_pHiddenView, SIGNAL(unhide()), this, SLOT(slotUnhideHidden())); + connect(m_pHiddenView, SIGNAL(purge()), this, SLOT(slotPurge())); + connect(m_pHiddenView, SIGNAL(selectAll()), this, SLOT(selectAll())); + + m_pMissingView = new DlgMissing(m_pTab); + m_pMissingView->setTableModel(getMissingTableModel()); + m_pMissingView->installEventFilter(pKeyboard); + connect(m_pMissingView, SIGNAL(purge()), this, SLOT(slotPurge())); + connect(m_pMissingView, SIGNAL(selectAll()), this, SLOT(selectAll())); + + m_idExpandedHidden = m_pTab->addTab(m_pHiddenView, kHiddenTitle); + m_idExpandedMissing = m_pTab->addTab(m_pMissingView, kMissingTitle); + + return m_pTab; +} + +QWidget* MaintenanceFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, + int paneId) { + WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); + + return pTable; +} + +void MaintenanceFeature::slotTabIndexChanged(int index) { + QPointer pTable = getFocusedTable(); + + DEBUG_ASSERT_AND_HANDLE(!pTable.isNull()) { + return; + } + pTable->setSortingEnabled(false); + const QString* title; + + if (index == m_idExpandedHidden) { + DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull()) { + return; + } + m_idPaneCurrent[m_featureFocus] = Pane::Hidden; + pTable->loadTrackModel(getHiddenTableModel()); + + title = &kHiddenTitle; + m_pHiddenView->onShow(); + } else if (index == m_idExpandedMissing) { + DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull()) { + return; + } + + m_idPaneCurrent[m_featureFocus] = Pane::Missing; + pTable->loadTrackModel(getMissingTableModel()); + + title = &kMissingTitle; + m_pMissingView->onShow(); + } else { + return; + } + + // This is the only way to get the selection signal changing the track + // models, every time the model changes the selection model changes too + // so we need to reconnect + connect(pTable->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + this, + SLOT(selectionChanged(const QItemSelection &, const QItemSelection &))); + switchToFeature(); + restoreSearch(""); + showBreadCrumb(kMaintenanceTitle % " > " % (*title)); + emit(enableCoverArtDisplay(true)); +} + +void MaintenanceFeature::slotUnhideHidden() { + QPointer pTable = getFocusedTable(); + if (pTable.isNull()) { + return; + } + + pTable->slotUnhide(); +} + +void MaintenanceFeature::slotPurge() { + QPointer pTable = getFocusedTable(); + if (pTable.isNull()) { + return; + } + pTable->slotPurge(); +} + +HiddenTableModel* MaintenanceFeature::getHiddenTableModel() { + if (m_pHiddenTableModel.isNull()) { + m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); + } + return m_pHiddenTableModel; +} + +MissingTableModel* MaintenanceFeature::getMissingTableModel() { + if (m_pMissingTableModel.isNull()) { + m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); + } + return m_pMissingTableModel; } diff --git a/src/library/maintenancefeature.h b/src/library/maintenancefeature.h index 73091946c87..f54158e01a5 100644 --- a/src/library/maintenancefeature.h +++ b/src/library/maintenancefeature.h @@ -1,23 +1,71 @@ #ifndef MAINTENANCEFEATURE_H #define MAINTENANCEFEATURE_H + +#include +#include +#include + #include "library/libraryfeature.h" +class DlgHidden; +class DlgMissing; +class HiddenTableModel; +class MissingTableModel; + class MaintenanceFeature : public LibraryFeature { + Q_OBJECT public: MaintenanceFeature(UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection* pTrackCollection, - QObject* parent); + Library* pLibrary, QObject* parent, + TrackCollection* pTrackCollection); QVariant title(); QIcon getIcon(); - + TreeItemModel* getChildModel(); + public slots: void activate(); + void selectionChanged(const QItemSelection&, const QItemSelection&); + void selectAll(); + + protected: + + QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); + QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId); private: + + enum Pane { + Hidden = 1, + Missing = 2 + }; + + const QString kMaintenanceTitle; + const QString kHiddenTitle; + const QString kMissingTitle; + + private slots: - QString kMaintenanceTitle; + void slotTabIndexChanged(int index); + void slotUnhideHidden(); + void slotPurge(); + + private: + + HiddenTableModel* getHiddenTableModel(); + MissingTableModel* getMissingTableModel(); + + QPointer m_pHiddenView; + QPointer m_pMissingView; + QPointer m_pTab; + QHash m_idPaneCurrent; + + int m_idExpandedHidden; + int m_idExpandedMissing; + + QPointer m_pHiddenTableModel; + QPointer m_pMissingTableModel; }; #endif // MAINTENANCEFEATURE_H diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index f485bcafad1..30059548020 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -9,8 +9,6 @@ #include "library/library.h" #include "library/basetrackcache.h" #include "library/librarytablemodel.h" -#include "library/missingtablemodel.h" -#include "library/hiddentablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" #include "library/dlghidden.h" @@ -28,18 +26,6 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), kLibraryTitle(tr("Library")), - kHiddenTitle(tr("Hidden Tracks")), - kMissingTitle(tr("Missing Tracks")), - m_pHiddenView(nullptr), - m_pMissingView(nullptr), - m_idExpandedHidden(-1), - m_idExpandedMissing(-1), - m_idExpandedControls(-1), - m_idExpandedTree(-1), - m_pHiddenTableModel(nullptr), - m_pMissingTableModel(nullptr), - m_pExpandedStack(nullptr), - m_pSidebarTab(nullptr), m_trackDao(pTrackCollection->getTrackDAO()), m_pTrackCollection(pTrackCollection) { QStringList columns; @@ -124,13 +110,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TreeItem* pLibraryChildItem = new TreeItem(kLibraryTitle, kLibraryTitle, this, pRootItem); pLibraryChildItem->setIcon(getIcon()); - TreeItem* pmissingChildItem = new TreeItem(kMissingTitle, kMissingTitle, - this, pRootItem); - TreeItem* phiddenChildItem = new TreeItem(kHiddenTitle, kHiddenTitle, - this, pRootItem); pRootItem->appendChild(pLibraryChildItem); - pRootItem->appendChild(pmissingChildItem); - pRootItem->appendChild(phiddenChildItem); m_childModel.setRootItem(pRootItem); } @@ -139,51 +119,6 @@ MixxxLibraryFeature::~MixxxLibraryFeature() { delete m_pLibraryTableModel; } -QWidget *MixxxLibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, - int paneId) { - WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); - - connect(this, SIGNAL(unhideHidden()), pTable, SLOT(slotUnhide())); - connect(this, SIGNAL(purgeHidden()), pTable, SLOT(slotPurge())); - connect(this, SIGNAL(purgeMissing()), pTable, SLOT(slotPurge())); - - return pTable; -} - -QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { - m_pSidebarTab = new QTabWidget(nullptr); - - // Create tree - WLibrarySidebar* pSidebar = createLibrarySidebarWidget(pKeyboard); - m_idExpandedTree = m_pSidebarTab->addTab(pSidebar, tr("Tree")); - - // Create tabs - m_pExpandedStack = new QStackedWidget(m_pSidebarTab); - - // Create Hidden View controls - m_pHiddenView = new DlgHidden(pSidebar); - m_pHiddenView->setTableModel(getHiddenTableModel()); - m_pHiddenView->installEventFilter(pKeyboard); - - connect(m_pHiddenView, SIGNAL(unhide()), this, SIGNAL(unhideHidden())); - connect(m_pHiddenView, SIGNAL(purge()), this, SIGNAL(purgeHidden())); - connect(m_pHiddenView, SIGNAL(selectAll()), this, SLOT(selectAll())); - m_idExpandedHidden = m_pExpandedStack->addWidget(m_pHiddenView); - - // Create Missing View controls - m_pMissingView = new DlgMissing(pSidebar); - m_pMissingView->setTableModel(getMissingTableModel()); - m_pMissingView->installEventFilter(pKeyboard); - - connect(m_pMissingView, SIGNAL(purge()), this, SIGNAL(purgeMissing())); - connect(m_pMissingView, SIGNAL(selectAll()), this, SLOT(selectAll())); - m_idExpandedMissing = m_pExpandedStack->addWidget(m_pMissingView); - - m_idExpandedControls = m_pSidebarTab->addTab(m_pExpandedStack, tr("Controls")); - - return m_pSidebarTab; -} - QVariant MixxxLibraryFeature::title() { return kLibraryTitle; } @@ -200,37 +135,6 @@ void MixxxLibraryFeature::refreshLibraryModels() { if (m_pLibraryTableModel) { m_pLibraryTableModel->select(); } - if (!m_pMissingView.isNull()) { - m_pMissingView->onShow(); - } - if (!m_pHiddenView.isNull()) { - m_pHiddenView->onShow(); - } -} - -void MixxxLibraryFeature::selectionChanged(const QItemSelection&, - const QItemSelection&) { - WTrackTableView* pTable = getFocusedTable(); - if (pTable == nullptr) { - return; - } - - auto it = m_idPaneCurrent.find(m_featureFocus); - if (it == m_idPaneCurrent.end()) { - return; - } - - const QModelIndexList& selection = pTable->selectionModel()->selectedIndexes(); - switch (*it) { - case Panes::Hidden: - m_pHiddenView->setSelectedIndexes(selection); - break; - case Panes::Missing: - m_pMissingView->setSelectedIndexes(selection); - break; - default: - break; - } } void MixxxLibraryFeature::selectAll() { @@ -243,15 +147,6 @@ void MixxxLibraryFeature::selectAll() { void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; - - m_idPaneCurrent[m_featureFocus] = Panes::MixxxLibrary; - QPointer pTable = getFocusedTable(); - if (pTable.isNull()) { - return; - } - - m_pSidebarTab->setTabEnabled(m_idExpandedControls, false); - pTable->setSortingEnabled(true); showTrackModel(m_pLibraryTableModel); m_pLibrary->restoreSearch(""); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); @@ -261,57 +156,11 @@ void MixxxLibraryFeature::activate() { void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); - TreeItem* pTree = static_cast (index.internalPointer()); - QPointer pTable = getFocusedTable(); if (itemName == kLibraryTitle) { activate(); return; } - - DEBUG_ASSERT_AND_HANDLE(!m_pExpandedStack.isNull() && !pTable.isNull()) { - return; - } - pTable->setSortingEnabled(false); - - if (itemName == kHiddenTitle) { - DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull()) { - return; - } - - m_idPaneCurrent[m_featureFocus] = Panes::Hidden; - pTable->loadTrackModel(getHiddenTableModel()); - - m_pHiddenView->onShow(); - m_pExpandedStack->setCurrentIndex(m_idExpandedHidden); - - } else if (itemName == kMissingTitle) { - DEBUG_ASSERT_AND_HANDLE(!m_pMissingView.isNull()) { - return; - } - - m_idPaneCurrent[m_featureFocus] = Panes::Missing; - pTable->loadTrackModel(getMissingTableModel()); - - m_pMissingView->onShow(); - m_pExpandedStack->setCurrentIndex(m_idExpandedMissing); - } else { - return; - } - - // This is the only way to get the selection signal changing the track - // models, every time the model changes the selection model changes too - // so we need to reconnect - connect(pTable->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - - m_pSidebarTab->setTabEnabled(m_idExpandedControls, true); - switchToFeature(); - m_pLibrary->restoreSearch(""); - m_pLibrary->showBreadCrumb(pTree); - emit(enableCoverArtDisplay(true)); } bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { @@ -330,17 +179,3 @@ bool MixxxLibraryFeature::dragMoveAccept(QUrl url) { return SoundSourceProxy::isUrlSupported(url) || Parser::isPlaylistFilenameSupported(url.toLocalFile()); } - -HiddenTableModel* MixxxLibraryFeature::getHiddenTableModel() { - if (m_pHiddenTableModel.isNull()) { - m_pHiddenTableModel = new HiddenTableModel(this, m_pTrackCollection); - } - return m_pHiddenTableModel; -} - -MissingTableModel* MixxxLibraryFeature::getMissingTableModel() { - if (m_pMissingTableModel.isNull()) { - m_pMissingTableModel = new MissingTableModel(this, m_pTrackCollection); - } - return m_pMissingTableModel; -} diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 460e8b5a0b6..04d70841163 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -46,17 +46,12 @@ class MixxxLibraryFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); - - QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId) override; - QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; public slots: void activate(); void activateChild(const QModelIndex& index); void refreshLibraryModels(); - void selectionChanged(const QItemSelection&, const QItemSelection&); - void selectAll(); @@ -72,27 +67,7 @@ class MixxxLibraryFeature : public LibraryFeature { Missing = 3 }; - HiddenTableModel* getHiddenTableModel(); - MissingTableModel* getMissingTableModel(); - const QString kLibraryTitle; - const QString kHiddenTitle; - const QString kMissingTitle; - QPointer m_pHiddenView; - QPointer m_pMissingView; - QHash m_idPaneCurrent; - - // SidebarExpanded pane's ids - int m_idExpandedHidden; - int m_idExpandedMissing; - int m_idExpandedControls; - int m_idExpandedTree; - - QPointer m_pHiddenTableModel; - QPointer m_pMissingTableModel; - - QPointer m_pExpandedStack; - QPointer m_pSidebarTab; QSharedPointer m_pBaseTrackCache; LibraryTableModel* m_pLibraryTableModel; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 5d5e0f965d6..46eeda7228e 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -564,6 +564,8 @@ void WTrackTableView::slotHide() { } void WTrackTableView::slotUnhide() { + qDebug() << "WTrackTableView::slotUnhide" << selectionModel(); + QModelIndexList indices = selectionModel()->selectedRows(); if (indices.size() > 0) { From e3ae730153f474463475e2aa12b21aa23df28dec Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 8 Jul 2016 12:07:00 +0200 Subject: [PATCH 249/552] Create TreeItemModel --- build/depends.py | 1 + src/library/librarytreemodel.cpp | 67 +++++++++++++++++++++++++++++ src/library/librarytreemodel.h | 26 +++++++++++ src/library/mixxxlibraryfeature.cpp | 27 ++++-------- src/library/mixxxlibraryfeature.h | 6 +-- src/library/treeitemmodel.h | 9 ++-- 6 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 src/library/librarytreemodel.cpp create mode 100644 src/library/librarytreemodel.h diff --git a/build/depends.py b/build/depends.py index 141dc809d3f..2325289c4ac 100644 --- a/build/depends.py +++ b/build/depends.py @@ -943,6 +943,7 @@ def sources(self, build): "library/treeitemmodel.cpp", "library/treeitem.cpp", + "library/librarytreemodel.cpp", "library/parser.cpp", "library/parserpls.cpp", diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp new file mode 100644 index 00000000000..edd61d3d457 --- /dev/null +++ b/src/library/librarytreemodel.cpp @@ -0,0 +1,67 @@ +#include + +#include "library/librarytreemodel.h" +#include "library/mixxxlibraryfeature.h" +#include "library/queryutil.h" +#include "library/trackcollection.h" +#include "library/treeitem.h" + +LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, + TrackCollection* pTrackCollection, + QObject* parent) + : TreeItemModel(parent), + m_pFeature(pFeature), + m_pTrackCollection(pTrackCollection) { + TreeItem* pRootItem = new TreeItem(); + pRootItem->setLibraryFeature(pFeature); + QString title = pFeature->title().toString(); + + TreeItem* pLibraryChildItem = new TreeItem(title, title, pFeature, pRootItem); + + pRootItem->appendChild(pLibraryChildItem); + setRootItem(pRootItem); + + // By default sort by Artist -> Album + // TODO(jmigual) store the sort order in the configuration + m_sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; + createTracksTree(); +} + +void LibraryTreeModel::createTracksTree() { + + QStringList columns; + for (const QString& col : m_sortOrder) { + columns << "library." + col; + } + + QString queryStr = "SELECT DISTINCT %1 " + "FROM library " + "WHERE library.%2 != 1 " + "ORDER BY %1"; + queryStr = queryStr.arg(columns.join(","), LIBRARYTABLE_MIXXXDELETED); + + + QSqlQuery query(m_pTrackCollection->getDatabase()); + query.prepare(queryStr); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + + qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); + + TreeItem* parent = m_pRootItem; + TreeItem* lastInserted = nullptr; + + int size = columns.size(); + QVector lastUsed(size); + + int index = 0; + +} + +void LibraryTreeModel::createTreeRecursive(TreeItem* parent, + QVector& lastInserted, + int index, QSqlQuery& query) { + +} diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h new file mode 100644 index 00000000000..ea0c274f038 --- /dev/null +++ b/src/library/librarytreemodel.h @@ -0,0 +1,26 @@ +#ifndef LIBRARYTREEMODEL_H +#define LIBRARYTREEMODEL_H + +#include +#include + +#include "library/treeitemmodel.h" + +class MixxxLibraryFeature; +class TrackCollection; + +class LibraryTreeModel : public TreeItemModel { + public: + LibraryTreeModel(MixxxLibraryFeature* pFeature, TrackCollection *pTrackCollection, QObject* parent = nullptr); + + private: + void createTracksTree(); + void createTreeRecursive(TreeItem* parent, QVector& lastInserted, + int index, QSqlQuery& query); + + MixxxLibraryFeature* m_pFeature; + TrackCollection* m_pTrackCollection; + QStringList m_sortOrder; +}; + +#endif // LIBRARYTREEMODEL_H diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 30059548020..031b77b46a9 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -5,20 +5,19 @@ #include "library/mixxxlibraryfeature.h" -#include "library/parser.h" -#include "library/library.h" #include "library/basetrackcache.h" +#include "library/dlghidden.h" +#include "library/dlgmissing.h" +#include "library/library.h" #include "library/librarytablemodel.h" +#include "library/parser.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/dlghidden.h" -#include "library/dlgmissing.h" -#include "treeitem.h" #include "sources/soundsourceproxy.h" +#include "util/dnd.h" #include "widget/wlibrary.h" -#include "widget/wlibrarystack.h" #include "widget/wlibrarysidebar.h" -#include "util/dnd.h" +#include "widget/wlibrarystack.h" MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, @@ -26,8 +25,8 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), kLibraryTitle(tr("Library")), - m_trackDao(pTrackCollection->getTrackDAO()), - m_pTrackCollection(pTrackCollection) { + m_childModel(this, pTrackCollection), + m_trackDao(pTrackCollection->getTrackDAO()) { QStringList columns; columns << "library." + LIBRARYTABLE_ID << "library." + LIBRARYTABLE_PLAYED @@ -103,16 +102,6 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, // These rely on the 'default' track source being present. m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection, "mixxx.db.model.library"); - - TreeItem* pRootItem = new TreeItem(); - pRootItem->setLibraryFeature(this); - - TreeItem* pLibraryChildItem = new TreeItem(kLibraryTitle, kLibraryTitle, - this, pRootItem); - pLibraryChildItem->setIcon(getIcon()); - pRootItem->appendChild(pLibraryChildItem); - - m_childModel.setRootItem(pRootItem); } MixxxLibraryFeature::~MixxxLibraryFeature() { diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 04d70841163..2e5a2a2a3e3 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -16,8 +16,8 @@ #include #include "library/libraryfeature.h" +#include "library/librarytreemodel.h" #include "library/dao/trackdao.h" -#include "treeitemmodel.h" #include "preferences/usersettings.h" class DlgHidden; @@ -66,14 +66,12 @@ class MixxxLibraryFeature : public LibraryFeature { Hidden = 2, Missing = 3 }; - const QString kLibraryTitle; QSharedPointer m_pBaseTrackCache; LibraryTableModel* m_pLibraryTableModel; - TreeItemModel m_childModel; + LibraryTreeModel m_childModel; TrackDAO& m_trackDao; - TrackCollection* m_pTrackCollection; }; #endif /* MIXXXLIBRARYFEATURE_H */ diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index f67ba9e2014..eb997d0beaf 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -35,14 +35,15 @@ class TreeItemModel : public QAbstractItemModel { // Return the underlying TreeItem. // If the index is invalid, the root item is returned. TreeItem* getItem(const QModelIndex &index) const; - - void triggerRepaint(); bool dropAccept(const QModelIndex& index, QList urls, QObject* pSource); bool dragMoveAccept(const QModelIndex& index, QUrl url); + + public slots: + void triggerRepaint(); - private: - TreeItem *m_pRootItem; + protected: + TreeItem* m_pRootItem; }; #endif From 4ff5f27f73261cd771e65a485604034dd37b3717 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 8 Jul 2016 14:53:43 +0200 Subject: [PATCH 250/552] Tree created --- src/library/librarytreemodel.cpp | 48 ++++++++++++++++++++++++-------- src/library/librarytreemodel.h | 4 +-- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index edd61d3d457..084ca6eb7cb 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -16,7 +16,8 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, pRootItem->setLibraryFeature(pFeature); QString title = pFeature->title().toString(); - TreeItem* pLibraryChildItem = new TreeItem(title, title, pFeature, pRootItem); + TreeItem* pLibraryChildItem = new TreeItem(title, title, m_pFeature, pRootItem); + pLibraryChildItem->setIcon(m_pFeature->getIcon()); pRootItem->appendChild(pLibraryChildItem); setRootItem(pRootItem); @@ -50,18 +51,43 @@ void LibraryTreeModel::createTracksTree() { qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); - TreeItem* parent = m_pRootItem; - TreeItem* lastInserted = nullptr; - int size = columns.size(); - QVector lastUsed(size); + if (size <= 0) { + return; + } - int index = 0; + QVector lastUsed(size); + QVector parent(size + 1, nullptr); + parent[0] = m_pRootItem; -} - -void LibraryTreeModel::createTreeRecursive(TreeItem* parent, - QVector& lastInserted, - int index, QSqlQuery& query) { + while (query.next()) { + for (int i = 0; i < size; ++i) { + QString value = query.value(i).toString(); + if (value == "") { + value = tr("Unknown"); + } + if (!lastUsed[i].isNull() && value == lastUsed[i]) { + continue; + } + + if (i == 0) { + // If a new top level is added all the following levels must be + // reset + for (QString& s : lastUsed) { + s = QString(); + } + + // TODO(jmigual) Check if a header must be added + + } + lastUsed[i] = value; + + // We need to create a new item + TreeItem* pTree = new TreeItem(value, value, m_pFeature, parent[i]); + parent[i]->appendChild(pTree); + parent[i + 1] = pTree; + } + } + triggerRepaint(); } diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index ea0c274f038..2d28a800c6b 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -15,9 +15,7 @@ class LibraryTreeModel : public TreeItemModel { private: void createTracksTree(); - void createTreeRecursive(TreeItem* parent, QVector& lastInserted, - int index, QSqlQuery& query); - + MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; QStringList m_sortOrder; From 04fa1fbec001efe0d45c558ffe42cc9bfcf4874f Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 8 Jul 2016 19:44:22 +0200 Subject: [PATCH 251/552] Add new header --- src/library/librarytreemodel.cpp | 14 ++++- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/sidebarmodel.cpp | 2 +- src/library/treeitem.cpp | 84 ++++++++++++++++++++--------- src/library/treeitem.h | 22 ++++---- src/library/treeitemmodel.cpp | 65 +++++++++++++--------- src/library/treeitemmodel.h | 8 ++- src/widget/wlibrarysidebar.cpp | 39 ++++++++++++-- src/widget/wlibrarysidebar.h | 10 ++++ 9 files changed, 174 insertions(+), 72 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 084ca6eb7cb..96f46b8f435 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -57,13 +57,16 @@ void LibraryTreeModel::createTracksTree() { } QVector lastUsed(size); + QChar lastHeader; QVector parent(size + 1, nullptr); parent[0] = m_pRootItem; while (query.next()) { for (int i = 0; i < size; ++i) { QString value = query.value(i).toString(); - if (value == "") { + + bool uknown = (value == ""); + if (uknown) { value = tr("Unknown"); } if (!lastUsed[i].isNull() && value == lastUsed[i]) { @@ -77,7 +80,14 @@ void LibraryTreeModel::createTracksTree() { s = QString(); } - // TODO(jmigual) Check if a header must be added + // Check if a header must be added + if (!uknown && lastHeader != value.at(0)) { + lastHeader = value.at(0); + TreeItem* pTree = + new TreeItem(lastHeader, lastHeader, m_pFeature, parent[0]); + pTree->setDivider(true); + parent[0]->appendChild(pTree); + } } lastUsed[i] = value; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 031b77b46a9..96f1971c72a 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -144,7 +144,7 @@ void MixxxLibraryFeature::activate() { } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { - QString itemName = index.data(TreeItemModel::kDataPathRole).toString(); + QString itemName = index.data(TreeItemModel::RoleDataPath).toString(); if (itemName == kLibraryTitle) { activate(); diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp index a87aaa44c60..a5fe522e72f 100644 --- a/src/library/sidebarmodel.cpp +++ b/src/library/sidebarmodel.cpp @@ -197,7 +197,7 @@ QVariant SidebarModel::data(const QModelIndex& index, int role) const { } else { return tree_item->dataPath(); } - } else if (role == TreeItemModel::kDataPathRole) { + } else if (role == TreeItemModel::RoleDataPath) { // We use Qt::UserRole to ask for the datapath. return tree_item->dataPath(); } else if (role == Qt::FontRole) { diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index dc4575579e0..1f34061f8ff 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -29,28 +29,40 @@ * - cratefeature.cpp * - *feature.cpp */ -TreeItem::TreeItem(const QString &data, const QString &data_path, - LibraryFeature* feature, TreeItem* parent) { - m_data = data; - m_dataPath = data_path; - m_parentItem = parent; - m_pFeature = feature; - m_bold = false; +TreeItem::TreeItem(const QString& data, const QString& data_path, + LibraryFeature* pFeature, TreeItem* parent) + : m_data(data), + m_dataPath(data_path), + m_pFeature(pFeature), + m_bold(false), + m_divider(false), + m_pParent(parent) { } -TreeItem::TreeItem() { - m_data = "$root"; - m_dataPath = "$root"; - m_parentItem = nullptr; - m_pFeature = nullptr; - m_bold = false; +TreeItem::TreeItem(LibraryFeature* pFeature) + : m_data("$root"), + m_dataPath("$root"), + m_pFeature(pFeature), + m_bold(false), + m_divider(false), + m_pParent(nullptr) { + +} + +TreeItem::TreeItem() + : m_data("$root"), + m_dataPath("$root"), + m_pFeature(nullptr), + m_bold(false), + m_divider(false), + m_pParent(nullptr) { } TreeItem::~TreeItem() { qDeleteAll(m_childItems); } -void TreeItem::appendChild(TreeItem *item) { +void TreeItem::appendChild(TreeItem* item) { m_childItems.append(item); } @@ -58,7 +70,7 @@ void TreeItem::removeChild(int index) { m_childItems.removeAt(index); } -TreeItem *TreeItem::child(int row) { +TreeItem* TreeItem::child(int row) { return m_childItems.value(row); } @@ -82,13 +94,13 @@ bool TreeItem::isFolder() const { return (m_childItems.count() != 0); } -TreeItem *TreeItem::parent() { - return m_parentItem; +TreeItem* TreeItem::parent() { + return m_pParent; } int TreeItem::row() const { - if (m_parentItem) { - return m_parentItem->m_childItems.indexOf(const_cast(this)); + if (m_pParent) { + return m_pParent->m_childItems.indexOf(const_cast(this)); } return 0; @@ -98,13 +110,30 @@ LibraryFeature* TreeItem::getFeature() { return m_pFeature; } -void TreeItem::setLibraryFeature(LibraryFeature *pFeature) { +void TreeItem::setLibraryFeature(LibraryFeature* pFeature) { m_pFeature = pFeature; } -bool TreeItem::insertChildren(QList &data, int position, int count) { - if (position < 0 || position > m_childItems.size()) +void TreeItem::setBold(bool bold) { + m_bold = bold; +} + +bool TreeItem::isBold() const { + return m_bold; +} + +void TreeItem::setDivider(bool divider) { + m_divider = divider; +} + +bool TreeItem::isDivider() const { + return m_divider; +} + +bool TreeItem::insertChildren(QList& data, int position, int count) { + if (position < 0 || position > m_childItems.size()) { return false; + } for (int row = 0; row < count; ++row) { TreeItem* item = data.at(row); @@ -115,24 +144,27 @@ bool TreeItem::insertChildren(QList &data, int position, int count) { } bool TreeItem::removeChildren(int position, int count) { - if (position < 0 || position + count > m_childItems.size()) + if (position < 0 || position + count > m_childItems.size()) { return false; + } for (int row = 0; row < count; ++row) { //Remove from list to avoid invalid pointers TreeItem* item = m_childItems.takeAt(position); - if(item) delete item; + if (item) { + delete item; + } } return true; } -bool TreeItem::setData(const QVariant &data, const QVariant &data_path) { +bool TreeItem::setData(const QVariant& data, const QVariant& data_path) { m_data = data.toString(); m_dataPath = data_path.toString(); return true; } -QIcon TreeItem::getIcon() { +QIcon TreeItem::getIcon() const { return m_icon; } diff --git a/src/library/treeitem.h b/src/library/treeitem.h index 6b7be0594a6..5b4409cb8b3 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -16,8 +16,9 @@ class TreeItem { TreeItem(); //creates an invisible root item for the tree TreeItem(const QString &data, const QString &data_path, - LibraryFeature* feature, + LibraryFeature* pFeature, TreeItem* parent); + TreeItem(LibraryFeature* pFeature); ~TreeItem(); /** appends a child item to this object **/ void appendChild(TreeItem *child); @@ -47,30 +48,29 @@ class TreeItem { bool isPlaylist() const; /** returns true if we have an inner node **/ bool isFolder() const; - /* Returns the Library feature object to which an item belongs to */ + // Returns the Library feature object to which an item belongs to LibraryFeature* getFeature(); void setLibraryFeature(LibraryFeature* pFeature); - void setBold(bool bold) { - m_bold = bold; - } - bool isBold() const { - return m_bold; - } + void setBold(bool bold); + bool isBold() const; + void setDivider(bool divider); + bool isDivider() const; void setIcon(const QIcon& icon); - QIcon getIcon(); + QIcon getIcon() const; private: QList m_childItems; - QString m_dataPath; QString m_data; + QString m_dataPath; LibraryFeature* m_pFeature; bool m_bold; + bool m_divider; - TreeItem *m_parentItem; + TreeItem* m_pParent; QIcon m_icon; }; diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 3270c598a0c..93b3cc16699 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -45,45 +45,52 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); - if (role != Qt::DisplayRole && role != kDataPathRole && - role != kBoldRole && role != Qt::DecorationRole) { + TreeItem* item = static_cast(index.internalPointer()); + if (item == nullptr) { return QVariant(); } - TreeItem *item = static_cast(index.internalPointer()); - - // We use Qt::UserRole to ask for the datapath. - if (role == kDataPathRole) { - return item->dataPath(); - } else if (role == kBoldRole) { - return item->isBold(); - } else if (role == Qt::DecorationRole) { - return item->getIcon(); + // We use Qt::UserRole to ask for the datapath. + switch(role) { + case Qt::DisplayRole: + return item->data(); + case Qt::DecorationRole: + return item->getIcon(); + case Role::RoleDataPath: + return item->dataPath(); + case Role::RoleBold: + return item->isBold(); + case Role::RoleDivider: + return item->isDivider(); } - return item->data(); + + return QVariant(); } bool TreeItemModel::setData(const QModelIndex &a_rIndex, const QVariant &a_rValue, int a_iRole) { // Get the item referred to by this index. TreeItem *pItem = static_cast(a_rIndex.internalPointer()); - if (pItem == NULL) { + if (pItem == nullptr) { return false; } // Set the relevant data. switch (a_iRole) { - case Qt::DisplayRole: - pItem->setData(a_rValue, pItem->dataPath()); - break; - case kDataPathRole: - pItem->setData(pItem->data(), a_rValue); - break; - case kBoldRole: - pItem->setBold(a_rValue.toBool()); - break; - default: - return false; + case Qt::DisplayRole: + pItem->setData(a_rValue, pItem->dataPath()); + break; + case Role::RoleDataPath: + pItem->setData(pItem->data(), a_rValue); + break; + case Role::RoleBold: + pItem->setBold(a_rValue.toBool()); + break; + case Role::RoleDivider: + pItem->setDivider(a_rValue.toBool()); + break; + default: + return false; } emit(dataChanged(a_rIndex, a_rIndex)); @@ -93,8 +100,14 @@ bool TreeItemModel::setData(const QModelIndex &a_rIndex, Qt::ItemFlags TreeItemModel::flags(const QModelIndex &index) const { if (!index.isValid()) return 0; - - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + Qt::ItemFlags flags = Qt::ItemIsEnabled; + + bool divider = index.data(Role::RoleDivider).toBool(); + if (!divider) { + flags |= Qt::ItemIsSelectable; + } + + return flags; } QVariant TreeItemModel::headerData(int section, Qt::Orientation orientation, int role) const { diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index eb997d0beaf..b69570758cc 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -12,8 +12,12 @@ class TreeItem; class TreeItemModel : public QAbstractItemModel { Q_OBJECT public: - static const int kDataPathRole = Qt::UserRole; - static const int kBoldRole = Qt::UserRole + 1; + + enum Role { + RoleDataPath = Qt::UserRole, + RoleBold, + RoleDivider + }; TreeItemModel(QObject *parent = 0); virtual ~TreeItemModel(); diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 3638159466c..5919e25d562 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -2,19 +2,52 @@ #include #include -#include -#include #include +#include +#include +#include -#include "library/sidebarmodel.h" #include "library/treeitemmodel.h" +#include "library/sidebarmodel.h" #include "util/dnd.h" const int expand_time = 250; + +WSidebarItemDelegate::WSidebarItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) { + +} + +void WSidebarItemDelegate::paint(QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const { + bool divider = index.data(TreeItemModel::RoleDivider).toBool(); + if (!divider) { + QStyledItemDelegate::paint(painter, option, index); + return; + } + + QString text = index.data().toString(); + QRect rect(option.rect); + // Set small padding left + rect.setLeft(rect.left() + 20); + + // Draw the text + painter->setPen(option.palette.color(QPalette::Text)); + painter->setFont(option.font); + painter->drawText(rect, text); + + // Draw line under text + painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); +} + + WLibrarySidebar::WLibrarySidebar(QWidget* parent) : QTreeView(parent), WBaseWidget(this) { + setItemDelegate(new WSidebarItemDelegate(this)); + //Set some properties setHeaderHidden(true); setSelectionMode(QAbstractItemView::SingleSelection); diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index 07ce7691592..26e0852405b 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -11,10 +11,20 @@ #include #include #include +#include #include "widget/wbasewidget.h" #include "library/libraryview.h" +class WSidebarItemDelegate : public QStyledItemDelegate { + Q_OBJECT + public: + WSidebarItemDelegate(QObject* parent = nullptr); + + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const; +}; + class WLibrarySidebar : public QTreeView, public WBaseWidget { Q_OBJECT public: From e5d8786db568a7e2f8da8cba6eb35dc473ed7c1f Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 8 Jul 2016 19:50:20 +0200 Subject: [PATCH 252/552] Fixed small issue with non capital letters --- src/library/librarytreemodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 96f46b8f435..91e28c445ad 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -81,8 +81,8 @@ void LibraryTreeModel::createTracksTree() { } // Check if a header must be added - if (!uknown && lastHeader != value.at(0)) { - lastHeader = value.at(0); + if (!uknown && lastHeader != value.at(0).toUpper()) { + lastHeader = value.at(0).toUpper(); TreeItem* pTree = new TreeItem(lastHeader, lastHeader, m_pFeature, parent[0]); pTree->setDivider(true); From 4cf77e5af2f34cfd9c16a5d1dde4c463666fa35c Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 9 Jul 2016 10:40:33 +0200 Subject: [PATCH 253/552] Finish tree filter, still needs option to choose group by and coverarts --- src/library/librarytreemodel.cpp | 63 ++++++++++++++++++++++++----- src/library/librarytreemodel.h | 8 +++- src/library/mixxxlibraryfeature.cpp | 16 ++++---- src/library/treeitem.cpp | 14 +++++++ src/library/treeitem.h | 5 ++- 5 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 91e28c445ad..8c316a90abd 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -12,14 +12,16 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, : TreeItemModel(parent), m_pFeature(pFeature), m_pTrackCollection(pTrackCollection) { + + // Create root item TreeItem* pRootItem = new TreeItem(); pRootItem->setLibraryFeature(pFeature); QString title = pFeature->title().toString(); - TreeItem* pLibraryChildItem = new TreeItem(title, title, m_pFeature, pRootItem); - pLibraryChildItem->setIcon(m_pFeature->getIcon()); + m_pLibraryItem = new TreeItem(title, title, m_pFeature, pRootItem); + m_pLibraryItem->setIcon(m_pFeature->getIcon()); - pRootItem->appendChild(pLibraryChildItem); + pRootItem->appendChild(m_pLibraryItem); setRootItem(pRootItem); // By default sort by Artist -> Album @@ -28,6 +30,43 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, createTracksTree(); } +QString LibraryTreeModel::getQuery(TreeItem* pTree) const { + DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { + return ""; + } + + if (pTree == m_pLibraryItem) { + return ""; + } + + int depth = 0; + TreeItem* pAux = pTree; + + // We need to know the depth of the item to apply the filter + while (pAux->parent() != m_pRootItem && pAux->parent() != nullptr) { + pAux = pAux->parent(); + ++depth; + } + + // Generate the query + QStringList result; + pAux = pTree; + while (depth >= 0) { + QString value; + if (pAux->dataPath().toString() == "") { + value = ""; + } else { + value = pAux->data().toString(); + } + + result << m_sortOrder[depth] % ":\"" % value % "\""; + pAux = pAux->parent(); + --depth; + } + + return result.join(" "); +} + void LibraryTreeModel::createTracksTree() { QStringList columns; @@ -64,9 +103,10 @@ void LibraryTreeModel::createTracksTree() { while (query.next()) { for (int i = 0; i < size; ++i) { QString value = query.value(i).toString(); + QString valueP = value; - bool uknown = (value == ""); - if (uknown) { + bool unknown = (value == ""); + if (unknown) { value = tr("Unknown"); } if (!lastUsed[i].isNull() && value == lastUsed[i]) { @@ -81,19 +121,20 @@ void LibraryTreeModel::createTracksTree() { } // Check if a header must be added - if (!uknown && lastHeader != value.at(0).toUpper()) { + if (!unknown && lastHeader != value.at(0).toUpper()) { lastHeader = value.at(0).toUpper(); - TreeItem* pTree = - new TreeItem(lastHeader, lastHeader, m_pFeature, parent[0]); + TreeItem* pTree = new TreeItem(parent[0]); + pTree->setLibraryFeature(m_pFeature); + pTree->setData(lastHeader, lastHeader); pTree->setDivider(true); + parent[0]->appendChild(pTree); - } - + } } lastUsed[i] = value; // We need to create a new item - TreeItem* pTree = new TreeItem(value, value, m_pFeature, parent[i]); + TreeItem* pTree = new TreeItem(value, valueP, m_pFeature, parent[i]); parent[i]->appendChild(pTree); parent[i + 1] = pTree; } diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 2d28a800c6b..e0cbe39b87e 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -11,14 +11,20 @@ class TrackCollection; class LibraryTreeModel : public TreeItemModel { public: - LibraryTreeModel(MixxxLibraryFeature* pFeature, TrackCollection *pTrackCollection, QObject* parent = nullptr); + LibraryTreeModel(MixxxLibraryFeature* pFeature, + TrackCollection* pTrackCollection, + QObject* parent = nullptr); + QString getQuery(TreeItem* pTree) const; + private: void createTracksTree(); MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; QStringList m_sortOrder; + + TreeItem* m_pLibraryItem; }; #endif // LIBRARYTREEMODEL_H diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 96f1971c72a..3aa2234b4b0 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -137,19 +137,21 @@ void MixxxLibraryFeature::selectAll() { void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; showTrackModel(m_pLibraryTableModel); - m_pLibrary->restoreSearch(""); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + restoreSearch(""); + showBreadCrumb(m_childModel.getItem(QModelIndex())); emit(enableCoverArtDisplay(true)); } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { - QString itemName = index.data(TreeItemModel::RoleDataPath).toString(); + TreeItem* pTree = static_cast(index.internalPointer()); + QString query = m_childModel.getQuery(pTree); + qDebug() << "MixxxLibraryFeature::activateChild" << query; - if (itemName == kLibraryTitle) { - activate(); - return; - } + m_pLibraryTableModel->search(query); + switchToFeature(); + showBreadCrumb(pTree); + restoreSearch(query); } bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 1f34061f8ff..5a63a1179f7 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -46,6 +46,16 @@ TreeItem::TreeItem(LibraryFeature* pFeature) m_bold(false), m_divider(false), m_pParent(nullptr) { + +} + +TreeItem::TreeItem(TreeItem* parent) + : m_data("$root"), + m_dataPath("$root"), + m_pFeature(nullptr), + m_bold(false), + m_divider(false), + m_pParent(parent) { } @@ -98,6 +108,10 @@ TreeItem* TreeItem::parent() { return m_pParent; } +void TreeItem::setParent(TreeItem* parent) { + m_pParent = parent; +} + int TreeItem::row() const { if (m_pParent) { return m_pParent->m_childItems.indexOf(const_cast(this)); diff --git a/src/library/treeitem.h b/src/library/treeitem.h index 5b4409cb8b3..e432ec6a266 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -19,6 +19,7 @@ class TreeItem { LibraryFeature* pFeature, TreeItem* parent); TreeItem(LibraryFeature* pFeature); + TreeItem(TreeItem* parent); ~TreeItem(); /** appends a child item to this object **/ void appendChild(TreeItem *child); @@ -31,7 +32,9 @@ class TreeItem { /** Returns the position of this object within its parent **/ int row() const; /** returns the parent **/ - TreeItem *parent(); + TreeItem* parent(); + /** sets the parent **/ + void setParent(TreeItem* parent); /** for dynamic resizing models **/ bool insertChildren(QList &data, int position, int count); From 21450fa83f99fd507051b10e79aeb13f61a58e1a Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 9 Jul 2016 20:33:55 +0200 Subject: [PATCH 254/552] Added custom ordering in LibraryTree --- src/library/librarytreemodel.cpp | 33 ++++++++++++++++++----------- src/library/librarytreemodel.h | 5 ++++- src/library/mixxxlibraryfeature.cpp | 33 ++++++++++++++++++++++++++++- src/library/mixxxlibraryfeature.h | 1 + 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 8c316a90abd..5a830323e92 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -13,21 +13,14 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, m_pFeature(pFeature), m_pTrackCollection(pTrackCollection) { - // Create root item - TreeItem* pRootItem = new TreeItem(); - pRootItem->setLibraryFeature(pFeature); - QString title = pFeature->title().toString(); - - m_pLibraryItem = new TreeItem(title, title, m_pFeature, pRootItem); - m_pLibraryItem->setIcon(m_pFeature->getIcon()); - - pRootItem->appendChild(m_pLibraryItem); - setRootItem(pRootItem); - // By default sort by Artist -> Album // TODO(jmigual) store the sort order in the configuration m_sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; - createTracksTree(); + reloadTracksTree(); +} + +void LibraryTreeModel::setSortOrder(QStringList sortOrder) { + m_sortOrder = sortOrder; } QString LibraryTreeModel::getQuery(TreeItem* pTree) const { @@ -67,6 +60,22 @@ QString LibraryTreeModel::getQuery(TreeItem* pTree) const { return result.join(" "); } +void LibraryTreeModel::reloadTracksTree() { + // Create root item + TreeItem* pRootItem = new TreeItem(); + pRootItem->setLibraryFeature(m_pFeature); + QString title = m_pFeature->title().toString(); + + m_pLibraryItem = new TreeItem(title, title, m_pFeature, pRootItem); + m_pLibraryItem->setIcon(m_pFeature->getIcon()); + + pRootItem->appendChild(m_pLibraryItem); + + // Deletes the old root item if the previous root item was not null + setRootItem(pRootItem); + createTracksTree(); +} + void LibraryTreeModel::createTracksTree() { QStringList columns; diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index e0cbe39b87e..4df52eee06d 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -15,9 +15,12 @@ class LibraryTreeModel : public TreeItemModel { TrackCollection* pTrackCollection, QObject* parent = nullptr); + void setSortOrder(QStringList sortOrder); QString getQuery(TreeItem* pTree) const; - private: + void reloadTracksTree(); + + private: void createTracksTree(); MixxxLibraryFeature* m_pFeature; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 3aa2234b4b0..9c786181030 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -1,7 +1,8 @@ // mixxxlibraryfeature.cpp // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) -#include +#include +#include #include "library/mixxxlibraryfeature.h" @@ -154,6 +155,36 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { restoreSearch(query); } +void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, + const QModelIndex&) { + // Create the sort menu + QMenu menu; + QAction* artist_album = menu.addAction(tr("Artist > Album")); + QAction* album_artist = menu.addAction(tr("Album > Artist")); + QAction* genre_artist = menu.addAction(tr("Genre > Artist > Album")); + QAction* genre_album = menu.addAction(tr("Genre > Album > Artist")); + + QAction* selected = menu.exec(pos); + + QStringList sortOrder; + if (selected == artist_album) { + sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; + } else if (selected == album_artist) { + sortOrder << LIBRARYTABLE_ALBUM << LIBRARYTABLE_ARTIST; + } else if (selected == genre_artist) { + sortOrder << LIBRARYTABLE_GENRE << LIBRARYTABLE_ARTIST + << LIBRARYTABLE_ALBUM; + } else if (selected == genre_album) { + sortOrder << LIBRARYTABLE_GENRE << LIBRARYTABLE_ALBUM + << LIBRARYTABLE_ARTIST; + } else { + // Menu rejected + return; + } + m_childModel.setSortOrder(sortOrder); + m_childModel.reloadTracksTree(); +} + bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { if (pSource) { return false; diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 2e5a2a2a3e3..04b40350d70 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -50,6 +50,7 @@ class MixxxLibraryFeature : public LibraryFeature { public slots: void activate(); void activateChild(const QModelIndex& index); + void onRightClickChild(const QPoint& pos, const QModelIndex&); void refreshLibraryModels(); void selectAll(); From 9e211fd393911f65ea22996ea6eedaf773d4152d Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 10 Jul 2016 18:57:43 +0200 Subject: [PATCH 255/552] Begin of cover art addition --- src/library/coverart.h | 4 ++ src/library/librarytreemodel.cpp | 70 +++++++++++++++++++++++++++++++- src/library/librarytreemodel.h | 11 +++++ src/library/treeitem.cpp | 9 ++++ src/library/treeitem.h | 6 +++ 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/library/coverart.h b/src/library/coverart.h index 9c9ad41f003..d081bec59da 100644 --- a/src/library/coverart.h +++ b/src/library/coverart.h @@ -34,6 +34,8 @@ struct CoverInfo { trackLocation(QString()), // This default value is fine: qChecksum(NULL, 0) is 0. hash(0) {} + + CoverInfo(const CoverInfo& c) = default; bool operator==(const CoverInfo& other) const { return other.source == source && @@ -45,6 +47,8 @@ struct CoverInfo { bool operator!=(const CoverInfo& other) const { return !(*this == other); } + + CoverInfo& operator=(const CoverInfo& other) = default; Source source; Type type; diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 5a830323e92..689fb4bb7e8 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -1,5 +1,6 @@ #include +#include "library/coverartcache.h" #include "library/librarytreemodel.h" #include "library/mixxxlibraryfeature.h" #include "library/queryutil.h" @@ -16,9 +17,60 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, // By default sort by Artist -> Album // TODO(jmigual) store the sort order in the configuration m_sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; + QStringList aux; + + aux << LIBRARYTABLE_COVERART + << LIBRARYTABLE_COVERART_HASH + << LIBRARYTABLE_COVERART_LOCATION + << LIBRARYTABLE_COVERART_SOURCE + << LIBRARYTABLE_COVERART_TYPE; + + for (QString& s : aux) { + s.prepend("library."); + } + m_coverQuery = aux.join(","); + reloadTracksTree(); } +QVariant LibraryTreeModel::data(const QModelIndex& index, int role) { + + // The decoration role contains the icon in QTreeView + if (role != Qt::DecorationRole) { + return TreeItemModel::data(index, role); + } + + TreeItem* pTree = static_cast(index.internalPointer()); + DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { + return QVariant(); + } + + // The library item has its own icon + if (pTree == m_pLibraryItem) { + return pTree->getIcon(); + } + + const CoverInfo& info = pTree->getCoverInfo(); + + // Currently we only support this two types of cover info + if (info.type != CoverInfo::METADATA || info.type != CoverInfo::FILE) { + return QVariant(); + } + + CoverArtCache* pCache = CoverArtCache::instance(); + QPixmap pixmap = pCache->requestCover(info, this, info.hash); + + if (pixmap.isNull()) { + // The icon is not in the cache so we need to wait until the + // coverFound slot is called + m_hashToIndex.insert(info.type, index); + } else { + // Good luck icon found + return QIcon(pixmap); + } + return QVariant(); +} + void LibraryTreeModel::setSortOrder(QStringList sortOrder) { m_sortOrder = sortOrder; } @@ -76,6 +128,20 @@ void LibraryTreeModel::reloadTracksTree() { createTracksTree(); } +void LibraryTreeModel::coverFound(const QObject* requestor, int requestReference, + const CoverInfo&, QPixmap pixmap, bool fromCache) { + + if (requestor == this && !pixmap.isNull() && !fromCache) { + auto it = m_hashToIndex.find(requestReference); + if (it == m_hashToIndex.end()) { + return; + } + + const QModelIndex& index = *it; + emit(dataChanged(index, index)); + } +} + void LibraryTreeModel::createTracksTree() { QStringList columns; @@ -83,9 +149,9 @@ void LibraryTreeModel::createTracksTree() { columns << "library." + col; } - QString queryStr = "SELECT DISTINCT %1 " + QString queryStr = "SELECT DISTINCT %1,%2 " "FROM library " - "WHERE library.%2 != 1 " + "WHERE library.%3 != 1 " "ORDER BY %1"; queryStr = queryStr.arg(columns.join(","), LIBRARYTABLE_MIXXXDELETED); diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 4df52eee06d..eb9114dec3c 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -1,11 +1,13 @@ #ifndef LIBRARYTREEMODEL_H #define LIBRARYTREEMODEL_H +#include #include #include #include "library/treeitemmodel.h" +class CoverInfo; class MixxxLibraryFeature; class TrackCollection; @@ -15,19 +17,28 @@ class LibraryTreeModel : public TreeItemModel { TrackCollection* pTrackCollection, QObject* parent = nullptr); + virtual QVariant data(const QModelIndex &index, int role); + void setSortOrder(QStringList sortOrder); QString getQuery(TreeItem* pTree) const; void reloadTracksTree(); + private slots: + + void coverFound(const QObject* requestor, int requestReference, const CoverInfo&, + QPixmap pixmap, bool fromCache); + private: void createTracksTree(); MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; QStringList m_sortOrder; + QString m_coverQuery; TreeItem* m_pLibraryItem; + QHash m_hashToIndex; }; #endif // LIBRARYTREEMODEL_H diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 5a63a1179f7..7a97269673b 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -3,6 +3,7 @@ #include +#include "library/coverart.h" #include "library/treeitem.h" /* @@ -185,3 +186,11 @@ QIcon TreeItem::getIcon() const { void TreeItem::setIcon(const QIcon& icon) { m_icon = icon; } + +void TreeItem::setCoverInfo(const CoverInfo &cover) { + m_cover = cover; +} + +const CoverInfo& TreeItem::getCoverInfo() const { + return m_cover; +} diff --git a/src/library/treeitem.h b/src/library/treeitem.h index e432ec6a266..2895a68d55b 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -11,6 +11,8 @@ #include "library/libraryfeature.h" +class CoverInfo; + class TreeItem { public: TreeItem(); //creates an invisible root item for the tree @@ -64,6 +66,9 @@ class TreeItem { void setIcon(const QIcon& icon); QIcon getIcon() const; + + void setCoverInfo(const CoverInfo& cover); + const CoverInfo& getCoverInfo() const; private: QList m_childItems; @@ -75,6 +80,7 @@ class TreeItem { TreeItem* m_pParent; QIcon m_icon; + CoverInfo m_cover; }; #endif From abc76c8034893554b1246d888e355edd9365464a Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 10 Jul 2016 21:00:52 +0200 Subject: [PATCH 256/552] Finished cover art addition --- src/library/librarytreemodel.cpp | 71 ++++++++++++++++++++++++-------- src/library/librarytreemodel.h | 12 ++++-- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 689fb4bb7e8..e0701ba9256 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -7,6 +7,10 @@ #include "library/trackcollection.h" #include "library/treeitem.h" +namespace { +QHash m_hashToIndex; +} + LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, TrackCollection* pTrackCollection, QObject* parent) @@ -17,23 +21,21 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, // By default sort by Artist -> Album // TODO(jmigual) store the sort order in the configuration m_sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; - QStringList aux; - aux << LIBRARYTABLE_COVERART - << LIBRARYTABLE_COVERART_HASH - << LIBRARYTABLE_COVERART_LOCATION - << LIBRARYTABLE_COVERART_SOURCE - << LIBRARYTABLE_COVERART_TYPE; + m_coverQuery << LIBRARYTABLE_COVERART_HASH + << LIBRARYTABLE_COVERART_LOCATION + << LIBRARYTABLE_COVERART_SOURCE + << LIBRARYTABLE_COVERART_TYPE; - for (QString& s : aux) { + for (QString& s : m_coverQuery) { s.prepend("library."); } - m_coverQuery = aux.join(","); + m_coverQuery << "track_locations." + TRACKLOCATIONSTABLE_LOCATION; reloadTracksTree(); } -QVariant LibraryTreeModel::data(const QModelIndex& index, int role) { +QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { // The decoration role contains the icon in QTreeView if (role != Qt::DecorationRole) { @@ -53,16 +55,19 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) { const CoverInfo& info = pTree->getCoverInfo(); // Currently we only support this two types of cover info - if (info.type != CoverInfo::METADATA || info.type != CoverInfo::FILE) { + if (info.type != CoverInfo::METADATA && info.type != CoverInfo::FILE) { return QVariant(); } CoverArtCache* pCache = CoverArtCache::instance(); - QPixmap pixmap = pCache->requestCover(info, this, info.hash); + // Set a maximum size of 64px to not use many cache + QPixmap pixmap = pCache->requestCover(info, this, info.hash, 64); if (pixmap.isNull()) { // The icon is not in the cache so we need to wait until the - // coverFound slot is called + // coverFound slot is called. Since the data function is const + // and we cannot change that we use m_hashToIndex in an anonymous + // namespace to store the future value that we will get m_hashToIndex.insert(info.type, index); } else { // Good luck icon found @@ -150,10 +155,16 @@ void LibraryTreeModel::createTracksTree() { } QString queryStr = "SELECT DISTINCT %1,%2 " - "FROM library " - "WHERE library.%3 != 1 " - "ORDER BY %1"; - queryStr = queryStr.arg(columns.join(","), LIBRARYTABLE_MIXXXDELETED); + "FROM library LEFT JOIN track_locations " + "ON (%3 = %4) " + "WHERE %5 != 1 " + "GROUP BY %2 " + "ORDER BY %2"; + queryStr = queryStr.arg(m_coverQuery.join(","), + columns.join(","), + "library." + LIBRARYTABLE_ID, + "track_locations." + TRACKLOCATIONSTABLE_ID, + "library." + LIBRARYTABLE_MIXXXDELETED); QSqlQuery query(m_pTrackCollection->getDatabase()); @@ -169,7 +180,20 @@ void LibraryTreeModel::createTracksTree() { if (size <= 0) { return; } + QSqlRecord record = query.record(); + + int iAlbum = record.indexOf(LIBRARYTABLE_ALBUM); + int iCoverHash = record.indexOf(LIBRARYTABLE_COVERART_HASH); + int iCoverLoc = record.indexOf(LIBRARYTABLE_COVERART_LOCATION); + int iCoverSrc = record.indexOf(LIBRARYTABLE_COVERART_SOURCE); + int iCoverType = record.indexOf(LIBRARYTABLE_COVERART_TYPE); + int iTrackLoc = record.indexOf(TRACKLOCATIONSTABLE_LOCATION); + + for (int i = 0; i < record.count(); ++i) { + qDebug() << record.fieldName(i); + } + int extraSize = m_coverQuery.size(); QVector lastUsed(size); QChar lastHeader; QVector parent(size + 1, nullptr); @@ -177,7 +201,7 @@ void LibraryTreeModel::createTracksTree() { while (query.next()) { for (int i = 0; i < size; ++i) { - QString value = query.value(i).toString(); + QString value = query.value(extraSize + i).toString(); QString valueP = value; bool unknown = (value == ""); @@ -212,6 +236,19 @@ void LibraryTreeModel::createTracksTree() { TreeItem* pTree = new TreeItem(value, valueP, m_pFeature, parent[i]); parent[i]->appendChild(pTree); parent[i + 1] = pTree; + + if (extraSize + i == iAlbum) { + CoverInfo c; + c.hash = query.value(iCoverHash).toInt(); + c.coverLocation = query.value(iCoverLoc).toString(); + c.trackLocation = query.value(iTrackLoc).toString(); + + quint16 source = query.value(iCoverSrc).toInt(); + quint16 type = query.value(iCoverType).toInt(); + c.source = static_cast(source); + c.type = static_cast(type); + pTree->setCoverInfo(c); + } } } diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index eb9114dec3c..4706666c414 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -17,28 +17,34 @@ class LibraryTreeModel : public TreeItemModel { TrackCollection* pTrackCollection, QObject* parent = nullptr); - virtual QVariant data(const QModelIndex &index, int role); + virtual QVariant data(const QModelIndex &index, int role) const; void setSortOrder(QStringList sortOrder); QString getQuery(TreeItem* pTree) const; void reloadTracksTree(); + signals: + + void markInHash(quint16, const QModelIndex&); + private slots: void coverFound(const QObject* requestor, int requestReference, const CoverInfo&, QPixmap pixmap, bool fromCache); + void slotMarkInHash(quint16 hash, const QModelIndex& index); + private: void createTracksTree(); MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; QStringList m_sortOrder; - QString m_coverQuery; + QStringList m_coverQuery; TreeItem* m_pLibraryItem; - QHash m_hashToIndex; + }; #endif // LIBRARYTREEMODEL_H From 09bc4e148092db6f4f4ff634c731c28c948c58fa Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 10 Jul 2016 21:29:17 +0200 Subject: [PATCH 257/552] Finished Icons in tree --- src/library/libraryfeature.cpp | 1 + src/library/librarytreemodel.cpp | 14 ++++---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index b10342ce0d0..770511b4a69 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -104,6 +104,7 @@ WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); pSidebar->installEventFilter(pKeyboard); pSidebar->setModel(getChildModel()); + pSidebar->setIconSize(QSize(32, 32)); connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), this, SLOT(activateChild(const QModelIndex&))); diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index e0701ba9256..cef03ad6a5b 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -46,22 +46,16 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { return QVariant(); } - - // The library item has its own icon - if (pTree == m_pLibraryItem) { - return pTree->getIcon(); - } - - const CoverInfo& info = pTree->getCoverInfo(); + const CoverInfo& info = pTree->getCoverInfo(); // Currently we only support this two types of cover info if (info.type != CoverInfo::METADATA && info.type != CoverInfo::FILE) { - return QVariant(); + return TreeItemModel::data(index, role); } CoverArtCache* pCache = CoverArtCache::instance(); - // Set a maximum size of 64px to not use many cache - QPixmap pixmap = pCache->requestCover(info, this, info.hash, 64); + // Set a maximum size of 32px to not use many cache + QPixmap pixmap = pCache->requestCover(info, this, info.hash, 32); if (pixmap.isNull()) { // The icon is not in the cache so we need to wait until the From adfbfbbb988938e02320427aabcad20e9dc6f825 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 18:57:01 +0200 Subject: [PATCH 258/552] Added track count in tree --- src/library/librarytreemodel.cpp | 57 ++++++++++++++++---------------- src/library/treeitem.cpp | 17 ++++++++++ src/library/treeitem.h | 4 +++ 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index cef03ad6a5b..e36d2a047fa 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -96,12 +96,7 @@ QString LibraryTreeModel::getQuery(TreeItem* pTree) const { QStringList result; pAux = pTree; while (depth >= 0) { - QString value; - if (pAux->dataPath().toString() == "") { - value = ""; - } else { - value = pAux->data().toString(); - } + QString value = pAux->dataPath().toString(); result << m_sortOrder[depth] % ":\"" % value % "\""; pAux = pAux->parent(); @@ -148,7 +143,7 @@ void LibraryTreeModel::createTracksTree() { columns << "library." + col; } - QString queryStr = "SELECT DISTINCT %1,%2 " + QString queryStr = "SELECT COUNT(%3),%1,%2 " "FROM library LEFT JOIN track_locations " "ON (%3 = %4) " "WHERE %5 != 1 " @@ -168,7 +163,7 @@ void LibraryTreeModel::createTracksTree() { LOG_FAILED_QUERY(query); } - qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); + //qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); int size = columns.size(); if (size <= 0) { @@ -183,11 +178,7 @@ void LibraryTreeModel::createTracksTree() { int iCoverType = record.indexOf(LIBRARYTABLE_COVERART_TYPE); int iTrackLoc = record.indexOf(TRACKLOCATIONSTABLE_LOCATION); - for (int i = 0; i < record.count(); ++i) { - qDebug() << record.fieldName(i); - } - - int extraSize = m_coverQuery.size(); + int extraSize = m_coverQuery.size() + 1; QVector lastUsed(size); QChar lastHeader; QVector parent(size + 1, nullptr); @@ -198,40 +189,39 @@ void LibraryTreeModel::createTracksTree() { QString value = query.value(extraSize + i).toString(); QString valueP = value; - bool unknown = (value == ""); + bool unknown = valueP.isNull(); if (unknown) { + valueP = ""; value = tr("Unknown"); } - if (!lastUsed[i].isNull() && value == lastUsed[i]) { + if (!lastUsed[i].isNull() && valueP == lastUsed[i]) { continue; } - - if (i == 0) { + + if (i == 0 && !unknown) { // If a new top level is added all the following levels must be // reset - for (QString& s : lastUsed) { - s = QString(); - } + lastUsed.fill(QString()); // Check if a header must be added - if (!unknown && lastHeader != value.at(0).toUpper()) { + if (lastHeader != value.at(0).toUpper()) { lastHeader = value.at(0).toUpper(); - TreeItem* pTree = new TreeItem(parent[0]); - pTree->setLibraryFeature(m_pFeature); - pTree->setData(lastHeader, lastHeader); + TreeItem* pTree = new TreeItem(lastHeader, lastHeader, + m_pFeature, parent[0]); pTree->setDivider(true); - parent[0]->appendChild(pTree); } } - lastUsed[i] = value; + + lastUsed[i] = valueP; // We need to create a new item TreeItem* pTree = new TreeItem(value, valueP, m_pFeature, parent[i]); + pTree->setTrackCount(0); parent[i]->appendChild(pTree); parent[i + 1] = pTree; - if (extraSize + i == iAlbum) { + if (extraSize + i == iAlbum && !unknown) { CoverInfo c; c.hash = query.value(iCoverHash).toInt(); c.coverLocation = query.value(iCoverLoc).toString(); @@ -243,7 +233,18 @@ void LibraryTreeModel::createTracksTree() { c.type = static_cast(type); pTree->setCoverInfo(c); } - } + } + + // Set track count + int val = query.value(0).toInt(); + for (int i = 1; i < size + 1; ++i) { + TreeItem* pTree = parent[i]; + if (pTree == nullptr) { + continue; + } + + pTree->setTrackCount(pTree->getTrackCount() + val); + } } triggerRepaint(); diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 7a97269673b..ef760bcc32f 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -1,6 +1,7 @@ // TreeItem.cpp // Created 10/02/2010 by Tobias Rafreider +#include #include #include "library/coverart.h" @@ -37,6 +38,7 @@ TreeItem::TreeItem(const QString& data, const QString& data_path, m_pFeature(pFeature), m_bold(false), m_divider(false), + m_trackCount(-1), m_pParent(parent) { } @@ -46,6 +48,7 @@ TreeItem::TreeItem(LibraryFeature* pFeature) m_pFeature(pFeature), m_bold(false), m_divider(false), + m_trackCount(-1), m_pParent(nullptr) { } @@ -56,6 +59,7 @@ TreeItem::TreeItem(TreeItem* parent) m_pFeature(nullptr), m_bold(false), m_divider(false), + m_trackCount(-1), m_pParent(parent) { } @@ -66,6 +70,7 @@ TreeItem::TreeItem() m_pFeature(nullptr), m_bold(false), m_divider(false), + m_trackCount(-1), m_pParent(nullptr) { } @@ -90,6 +95,10 @@ int TreeItem::childCount() const { } QVariant TreeItem::data() const { + if (m_trackCount >= 0) { + return m_data + " (" + QString::number(m_trackCount) + ")"; + } + return m_data; } @@ -194,3 +203,11 @@ void TreeItem::setCoverInfo(const CoverInfo &cover) { const CoverInfo& TreeItem::getCoverInfo() const { return m_cover; } + +void TreeItem::setTrackCount(int count) { + m_trackCount = count; +} + +int TreeItem::getTrackCount() { + return m_trackCount; +} diff --git a/src/library/treeitem.h b/src/library/treeitem.h index 2895a68d55b..abd19a4372c 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -69,6 +69,9 @@ class TreeItem { void setCoverInfo(const CoverInfo& cover); const CoverInfo& getCoverInfo() const; + + void setTrackCount(int count); + int getTrackCount(); private: QList m_childItems; @@ -77,6 +80,7 @@ class TreeItem { LibraryFeature* m_pFeature; bool m_bold; bool m_divider; + int m_trackCount; TreeItem* m_pParent; QIcon m_icon; From 6aac36c56f32f940454e529f5e103218060c9fbf Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 19:59:01 +0200 Subject: [PATCH 259/552] Add is null search query integrated with tree --- src/library/librarytreemodel.cpp | 7 +++++-- src/library/searchqueryparser.cpp | 6 ++++++ src/library/searchqueryparser.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index e36d2a047fa..1533f7898e0 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -97,8 +97,11 @@ QString LibraryTreeModel::getQuery(TreeItem* pTree) const { pAux = pTree; while (depth >= 0) { QString value = pAux->dataPath().toString(); - - result << m_sortOrder[depth] % ":\"" % value % "\""; + if (value == "") { + result << "\\+" + m_sortOrder[depth]; + } else { + result << m_sortOrder[depth] % ":\"" % value % "\""; + } pAux = pAux->parent(); --depth; } diff --git a/src/library/searchqueryparser.cpp b/src/library/searchqueryparser.cpp index f261088d805..f5bdaf4b8b1 100644 --- a/src/library/searchqueryparser.cpp +++ b/src/library/searchqueryparser.cpp @@ -54,6 +54,7 @@ SearchQueryParser::SearchQueryParser(QSqlDatabase& database) m_allFilters.append(m_specialFilters); m_fuzzyMatcher = QRegExp(QString("^~(%1)$").arg(m_allFilters.join("|"))); + m_isNullMatcher = QRegExp(QString("^\\\\\\+(%1)$").arg(m_allFilters.join("|"))); m_textFilterMatcher = QRegExp(QString("^-?(%1):(.*)$").arg(m_textFilters.join("|"))); m_numericFilterMatcher = QRegExp(QString("^-?(%1):(.*)$").arg(m_numericFilters.join("|"))); m_specialFilterMatcher = QRegExp(QString("^[~-]?(%1):(.*)$").arg(m_specialFilters.join("|"))); @@ -116,6 +117,11 @@ void SearchQueryParser::parseTokens(QStringList tokens, if (m_fuzzyMatcher.indexIn(token) != -1) { // TODO(XXX): implement this feature. + } else if (m_isNullMatcher.indexIn(token) != -1) { + QString field = m_isNullMatcher.cap(1); + std::unique_ptr pNode(std::make_unique( + field + " IS NULL")); + pQuery->addNode(std::move(pNode)); } else if (m_textFilterMatcher.indexIn(token) != -1) { bool negate = token.startsWith(kNegatePrefix); QString field = m_textFilterMatcher.cap(1); diff --git a/src/library/searchqueryparser.h b/src/library/searchqueryparser.h index f505abcb335..1358d52432b 100644 --- a/src/library/searchqueryparser.h +++ b/src/library/searchqueryparser.h @@ -34,6 +34,7 @@ class SearchQueryParser { QStringList m_allFilters; QHash m_fieldToSqlColumns; + QRegExp m_isNullMatcher; QRegExp m_fuzzyMatcher; QRegExp m_textFilterMatcher; QRegExp m_numericFilterMatcher; From f2cfb7fa2286b754908c3d21814e382341504d54 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 20:06:01 +0200 Subject: [PATCH 260/552] Fix wrong icon size in tree in some features --- src/library/libraryfeature.cpp | 1 - src/library/mixxxlibraryfeature.cpp | 6 ++++++ src/library/mixxxlibraryfeature.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 770511b4a69..b10342ce0d0 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -104,7 +104,6 @@ WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); pSidebar->installEventFilter(pKeyboard); pSidebar->setModel(getChildModel()); - pSidebar->setIconSize(QSize(32, 32)); connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), this, SLOT(activateChild(const QModelIndex&))); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 9c786181030..be6f2be3d5c 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -121,6 +121,12 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { return &m_childModel; } +QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { + WLibrarySidebar* pSidebar = createSidebarWidget(pKeyboard); + pSidebar->setIconSize(QSize(32, 32)); + return pSidebar; +} + void MixxxLibraryFeature::refreshLibraryModels() { if (m_pLibraryTableModel) { m_pLibraryTableModel->select(); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 04b40350d70..768d0f596dd 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -46,6 +46,7 @@ class MixxxLibraryFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); + virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter *pKeyboard); public slots: void activate(); From b86a673994e4be837e3f725fbb5d843a578eb6d8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 20:06:52 +0200 Subject: [PATCH 261/552] Fix not building --- src/library/mixxxlibraryfeature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index be6f2be3d5c..ecf6106e520 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -122,7 +122,7 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { } QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { - WLibrarySidebar* pSidebar = createSidebarWidget(pKeyboard); + WLibrarySidebar* pSidebar = createLibrarySidebarWidget(pKeyboard); pSidebar->setIconSize(QSize(32, 32)); return pSidebar; } From ab455ebfb45561bde8cd5bd36f42971caf4ef46c Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 20:09:53 +0200 Subject: [PATCH 262/552] Fix wrong indentation --- src/library/libraryfeature.h | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 165efa4f4c2..d2e58d75342 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -106,37 +106,37 @@ class LibraryFeature : public QObject { void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); -protected: - inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } - inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } - - // Creates a table widget with no model - virtual WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, - int paneId); - - // Creates a WLibrarySidebar widget with the getChildModel() function as - // model - WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); - - // Override this function to create a custom inner widget for the sidebar, - // the default widget is a WLibrarySidebar widget - virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); - - void showTrackModel(QAbstractItemModel *model); - void switchToFeature(); - void restoreSearch(const QString& search); - void showBreadCrumb(TreeItem* pTree); - void showBreadCrumb(const QString& text); - - WTrackTableView* getFocusedTable(); - - UserSettingsPointer m_pConfig; - Library* m_pLibrary; - TrackCollection* m_pTrackCollection; - - int m_featureFocus; - int m_focusedPane; - + protected: + inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } + inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + + // Creates a table widget with no model + virtual WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, + int paneId); + + // Creates a WLibrarySidebar widget with the getChildModel() function as + // model + WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); + + // Override this function to create a custom inner widget for the sidebar, + // the default widget is a WLibrarySidebar widget + virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); + + void showTrackModel(QAbstractItemModel *model); + void switchToFeature(); + void restoreSearch(const QString& search); + void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QString& text); + + WTrackTableView* getFocusedTable(); + + UserSettingsPointer m_pConfig; + Library* m_pLibrary; + TrackCollection* m_pTrackCollection; + + int m_featureFocus; + int m_focusedPane; + private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); QHash > m_trackTables; From f0460d69982900b4119ccdef3ca1e02783743805 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 11 Jul 2016 20:28:56 +0200 Subject: [PATCH 263/552] MixxxLibraryFeature remove selection on search --- src/library/library.cpp | 5 +---- src/library/libraryfeature.h | 3 +++ src/library/librarypanemanager.cpp | 10 +++++++++- src/library/librarypanemanager.h | 4 ++-- src/library/mixxxlibraryfeature.cpp | 10 +++++++--- src/library/mixxxlibraryfeature.h | 3 ++- src/widget/wbaselibrary.cpp | 4 ++++ src/widget/wbaselibrary.h | 2 ++ src/widget/wlibrary.h | 2 +- 9 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 92fbfe02f32..b6a6429757c 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -127,10 +127,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, // Get the value once to avoid searching again in the hash LibraryPaneManager* pPane = getPane(paneId); - pPane->bindPaneWidget(pLibraryWidget, pKeyboard); - - connect(pPane, SIGNAL(search(const QString&)), - pLibraryWidget, SLOT(search(const QString&))); + pPane->bindPaneWidget(pLibraryWidget, pKeyboard); // Set the current font and row height on all the WTrackTableViews that were // just connected to us. diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index d2e58d75342..6bd3654bc6a 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -91,6 +91,9 @@ class LibraryFeature : public QObject { virtual void onLazyChildExpandation(const QModelIndex&) { } + virtual void onSearch(const QString&) { + } + signals: void loadTrack(TrackPointer); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index bdc759649ac..2315533e0da 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -52,7 +52,7 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { pSearchBar->installEventFilter(this); connect(pSearchBar, SIGNAL(search(const QString&)), - this, SIGNAL(search(const QString&))); + this, SLOT(slotSearch(const QString&))); connect(pSearchBar, SIGNAL(searchCleared()), this, SIGNAL(searchCleared())); connect(pSearchBar, SIGNAL(searchStarting()), @@ -145,6 +145,14 @@ void LibraryPaneManager::slotPaneFocused() { m_pLibrary->slotPaneFocused(this); } +void LibraryPaneManager::slotSearch(const QString& text) { + DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { + return; + } + m_pPaneWidget->search(text); + m_pCurrentFeature->onSearch(text); +} + bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { if (m_pPaneWidget.isNull()) { return false; diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 10e36f83fe5..ff84a95be81 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -52,8 +52,7 @@ class LibraryPaneManager : public QObject { } signals: - - void search(const QString& text); + void searchCleared(); void searchStarting(); @@ -62,6 +61,7 @@ class LibraryPaneManager : public QObject { void slotPaneCollapsed(); void slotPaneUncollapsed(); void slotPaneFocused(); + void slotSearch(const QString& text); protected: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index ecf6106e520..3698aa87004 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -122,9 +122,9 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { } QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { - WLibrarySidebar* pSidebar = createLibrarySidebarWidget(pKeyboard); - pSidebar->setIconSize(QSize(32, 32)); - return pSidebar; + m_pSidebar = createLibrarySidebarWidget(pKeyboard); + m_pSidebar->setIconSize(QSize(32, 32)); + return m_pSidebar; } void MixxxLibraryFeature::refreshLibraryModels() { @@ -140,6 +140,10 @@ void MixxxLibraryFeature::selectAll() { } } +void MixxxLibraryFeature::onSearch(const QString&) { + m_pSidebar->clearSelection(); +} + void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 768d0f596dd..0d6884d75bf 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -55,7 +55,7 @@ class MixxxLibraryFeature : public LibraryFeature { void refreshLibraryModels(); void selectAll(); - + void onSearch(const QString&) override; signals: void unhideHidden(); @@ -71,6 +71,7 @@ class MixxxLibraryFeature : public LibraryFeature { const QString kLibraryTitle; QSharedPointer m_pBaseTrackCache; + QPointer m_pSidebar; LibraryTableModel* m_pLibraryTableModel; LibraryTreeModel m_childModel; TrackDAO& m_trackDao; diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index 92bfe51b8b9..c3b09efc516 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -54,6 +54,10 @@ void WBaseLibrary::switchToFeature(LibraryFeature *pFeature) { } } +void WBaseLibrary::search(const QString&) { + +} + bool WBaseLibrary::eventFilter(QObject*, QEvent* pEvent) { if (pEvent->type() == QEvent::FocusIn) { //qDebug() << "WBaseLibrary::eventFilter FocusIn"; diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 9975aa324b7..637f17e39e4 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -35,6 +35,8 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget public slots: virtual void switchToFeature(LibraryFeature* pFeature); + + virtual void search(const QString&); protected: diff --git a/src/widget/wlibrary.h b/src/widget/wlibrary.h index 7115b3933e0..393704da9eb 100644 --- a/src/widget/wlibrary.h +++ b/src/widget/wlibrary.h @@ -36,7 +36,7 @@ class WLibrary : public WBaseLibrary { // registered view. void switchToFeature(LibraryFeature* pFeature); - void search(const QString&); + void search(const QString& name) override; private: QMutex m_mutex; From 4b8cbf3f7dbf9f297637bcf3860a6332b9d09651 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 09:51:08 +0200 Subject: [PATCH 264/552] Add usefull functions in LibraryFeature to avoid coding --- src/library/baseplaylistfeature.cpp | 8 ++-- src/library/historyfeature.cpp | 3 +- src/library/historyfeature.h | 2 +- src/library/libraryfeature.cpp | 8 ++++ src/library/libraryfeature.h | 58 +++++++++++++++-------------- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 1b959c75e6e..7392e8b0046 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -146,9 +146,9 @@ void BasePlaylistFeature::activate() { (*it)->setCurrentIndex(*itId); switchToFeature(); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->restoreSearch(QString()); // Null String disables search box + restoreSearch(QString()); // Null String disables search box emit(enableCoverArtDisplay(true)); m_featureFocus = -1; } @@ -175,8 +175,8 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pPlaylistTableModel); m_featureFocus = -1; - m_pLibrary->restoreSearch(""); - m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); + restoreSearch(""); + showBreadCrumb(static_cast(index.internalPointer())); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 6c8fd71e391..11dcf7e17da 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -54,8 +54,7 @@ QIcon HistoryFeature::getIcon() { return QIcon(":/images/library/ic_library_history.png"); } -void HistoryFeature::onRightClick(const QPoint& globalPos) { - Q_UNUSED(globalPos); +void HistoryFeature::onRightClick(const QPoint&) { m_lastRightClickedIndex = QModelIndex(); // Create the right-click menu diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index beeeb7376e9..dffda06d245 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -26,7 +26,7 @@ class HistoryFeature : public BasePlaylistFeature { QIcon getIcon(); public slots: - void onRightClick(const QPoint& globalPos); + void onRightClick(const QPoint&); void onRightClickChild(const QPoint& globalPos, QModelIndex index); void slotJoinWithPrevious(); void slotGetNewPlaylist(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 202d5dda260..f35974d0ec5 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -129,6 +129,14 @@ void LibraryFeature::switchToFeature() { m_pLibrary->switchToFeature(this); } +void LibraryFeature::restoreSearch(const QString& search) { + m_pLibrary->restoreSearch(search); +} + +void LibraryFeature::showBreadCrumb(TreeItem* pTree) { + m_pLibrary->showBreadCrumb(pTree); +} + WTrackTableView *LibraryFeature::getFocusedTable() { auto it = m_trackTables.find(m_featureFocus); if (it == m_trackTables.end() || it->isNull()) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index fd8307d9ddd..e9c0b647cf5 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -73,34 +73,6 @@ class LibraryFeature : public QObject { virtual void setFocusedPane(int paneId); - protected: - inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } - inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } - - // Creates a table widget with no model - WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, - int paneId); - - // Creates a WLibrarySidebar widget with the getChildModel() function as - // model - WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); - - // Override this function to create a custom inner widget for the sidebar, - // the default widget is a WLibrarySidebar widget - virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); - - void showTrackModel(QAbstractItemModel *model); - void switchToFeature(); - - WTrackTableView* getFocusedTable(); - - UserSettingsPointer m_pConfig; - Library* m_pLibrary; - TrackCollection* m_pTrackCollection; - - int m_featureFocus; - int m_focusedPane; - public slots: // called when you single click on the root item virtual void activate() = 0; @@ -133,6 +105,36 @@ class LibraryFeature : public QObject { // emit this signal to enable/disable the cover art widget void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); + + protected: + inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } + inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + + // Creates a table widget with no model + WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, + int paneId); + + // Creates a WLibrarySidebar widget with the getChildModel() function as + // model + WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); + + // Override this function to create a custom inner widget for the sidebar, + // the default widget is a WLibrarySidebar widget + virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); + + void showTrackModel(QAbstractItemModel *model); + void switchToFeature(); + void restoreSearch(const QString& search); + void showBreadCrumb(TreeItem *pTree); + + WTrackTableView* getFocusedTable(); + + UserSettingsPointer m_pConfig; + Library* m_pLibrary; + TrackCollection* m_pTrackCollection; + + int m_featureFocus; + int m_focusedPane; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); From 3a78153e418e60e4f76180e9f4d656aab71a0761 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 10:30:31 +0200 Subject: [PATCH 265/552] Fix sorting problem when setting a new trackModel --- src/widget/wtracktableview.cpp | 5 ----- src/widget/wtracktableview.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 5d5e0f965d6..de4e3e075cc 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1284,11 +1284,6 @@ void WTrackTableView::loadSelectedTrackToGroup(QString group, bool play) { loadSelectionToGroup(group, play); } -void WTrackTableView::setSortingEnabled(bool sorting) { - m_sorting = sorting; - WLibraryTableView::setSortingEnabled(sorting); -} - void WTrackTableView::slotSendToAutoDJ() { // append to auto DJ sendToAutoDJ(false); // bTop = false diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index d503a9b37ca..9bff23196f5 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -35,7 +35,6 @@ class WTrackTableView : public WLibraryTableView { void keyPressEvent(QKeyEvent* event) override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(QString group, bool play) override; - void setSortingEnabled(bool sorting); public slots: void loadTrackModel(QAbstractItemModel* model); From 083e5fb929a783e2662c8cf9413338158b0734b9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 11:01:17 +0200 Subject: [PATCH 266/552] Fixed bug with HistoryFeature causing SIGSEGV --- src/library/baseplaylistfeature.cpp | 3 +++ src/library/baseplaylistfeature.h | 2 +- src/library/historyfeature.cpp | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 7392e8b0046..33221f1cf7e 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -130,6 +130,9 @@ int BasePlaylistFeature::playlistIdFromIndex(QModelIndex index) { } QPointer BasePlaylistFeature::getPlaylistTableModel(int paneId) { + if (paneId < 0) { + paneId = m_focusedPane; + } auto it = m_playlistTableModel.find(paneId); if (it == m_playlistTableModel.end() || it->isNull()) { it = m_playlistTableModel.insert(paneId, constructTableModel()); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 9f3159b07f9..73391ef52fc 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -85,7 +85,7 @@ class BasePlaylistFeature : public LibraryFeature { PlaylistDAO &m_playlistDao; TrackDAO &m_trackDao; - PlaylistTableModel* m_pPlaylistTableModel; + QPointer m_pPlaylistTableModel; QHash > m_playlistTableModel; QAction *m_pCreatePlaylistAction; QAction *m_pDeletePlaylistAction; diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 11dcf7e17da..14e8c222b99 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -261,6 +261,8 @@ void HistoryFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) { if (!currentPlayingTrackId.isValid()) { return; } + + m_pPlaylistTableModel = getPlaylistTableModel(-1); if (m_pPlaylistTableModel->getPlaylist() == m_playlistId) { // View needs a refresh From 06d19de5a7b92c652788c49444dcee569a40a403 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 19:10:26 +0200 Subject: [PATCH 267/552] Add locale aware compare in tree generation --- src/library/librarytreemodel.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 1533f7898e0..ca300674f40 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -145,18 +145,28 @@ void LibraryTreeModel::createTracksTree() { for (const QString& col : m_sortOrder) { columns << "library." + col; } + + QStringList sortColumns; +#ifdef __SQLITE3__ + for (const QString& col : m_sortOrder) { + sortColumns << col + " COLLATE localeAwareCompare"; + } +#else + sortColumns = m_sortOrder; +#endif QString queryStr = "SELECT COUNT(%3),%1,%2 " "FROM library LEFT JOIN track_locations " "ON (%3 = %4) " "WHERE %5 != 1 " "GROUP BY %2 " - "ORDER BY %2"; + "ORDER BY %6 "; queryStr = queryStr.arg(m_coverQuery.join(","), columns.join(","), "library." + LIBRARYTABLE_ID, "track_locations." + TRACKLOCATIONSTABLE_ID, - "library." + LIBRARYTABLE_MIXXXDELETED); + "library." + LIBRARYTABLE_MIXXXDELETED, + sortColumns.join(",")); QSqlQuery query(m_pTrackCollection->getDatabase()); @@ -164,9 +174,12 @@ void LibraryTreeModel::createTracksTree() { if (!query.exec()) { LOG_FAILED_QUERY(query); + return; } - //qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); + qDebug() << QString("A").compare("Ä") << QString("A").localeAwareCompare("Â"); + qDebug() << QString("B").compare("Ä") << QString("B").localeAwareCompare("Ä"); + qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); int size = columns.size(); if (size <= 0) { @@ -197,7 +210,7 @@ void LibraryTreeModel::createTracksTree() { valueP = ""; value = tr("Unknown"); } - if (!lastUsed[i].isNull() && valueP == lastUsed[i]) { + if (!lastUsed[i].isNull() && valueP.localeAwareCompare(lastUsed[i]) == 0) { continue; } @@ -224,6 +237,7 @@ void LibraryTreeModel::createTracksTree() { parent[i]->appendChild(pTree); parent[i + 1] = pTree; + // Add coverart info if (extraSize + i == iAlbum && !unknown) { CoverInfo c; c.hash = query.value(iCoverHash).toInt(); From 341ca0945c8bd3907936547ef7ebe801a51a4e49 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 19:29:32 +0200 Subject: [PATCH 268/552] Add new "IS NULL" behavior --- src/library/librarytreemodel.cpp | 6 +----- src/library/searchqueryparser.cpp | 10 ++++------ src/library/searchqueryparser.h | 1 - 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index ca300674f40..a9055360663 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -97,11 +97,7 @@ QString LibraryTreeModel::getQuery(TreeItem* pTree) const { pAux = pTree; while (depth >= 0) { QString value = pAux->dataPath().toString(); - if (value == "") { - result << "\\+" + m_sortOrder[depth]; - } else { - result << m_sortOrder[depth] % ":\"" % value % "\""; - } + result << m_sortOrder[depth] % ":\"" % value % "\""; pAux = pAux->parent(); --depth; } diff --git a/src/library/searchqueryparser.cpp b/src/library/searchqueryparser.cpp index f5bdaf4b8b1..fe34e76f70c 100644 --- a/src/library/searchqueryparser.cpp +++ b/src/library/searchqueryparser.cpp @@ -54,7 +54,6 @@ SearchQueryParser::SearchQueryParser(QSqlDatabase& database) m_allFilters.append(m_specialFilters); m_fuzzyMatcher = QRegExp(QString("^~(%1)$").arg(m_allFilters.join("|"))); - m_isNullMatcher = QRegExp(QString("^\\\\\\+(%1)$").arg(m_allFilters.join("|"))); m_textFilterMatcher = QRegExp(QString("^-?(%1):(.*)$").arg(m_textFilters.join("|"))); m_numericFilterMatcher = QRegExp(QString("^-?(%1):(.*)$").arg(m_numericFilters.join("|"))); m_specialFilterMatcher = QRegExp(QString("^[~-]?(%1):(.*)$").arg(m_specialFilters.join("|"))); @@ -117,11 +116,6 @@ void SearchQueryParser::parseTokens(QStringList tokens, if (m_fuzzyMatcher.indexIn(token) != -1) { // TODO(XXX): implement this feature. - } else if (m_isNullMatcher.indexIn(token) != -1) { - QString field = m_isNullMatcher.cap(1); - std::unique_ptr pNode(std::make_unique( - field + " IS NULL")); - pQuery->addNode(std::move(pNode)); } else if (m_textFilterMatcher.indexIn(token) != -1) { bool negate = token.startsWith(kNegatePrefix); QString field = m_textFilterMatcher.cap(1); @@ -135,6 +129,10 @@ void SearchQueryParser::parseTokens(QStringList tokens, pNode = std::make_unique(std::move(pNode)); } pQuery->addNode(std::move(pNode)); + } else { + std::unique_ptr pNode(std::make_unique( + field + " IS NULL")); + pQuery->addNode(std::move(pNode)); } } else if (m_numericFilterMatcher.indexIn(token) != -1) { bool negate = token.startsWith(kNegatePrefix); diff --git a/src/library/searchqueryparser.h b/src/library/searchqueryparser.h index 1358d52432b..f505abcb335 100644 --- a/src/library/searchqueryparser.h +++ b/src/library/searchqueryparser.h @@ -34,7 +34,6 @@ class SearchQueryParser { QStringList m_allFilters; QHash m_fieldToSqlColumns; - QRegExp m_isNullMatcher; QRegExp m_fuzzyMatcher; QRegExp m_textFilterMatcher; QRegExp m_numericFilterMatcher; From b079e216f4f36d54e3d412afe604be5f354367ca Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 12 Jul 2016 20:53:30 +0200 Subject: [PATCH 269/552] Update tree on hidden tracks --- src/library/librarytreemodel.cpp | 8 ++------ src/library/librarytreemodel.h | 10 +++------- src/library/mixxxlibraryfeature.cpp | 20 ++++++++++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index a9055360663..94b5c7f4840 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -1,5 +1,3 @@ -#include - #include "library/coverartcache.h" #include "library/librarytreemodel.h" #include "library/mixxxlibraryfeature.h" @@ -31,7 +29,6 @@ LibraryTreeModel::LibraryTreeModel(MixxxLibraryFeature* pFeature, s.prepend("library."); } m_coverQuery << "track_locations." + TRACKLOCATIONSTABLE_LOCATION; - reloadTracksTree(); } @@ -106,6 +103,8 @@ QString LibraryTreeModel::getQuery(TreeItem* pTree) const { } void LibraryTreeModel::reloadTracksTree() { + qDebug() << "LibraryTreeModel::reloadTracksTree"; + // Create root item TreeItem* pRootItem = new TreeItem(); pRootItem->setLibraryFeature(m_pFeature); @@ -172,9 +171,6 @@ void LibraryTreeModel::createTracksTree() { LOG_FAILED_QUERY(query); return; } - - qDebug() << QString("A").compare("Ä") << QString("A").localeAwareCompare("Â"); - qDebug() << QString("B").compare("Ä") << QString("B").localeAwareCompare("Ä"); qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); int size = columns.size(); diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 4706666c414..a7cee16adb4 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -2,6 +2,7 @@ #define LIBRARYTREEMODEL_H #include +#include #include #include @@ -12,6 +13,7 @@ class MixxxLibraryFeature; class TrackCollection; class LibraryTreeModel : public TreeItemModel { + Q_OBJECT public: LibraryTreeModel(MixxxLibraryFeature* pFeature, TrackCollection* pTrackCollection, @@ -22,19 +24,13 @@ class LibraryTreeModel : public TreeItemModel { void setSortOrder(QStringList sortOrder); QString getQuery(TreeItem* pTree) const; + public slots: void reloadTracksTree(); - signals: - - void markInHash(quint16, const QModelIndex&); - private slots: - void coverFound(const QObject* requestor, int requestReference, const CoverInfo&, QPixmap pixmap, bool fromCache); - void slotMarkInHash(quint16 hash, const QModelIndex& index); - private: void createTracksTree(); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 3698aa87004..266a820f869 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -98,7 +98,16 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); + connect(&m_trackDao, SIGNAL(trackChanged(TrackId)), + &m_childModel, SLOT(reloadTracksTree())); + connect(&m_trackDao, SIGNAL(tracksRemoved(QSet)), + &m_childModel, SLOT(reloadTracksTree())); + connect(&m_trackDao, SIGNAL(tracksAdded(QSet)), + &m_childModel, SLOT(reloadTracksTree())); + m_pBaseTrackCache = QSharedPointer(pBaseTrackCache); + + pTrackCollection->setTrackSource(m_pBaseTrackCache); // These rely on the 'default' track source being present. @@ -170,23 +179,22 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, // Create the sort menu QMenu menu; QAction* artist_album = menu.addAction(tr("Artist > Album")); - QAction* album_artist = menu.addAction(tr("Album > Artist")); + QAction* album = menu.addAction(tr("Album")); QAction* genre_artist = menu.addAction(tr("Genre > Artist > Album")); - QAction* genre_album = menu.addAction(tr("Genre > Album > Artist")); + QAction* genre_album = menu.addAction(tr("Genre > Album")); QAction* selected = menu.exec(pos); QStringList sortOrder; if (selected == artist_album) { sortOrder << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; - } else if (selected == album_artist) { - sortOrder << LIBRARYTABLE_ALBUM << LIBRARYTABLE_ARTIST; + } else if (selected == album) { + sortOrder << LIBRARYTABLE_ALBUM; } else if (selected == genre_artist) { sortOrder << LIBRARYTABLE_GENRE << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; } else if (selected == genre_album) { - sortOrder << LIBRARYTABLE_GENRE << LIBRARYTABLE_ALBUM - << LIBRARYTABLE_ARTIST; + sortOrder << LIBRARYTABLE_GENRE << LIBRARYTABLE_ALBUM; } else { // Menu rejected return; From 89d6de824c9ddb73fc1dbfd25c96ad5cfec657d0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 09:32:15 +0200 Subject: [PATCH 270/552] Avoid showing missing tracks --- src/library/librarytreemodel.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 94b5c7f4840..363e82edb75 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -153,7 +153,7 @@ void LibraryTreeModel::createTracksTree() { QString queryStr = "SELECT COUNT(%3),%1,%2 " "FROM library LEFT JOIN track_locations " "ON (%3 = %4) " - "WHERE %5 != 1 " + "WHERE %5 != 1 AND %7 != 1 " "GROUP BY %2 " "ORDER BY %6 "; queryStr = queryStr.arg(m_coverQuery.join(","), @@ -161,7 +161,8 @@ void LibraryTreeModel::createTracksTree() { "library." + LIBRARYTABLE_ID, "track_locations." + TRACKLOCATIONSTABLE_ID, "library." + LIBRARYTABLE_MIXXXDELETED, - sortColumns.join(",")); + sortColumns.join(","), + "track_locations." + TRACKLOCATIONSTABLE_FSDELETED); QSqlQuery query(m_pTrackCollection->getDatabase()); From 1f9feb0980bdcc7b137a5be8caa724e471f59b23 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 10:33:59 +0200 Subject: [PATCH 271/552] Solve problem with headers and non ASCII characters --- src/library/librarytreemodel.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 363e82edb75..3d7783e1575 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -212,9 +212,24 @@ void LibraryTreeModel::createTracksTree() { // reset lastUsed.fill(QString()); + QChar c = value.at(0); + + // This removes the accents of the characters + if (c.isLetter()) { + // We only can remove the accents if its a latin character + if (c.toLatin1() != 0) { + QString s1 = value.normalized(QString::NormalizationForm_KD); + s1.remove(QRegExp("[^a-zA-Z]")); + + if (s1.size() > 0) { + c = s1.at(0).toUpper(); + } + } + } + // Check if a header must be added - if (lastHeader != value.at(0).toUpper()) { - lastHeader = value.at(0).toUpper(); + if (lastHeader != c) { + lastHeader = c; TreeItem* pTree = new TreeItem(lastHeader, lastHeader, m_pFeature, parent[0]); pTree->setDivider(true); From 9770ccce0bf856eeae5bb465ff1c8a7898077c1a Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:24:35 +0200 Subject: [PATCH 272/552] Add new mini view scrollbar --- build/depends.py | 2 + src/widget/wminiviewscrollbar.cpp | 65 ++++++++++++++++++++++++++++ src/widget/wminiviewscrollbar.h | 27 ++++++++++++ src/widget/wtableminiview.cpp | 71 +++++++++++++++++++++++++++++++ src/widget/wtableminiview.h | 27 ++++++++++++ src/widget/wtracktableview.cpp | 8 ++++ src/widget/wtracktableview.h | 2 + 7 files changed, 202 insertions(+) create mode 100644 src/widget/wminiviewscrollbar.cpp create mode 100644 src/widget/wminiviewscrollbar.h create mode 100644 src/widget/wtableminiview.cpp create mode 100644 src/widget/wtableminiview.h diff --git a/build/depends.py b/build/depends.py index 2325289c4ac..389a719352c 100644 --- a/build/depends.py +++ b/build/depends.py @@ -830,6 +830,8 @@ def sources(self, build): "widget/wfeatureclickbutton.cpp", "widget/wlibrarystack.cpp", "widget/wlibrarybreadcrumb.cpp", + "widget/wminiviewscrollbar.cpp", + "widget/wtableminiview.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp new file mode 100644 index 00000000000..43fd49bc16f --- /dev/null +++ b/src/widget/wminiviewscrollbar.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include "wminiviewscrollbar.h" + +WMiniViewScrollBar::WMiniViewScrollBar(QWidget* parent) + : QScrollBar(parent) { + +} + +void WMiniViewScrollBar::setShowLetters(bool show) { + m_showLetters = show; +} + +bool WMiniViewScrollBar::showLetters() const { + return m_showLetters; +} + +void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { + QScrollBar::paintEvent(event); + + if (m_showLetters) { + lettersPaint(event); + } +} + +void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { + QPainter painter(this); + + QStyleOptionSlider style; + style.init(this); + + style.orientation = orientation(); + style.maximum = maximum(); + style.minimum = minimum(); + style.sliderPosition = sliderPosition(); + style.sliderValue = value(); + style.singleStep = singleStep(); + style.pageStep = pageStep(); + + // Get total count + int totalCount = 0; + for (int x : m_count) { + totalCount += x; + } + + // Get total size + const QRect& total = style.rect; + QPoint topLeft = total.topLeft(); + + for (const QChar& c : m_letters) { + + // Get letter count + int count = m_count[c]; + int height = interpolHeight(count, 0, totalCount, + total.topLeft().y(), total.bottomLeft().y()); + } +} + +int WMiniViewScrollBar::interpolHeight(int current, int min1, int max1, int min2, + int max2) { + int aux1 = (current - min1)*(max2 - min2); + return (aux1/(max1 - min1)) + min2; +} + diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h new file mode 100644 index 00000000000..436f8e53b11 --- /dev/null +++ b/src/widget/wminiviewscrollbar.h @@ -0,0 +1,27 @@ +#ifndef WMINIVIEWSCROLLBAR_H +#define WMINIVIEWSCROLLBAR_H + +#include + +class WMiniViewScrollBar : public QScrollBar +{ + public: + WMiniViewScrollBar(QWidget* parent = nullptr); + + void setShowLetters(bool show); + bool showLetters() const; + + protected: + void paintEvent(QPaintEvent* event) override; + void lettersPaint(QPaintEvent* event); + + QHash m_count; + QVector m_letters; + + private: + int interpolHeight(int current, int min1, int max1, int min2, int max2); + + bool m_showLetters; +}; + +#endif // WMINIVIEWSCROLLBAR_H diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp new file mode 100644 index 00000000000..c41ed5a354d --- /dev/null +++ b/src/widget/wtableminiview.cpp @@ -0,0 +1,71 @@ +#include "widget/wtableminiview.h" + +WTableMiniView::WTableMiniView(QWidget* parent) + : WMiniViewScrollBar(parent) { + +} + +void WTableMiniView::setModel(QAbstractItemModel *model) { + m_pModel = model; + + connect(m_pModel.data(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(refreshCharMap())); + + refreshCharMap(); +} + +void WTableMiniView::setSortColumn(int column) { + m_sortColumn = column; + refreshCharMap(); +} + +void WTableMiniView::refreshCharMap() { + if (m_pModel.isNull()) { + return; + } + + m_count.clear(); + int size = m_pModel->rowCount(); + + for (int i = 0; i < size; ++i) { + const QModelIndex& index = m_pModel->index(i, m_sortColumn); + QString text = index.data().toString(); + QChar c = getFirstChar(text); + + // Add character to letters order vector + if (m_letters.size() <= 0 || c != m_letters.last()) { + m_letters.append(c); + } + + // Add character to character map + auto it = m_count.find(c); + if (it == m_count.end()) { + m_count.insert(c, 1); + } else { + ++(*it); + } + } + + repaint(); +} + +QChar WTableMiniView::getFirstChar(const QString& text) { + QChar c = text.at(0); + if (!c.isLetter()) { + return c; + } + + // This removes the accents of the characters + // We only can remove the accents if its a latin character + if (c.toLatin1() != 0) { + QString s1 = text.normalized(QString::NormalizationForm_KD); + s1.remove(QRegExp("[^a-zA-Z]")); + + if (s1.size() > 0) { + c = s1.at(0).toUpper(); + } + } + return c; +} + + diff --git a/src/widget/wtableminiview.h b/src/widget/wtableminiview.h new file mode 100644 index 00000000000..79a97311986 --- /dev/null +++ b/src/widget/wtableminiview.h @@ -0,0 +1,27 @@ +#ifndef WTABLEMINIVIEW_H +#define WTABLEMINIVIEW_H + +#include +#include + +#include "widget/wminiviewscrollbar.h" + +class WTableMiniView : public WMiniViewScrollBar +{ + public: + WTableMiniView(QWidget* parent = nullptr); + + void setModel(QAbstractItemModel *model); + void setSortColumn(int column); + + private slots: + void refreshCharMap(); + + private: + QChar getFirstChar(const QString& text); + + QPointer m_pModel; + int m_sortColumn; +}; + +#endif // WTABLEMINIVIEW_H diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 061b7e2579e..0ca9d8dba4c 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -356,6 +356,10 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) { setVisible(true); trackModel->select(); + + if (!m_pScrollBar.isNull()) { + m_pScrollBar->setModel(model); + } } void WTrackTableView::createActions() { @@ -1553,6 +1557,10 @@ void WTrackTableView::doSortByColumn(int headerSection) { scrollTo(first, QAbstractItemView::EnsureVisible); //scrollTo(first, QAbstractItemView::PositionAtCenter); } + + if (!m_pScrollBar.isNull()) { + m_pScrollBar->setSortColumn(headerSection); + } } void WTrackTableView::slotLockBpm() { diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 9bff23196f5..79bd816879a 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -13,6 +13,7 @@ #include "track/track.h" #include "util/duration.h" #include "widget/wlibrarytableview.h" +#include "widget/wtableminiview.h" class ControlProxy; class DlgTrackInfo; @@ -157,6 +158,7 @@ class WTrackTableView : public WLibraryTableView { // Replay Gain feature QAction *m_pReplayGainResetAction; + QPointer m_pScrollBar; bool m_sorting; From 4a02937cba2b98106625ed5c51cd2f11ed173c8b Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:24:59 +0200 Subject: [PATCH 273/552] Remove unnecessary code in AutoDJ --- src/library/autodj/autodjfeature.cpp | 35 ++++++---------------------- src/library/autodj/autodjfeature.h | 1 - 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index e222477143d..2060de531a7 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -100,23 +100,7 @@ QIcon AutoDJFeature::getIcon() { } QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTableView = - new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, false); - - pTrackTableView->installEventFilter(pKeyboard); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(const QFont&)), - pTrackTableView, SLOT(setTrackTableFont(const QFont&))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - - connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), - m_pLibrary, SIGNAL(trackSelected(TrackPointer))); - - m_trackTables[paneId] = pTrackTableView; - - pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); - + WTrackTableView* pTrackTableView = createTableWidget(pKeyboard, paneId); connect(pTrackTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, @@ -167,9 +151,9 @@ void AutoDJFeature::activate() { m_pAutoDJView->onShow(); - m_pLibrary->switchToFeature(this); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->restoreSearch(QString()); //Null String disables search box + showTrackModel(m_pAutoDJProcessor->getTableModel()); + showBreadCrumb(m_childModel.getItem(QModelIndex())); + restoreSearch(QString()); //Null String disables search box emit(enableCoverArtDisplay(true)); } @@ -428,15 +412,10 @@ void AutoDJFeature::slotRandomQueue(int tracksToAdd) { } void AutoDJFeature::selectionChanged(const QItemSelection&, const QItemSelection&) { - DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull()) { - return; - } - - auto it = m_trackTables.find(m_featureFocus); - if (it == m_trackTables.end() || it->isNull()) { + QPointer pTable = getFocusedTable(); + DEBUG_ASSERT_AND_HANDLE(!m_pAutoDJView.isNull() && !pTable.isNull()) { return; } - const QModelIndexList& selectedRows = (*it)->selectionModel()->selectedRows(); - m_pAutoDJView->setSelectedRows(selectedRows); + m_pAutoDJView->setSelectedRows(pTable->selectionModel()->selectedRows()); } diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index a433ec07237..7061d6df15c 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -65,7 +65,6 @@ class AutoDJFeature : public LibraryFeature { AutoDJProcessor* m_pAutoDJProcessor; TreeItemModel m_childModel; QPointer m_pAutoDJView; - QHash > m_trackTables; // Initialize the list of crates loaded into the auto-DJ queue. void constructCrateChildModel(); From d647c097e86a66f79ab4c865760ebf1b49be3657 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:25:37 +0200 Subject: [PATCH 274/552] Separate in small functions create tracks tree --- src/library/libraryfeature.cpp | 4 ++ src/library/librarytreemodel.cpp | 71 ++++++++++++++++++-------------- src/library/librarytreemodel.h | 13 ++++++ 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index b10342ce0d0..cecf938adde 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -17,6 +17,7 @@ #include "widget/wbaselibrary.h" #include "widget/wlibrarysidebar.h" #include "widget/wtracktableview.h" +#include "widget/wtableminiview.h" // KEEP THIS cpp file to tell scons that moc should be called on the class!!! // The reason for this is that LibraryFeature uses slots/signals and for this @@ -80,6 +81,9 @@ WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboar pTrackTableView->installEventFilter(pKeyboard); + WTableMiniView* pScrollBar = new WTableMiniView(pTrackTableView); + pTrackTableView->setVerticalScrollBar(pScrollBar); + connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); connect(pTrackTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 3d7783e1575..6fd30cfd7ab 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -181,11 +181,12 @@ void LibraryTreeModel::createTracksTree() { QSqlRecord record = query.record(); int iAlbum = record.indexOf(LIBRARYTABLE_ALBUM); - int iCoverHash = record.indexOf(LIBRARYTABLE_COVERART_HASH); - int iCoverLoc = record.indexOf(LIBRARYTABLE_COVERART_LOCATION); - int iCoverSrc = record.indexOf(LIBRARYTABLE_COVERART_SOURCE); - int iCoverType = record.indexOf(LIBRARYTABLE_COVERART_TYPE); - int iTrackLoc = record.indexOf(TRACKLOCATIONSTABLE_LOCATION); + CoverIndex cIndex; + cIndex.iCoverHash = record.indexOf(LIBRARYTABLE_COVERART_HASH); + cIndex.iCoverLoc = record.indexOf(LIBRARYTABLE_COVERART_LOCATION); + cIndex.iCoverSrc = record.indexOf(LIBRARYTABLE_COVERART_SOURCE); + cIndex.iCoverType = record.indexOf(LIBRARYTABLE_COVERART_TYPE); + cIndex.iTrackLoc = record.indexOf(TRACKLOCATIONSTABLE_LOCATION); int extraSize = m_coverQuery.size() + 1; QVector lastUsed(size); @@ -212,22 +213,8 @@ void LibraryTreeModel::createTracksTree() { // reset lastUsed.fill(QString()); - QChar c = value.at(0); - - // This removes the accents of the characters - if (c.isLetter()) { - // We only can remove the accents if its a latin character - if (c.toLatin1() != 0) { - QString s1 = value.normalized(QString::NormalizationForm_KD); - s1.remove(QRegExp("[^a-zA-Z]")); - - if (s1.size() > 0) { - c = s1.at(0).toUpper(); - } - } - } - // Check if a header must be added + QChar c = getFirstChar(value); if (lastHeader != c) { lastHeader = c; TreeItem* pTree = new TreeItem(lastHeader, lastHeader, @@ -247,16 +234,7 @@ void LibraryTreeModel::createTracksTree() { // Add coverart info if (extraSize + i == iAlbum && !unknown) { - CoverInfo c; - c.hash = query.value(iCoverHash).toInt(); - c.coverLocation = query.value(iCoverLoc).toString(); - c.trackLocation = query.value(iTrackLoc).toString(); - - quint16 source = query.value(iCoverSrc).toInt(); - quint16 type = query.value(iCoverType).toInt(); - c.source = static_cast(source); - c.type = static_cast(type); - pTree->setCoverInfo(c); + addCoverArt(cIndex, query, pTree); } } @@ -274,3 +252,36 @@ void LibraryTreeModel::createTracksTree() { triggerRepaint(); } + +void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, + const QSqlQuery& query, TreeItem* pTree) { + CoverInfo c; + c.hash = query.value(index.iCoverHash).toInt(); + c.coverLocation = query.value(index.iCoverLoc).toString(); + c.trackLocation = query.value(index.iTrackLoc).toString(); + + quint16 source = query.value(index.iCoverSrc).toInt(); + quint16 type = query.value(index.iCoverType).toInt(); + c.source = static_cast(source); + c.type = static_cast(type); + pTree->setCoverInfo(c); +} + +QChar LibraryTreeModel::getFirstChar(const QString& text) { + QChar c = text.at(0); + if (!c.isLetter()) { + return c; + } + + // This removes the accents of the characters + // We only can remove the accents if its a latin character + if (c.toLatin1() != 0) { + QString s1 = text.normalized(QString::NormalizationForm_KD); + s1.remove(QRegExp("[^a-zA-Z]")); + + if (s1.size() > 0) { + c = s1.at(0).toUpper(); + } + } + return c; +} diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index a7cee16adb4..9864dfbe5ec 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -27,12 +27,25 @@ class LibraryTreeModel : public TreeItemModel { public slots: void reloadTracksTree(); + private: + + struct CoverIndex { + int iCoverHash; + int iCoverLoc; + int iTrackLoc; + int iCoverSrc; + int iCoverType; + }; + private slots: void coverFound(const QObject* requestor, int requestReference, const CoverInfo&, QPixmap pixmap, bool fromCache); private: void createTracksTree(); + void addCoverArt(const CoverIndex& index, const QSqlQuery& query, TreeItem* pTree); + + QChar getFirstChar(const QString &text); MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; From 0aae8e4d32388bf73d3b93fac609ddd4326c4f56 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:31:13 +0200 Subject: [PATCH 275/552] Removed unnecessary code from Recording feature --- src/library/autodj/autodjfeature.cpp | 2 +- src/library/recording/recordingfeature.cpp | 24 +++++++--------------- src/library/recording/recordingfeature.h | 2 +- src/widget/wtracktableview.cpp | 4 ++++ src/widget/wtracktableview.h | 1 + 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 2060de531a7..79012a70c50 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -100,7 +100,7 @@ QIcon AutoDJFeature::getIcon() { } QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTableView = createTableWidget(pKeyboard, paneId); + WTrackTableView* pTrackTableView = LibraryFeature::createTableWidget(pKeyboard, paneId); connect(pTrackTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 7b3b369d393..87a824ee44d 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -43,20 +43,10 @@ TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } -QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int) { - WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, - m_pConfig, - m_pTrackCollection, - false); // No sorting - pTrackTableView->installEventFilter(pKeyboard); - - connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), - pTrackTableView, SLOT(setTrackTableFont(QFont))); - connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), - pTrackTableView, SLOT(setTrackTableRowHeight(int))); - pTrackTableView->loadTrackModel(getProxyTrackModel()); - - return pTrackTableView; +QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { + WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); + pTable->setSorting(false); + return pTable; } QWidget *RecordingFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { @@ -77,9 +67,9 @@ void RecordingFeature::activate() { } m_pRecordingView->refreshBrowseModel(); - m_pLibrary->switchToFeature(this); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->restoreSearch(""); + showTrackModel(getProxyTrackModel()); + showBreadCrumb(m_childModel.getItem(QModelIndex())); + restoreSearch(""); emit(enableCoverArtDisplay(false)); } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 01e241092a3..77293d2cb69 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -31,7 +31,7 @@ class RecordingFeature : public LibraryFeature { QVariant title(); QIcon getIcon(); - QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int) override; + QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int paneId) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; TreeItemModel* getChildModel(); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 0ca9d8dba4c..9c5619110dd 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1290,6 +1290,10 @@ void WTrackTableView::loadSelectedTrackToGroup(QString group, bool play) { loadSelectionToGroup(group, play); } +void WTrackTableView::setSorting(bool sorting) { + m_sorting = sorting; +} + void WTrackTableView::slotSendToAutoDJ() { // append to auto DJ sendToAutoDJ(false); // bTop = false diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 79bd816879a..454d4849b52 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -36,6 +36,7 @@ class WTrackTableView : public WLibraryTableView { void keyPressEvent(QKeyEvent* event) override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(QString group, bool play) override; + void setSorting(bool sorting); public slots: void loadTrackModel(QAbstractItemModel* model); From 162e7b30247cc7657adffd95be87d4c4d1996ed6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:32:40 +0200 Subject: [PATCH 276/552] Removed loading unnecessarily track model --- src/library/analysisfeature.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 3d0ac1ec164..abc6542d5b1 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -63,7 +63,6 @@ QIcon AnalysisFeature::getIcon() { QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); - pTable->loadTrackModel(getAnalysisTableModel()); connect(pTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, @@ -111,12 +110,11 @@ void AnalysisFeature::selectAll() { void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; - //m_pLibrary->switchToView(m_sAnalysisViewName); - m_pLibrary->switchToFeature(this); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showTrackModel(getAnalysisTableModel()); + showBreadCrumb(m_childModel.getItem(QModelIndex())); if (!m_pAnalysisView.isNull()) { - m_pLibrary->restoreSearch(m_pAnalysisView->currentSearch()); + restoreSearch(m_pAnalysisView->currentSearch()); } emit(enableCoverArtDisplay(true)); } From a8512d4bb0a87c400a33675083254a6c1d5ca1a1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 14:57:08 +0200 Subject: [PATCH 277/552] Begin of scrollbar painter implementation --- src/library/libraryfeature.cpp | 2 +- src/widget/wminiviewscrollbar.cpp | 31 ++++++++++++++++++++----------- src/widget/wtableminiview.cpp | 3 +++ src/widget/wtracktableview.cpp | 5 +++++ src/widget/wtracktableview.h | 1 + 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index cecf938adde..6c051c3d2f0 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -82,7 +82,7 @@ WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboar pTrackTableView->installEventFilter(pKeyboard); WTableMiniView* pScrollBar = new WTableMiniView(pTrackTableView); - pTrackTableView->setVerticalScrollBar(pScrollBar); + pTrackTableView->setScrollBar(pScrollBar); connect(pTrackTableView, SIGNAL(loadTrack(TrackPointer)), this, SIGNAL(loadTrack(TrackPointer))); diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 43fd49bc16f..1c3067d3611 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -1,10 +1,13 @@ +#include #include +#include #include #include "wminiviewscrollbar.h" WMiniViewScrollBar::WMiniViewScrollBar(QWidget* parent) - : QScrollBar(parent) { + : QScrollBar(parent), + m_showLetters(true) { } @@ -27,16 +30,16 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { QPainter painter(this); - QStyleOptionSlider style; - style.init(this); + QStyleOptionSlider styleOpts; + styleOpts.init(this); - style.orientation = orientation(); - style.maximum = maximum(); - style.minimum = minimum(); - style.sliderPosition = sliderPosition(); - style.sliderValue = value(); - style.singleStep = singleStep(); - style.pageStep = pageStep(); + styleOpts.orientation = orientation(); + styleOpts.maximum = maximum(); + styleOpts.minimum = minimum(); + styleOpts.sliderPosition = sliderPosition(); + styleOpts.sliderValue = value(); + styleOpts.singleStep = singleStep(); + styleOpts.pageStep = pageStep(); // Get total count int totalCount = 0; @@ -45,7 +48,7 @@ void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { } // Get total size - const QRect& total = style.rect; + const QRect& total = event->rect(); QPoint topLeft = total.topLeft(); for (const QChar& c : m_letters) { @@ -54,6 +57,12 @@ void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { int count = m_count[c]; int height = interpolHeight(count, 0, totalCount, total.topLeft().y(), total.bottomLeft().y()); + + QPoint bottomRight = topLeft + QPoint(total.width(), height); + painter.setBrush(palette().color(QPalette::Text)); + painter.drawText(QRect(topLeft, bottomRight), QString(c)); + + topLeft += QPoint(0, height); } } diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp index c41ed5a354d..d5fd8f20477 100644 --- a/src/widget/wtableminiview.cpp +++ b/src/widget/wtableminiview.cpp @@ -30,6 +30,9 @@ void WTableMiniView::refreshCharMap() { for (int i = 0; i < size; ++i) { const QModelIndex& index = m_pModel->index(i, m_sortColumn); QString text = index.data().toString(); + if (text.isEmpty()) { + continue; + } QChar c = getFirstChar(text); // Add character to letters order vector diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 9c5619110dd..f5aeb682e66 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1294,6 +1294,11 @@ void WTrackTableView::setSorting(bool sorting) { m_sorting = sorting; } +void WTrackTableView::setScrollBar(WTableMiniView *pScrollbar) { + m_pScrollBar = pScrollbar; + setVerticalScrollBar(pScrollbar); +} + void WTrackTableView::slotSendToAutoDJ() { // append to auto DJ sendToAutoDJ(false); // bTop = false diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 454d4849b52..44a20d23f50 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -37,6 +37,7 @@ class WTrackTableView : public WLibraryTableView { void loadSelectedTrack() override; void loadSelectedTrackToGroup(QString group, bool play) override; void setSorting(bool sorting); + void setScrollBar(WTableMiniView* pScrollbar); public slots: void loadTrackModel(QAbstractItemModel* model); From f5e5161b1bfe7f145be6c7ab785c72e3ec261232 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 13 Jul 2016 18:09:37 +0200 Subject: [PATCH 278/552] Improve letter draw in paint event --- src/widget/wminiviewscrollbar.cpp | 19 +++++++------------ src/widget/wminiviewscrollbar.h | 2 +- src/widget/wtableminiview.cpp | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 1c3067d3611..34f81aa3171 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -27,20 +27,12 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { } } -void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { +void WMiniViewScrollBar::lettersPaint(QPaintEvent*) { QPainter painter(this); QStyleOptionSlider styleOpts; styleOpts.init(this); - - styleOpts.orientation = orientation(); - styleOpts.maximum = maximum(); - styleOpts.minimum = minimum(); - styleOpts.sliderPosition = sliderPosition(); - styleOpts.sliderValue = value(); - styleOpts.singleStep = singleStep(); - styleOpts.pageStep = pageStep(); - + // Get total count int totalCount = 0; for (int x : m_count) { @@ -48,8 +40,10 @@ void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { } // Get total size - const QRect& total = event->rect(); + const QRect& total = styleOpts.rect; QPoint topLeft = total.topLeft(); + QFont f(font()); + f.setPointSize(f.pointSize()/1.5); for (const QChar& c : m_letters) { @@ -60,7 +54,8 @@ void WMiniViewScrollBar::lettersPaint(QPaintEvent* event) { QPoint bottomRight = topLeft + QPoint(total.width(), height); painter.setBrush(palette().color(QPalette::Text)); - painter.drawText(QRect(topLeft, bottomRight), QString(c)); + painter.setFont(f); + painter.drawText(QRect(topLeft, bottomRight), Qt::AlignTop | Qt::AlignHCenter, QString(c)); topLeft += QPoint(0, height); } diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index 436f8e53b11..7b6e5bbaa8e 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -13,7 +13,7 @@ class WMiniViewScrollBar : public QScrollBar protected: void paintEvent(QPaintEvent* event) override; - void lettersPaint(QPaintEvent* event); + void lettersPaint(QPaintEvent*); QHash m_count; QVector m_letters; diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp index d5fd8f20477..7c6ea581f76 100644 --- a/src/widget/wtableminiview.cpp +++ b/src/widget/wtableminiview.cpp @@ -49,7 +49,7 @@ void WTableMiniView::refreshCharMap() { } } - repaint(); + update(); } QChar WTableMiniView::getFirstChar(const QString& text) { From 975b7f32f2f4988b74481e01b0d628e7b6267459 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 14 Jul 2016 10:50:53 +0200 Subject: [PATCH 279/552] Added stringhelper class and added tests for string helper Solved problem with Finnish and other special characters sorting --- build/depends.py | 1 + src/library/librarytreemodel.cpp | 23 ++-------- src/library/librarytreemodel.h | 2 - src/test/searchqueryparsertest.cpp | 9 ++-- src/test/stringhelpertest.cpp | 68 ++++++++++++++++++++++++++++++ src/util/stringhelper.cpp | 36 ++++++++++++++++ src/util/stringhelper.h | 12 ++++++ src/widget/wtableminiview.cpp | 24 ++--------- src/widget/wtableminiview.h | 4 +- 9 files changed, 127 insertions(+), 52 deletions(-) create mode 100644 src/test/stringhelpertest.cpp create mode 100644 src/util/stringhelper.cpp create mode 100644 src/util/stringhelper.h diff --git a/build/depends.py b/build/depends.py index 389a719352c..aaf66c2e8c3 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1082,6 +1082,7 @@ def sources(self, build): "util/rotary.cpp", "util/logging.cpp", "util/cmdlineargs.cpp", + "util/stringhelper.cpp", '#res/mixxx.qrc' ] diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 6fd30cfd7ab..4b1626c6cd5 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -5,6 +5,8 @@ #include "library/trackcollection.h" #include "library/treeitem.h" +#include "util/stringhelper.h" + namespace { QHash m_hashToIndex; } @@ -214,7 +216,7 @@ void LibraryTreeModel::createTracksTree() { lastUsed.fill(QString()); // Check if a header must be added - QChar c = getFirstChar(value); + QChar c = StringHelper::getFirstChar(value); if (lastHeader != c) { lastHeader = c; TreeItem* pTree = new TreeItem(lastHeader, lastHeader, @@ -266,22 +268,3 @@ void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, c.type = static_cast(type); pTree->setCoverInfo(c); } - -QChar LibraryTreeModel::getFirstChar(const QString& text) { - QChar c = text.at(0); - if (!c.isLetter()) { - return c; - } - - // This removes the accents of the characters - // We only can remove the accents if its a latin character - if (c.toLatin1() != 0) { - QString s1 = text.normalized(QString::NormalizationForm_KD); - s1.remove(QRegExp("[^a-zA-Z]")); - - if (s1.size() > 0) { - c = s1.at(0).toUpper(); - } - } - return c; -} diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 9864dfbe5ec..d9515052ccd 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -45,8 +45,6 @@ class LibraryTreeModel : public TreeItemModel { void createTracksTree(); void addCoverArt(const CoverIndex& index, const QSqlQuery& query, TreeItem* pTree); - QChar getFirstChar(const QString &text); - MixxxLibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; QStringList m_sortOrder; diff --git a/src/test/searchqueryparsertest.cpp b/src/test/searchqueryparsertest.cpp index 5400d69ac7b..6d0522221f9 100644 --- a/src/test/searchqueryparsertest.cpp +++ b/src/test/searchqueryparsertest.cpp @@ -189,17 +189,14 @@ TEST_F(SearchQueryParserTest, TextFilterEmpty) { searchColumns << "artist" << "album"; - // An empty argument should pass everything. + // An empty argument should pass "is null" elements. auto pQuery( m_parser.parseQuery("comment:", searchColumns, "")); TrackPointer pTrack(Track::newTemporary()); pTrack->setComment("test ASDF test"); - EXPECT_TRUE(pQuery->match(pTrack)); - - EXPECT_STREQ( - qPrintable(QString("")), - qPrintable(pQuery->toSql())); + EXPECT_TRUE(pQuery->match(pTrack)); + EXPECT_TRUE(pQuery->toSql().contains(QRegExp(".*IS NULL.*"))); } TEST_F(SearchQueryParserTest, TextFilterQuote) { diff --git a/src/test/stringhelpertest.cpp b/src/test/stringhelpertest.cpp new file mode 100644 index 00000000000..c8aa7b1d681 --- /dev/null +++ b/src/test/stringhelpertest.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#include + +#include "util/stringhelper.h" + +namespace { + +TEST(StringHelperTest, Ascii) { + QChar c = StringHelper::getFirstChar("a"); + ASSERT_EQ(c, QChar('A')); +} + +TEST(StringHelperTest, Null) { + QChar c = StringHelper::getFirstChar(""); + ASSERT_TRUE(c.isNull()); +} + +TEST(StringHelperTest, Change) { + QString s1 = QString::fromUtf8("ç"); + QString s2 = QString::fromUtf8("C"); + QChar c1 = StringHelper::getFirstChar(s1); + QChar c2 = s2.at(0); + ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) + << qPrintable(c1) << " " << qPrintable(c2); +} + +TEST(StringHelperTest, RemoveAccent) { + QString s1 = QString::fromUtf8("à"); + QString s2 = QString::fromUtf8("A"); + QChar c1 = StringHelper::getFirstChar(s1); + QChar c2 = s2.at(0); + ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) + << qPrintable(c1) << " " << qPrintable(c2); +} + +TEST(StringHelperTest, Finnish) { + QLocale prev; + QLocale::setDefault(QLocale::Finnish); + + QString s1 = QString::fromUtf8("å"); + QString s2 = QString::fromUtf8("Å"); + QChar c1 = StringHelper::getFirstChar(s1); + QChar c2 = s2.at(0); + ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) + << qPrintable(c1) << " " << qPrintable(c2); + + QLocale::setDefault(prev); +} + +TEST(StringHelperTest, Chinese) { + QLocale prev; + QLocale::setDefault(QLocale::Chinese); + + QString s1 = QString::fromUtf8("诶"); + QString s2 = QString::fromUtf8("诶"); + QChar c1 = StringHelper::getFirstChar(s1); + QChar c2 = s2.at(0); + ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) + << qPrintable(c1) << " " << qPrintable(c2); + + QLocale::setDefault(prev); +} + +} diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp new file mode 100644 index 00000000000..b77a2cd98ab --- /dev/null +++ b/src/util/stringhelper.cpp @@ -0,0 +1,36 @@ +#include +#include + +#include "stringhelper.h" + +StringHelper::StringHelper() { + +} + +QChar StringHelper::getFirstChar(const QString& text) { + if (text.size() <= 0) { + return QChar(); + } + + QChar c = text.at(0); + if (!c.isLetter()) { + return c; + } + c = c.toUpper(); + QString letter(c); + QString limmit("Z"); + if (QString::localeAwareCompare(limmit, letter) < 0) { + // The letter is above z so we must not change it + return c; + } + + // This removes the accents of the characters + QString s1 = letter.normalized(QString::NormalizationForm_KD); + s1.remove(QRegExp("[^A-Z]")); + + if (s1.size() > 0) { + c = s1.at(0).toUpper(); + } + return c; +} + diff --git a/src/util/stringhelper.h b/src/util/stringhelper.h new file mode 100644 index 00000000000..ceb77e2536c --- /dev/null +++ b/src/util/stringhelper.h @@ -0,0 +1,12 @@ +#ifndef STRINGHELPER_H +#define STRINGHELPER_H + +class StringHelper +{ + public: + StringHelper(); + + static QChar getFirstChar(const QString &text); +}; + +#endif // STRINGHELPER_H diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp index 7c6ea581f76..91af868e06a 100644 --- a/src/widget/wtableminiview.cpp +++ b/src/widget/wtableminiview.cpp @@ -1,5 +1,7 @@ #include "widget/wtableminiview.h" +#include "util/stringhelper.h" + WTableMiniView::WTableMiniView(QWidget* parent) : WMiniViewScrollBar(parent) { @@ -33,7 +35,7 @@ void WTableMiniView::refreshCharMap() { if (text.isEmpty()) { continue; } - QChar c = getFirstChar(text); + QChar c = StringHelper::getFirstChar(text); // Add character to letters order vector if (m_letters.size() <= 0 || c != m_letters.last()) { @@ -52,23 +54,3 @@ void WTableMiniView::refreshCharMap() { update(); } -QChar WTableMiniView::getFirstChar(const QString& text) { - QChar c = text.at(0); - if (!c.isLetter()) { - return c; - } - - // This removes the accents of the characters - // We only can remove the accents if its a latin character - if (c.toLatin1() != 0) { - QString s1 = text.normalized(QString::NormalizationForm_KD); - s1.remove(QRegExp("[^a-zA-Z]")); - - if (s1.size() > 0) { - c = s1.at(0).toUpper(); - } - } - return c; -} - - diff --git a/src/widget/wtableminiview.h b/src/widget/wtableminiview.h index 79a97311986..2a65c12df82 100644 --- a/src/widget/wtableminiview.h +++ b/src/widget/wtableminiview.h @@ -17,9 +17,7 @@ class WTableMiniView : public WMiniViewScrollBar private slots: void refreshCharMap(); - private: - QChar getFirstChar(const QString& text); - + private: QPointer m_pModel; int m_sortColumn; }; From c0328b02b28e04fcbbff41a573499968908ad805 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 14 Jul 2016 14:29:08 +0200 Subject: [PATCH 280/552] Improve painting function in MiniView ScrollBar --- src/library/librarytreemodel.cpp | 2 +- src/test/stringhelpertest.cpp | 12 +-- src/util/stringhelper.cpp | 7 +- src/util/stringhelper.h | 2 +- src/widget/wminiviewscrollbar.cpp | 146 +++++++++++++++++++++++++----- src/widget/wminiviewscrollbar.h | 21 ++++- src/widget/wtableminiview.cpp | 28 +++--- 7 files changed, 163 insertions(+), 55 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 4b1626c6cd5..4d5ee378bc2 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -216,7 +216,7 @@ void LibraryTreeModel::createTracksTree() { lastUsed.fill(QString()); // Check if a header must be added - QChar c = StringHelper::getFirstChar(value); + QChar c = StringHelper::getFirstCharForGrouping(value); if (lastHeader != c) { lastHeader = c; TreeItem* pTree = new TreeItem(lastHeader, lastHeader, diff --git a/src/test/stringhelpertest.cpp b/src/test/stringhelpertest.cpp index c8aa7b1d681..afe4de2cbae 100644 --- a/src/test/stringhelpertest.cpp +++ b/src/test/stringhelpertest.cpp @@ -10,19 +10,19 @@ namespace { TEST(StringHelperTest, Ascii) { - QChar c = StringHelper::getFirstChar("a"); + QChar c = StringHelper::getFirstCharForGrouping("a"); ASSERT_EQ(c, QChar('A')); } TEST(StringHelperTest, Null) { - QChar c = StringHelper::getFirstChar(""); + QChar c = StringHelper::getFirstCharForGrouping(""); ASSERT_TRUE(c.isNull()); } TEST(StringHelperTest, Change) { QString s1 = QString::fromUtf8("ç"); QString s2 = QString::fromUtf8("C"); - QChar c1 = StringHelper::getFirstChar(s1); + QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); @@ -31,7 +31,7 @@ TEST(StringHelperTest, Change) { TEST(StringHelperTest, RemoveAccent) { QString s1 = QString::fromUtf8("à"); QString s2 = QString::fromUtf8("A"); - QChar c1 = StringHelper::getFirstChar(s1); + QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); @@ -43,7 +43,7 @@ TEST(StringHelperTest, Finnish) { QString s1 = QString::fromUtf8("å"); QString s2 = QString::fromUtf8("Å"); - QChar c1 = StringHelper::getFirstChar(s1); + QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); @@ -57,7 +57,7 @@ TEST(StringHelperTest, Chinese) { QString s1 = QString::fromUtf8("诶"); QString s2 = QString::fromUtf8("诶"); - QChar c1 = StringHelper::getFirstChar(s1); + QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp index b77a2cd98ab..1fa299cbf7d 100644 --- a/src/util/stringhelper.cpp +++ b/src/util/stringhelper.cpp @@ -7,7 +7,7 @@ StringHelper::StringHelper() { } -QChar StringHelper::getFirstChar(const QString& text) { +QChar StringHelper::getFirstCharForGrouping(const QString& text) { if (text.size() <= 0) { return QChar(); } @@ -20,7 +20,10 @@ QChar StringHelper::getFirstChar(const QString& text) { QString letter(c); QString limmit("Z"); if (QString::localeAwareCompare(limmit, letter) < 0) { - // The letter is above z so we must not change it + // The letter is above z so we must not change it this is due to + // Chinese letters or Finnish sorting. In Finnish the correct sorting + // is a-z, å, ä, ö and the user will expect these letters at the + // end and not like this a, ä, å, b-o, ö, p-z return c; } diff --git a/src/util/stringhelper.h b/src/util/stringhelper.h index ceb77e2536c..f014882cccc 100644 --- a/src/util/stringhelper.h +++ b/src/util/stringhelper.h @@ -6,7 +6,7 @@ class StringHelper public: StringHelper(); - static QChar getFirstChar(const QString &text); + static QChar getFirstCharForGrouping(const QString &text); }; #endif // STRINGHELPER_H diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 34f81aa3171..097c7bf34a6 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -8,7 +8,6 @@ WMiniViewScrollBar::WMiniViewScrollBar(QWidget* parent) : QScrollBar(parent), m_showLetters(true) { - } void WMiniViewScrollBar::setShowLetters(bool show) { @@ -19,6 +18,14 @@ bool WMiniViewScrollBar::showLetters() const { return m_showLetters; } +void WMiniViewScrollBar::setLetters(const QVector >& letters) { + m_lettersMutex.lock(); + m_letters = letters; + m_lettersMutex.unlock(); + computeLettersSize(); + update(); +} + void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { QScrollBar::paintEvent(event); @@ -27,43 +34,134 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { } } +void WMiniViewScrollBar::resizeEvent(QResizeEvent* pEvent) { + computeLettersSize(); + QScrollBar::resizeEvent(pEvent); +} + void WMiniViewScrollBar::lettersPaint(QPaintEvent*) { QPainter painter(this); - - QStyleOptionSlider styleOpts; - styleOpts.init(this); + painter.setBrush(palette().color(QPalette::Text)); + painter.setFont(font()); - // Get total count - int totalCount = 0; - for (int x : m_count) { - totalCount += x; - } + int flags = Qt::AlignTop | Qt::AlignHCenter; // Get total size - const QRect& total = styleOpts.rect; + const QRect& total = rect(); QPoint topLeft = total.topLeft(); - QFont f(font()); - f.setPointSize(f.pointSize()/1.5); - - for (const QChar& c : m_letters) { + + QMutexLocker lock(&m_computeMutex); + for (const QPair& p : m_computedSize) { // Get letter count - int count = m_count[c]; - int height = interpolHeight(count, 0, totalCount, - total.topLeft().y(), total.bottomLeft().y()); + int height = p.second; QPoint bottomRight = topLeft + QPoint(total.width(), height); - painter.setBrush(palette().color(QPalette::Text)); - painter.setFont(f); - painter.drawText(QRect(topLeft, bottomRight), Qt::AlignTop | Qt::AlignHCenter, QString(c)); + painter.drawText(QRect(topLeft, bottomRight), flags, p.first); topLeft += QPoint(0, height); } } -int WMiniViewScrollBar::interpolHeight(int current, int min1, int max1, int min2, - int max2) { - int aux1 = (current - min1)*(max2 - min2); - return (aux1/(max1 - min1)) + min2; +void WMiniViewScrollBar::computeLettersSize() { + m_lettersMutex.lock(); + const QRect& total(rect()); + + // Height of a letter + int letterSize = fontMetrics().height(); + int totalLetters = m_letters.size(); + bool enoughSpace = total.height() >= letterSize*totalLetters; + const int totalLinearSize = total.height(); + int difference = 0; + int prevSpace = 0; + int totalCount = 0; + // Get the total count of letters appearance to make a linear interpolation + // with the current widget height + for (const QPair& p : m_letters) { + totalCount += p.second; + } + + QMutexLocker locker(&m_computeMutex); + m_computedSize = m_letters; + m_lettersMutex.unlock(); + + if (!enoughSpace) { + // Remove the letters from smaller letter to biggest + // since we need to preserve the current sort order we can't sort + // the vector by size and we'll need to find each letter one by one + int neededSpace = abs(totalLinearSize - letterSize*totalLetters); + + while (neededSpace > 0.5) { + int index = findSmallest(m_computedSize); + neededSpace -= letterSize; + m_computedSize.remove(index); + } + } + + int totalSizeCheck = 0; + for (QPair& p : m_computedSize) { + int height = interpolHeight(p.second, + 0, totalCount, + 0, totalLinearSize); + + int auxDifference = abs(letterSize - height); + + if (height >= letterSize) { + prevSpace = qMax(0, auxDifference - difference); + difference = qMax(0, difference - auxDifference); + } else { + // Add a difference to remove it when a letter is bigger than the + // size it needs + difference += auxDifference; + prevSpace = 0; + } + int itemSize = letterSize + prevSpace; + totalSizeCheck += itemSize; + p.second = itemSize; + } + + if (totalSizeCheck > totalLinearSize) { + // Do the same algorithm reversed, it should take the space from the + // biggest elements in the other direction. + + int difference = 0; + int prevSpace = 0; + for (int i = m_computedSize.size() - 1; i >= 0; --i) { + int height = m_computedSize[i].second; + int auxDifference = abs(letterSize - height); + + if (height >= letterSize) { + prevSpace = qMax(0, auxDifference - difference); + difference = qMax(0, difference - auxDifference); + } else { + // Add a difference to remove it when a letter is bigger than the + // size it needs + difference += auxDifference; + prevSpace = 0; + } + m_computedSize[i].second = letterSize + prevSpace; + } + } +} + +float WMiniViewScrollBar::interpolHeight(float current, float min1, float max1, + float min2, float max2) { + float aux1 = (current - min1)*(max2 - min2); + float res = (aux1/(max1 - min1)) + min2; + return res; +} + +int WMiniViewScrollBar::findSmallest(const QVector >& vector) { + if (vector.size() <= 0) { + return -1; + } + + int smallestIndex = 0; + for (int i = 1; i < vector.size(); ++i) { + if (vector[i].second < vector[smallestIndex].second) { + smallestIndex = i; + } + } + return smallestIndex; } diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index 7b6e5bbaa8e..9aa3f55c84d 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -1,6 +1,7 @@ #ifndef WMINIVIEWSCROLLBAR_H #define WMINIVIEWSCROLLBAR_H +#include #include class WMiniViewScrollBar : public QScrollBar @@ -10,18 +11,28 @@ class WMiniViewScrollBar : public QScrollBar void setShowLetters(bool show); bool showLetters() const; + + // Sets the letters to be shown and triggers a update + void setLetters(const QVector >& letters); protected: - void paintEvent(QPaintEvent* event) override; + virtual void paintEvent(QPaintEvent* event); + virtual void resizeEvent(QResizeEvent*pEvent); void lettersPaint(QPaintEvent*); - - QHash m_count; - QVector m_letters; private: - int interpolHeight(int current, int min1, int max1, int min2, int max2); + // The purpose of this function is to avoid computing all the sizes in the + // paintEvent function which can block the GUI thread + void computeLettersSize(); + + static float interpolHeight(float current, float min1, float max1, float min2, float max2); + static int findSmallest(const QVector >& vector); bool m_showLetters; + QVector > m_letters; + QVector > m_computedSize; + QMutex m_computeMutex; + QMutex m_lettersMutex; }; #endif // WMINIVIEWSCROLLBAR_H diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp index 91af868e06a..d6b83afa861 100644 --- a/src/widget/wtableminiview.cpp +++ b/src/widget/wtableminiview.cpp @@ -26,31 +26,27 @@ void WTableMiniView::refreshCharMap() { return; } - m_count.clear(); int size = m_pModel->rowCount(); + QVector > letters; for (int i = 0; i < size; ++i) { const QModelIndex& index = m_pModel->index(i, m_sortColumn); QString text = index.data().toString(); - if (text.isEmpty()) { - continue; - } - QChar c = StringHelper::getFirstChar(text); - - // Add character to letters order vector - if (m_letters.size() <= 0 || c != m_letters.last()) { - m_letters.append(c); - } + QChar c = StringHelper::getFirstCharForGrouping(text); - // Add character to character map - auto it = m_count.find(c); - if (it == m_count.end()) { - m_count.insert(c, 1); + if (letters.size() <= 0) { + letters.append(qMakePair(c, 1)); } else { - ++(*it); + QPair &last = letters.last(); + + if (last.first == c) { + ++last.second; + } else { + letters.append(qMakePair(c, 1)); + } } } - update(); + setLetters(letters); } From d15d4646966e6c75910f10d173472b1fd21130f1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 14 Jul 2016 14:43:58 +0200 Subject: [PATCH 281/552] Miniview sidebar fully working on WTrackTable --- res/skins/Deere/style.qss | 5 +++++ src/widget/wminiviewscrollbar.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 665abc0739d..8e88530f805 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -129,6 +129,11 @@ QTableView { gridline-color: red; } +QTableView QScrollBar { + color: #d2d2d2; + font-size: 8pt; +} + /* checkbox in library "Played" column */ QTableView::indicator { width: 12px; diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 097c7bf34a6..dc9d276da71 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -124,8 +124,8 @@ void WMiniViewScrollBar::computeLettersSize() { // Do the same algorithm reversed, it should take the space from the // biggest elements in the other direction. - int difference = 0; - int prevSpace = 0; + difference = totalSizeCheck - totalLinearSize; + prevSpace = 0; for (int i = m_computedSize.size() - 1; i >= 0; --i) { int height = m_computedSize[i].second; int auxDifference = abs(letterSize - height); From f289da656b9a5225eb74e6b10fd7a257c6701546 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 14 Jul 2016 22:18:26 +0200 Subject: [PATCH 282/552] Add scrollbar mini view to tree --- build/depends.py | 1 + res/skins/Deere/style.qss | 5 ++++ src/library/libraryfeature.cpp | 9 ++++++- src/library/librarytreemodel.cpp | 2 +- src/util/stringhelper.cpp | 4 +--- src/widget/wminiviewscrollbar.cpp | 11 +++++++++ src/widget/wminiviewscrollbar.h | 6 +++++ src/widget/wtableminiview.cpp | 11 +-------- src/widget/wtableminiview.h | 4 +--- src/widget/wtreeminiview.cpp | 40 +++++++++++++++++++++++++++++++ src/widget/wtreeminiview.h | 14 +++++++++++ 11 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 src/widget/wtreeminiview.cpp create mode 100644 src/widget/wtreeminiview.h diff --git a/build/depends.py b/build/depends.py index aaf66c2e8c3..34219b442f1 100644 --- a/build/depends.py +++ b/build/depends.py @@ -832,6 +832,7 @@ def sources(self, build): "widget/wlibrarybreadcrumb.cpp", "widget/wminiviewscrollbar.cpp", "widget/wtableminiview.cpp", + "widget/wtreeminiview.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 8e88530f805..7779ea34470 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -357,6 +357,11 @@ QTreeView { margin: 4px 0px 0px 0px; } +QTreeView QScrollBar { + color: #d2d2d2; + font-size: 8pt; +} + /* sidebar, as well as root items for playlists, crates, and history */ QTextBrowser, QTreeView { color: #d2d2d2; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 6c051c3d2f0..fc4b40514c0 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -18,6 +18,7 @@ #include "widget/wlibrarysidebar.h" #include "widget/wtracktableview.h" #include "widget/wtableminiview.h" +#include "widget/wtreeminiview.h" // KEEP THIS cpp file to tell scons that moc should be called on the class!!! // The reason for this is that LibraryFeature uses slots/signals and for this @@ -107,7 +108,13 @@ QWidget* LibraryFeature::createInnerSidebarWidget(KeyboardEventFilter *pKeyboard WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter *pKeyboard) { WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); pSidebar->installEventFilter(pKeyboard); - pSidebar->setModel(getChildModel()); + QAbstractItemModel* pModel = getChildModel(); + pSidebar->setModel(pModel); + + // Set sidebar mini view + WTreeMiniView* pMiniView = new WTreeMiniView(pSidebar); + pMiniView->setModel(pModel); + pSidebar->setVerticalScrollBar(pMiniView); connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), this, SLOT(activateChild(const QModelIndex&))); diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 4d5ee378bc2..653c86d8396 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -112,7 +112,7 @@ void LibraryTreeModel::reloadTracksTree() { pRootItem->setLibraryFeature(m_pFeature); QString title = m_pFeature->title().toString(); - m_pLibraryItem = new TreeItem(title, title, m_pFeature, pRootItem); + m_pLibraryItem = new TreeItem(title, "", m_pFeature, pRootItem); m_pLibraryItem->setIcon(m_pFeature->getIcon()); pRootItem->appendChild(m_pLibraryItem); diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp index 1fa299cbf7d..09859cafd4c 100644 --- a/src/util/stringhelper.cpp +++ b/src/util/stringhelper.cpp @@ -28,9 +28,7 @@ QChar StringHelper::getFirstCharForGrouping(const QString& text) { } // This removes the accents of the characters - QString s1 = letter.normalized(QString::NormalizationForm_KD); - s1.remove(QRegExp("[^A-Z]")); - + QString s1 = letter.normalized(QString::NormalizationForm_KD); if (s1.size() > 0) { c = s1.at(0).toUpper(); } diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index dc9d276da71..7905c10e0ba 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -26,6 +26,17 @@ void WMiniViewScrollBar::setLetters(const QVector >& letters) update(); } +void WMiniViewScrollBar::setModel(QAbstractItemModel *model) { + m_pModel = model; + if (!m_pModel.isNull()) { + connect(m_pModel.data(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(refreshCharMap())); + + refreshCharMap(); + update(); + } +} + void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { QScrollBar::paintEvent(event); diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index 9aa3f55c84d..b24ffb77cbe 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -1,7 +1,9 @@ #ifndef WMINIVIEWSCROLLBAR_H #define WMINIVIEWSCROLLBAR_H +#include #include +#include #include class WMiniViewScrollBar : public QScrollBar @@ -14,12 +16,16 @@ class WMiniViewScrollBar : public QScrollBar // Sets the letters to be shown and triggers a update void setLetters(const QVector >& letters); + void setModel(QAbstractItemModel *model); protected: virtual void paintEvent(QPaintEvent* event); virtual void resizeEvent(QResizeEvent*pEvent); + virtual void refreshCharMap() = 0; void lettersPaint(QPaintEvent*); + QPointer m_pModel; + private: // The purpose of this function is to avoid computing all the sizes in the // paintEvent function which can block the GUI thread diff --git a/src/widget/wtableminiview.cpp b/src/widget/wtableminiview.cpp index d6b83afa861..ebd8014a27d 100644 --- a/src/widget/wtableminiview.cpp +++ b/src/widget/wtableminiview.cpp @@ -7,15 +7,6 @@ WTableMiniView::WTableMiniView(QWidget* parent) } -void WTableMiniView::setModel(QAbstractItemModel *model) { - m_pModel = model; - - connect(m_pModel.data(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(refreshCharMap())); - - refreshCharMap(); -} - void WTableMiniView::setSortColumn(int column) { m_sortColumn = column; refreshCharMap(); @@ -37,7 +28,7 @@ void WTableMiniView::refreshCharMap() { if (letters.size() <= 0) { letters.append(qMakePair(c, 1)); } else { - QPair &last = letters.last(); + QPair& last = letters.last(); if (last.first == c) { ++last.second; diff --git a/src/widget/wtableminiview.h b/src/widget/wtableminiview.h index 2a65c12df82..2252641b059 100644 --- a/src/widget/wtableminiview.h +++ b/src/widget/wtableminiview.h @@ -11,14 +11,12 @@ class WTableMiniView : public WMiniViewScrollBar public: WTableMiniView(QWidget* parent = nullptr); - void setModel(QAbstractItemModel *model); void setSortColumn(int column); private slots: - void refreshCharMap(); + void refreshCharMap() override; private: - QPointer m_pModel; int m_sortColumn; }; diff --git a/src/widget/wtreeminiview.cpp b/src/widget/wtreeminiview.cpp new file mode 100644 index 00000000000..db8c15431c0 --- /dev/null +++ b/src/widget/wtreeminiview.cpp @@ -0,0 +1,40 @@ +#include "widget/wtreeminiview.h" + +#include "library/treeitemmodel.h" +#include "util/stringhelper.h" + +WTreeMiniView::WTreeMiniView(QWidget* parent) + : WMiniViewScrollBar(parent) { + +} + +void WTreeMiniView::refreshCharMap() { + if (m_pModel.isNull()) { + return; + } + + const QModelIndex& rootIndex = m_pModel->index(0, 0); + int size = m_pModel->rowCount(); + QVector > letters; + + for (int i = 0; i < size; ++i) { + const QModelIndex& index = rootIndex.sibling(i, 0); + QString text = index.data(TreeItemModel::RoleDataPath).toString(); + QChar c = StringHelper::getFirstCharForGrouping(text); + + if (letters.size() <= 0) { + letters.append(qMakePair(c, 1)); + } else { + QPair& last = letters.last(); + + if (last.first == c) { + ++last.second; + } else { + letters.append(qMakePair(c, 1)); + } + } + } + + setLetters(letters); +} + diff --git a/src/widget/wtreeminiview.h b/src/widget/wtreeminiview.h new file mode 100644 index 00000000000..14eeab9d544 --- /dev/null +++ b/src/widget/wtreeminiview.h @@ -0,0 +1,14 @@ +#ifndef WTREEMINIVIEW_H +#define WTREEMINIVIEW_H +#include "widget/wminiviewscrollbar.h" + +class WTreeMiniView : public WMiniViewScrollBar +{ + public: + WTreeMiniView(QWidget* parent = nullptr); + + protected: + void refreshCharMap() override; +}; + +#endif // WTREEMINIVIEW_H From c1524d1787a4a0c5924448eb9f603b24897fdf14 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 15 Jul 2016 10:04:36 +0200 Subject: [PATCH 283/552] Add style to LateNight and Shade skins in new scrollbar --- res/skins/LateNight/style.qss | 28 ++++++---------------------- res/skins/Shade/skin.xml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 6574cba37f2..89bb7bcf17a 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1,3 +1,4 @@ + #debugbg { background-color: #fff; } @@ -1323,21 +1324,15 @@ QHeaderView::section { } /* QScrollbar styling is even harder */ -QScrollBar:horizontal { - border: 1px solid #585858; - min-width: 12px; - height: 15px; - background: #1a1a1a; - border-radius: 3px; - padding: 1px; -} -QScrollBar:vertical { +QScrollBar { border: 1px solid #585858; min-height: 12px; width: 15px; background: #1a1a1a; border-radius: 3px; padding: 1px; + color: #999999; + font-size: 8pt; } /* "add-page" and "sub-page" are the gutter of the scrollbar */ QScrollBar::add-page, QScrollBar::sub-page { @@ -1347,25 +1342,14 @@ QScrollBar::add-page, QScrollBar::sub-page { background-color: #1a1a1a; border-radius: 3px; } -QScrollBar::handle:horizontal { - min-width: 25px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #725309, stop:1 #412f05); - border-radius: 3px; - border: 1px solid #725309; -} -QScrollBar::handle:vertical { +QScrollBar::handle { min-height: 25px; background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #725309, stop:1 #412f05); border-radius: 3px; border: 1px solid #725309; } /* Turn off buttons */ -QScrollBar::add-line:horizontal, QScrollBar::add-line:vertical { - width: 0px; - height: 0px; - border: 0px solid white; -} -QScrollBar::sub-line:horizontal, QScrollBar::sub-line:vertical { +QScrollBar::add-line, QScrollBar::sub-line { width: 0px; height: 0px; border: 0px solid white; diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 3cf830d730b..2a59c3bcad0 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -1,4 +1,5 @@ + QTreeView { margin: 0px 0px 0px 5px; } diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 14c70d17c85..9eb011c6ed0 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -379,6 +379,8 @@ QWidget* LegacySkinParser::parseSkin(const QString& skinPath, QWidget* pParent) ImgLoader* loader = new ImgLoader; QSharedPointer mono(new ImgMonoColor(loader, color)); WPixmapStore::setLibraryIconLoader(mono); + } else { + WPixmapStore::setLibraryIconLoader(QSharedPointer()); } QStringList skinPaths(skinPath); diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index 92afa94c3de..edbe8abb1d0 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -15,18 +15,11 @@ WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* pare setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); setAcceptDrops(true); connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); - + setIcon(m_pFeature->getIcon()); m_textControl.connectValueChanged(SLOT(slotTextDisplayChanged(double))); - - slotTextDisplayChanged(m_textControl.get()); -} -void WFeatureClickButton::setText(const QString& text) { - QToolButton::setText(text); - - //QSize size = fontMetrics().boundingRect(text).size(); - //setFixedSize(size); + slotTextDisplayChanged(m_textControl.get()); } void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { @@ -37,7 +30,7 @@ void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { } void WFeatureClickButton::dragEnterEvent(QDragEnterEvent* event) { - qDebug() << "WFeatureClickButton::dragEnterEvent" << event; + //qDebug() << "WFeatureClickButton::dragEnterEvent" << event; if (!event->mimeData()->hasUrls() || event->source() == this) { event->ignore(); return; diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index 018f4546a72..a3136eef0a6 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -11,38 +11,36 @@ class WFeatureClickButton : public QToolButton { Q_OBJECT - -public: - WFeatureClickButton(LibraryFeature* pFeature = nullptr, + + public: + WFeatureClickButton(LibraryFeature* pFeature = nullptr, QWidget* parent = nullptr); - - void setText(const QString& text); - -signals: - + + signals: + void clicked(LibraryFeature*); void rightClicked(const QPoint&); void hoverShow(LibraryFeature*); - -protected: - + + protected: + void mousePressEvent(QMouseEvent* event); - + void dragEnterEvent(QDragEnterEvent* event); void dragLeaveEvent(QDragLeaveEvent*); void dropEvent(QDropEvent* event); - + void timerEvent(QTimerEvent* event); - -private slots: - + + private slots: + void slotClicked(); void slotTextDisplayChanged(double value); - -private: - + + private: + static const int kHoverTime; - + ControlProxy m_textControl; LibraryFeature* m_pFeature; QBasicTimer m_hoverTimer; From b02eb9f9001ccc046c766dbb7bf678ecfb61f425 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 6 Aug 2016 12:21:16 +0200 Subject: [PATCH 332/552] Fix some issues with ImgSource pointers --- src/skin/colorschemeparser.cpp | 10 +++++----- src/skin/imgcolor.cpp | 6 +++--- src/skin/imgcolor.h | 14 +++++++------- src/skin/imginvert.h | 2 +- src/skin/imgsource.h | 22 +++++++++++----------- src/skin/legacyskinparser.cpp | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/skin/colorschemeparser.cpp b/src/skin/colorschemeparser.cpp index 87c2c8b167a..46aa4ff991c 100644 --- a/src/skin/colorschemeparser.cpp +++ b/src/skin/colorschemeparser.cpp @@ -67,13 +67,13 @@ ImgSource* ColorSchemeParser::parseFilters(QDomNode filt) { while (!f.isNull()) { QString name = f.nodeName().toLower(); if (name == "invert") { - ret = new ImgInvert(ret); + ret = new ImgInvert(QSharedPointer(ret)); } else if (name == "hueinv") { - ret = new ImgHueInv(ret); + ret = new ImgHueInv(QSharedPointer(ret)); } else if (name == "add") { - ret = new ImgAdd(ret, XmlParse::selectNodeInt(f, "Amount")); + ret = new ImgAdd(QSharedPointer(ret), XmlParse::selectNodeInt(f, "Amount")); } else if (name == "scalewhite") { - ret = new ImgScaleWhite(ret, XmlParse::selectNodeFloat(f, "Amount")); + ret = new ImgScaleWhite(QSharedPointer(ret), XmlParse::selectNodeFloat(f, "Amount")); } else if (name == "hsvtweak") { int hmin = 0; int hmax = 359; @@ -103,7 +103,7 @@ ImgSource* ColorSchemeParser::parseFilters(QDomNode filt) { if (!f.namedItem("SFact").isNull()) { sfact = XmlParse::selectNodeFloat(f, "SFact"); } if (!f.namedItem("VFact").isNull()) { vfact = XmlParse::selectNodeFloat(f, "VFact"); } - ret = new ImgHSVTweak(ret, hmin, hmax, smin, smax, vmin, vmax, hfact, hconst, + ret = new ImgHSVTweak(QSharedPointer(ret), hmin, hmax, smin, smax, vmin, vmax, hfact, hconst, sfact, sconst, vfact, vconst); } else { qDebug() << "Unknown image filter:" << name; diff --git a/src/skin/imgcolor.cpp b/src/skin/imgcolor.cpp index 17bdda86df6..ac52643490b 100644 --- a/src/skin/imgcolor.cpp +++ b/src/skin/imgcolor.cpp @@ -30,7 +30,7 @@ QColor ImgScaleWhite::doColorCorrection(QColor c) { return c; } -ImgAdd::ImgAdd(ImgSource * parent, int amt) +ImgAdd::ImgAdd(const QSharedPointer &parent, int amt) : ImgColorProcessor(parent), m_amt(amt) { // Nothing left to do } @@ -48,7 +48,7 @@ QColor ImgAdd::doColorCorrection(QColor c) { return QColor(r, g, b, c.alpha()); } -ImgMax::ImgMax(ImgSource * parent, int amt) +ImgMax::ImgMax(const QSharedPointer &parent, int amt) : ImgColorProcessor(parent), m_amt(amt) { } @@ -88,7 +88,7 @@ QColor ImgHSVTweak::doColorCorrection(QColor c) { return c; } -ImgMonoColor::ImgMonoColor(ImgSource* parent, const QColor& baseColor) +ImgMonoColor::ImgMonoColor(const QSharedPointer &parent, const QColor& baseColor) : ImgColorProcessor(parent), m_baseColor(baseColor) { } diff --git a/src/skin/imgcolor.h b/src/skin/imgcolor.h index ebe5ce9fb78..d29e04626c2 100644 --- a/src/skin/imgcolor.h +++ b/src/skin/imgcolor.h @@ -23,7 +23,7 @@ class ImgAdd : public ImgColorProcessor { public: - ImgAdd(ImgSource* parent, int amt); + ImgAdd(const QSharedPointer& parent, int amt); virtual QColor doColorCorrection(QColor c); private: @@ -33,7 +33,7 @@ class ImgAdd : public ImgColorProcessor { class ImgMax : public ImgColorProcessor { public: - ImgMax(ImgSource* parent, int amt); + ImgMax(const QSharedPointer& parent, int amt); virtual QColor doColorCorrection(QColor c); private: @@ -43,7 +43,7 @@ class ImgMax : public ImgColorProcessor { class ImgMonoColor : public ImgColorProcessor { public: - ImgMonoColor(ImgSource* parent, const QColor &baseColor); + ImgMonoColor(const QSharedPointer& parent, const QColor &baseColor); virtual QColor doColorCorrection(QColor c); private: QColor m_baseColor; @@ -52,7 +52,7 @@ class ImgMonoColor : public ImgColorProcessor { class ImgScaleWhite : public ImgColorProcessor { public: - inline ImgScaleWhite(ImgSource* parent, float amt) + inline ImgScaleWhite(const QSharedPointer& parent, float amt) : ImgColorProcessor(parent), m_amt(amt) {} virtual QColor doColorCorrection(QColor c); private: @@ -62,7 +62,7 @@ class ImgScaleWhite : public ImgColorProcessor { class ImgHueRot : public ImgColorProcessor { public: - inline ImgHueRot(ImgSource* parent, int amt) + inline ImgHueRot(QSharedPointer parent, int amt) : ImgColorProcessor(parent), m_amt(amt) {} virtual QColor doColorCorrection(QColor c); @@ -73,13 +73,13 @@ class ImgHueRot : public ImgColorProcessor { class ImgHueInv : public ImgColorProcessor { public: - inline ImgHueInv(ImgSource* parent) : ImgColorProcessor(parent) {} + inline ImgHueInv(const QSharedPointer& parent) : ImgColorProcessor(parent) {} virtual QColor doColorCorrection(QColor c); }; class ImgHSVTweak : public ImgColorProcessor { public: - inline ImgHSVTweak(ImgSource* parent, int hmin, int hmax, int smin, + inline ImgHSVTweak(const QSharedPointer& parent, int hmin, int hmax, int smin, int smax, int vmin, int vmax, float hfact, int hconst, float sfact, int sconst, float vfact, int vconst) : ImgColorProcessor(parent), diff --git a/src/skin/imginvert.h b/src/skin/imginvert.h index 2cf862609dc..9498f53f699 100644 --- a/src/skin/imginvert.h +++ b/src/skin/imginvert.h @@ -23,7 +23,7 @@ class ImgInvert : public ImgColorProcessor { public: - inline ImgInvert(ImgSource* parent) : ImgColorProcessor(parent) {} + inline ImgInvert(const QSharedPointer& parent) : ImgColorProcessor(parent) {} virtual QColor doColorCorrection(QColor c); }; diff --git a/src/skin/imgsource.h b/src/skin/imgsource.h index ad8c7b52ff1..e542d34dc2f 100644 --- a/src/skin/imgsource.h +++ b/src/skin/imgsource.h @@ -20,33 +20,32 @@ #include #include -#include +#include #include -#include +#include +#include class ImgSource { public: virtual ~ImgSource() {} virtual QImage* getImage(QString img) = 0; virtual inline QColor getCorrectColor(QColor c) { return c; } - virtual void correctImageColors(QImage* p) { (void)p; } + virtual void correctImageColors(QImage*) {} }; class ImgProcessor : public ImgSource { public: - virtual ~ImgProcessor() { - delete m_parent; - } - inline ImgProcessor(ImgSource* parent) : m_parent(parent) {} - virtual QColor doColorCorrection(QColor c) = 0; + virtual ~ImgProcessor() {} + inline ImgProcessor(const QSharedPointer& parent) : m_parent(parent) {} + virtual QColor doColorCorrection(QColor) = 0; inline QColor getCorrectColor(QColor c) { return doColorCorrection(m_parent->getCorrectColor(c)); } - virtual void correctImageColors(QImage* p) { (void)p; } + virtual void correctImageColors(QImage*) {} protected: - ImgSource* m_parent; + QSharedPointer m_parent; }; class ImgColorProcessor : public ImgProcessor { @@ -54,7 +53,8 @@ class ImgColorProcessor : public ImgProcessor { public: virtual ~ImgColorProcessor() {} - inline ImgColorProcessor(ImgSource* parent) : ImgProcessor(parent) {} + inline ImgColorProcessor(const QSharedPointer& parent) + : ImgProcessor(parent) {} inline virtual QImage* getImage(QString img) { QImage* i = m_parent->getImage(img); diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 9eb011c6ed0..5fa21d0f563 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -376,7 +376,7 @@ QWidget* LegacySkinParser::parseSkin(const QString& skinPath, QWidget* pParent) QString colorName = m_pContext->selectString(skinDocument, "LibraryIconsColor"); if (!colorName.isEmpty()) { QColor color(colorName); - ImgLoader* loader = new ImgLoader; + QSharedPointer loader(new ImgLoader); QSharedPointer mono(new ImgMonoColor(loader, color)); WPixmapStore::setLibraryIconLoader(mono); } else { From fba27d5cba668a6bc113b4fede7e729c48b738d1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 7 Aug 2016 16:52:48 +0200 Subject: [PATCH 333/552] Begin creating new Folders item in Library Tree --- src/library/browse/browsefeature.cpp | 21 +++++++++++---------- src/library/librarytreemodel.cpp | 4 ++++ src/library/librarytreemodel.h | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index b6923b4a3ff..8d2880b939a 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -246,21 +246,20 @@ void BrowseFeature::activate() { // Note: This is executed whenever you single click on an child item // Single clicks will not populate sub folders void BrowseFeature::activateChild(const QModelIndex& index) { - TreeItem *item = static_cast(index.internalPointer()); - qDebug() << "BrowseFeature::activateChild " << item->data() << " " - << item->dataPath(); - - QString path = item->dataPath().toString(); - if (path == QUICK_LINK_NODE || path == DEVICE_NODE) { + QString data = index.data().toString(); + QString dataPath = index.data(TreeItemModel::RoleDataPath).toString(); + qDebug() << "BrowseFeature::activateChild " << data << dataPath; + + if (dataPath == QUICK_LINK_NODE || dataPath == DEVICE_NODE) { m_browseModel.setPath(MDir()); } else { // Open a security token for this path and if we do not have access, ask // for it. - MDir dir(path); + MDir dir(dataPath); if (!dir.canAccess()) { - if (Sandbox::askForAccess(path)) { + if (Sandbox::askForAccess(dataPath)) { // Re-create to get a new token. - dir = MDir(path); + dir = MDir(dataPath); } else { // TODO(rryan): Activate an info page about sandboxing? return; @@ -277,9 +276,11 @@ void BrowseFeature::activateChild(const QModelIndex& index) { return; } + QString bread = index.data(TreeItemModel::RoleBreadCrumb).toString(); + (*it)->setCurrentIndex(*itId); showTrackModel(&m_proxyModel); - m_pLibrary->showBreadCrumb(item); + showBreadCrumb(bread, getIcon()); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 09d9b3a3012..1036c9bfab8 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -268,6 +268,10 @@ void LibraryTreeModel::createTracksTree() { triggerRepaint(); } +void LibraryTreeModel::createFoldersTree() { + QSqlQuery query; +} + void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, const QSqlQuery& query, TreeItem* pTree) { CoverInfo c; diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 079e27c82cf..3083e9e54db 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -47,6 +47,7 @@ class LibraryTreeModel : public TreeItemModel { private: QString getQuery(TreeItem* pTree) const; void createTracksTree(); + void createFoldersTree(); void addCoverArt(const CoverIndex& index, const QSqlQuery& query, TreeItem* pTree); LibraryFeature* m_pFeature; From d7c4d326ad9157d79915209f1790ecbbf4a29fb4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 8 Aug 2016 11:56:56 +0200 Subject: [PATCH 334/552] Fix double scrollbar again --- res/skins/Shade/skin.xml | 5 +++++ src/widget/wbuttonbar.cpp | 24 ++++++++++++++++++++++-- src/widget/wverticalscrollarea.cpp | 7 +++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 51f97ccaf4f..d2c84def9e0 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -1,5 +1,6 @@ + + See CHANGELOG.txt for the list of changes. + --> - - - - Shade - jus - 1.12.0.01 - A 2-deck split-waveform skin with 4 samplers. - en - Creative Commons Attribution, Share-Alike 3.0 Unported - - 2 - 4 - 1 - - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - - - - - - - - Classic - - - - Dark - - - 90 - -30 - -30 - - - -40 - - - - - Summer Sunset - - - 100 - 0.7 - 0.3 - - - 50 - 0 - 50 - 120 - -10 - - - - - - - - - Mixxx - - style/style_bg_deck.png - - - - - 5,200 - 372,50 + + style/style_bg_deck.png + + + + + 5,200 + 372,50 f,f - - - - 100,0 - 93,50 - - - - + + + + 100,0 + 93,50 + + + + [Microphone2],enabled visible - - - - [Microphone],show_microphone - visible - - - - - - - - 260,265 - - - - - - 378,265 - f,f - - - 1,6 - 375,255 - - style/style_bg_deck.png - - - - - 5,200 - 372,50 + + + + [Microphone],show_microphone + visible + + + + + + + + 260,265 + + + + + + 378,265 + f,f + + + 1,6 + 375,255 + + style/style_bg_deck.png + + + + + 5,200 + 372,50 f,f - - - - 109,0 - 108,50 - - - - + + + + 109,0 + 108,50 + + + + [Auxiliary2],enabled visible - - - [Microphone],show_microphone - visible - - - - - - - + + + [Microphone],show_microphone + visible + + + + + + + [Master],maximize_library visible @@ -275,24 +277,24 @@ - - - - - 1024,105 - me,me - vertical - - - + + + + + 1024,105 + me,me + vertical + + + me,f @@ -368,514 +370,526 @@ - - - Library - 0,0 - e,e - me,me - horizontal - - - - me,me - [Shade],LibrarySidebarSplitSize - 1,e - - - vertical - - - - - horizontal - - - - vertical - - - - horizontal - - - - text - - [PreviewDeck1] - - 50me,15f - right - - - - eject - - 1 - - 0 - btn_eject1_over.png - btn_eject1.png - - - - [PreviewDeck1],eject - true - LeftButton - false - - - - - - - - horizontal - - - play_start - - 2 - true - - 0 - btn_play_sampler_down.png - btn_play_sampler.png - - - 1 - btn_play_sampler_overdown.png - btn_play_sampler_over.png - - 2,2 - - [PreviewDeck1],play - true - LeftButton - - - [PreviewDeck1],start - true - RightButton - false - - - - waveform_overview - - [PreviewDeck1] - me,30f - #8D98A3 - #FFE300 - #0099FF - #FF0035 - #FF8000 - #00FF00 - - bottom - #FFFFFF - #00FF00 - %1 - - - cue_point - C - top - #FF001C - #00FF00 - - - [PreviewDeck1],playposition - false - - - - - - - - - - 20,62 - - - - - preview_PeakIndicator - - btn_clipping_previewdeck_over.png - btn_clipping_previewdeck.png - 0,1 - - [PreviewDeck1],PeakIndicator - - - - - - channel_VuMeter - - btn_volume_display_previewdeck_over.png - btn_volume_display_previewdeck.png - 0,12 - false - 3 - 250 - 50 - 3 - - [PreviewDeck1],VuMeter - - - - - - [Deere],LibrarySidebarSplitSizepregain - - knob_volume_previewdeck.png - slider_volume_previewdeck.png - 10,2 - false - - [PreviewDeck1],pregain - false - - - - - - - [PreviewDeck],show_previewdeck - visible - - - - - horizontal - - - LibrarySidebarButtons - - - 3,0 - - - vertical - 8,2 - me,me - - - LibrarySidebarExpanded - - - - 30,30 - me,me - - [Library],show_coverart - visible - - - - - - - - - - vertical - - - 1 - - - 1 - - - 1 - - - - - vertical - - - 2 - - - 2 - - - 2 - - - - - - - - - - + + QPushButton#LibraryPreviewButton { width: 23px; height: 12px; background: transparent; border: 0; } + QPushButton#LibraryPreviewButton:!checked{ image: url(skin:/style/style_library_preview_play.png); } + QPushButton#LibraryPreviewButton:checked{ image: url(skin:/style/style_library_preview_pause.png); } + + QPushButton#LibraryBPMButton {background: transparent; border: 0;} + QPushButton#LibraryBPMButton::checked {image: url(:/images/library/ic_library_checked.png);} + QPushButton#LibraryBPMButton::!checked {image: url(:/images/library/ic_library_unchecked.png);} + + QHeaderView { font: 11px/13px sans-serif; + font-family: "Open Sans";} + + + + QSpinBox:editable { + font: 12px/14px sans-serif; + font-family: "Open Sans"; + background: transparent; + color: #ACACAC; } + QSpinBox { min-height: 20px; max-height: 20px;min-width: 40px; max-width: 40px;} + + + WSearchLineEdit { + margin: 0px 0px 5px 5px; + padding: 2px; + border: 1px solid #656565; + font: 12px/14px sans-serif; + font-family: "Open Sans"; + background: transparent; + color: #ACACAC; + } + WSearchLineEdit:focus { + padding: 2px; + border: 2px solid #FF6600; + font: 12px/14px sans-serif; + font-family: "Open Sans"; + background: rgba(255, 102, 0,50); + color: #D6D6D6;} + + + WCoverArt { + font: 13px/15px sans-serif; + font-family: "Open Sans"; + background: transparent; + color: #ACACAC; + } + + + QSplitter::handle { image: url(skin:/style/style_handle_unchecked.png); background: none; } + QSplitter::handle:pressed { image: url(skin:/style/style_handle_checked.png); background: none; } + QSplitter::handle:horizontal { width: 6px; } + QSplitter::handle:vertical { height: 6px;} + + QAbstractButton { font: 12px/14px sans-serif; + font-family: "Open Sans";} + + QLabel, QRadioButton { + font: 12px/14px sans-serif; + font-family: "Open Sans"; + background: transparent; + color: #C1C1C1;} + + + WBaseLibrary QPushButton { + margin: 2px 3px; + padding: 3px 3px; + } + + /* Scroll bars */ + QScrollBar { + color: #474747; + font-size: 8pt; + padding: 3px; + background-color: #aab2b7; + } + + QScrollBar:horizontal { + border-top: 1px solid #141414; + min-width: 12px; + height: 15px; + } + QScrollBar:vertical { + border-left: 1px solid #141414; + min-height: 12px; + width: 15px; + } + /* "add-page" and "sub-page" are the gutter of the scrollbar */ + QScrollBar::add-page, QScrollBar::sub-page { + background: none; + } + + QScrollBar::handle { + min-height: 25px; + background: rgba(95, 95, 95, 150); + border: none; + } + QScrollBar::handle:hover { + background: rgba(120, 120, 120, 150); + } + + /* Turn off buttons */ + QScrollBar::add-line, QScrollBar::sub-line { + width: 0px; + height: 0px; + border: none; + } + + WBaseLibrary QScrollArea, + QScrollArea QWidget { + border: none; + background-color: transparent; + } + + WBaseLibrary QTabWidget QTreeView, + #DlgAutoDJ QScrollArea { + background-color: #191919; + border: none; + } + + #DlgAutoDJ QScrollArea QScrollBar { + background-color: #aab2b7; + } + + WBaseLibrary QTabWidget::pane { + background-color: #191919; + border: 1px solid #646464; + } + + WBaseLibrary QTreeView { + margin: 0px; + } + + WBaseLibrary QPushButton { + border: 1px solid black; + background-color: #aab2b7; + } + + #LibrarySidebarButtons { + border: none; + background-color: #aab2b7; + } + + #LibrarySidebarButtons WButtonBar { + background-color: #aab2b7; + } + + QScrollArea WButtonBar, + QScrollArea WButtonBar QWidget { + border: none; + } + + WButtonBar QToolButton { + padding: 2px 2px 2px 2px; + color: black; + border: none; + background-color: #aab2b7; + } + + WButtonBar QToolButton:hover { + border: 2px solid #626f87; + } + + WBaseLibrary[showFocus="0"] { + padding: 2px 0 0 0; + border: none; + } + + WBaseLibrary[showFocus="1"] { + padding: 2px 1px 1px 1px; + border-top: 2px solid aqua; + } + + WLibraryBreadCrumb QLabel { + margin: 2px 4px; + } + + WBaseLibrary QLabel { + margin-left: 5px; + margin-bottom: 5px; + } + + + QTreeView { margin: 0px 0px 0px 5px; } + + + QTreeView { show-decoration-selected: 0;} + QTreeView::branch:has-children:!has-siblings:closed, + QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(skin:/style/style_branch_closed.png);} + QTreeView::branch:open:has-children:!has-siblings, + QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(skin:/style/style_branch_open.png);} + + + + + me,me + [Shade],LibrarySidebarSplitSize + 1,e + + + vertical + + + + + horizontal + + + + vertical + + + + horizontal + + + + text + + [PreviewDeck1] + + 50me,15f + right + + + + eject + + 1 + + 0 + btn_eject1_over.png + btn_eject1.png + + + + [PreviewDeck1],eject + true + LeftButton + false + + + + + + + + horizontal + + + play_start + + 2 + true + + 0 + btn_play_sampler_down.png + btn_play_sampler.png + + + 1 + btn_play_sampler_overdown.png + btn_play_sampler_over.png + + 2,2 + + [PreviewDeck1],play + true + LeftButton + + + [PreviewDeck1],start + true + RightButton + false + + + + waveform_overview + + [PreviewDeck1] + me,30f + #8D98A3 + #FFE300 + #0099FF + #FF0035 + #FF8000 + #00FF00 + + bottom + #FFFFFF + #00FF00 + %1 + + + cue_point + C + top + #FF001C + #00FF00 + + + [PreviewDeck1],playposition + false + + + + + + + + + + 20,62 + + + + + preview_PeakIndicator + + btn_clipping_previewdeck_over.png + btn_clipping_previewdeck.png + 0,1 + + [PreviewDeck1],PeakIndicator + + + + + + channel_VuMeter + + btn_volume_display_previewdeck_over.png + btn_volume_display_previewdeck.png + 0,12 + false + 3 + 250 + 50 + 3 + + [PreviewDeck1],VuMeter + + + + + + [Deere],LibrarySidebarSplitSizepregain + + knob_volume_previewdeck.png + slider_volume_previewdeck.png + 10,2 + false + + [PreviewDeck1],pregain + false + + + + + + + [PreviewDeck],show_previewdeck + visible + + + + + horizontal + + + LibrarySidebarButtons + + + 3,0 + + + vertical + 8,2 + me,me + + + LibrarySidebarExpanded + + + + 30,30 + me,me + + [Library],show_coverart + visible + + + + + + + + + + vertical + + + 1 + + + 1 + + + 1 + + + + + vertical + + + 2 + + + 2 + + + 2 + + + + + + + + + + diff --git a/src/skin/imgloader.cpp b/src/skin/imgloader.cpp index dc7366acbff..84125d5dbac 100644 --- a/src/skin/imgloader.cpp +++ b/src/skin/imgloader.cpp @@ -8,3 +8,6 @@ QImage * ImgLoader::getImage(QString img) { return new QImage(img); } +void ImgLoader::correctImageColors(QImage*) { +} + diff --git a/src/skin/imgloader.h b/src/skin/imgloader.h index 321a2339c06..81fd21066c1 100644 --- a/src/skin/imgloader.h +++ b/src/skin/imgloader.h @@ -24,7 +24,8 @@ class ImgLoader : public ImgSource { public: ImgLoader(); - virtual QImage* getImage(QString img); + QImage* getImage(QString img) override; + void correctImageColors(QImage*) override; }; #endif diff --git a/src/skin/imgsource.h b/src/skin/imgsource.h index e542d34dc2f..7c584dc4fc1 100644 --- a/src/skin/imgsource.h +++ b/src/skin/imgsource.h @@ -30,39 +30,45 @@ class ImgSource { virtual ~ImgSource() {} virtual QImage* getImage(QString img) = 0; virtual inline QColor getCorrectColor(QColor c) { return c; } - virtual void correctImageColors(QImage*) {} + virtual void correctImageColors(QImage*) = 0; + protected: + virtual void correctImageColorsInner(QImage*) {} }; class ImgProcessor : public ImgSource { public: - virtual ~ImgProcessor() {} + ~ImgProcessor() override {} inline ImgProcessor(const QSharedPointer& parent) : m_parent(parent) {} virtual QColor doColorCorrection(QColor) = 0; - inline QColor getCorrectColor(QColor c) { + QColor getCorrectColor(QColor c) override { return doColorCorrection(m_parent->getCorrectColor(c)); } - virtual void correctImageColors(QImage*) {} - + void correctImageColors(QImage* pImg) override { + m_parent->correctImageColors(pImg); + correctImageColorsInner(pImg); + } protected: + void correctImageColorsInner(QImage*) override {}; QSharedPointer m_parent; }; class ImgColorProcessor : public ImgProcessor { -public: - virtual ~ImgColorProcessor() {} + public: + ~ImgColorProcessor() override {} inline ImgColorProcessor(const QSharedPointer& parent) : ImgProcessor(parent) {} - inline virtual QImage* getImage(QString img) { + virtual QImage* getImage(QString img) override { QImage* i = m_parent->getImage(img); - correctImageColors(i); + correctImageColorsInner(i); return i; } - virtual void correctImageColors(QImage* i) { + protected: + void correctImageColorsInner(QImage* i) override { if (i == NULL || i->isNull()) { return; } diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 9c230de9bf1..8920f65caa5 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -10,7 +10,7 @@ WButtonBar::WButtonBar(QWidget* parent) QHBoxLayout* pHb = new QHBoxLayout(this); pHb->setContentsMargins(0,0,0,0); - + QWidget* w1 = new QWidget(this); // QSizePolicy::Maximum -> treat the size hint as maximum. This protects us diff --git a/src/widget/wmainmenubar.cpp b/src/widget/wmainmenubar.cpp index b00e4ffafe0..a9d7c628305 100644 --- a/src/widget/wmainmenubar.cpp +++ b/src/widget/wmainmenubar.cpp @@ -137,15 +137,6 @@ void WMainMenuBar::initialize() { pLibraryRescan, SLOT(setDisabled(bool))); pLibraryMenu->addAction(pLibraryRescan); - QString showTextTitle = tr("Show text in sidebar icons"); - QString showTextText = tr("Shows the text below the icons in the sidebar"); - auto pLibraryText = new QAction(showTextTitle, this); - pLibraryText->setStatusTip(showTextText); - pLibraryText->setWhatsThis(buildWhatsThis(showTextTitle, showTextText)); - pLibraryText->setCheckable(true); - createVisibilityControl(pLibraryText, ConfigKey("[Library]", "show_icon_text")); - pLibraryMenu->addAction(pLibraryText); - pLibraryMenu->addSeparator(); QString createPlaylistTitle = tr("Create &New Playlist"); @@ -269,6 +260,14 @@ void WMainMenuBar::initialize() { createVisibilityControl(pViewShowCoverArt, ConfigKey("[Library]", "show_coverart")); pViewMenu->addAction(pViewShowCoverArt); + QString showTextTitle = tr("Show text in sidebar icons"); + QString showTextText = tr("Shows the text below the icons in the sidebar"); + auto pLibraryText = new QAction(showTextTitle, this); + pLibraryText->setStatusTip(showTextText); + pLibraryText->setWhatsThis(buildWhatsThis(showTextTitle, showTextText)); + pLibraryText->setCheckable(true); + createVisibilityControl(pLibraryText, ConfigKey("[Library]", "show_icon_text")); + pViewMenu->addAction(pLibraryText); QString maximizeLibraryTitle = tr("Maximize Library"); QString maximizeLibraryText = tr("Maximize the track library to take up all the available screen space.") + diff --git a/src/widget/wpixmapstore.cpp b/src/widget/wpixmapstore.cpp index 57ccfc5a43e..2fe67cd3103 100644 --- a/src/widget/wpixmapstore.cpp +++ b/src/widget/wpixmapstore.cpp @@ -374,11 +374,14 @@ QIcon WPixmapStore::getLibraryIcon(const QString& filename) { if (m_pIconLoader.isNull()) { return QIcon(filename); } + QImage* image = m_pIconLoader->getImage(filename); - + if (!m_pLoader.isNull()) { m_pLoader->correctImageColors(image); + } + QPixmap pixmap(QPixmap::fromImage(*image)); QIcon icon(pixmap); delete image; diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index 9380306afb5..5e5406f5858 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -22,7 +22,7 @@ bool WVerticalScrollArea::eventFilter(QObject* o, QEvent* e) { int width = widget()->minimumSizeHint().width(); int vScrollWidth = verticalScrollBar()->width(); // + 2 for a Gap between scroll area and bar - setFixedWidth(width + vScrollWidth + 2); + setFixedWidth(width + vScrollWidth); } return false; } From ef1b81fe3697f079f5b0fde96c9e059783070925 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 10:45:33 +0200 Subject: [PATCH 350/552] Move folder's tree to it's own class --- build/depends.py | 1 + src/library/libraryfoldermodel.cpp | 161 +++++++++++++++++++++++++++++ src/library/libraryfoldermodel.h | 40 +++++++ src/library/librarytreemodel.cpp | 129 ----------------------- src/library/librarytreemodel.h | 4 - 5 files changed, 202 insertions(+), 133 deletions(-) create mode 100644 src/library/libraryfoldermodel.cpp create mode 100644 src/library/libraryfoldermodel.h diff --git a/build/depends.py b/build/depends.py index e84f45c054f..60ff143d8cb 100644 --- a/build/depends.py +++ b/build/depends.py @@ -883,6 +883,7 @@ def sources(self, build): "library/dlgtrackinfo.cpp", "library/maintenancefeature.cpp", "library/historytreemodel.cpp", + "library/libraryfoldermodel.cpp", "library/browse/browsetablemodel.cpp", "library/browse/browsethread.cpp", diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp new file mode 100644 index 00000000000..9ef51e07d2f --- /dev/null +++ b/src/library/libraryfoldermodel.cpp @@ -0,0 +1,161 @@ +#include + +#include "library/libraryfoldermodel.h" + +#include "library/libraryfeature.h" +#include "library/treeitem.h" + +LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, + UserSettingsPointer pConfig, + QObject* parent) + : TreeItemModel(parent), + m_pFeature(pFeature), + m_pTrackCollection(pTrackCollection), + m_pConfig(pConfig), + m_pShowAllItem(nullptr) { + + QString recursive = m_pConfig->getValueString(ConfigKey("[Library]", + "FolderRecursive")); + m_folderRecursive = recursive.toInt() == 1; + + reloadFoldersTree(); +} + +QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { + if (role != TreeItemModel::RoleQuery) { + return TreeItemModel(index, role); + } + + // Role is Get query + TreeItem* pTree = static_cast(index.internalPointer()); + DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { + return QVariant(); + } + + // User has clicked the show all item + if (pTree == m_pShowAllItem) { + return ""; + } + + const QString param("%1:=\"%2\""); + + return param.arg("folder", pTree->dataPath().toString()); +} + +void LibraryFolderModel::setFolderRecursive(bool recursive) { + m_folderRecursive = recursive; + m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), + ConfigValue((int)recursive)); +} + +bool LibraryFolderModel::getFolderRecursive() { + return m_folderRecursive; +} + +void LibraryFolderModel::reloadFoldersTree() { + // Remove current root + m_pRootItem = new TreeItem(m_pFeature); + setRootItem(m_pRootItem); + + // Add "show all" item + m_pShowAllItem = new TreeItem(tr("Show all"), "", m_pFeature, m_pRootItem); + m_pRootItem->appendChild(m_pShowAllItem); + + // Get the Library directories + QStringList dirs(m_pTrackCollection->getDirectoryDAO().getDirs()); + + QString queryStr = "SELECT DISTINCT %1 FROM %2 " + "WHERE %3=0 AND %1 LIKE :dir " + "ORDER BY %1 COLLATE localeAwareCompare"; + queryStr = queryStr.arg(TRACKLOCATIONSTABLE_DIRECTORY, + "track_locations", + TRACKLOCATIONSTABLE_FSDELETED); + + QSqlQuery query(m_pTrackCollection->getDatabase()); + query.prepare(queryStr); + + m_pFoldersRoot = new TreeItem(tr("Folders"), "", m_pFeature, m_pRootItem); + QIcon icon(WPixmapStore::getLibraryIcon(":/images/library/ic_library_folder.png")); + m_pFoldersRoot->setIcon(icon); + m_pRootItem->appendChild(m_pFoldersRoot); + + for (const QString& dir : dirs) { + query.bindValue(":dir", dir + "%"); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + return; + } + + // For each source folder create the tree + createTreeFromSource(dir, query); + } +} + +void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& query) { + QStringList lastUsed; + QList parent; + parent.append(m_pFoldersRoot); + bool first = true; + + while (query.next()) { + QString value = query.value(0).toString(); + qDebug() << value; + + + // Remove the + QString dispValue = value.mid(dir.size()); + if (dispValue.startsWith("/")) { + dispValue = dispValue.mid(1); + } + + // Add a header + if (first) { + first = false; + QString path = dir; + if (m_folderRecursive) { + path.append("*"); + } + TreeItem* pTree = new TreeItem(dir, path, m_pFeature, m_pFoldersRoot); + pTree->setDivider(true); + m_pFoldersRoot->appendChild(pTree); + } + + // Do not add empty items + if (dispValue.isEmpty()) { + continue; + } + + QStringList parts = dispValue.split("/"); + if (parts.size() > lastUsed.size()) { + for (int i = lastUsed.size(); i < parts.size(); ++i) { + lastUsed.append(QString()); + parent.append(nullptr); + } + } + + bool change = false; + for (int i = 0; i < parts.size(); ++i) { + const QString& val = parts.at(i); + if (change || val != lastUsed.at(i)) { + change = true; + + QString fullPath = dir; + for (int j = 0; j <= i; ++j) { + fullPath += "/" + parts.at(j); + } + + if (m_folderRecursive) { + fullPath.append("*"); + } + + TreeItem* pItem = new TreeItem(val, fullPath, m_pFeature, parent[i]); + parent[i]->appendChild(pItem); + + parent[i + 1] = pItem; + lastUsed[i] = val; + } + } + } +} diff --git a/src/library/libraryfoldermodel.h b/src/library/libraryfoldermodel.h new file mode 100644 index 00000000000..f1df78e6101 --- /dev/null +++ b/src/library/libraryfoldermodel.h @@ -0,0 +1,40 @@ +#ifndef LIBRARYFOLDERMODEL_H +#define LIBRARYFOLDERMODEL_H + +#include + +#include "library/treeitemmodel.h" + +class LibraryFeature; +class TrackCollection; + +class LibraryFolderModel : public TreeItemModel +{ + public: + LibraryFolderModel(LibraryFeature *pFeature, + TrackCollection *pTrackCollection, + UserSettingsPointer pConfig, + QObject *parent); + + virtual QVariant data(const QModelIndex &index, int role) const; + + void setFolderRecursive(bool recursive); + bool getFolderRecursive(); + + public slots: + void reloadFoldersTree(); + + private: + + void createTreeFromSource(const QString& dir, QSqlQuery& query); + + LibraryFeature* m_pFeature; + TrackCollection* m_pTrackCollection; + UserSettingsPointer m_pConfig; + + TreeItem* m_pShowAllItem; + + bool m_folderRecursive; +}; + +#endif // LIBRARYFOLDERMODEL_H diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 96b62c1ab56..35909d0cbbc 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -31,9 +31,6 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, m_sortOrder = sort.split(","); } - QString recursive = m_pConfig->getValueString(ConfigKey("[Library]","FolderRecursive")); - m_folderRecursive = recursive.toInt() == 1; - m_coverQuery << LIBRARYTABLE_COVERART_HASH << LIBRARYTABLE_COVERART_LOCATION << LIBRARYTABLE_COVERART_SOURCE @@ -96,16 +93,6 @@ QStringList LibraryTreeModel::getSortOrder() { return m_sortOrder; } -void LibraryTreeModel::setFolderRecursive(bool recursive) { - m_folderRecursive = recursive; - m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), - ConfigValue((int)recursive)); -} - -bool LibraryTreeModel::getFolderRecursive() { - return m_folderRecursive; -} - void LibraryTreeModel::reloadTracksTree() { //qDebug() << "LibraryTreeModel::reloadTracksTree"; @@ -149,21 +136,6 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { } const QString param("%1:=\"%2\""); - // Find for folers root - TreeItem* pAux = pTree; - bool isFolderItem = false; - while (pAux->parent() != nullptr && pAux->parent() != m_pRootItem) { - if (pAux->parent() == m_pFoldersRoot) { - isFolderItem = true; - break; - } - pAux = pAux->parent(); - } - - if (isFolderItem) { - return param.arg("folder", pTree->dataPath().toString()); - } - // Find Artist / Album / Genre query int depth = 0; pAux = pTree; @@ -311,39 +283,6 @@ void LibraryTreeModel::createTracksTree() { triggerRepaint(); } -void LibraryTreeModel::createFoldersTree() { - - // Get the Library directories - QStringList dirs(m_pTrackCollection->getDirectoryDAO().getDirs()); - - QString queryStr = "SELECT DISTINCT %1 FROM %2 " - "WHERE %3=0 AND %1 LIKE :dir " - "ORDER BY %1 COLLATE localeAwareCompare"; - queryStr = queryStr.arg(TRACKLOCATIONSTABLE_DIRECTORY, - "track_locations", - TRACKLOCATIONSTABLE_FSDELETED); - - QSqlQuery query(m_pTrackCollection->getDatabase()); - query.prepare(queryStr); - - m_pFoldersRoot = new TreeItem(tr("Folders"), "", m_pFeature, m_pRootItem); - QIcon icon(WPixmapStore::getLibraryIcon(":/images/library/ic_library_folder.png")); - m_pFoldersRoot->setIcon(icon); - m_pRootItem->appendChild(m_pFoldersRoot); - - for (const QString& dir : dirs) { - query.bindValue(":dir", dir + "%"); - - if (!query.exec()) { - LOG_FAILED_QUERY(query); - return; - } - - // For each source folder create the tree - createTreeFromSource(dir, query); - } -} - void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, const QSqlQuery& query, TreeItem* pTree) { CoverInfo c; @@ -357,71 +296,3 @@ void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, c.type = static_cast(type); pTree->setCoverInfo(c); } - -void LibraryTreeModel::createTreeFromSource(const QString& dir, QSqlQuery& query) { - - QStringList lastUsed; - QList parent; - parent.append(m_pFoldersRoot); - bool first = true; - - while (query.next()) { - QString value = query.value(0).toString(); - qDebug() << value; - - - // Remove the - QString dispValue = value.mid(dir.size()); - if (dispValue.startsWith("/")) { - dispValue = dispValue.mid(1); - } - - // Add a header - if (first) { - first = false; - QString path = dir; - if (m_folderRecursive) { - path.append("*"); - } - TreeItem* pTree = new TreeItem(dir, path, m_pFeature, m_pFoldersRoot); - pTree->setDivider(true); - m_pFoldersRoot->appendChild(pTree); - } - - // Do not add empty items - if (dispValue.isEmpty()) { - continue; - } - - QStringList parts = dispValue.split("/"); - if (parts.size() > lastUsed.size()) { - for (int i = lastUsed.size(); i < parts.size(); ++i) { - lastUsed.append(QString()); - parent.append(nullptr); - } - } - - bool change = false; - for (int i = 0; i < parts.size(); ++i) { - const QString& val = parts.at(i); - if (change || val != lastUsed.at(i)) { - change = true; - - QString fullPath = dir; - for (int j = 0; j <= i; ++j) { - fullPath += "/" + parts.at(j); - } - - if (m_folderRecursive) { - fullPath.append("*"); - } - - TreeItem* pItem = new TreeItem(val, fullPath, m_pFeature, parent[i]); - parent[i]->appendChild(pItem); - - parent[i + 1] = pItem; - lastUsed[i] = val; - } - } - } -} diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index dafeab235b5..b38f4f77352 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -27,8 +27,6 @@ class LibraryTreeModel : public TreeItemModel { void setSortOrder(QStringList sortOrder); QStringList getSortOrder(); - void setFolderRecursive(bool recursive); - bool getFolderRecursive(); public slots: void reloadTracksTree(); @@ -50,9 +48,7 @@ class LibraryTreeModel : public TreeItemModel { private: QVariant getQuery(TreeItem* pTree) const; void createTracksTree(); - void createFoldersTree(); void addCoverArt(const CoverIndex& index, const QSqlQuery& query, TreeItem* pTree); - void createTreeFromSource(const QString& dir, QSqlQuery& query); LibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; From f0d7888e32e6ba48504a5efe3091cc54955075e9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 11:57:14 +0200 Subject: [PATCH 351/552] Add LibraryFodler feature for browsing the Library items with folders --- build/depends.py | 1 + src/library/historyfeature.cpp | 2 +- src/library/historyfeature.h | 2 +- src/library/library.cpp | 3 ++ src/library/libraryfeature.h | 2 +- src/library/libraryfoldermodel.cpp | 47 +++++++++++------------ src/library/libraryfoldermodel.h | 15 ++++---- src/library/libraryfoldersfeature.cpp | 48 ++++++++++++++++++++++++ src/library/libraryfoldersfeature.h | 23 ++++++++++++ src/library/librarytreemodel.cpp | 53 ++++++++++++-------------- src/library/librarytreemodel.h | 8 ++-- src/library/mixxxlibraryfeature.cpp | 54 +++++++++++++-------------- src/library/mixxxlibraryfeature.h | 20 ++++++---- src/library/treeitemmodel.cpp | 4 ++ src/library/treeitemmodel.h | 4 +- 15 files changed, 182 insertions(+), 104 deletions(-) create mode 100644 src/library/libraryfoldersfeature.cpp create mode 100644 src/library/libraryfoldersfeature.h diff --git a/build/depends.py b/build/depends.py index 60ff143d8cb..954206d281e 100644 --- a/build/depends.py +++ b/build/depends.py @@ -871,6 +871,7 @@ def sources(self, build): "library/autodj/autodjprocessor.cpp", "library/dao/directorydao.cpp", "library/mixxxlibraryfeature.cpp", + "library/libraryfoldersfeature.cpp", "library/baseplaylistfeature.cpp", "library/playlistfeature.cpp", "library/historyfeature.cpp", diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 39601f4e906..b43342172df 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -67,7 +67,7 @@ void HistoryFeature::onRightClick(const QPoint&) { // menu.exec(globalPos); } -void HistoryFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { +void HistoryFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex &index) { //Save the model index so we can get it in the action slots... m_lastRightClickedIndex = index; bool ok; diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index 207d5890934..f75125fa21b 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -29,7 +29,7 @@ class HistoryFeature : public BasePlaylistFeature { public slots: void onRightClick(const QPoint&) override; - void onRightClickChild(const QPoint& globalPos, QModelIndex index) override; + void onRightClickChild(const QPoint& globalPos, const QModelIndex& index) override; void slotJoinWithNext(); void slotGetNewPlaylist(); diff --git a/src/library/library.cpp b/src/library/library.cpp index d5267e7c0c7..0c425d99544 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -12,6 +12,7 @@ #include "library/banshee/bansheefeature.h" #include "library/browse/browsefeature.h" #include "library/cratefeature.h" +#include "library/libraryfoldersfeature.h" #include "library/historyfeature.h" #include "library/itunes/itunesfeature.h" #include "library/librarycontrol.h" @@ -503,6 +504,8 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(new AutoDJFeature(pConfig, this, this, pPlayerManager, m_pTrackCollection)); + addFeature(new LibraryFoldersFeature(pConfig, this, this, m_pTrackCollection)); + m_pPlaylistFeature = new PlaylistFeature(pConfig, this, this, m_pTrackCollection); addFeature(m_pPlaylistFeature); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 53e8e19fdb2..2b5ca188362 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -85,7 +85,7 @@ class LibraryFeature : public QObject { } // called when you right click on a child item, e.g., a concrete playlist or crate virtual void onRightClickChild(const QPoint& /* globalPos */, - QModelIndex /* index */) { + const QModelIndex& /* index */) { } // Only implement this, if using incremental or lazy childmodels, see BrowseFeature. // This method is executed whenever you **double** click child items diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index 9ef51e07d2f..ce933eee6d3 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -3,6 +3,8 @@ #include "library/libraryfoldermodel.h" #include "library/libraryfeature.h" +#include "library/queryutil.h" +#include "library/trackcollection.h" #include "library/treeitem.h" LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, @@ -19,12 +21,27 @@ LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, "FolderRecursive")); m_folderRecursive = recursive.toInt() == 1; - reloadFoldersTree(); + reloadTree(); +} + +bool LibraryFolderModel::setData(const QModelIndex& index, const QVariant& value, int role) { + if (role == TreeItemModel::RoleSettings) { + m_folderRecursive = value.toBool(); + m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), + ConfigValue((int)m_folderRecursive)); + return true; + } else { + return TreeItemModel::setData(index, value, role); + } } QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { + if (role == TreeItemModel::RoleSettings) { + return m_folderRecursive; + } + if (role != TreeItemModel::RoleQuery) { - return TreeItemModel(index, role); + return TreeItemModel::data(index, role); } // Role is Get query @@ -43,20 +60,9 @@ QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { return param.arg("folder", pTree->dataPath().toString()); } -void LibraryFolderModel::setFolderRecursive(bool recursive) { - m_folderRecursive = recursive; - m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), - ConfigValue((int)recursive)); -} - -bool LibraryFolderModel::getFolderRecursive() { - return m_folderRecursive; -} - -void LibraryFolderModel::reloadFoldersTree() { +void LibraryFolderModel::reloadTree() { // Remove current root - m_pRootItem = new TreeItem(m_pFeature); - setRootItem(m_pRootItem); + setRootItem(new TreeItem(m_pFeature)); // Add "show all" item m_pShowAllItem = new TreeItem(tr("Show all"), "", m_pFeature, m_pRootItem); @@ -75,11 +81,6 @@ void LibraryFolderModel::reloadFoldersTree() { QSqlQuery query(m_pTrackCollection->getDatabase()); query.prepare(queryStr); - m_pFoldersRoot = new TreeItem(tr("Folders"), "", m_pFeature, m_pRootItem); - QIcon icon(WPixmapStore::getLibraryIcon(":/images/library/ic_library_folder.png")); - m_pFoldersRoot->setIcon(icon); - m_pRootItem->appendChild(m_pFoldersRoot); - for (const QString& dir : dirs) { query.bindValue(":dir", dir + "%"); @@ -96,7 +97,7 @@ void LibraryFolderModel::reloadFoldersTree() { void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& query) { QStringList lastUsed; QList parent; - parent.append(m_pFoldersRoot); + parent.append(m_pRootItem); bool first = true; while (query.next()) { @@ -117,9 +118,9 @@ void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& que if (m_folderRecursive) { path.append("*"); } - TreeItem* pTree = new TreeItem(dir, path, m_pFeature, m_pFoldersRoot); + TreeItem* pTree = new TreeItem(dir, path, m_pFeature, m_pRootItem); pTree->setDivider(true); - m_pFoldersRoot->appendChild(pTree); + m_pRootItem->appendChild(pTree); } // Do not add empty items diff --git a/src/library/libraryfoldermodel.h b/src/library/libraryfoldermodel.h index f1df78e6101..7cb0eeb50ad 100644 --- a/src/library/libraryfoldermodel.h +++ b/src/library/libraryfoldermodel.h @@ -4,6 +4,7 @@ #include #include "library/treeitemmodel.h" +#include "preferences/usersettings.h" class LibraryFeature; class TrackCollection; @@ -11,18 +12,16 @@ class TrackCollection; class LibraryFolderModel : public TreeItemModel { public: - LibraryFolderModel(LibraryFeature *pFeature, - TrackCollection *pTrackCollection, + LibraryFolderModel(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, UserSettingsPointer pConfig, - QObject *parent); + QObject* parent = nullptr); + virtual bool setData(const QModelIndex& index, const QVariant& value, int role); virtual QVariant data(const QModelIndex &index, int role) const; - - void setFolderRecursive(bool recursive); - bool getFolderRecursive(); - + public slots: - void reloadFoldersTree(); + void reloadTree(); private: diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp new file mode 100644 index 00000000000..5623f6d9c4a --- /dev/null +++ b/src/library/libraryfoldersfeature.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +#include "library/libraryfoldersfeature.h" + +#include "library/libraryfoldermodel.h" + +LibraryFoldersFeature::LibraryFoldersFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : MixxxLibraryFeature(pConfig, pLibrary, parent, pTrackCollection) { + + setChildModel(new LibraryFolderModel(this, m_pTrackCollection, m_pConfig)); +} + +QVariant LibraryFoldersFeature::title() { + return "Folders"; +} + +QString LibraryFoldersFeature::getIconPath() { + return ":/images/library/ic_library_folder.png"; +} + +void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, + const QModelIndex&) { + + bool recursive = m_pChildModel->data(QModelIndex(), + TreeItemModel::RoleSettings).toBool(); + + QMenu menu; + QAction* showRecursive = menu.addAction(tr("Show recursive view in folders")); + showRecursive->setCheckable(true); + showRecursive->setChecked(recursive); + + QAction* selected = menu.exec(pos); + + if (selected == showRecursive) { + m_pChildModel->setData(QModelIndex(), selected->isChecked(), + TreeItemModel::RoleSettings); + } else { + // Menu rejected + return; + } + + m_pChildModel->reloadTree(); +} diff --git a/src/library/libraryfoldersfeature.h b/src/library/libraryfoldersfeature.h new file mode 100644 index 00000000000..b0ab4e0b7eb --- /dev/null +++ b/src/library/libraryfoldersfeature.h @@ -0,0 +1,23 @@ +#ifndef LIBRARYFOLDERSFEATURE_H +#define LIBRARYFOLDERSFEATURE_H + +#include "library/mixxxlibraryfeature.h" + +class LibraryFoldersModel; + +class LibraryFoldersFeature : public MixxxLibraryFeature +{ + public: + LibraryFoldersFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); + + QVariant title() override; + QString getIconPath() override; + + public slots: + void onRightClickChild(const QPoint& pos, const QModelIndex&) override; +}; + +#endif // LIBRARYFOLDERSFEATURE_H diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 35909d0cbbc..99e74eb2ba0 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -40,16 +40,21 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, s.prepend("library."); } m_coverQuery << "track_locations." + TRACKLOCATIONSTABLE_LOCATION; - reloadTracksTree(); + reloadTree(); } QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { - // The decoration role contains the icon in QTreeView + if (role == TreeItemModel::RoleSettings) { + return m_sortOrder; + } + + // The decoration role contains the icon in QTreeView if (role != Qt::DecorationRole && role != TreeItemModel::RoleQuery) { return TreeItemModel::data(index, role); } + TreeItem* pTree = static_cast(index.internalPointer()); DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { return QVariant(); @@ -83,17 +88,18 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { return QVariant(); } -void LibraryTreeModel::setSortOrder(QStringList sortOrder) { - m_sortOrder = sortOrder; - m_pConfig->set(ConfigKey("[Library]", LIBRARYTREEMODEL_SORT), - ConfigValue(m_sortOrder.join(","))); -} - -QStringList LibraryTreeModel::getSortOrder() { - return m_sortOrder; +bool LibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { + if (role == TreeItemModel::RoleSettings) { + m_sortOrder = value.toStringList(); + m_pConfig->set(ConfigKey("[Library]", LIBRARYTREEMODEL_SORT), + ConfigValue(m_sortOrder.join(","))); + return true; + } else { + return TreeItemModel::setData(index, value, role); + } } -void LibraryTreeModel::reloadTracksTree() { +void LibraryTreeModel::reloadTree() { //qDebug() << "LibraryTreeModel::reloadTracksTree"; // Create root item @@ -108,8 +114,8 @@ void LibraryTreeModel::reloadTracksTree() { // Deletes the old root item if the previous root item was not null setRootItem(pRootItem); - createFoldersTree(); createTracksTree(); + triggerRepaint(); } void LibraryTreeModel::coverFound(const QObject* requestor, int requestReference, @@ -136,30 +142,21 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { } const QString param("%1:=\"%2\""); - // Find Artist / Album / Genre query int depth = 0; - pAux = pTree; - - // We need to know the depth of the item to apply the filter - while (pAux->parent() != m_pRootItem && pAux->parent() != nullptr) { - pAux = pAux->parent(); - ++depth; - } - - // Generate the query + TreeItem* pAux = pTree; QStringList result; - pAux = pTree; - while (depth >= 0) { + // Generate the query + while (pAux->parent() != m_pRootItem && pAux->parent() != nullptr) { QString value = pAux->dataPath().toString(); if (pAux->isDivider()) { value.append("*"); } - result << param.arg(m_sortOrder[depth], value); + pAux = pAux->parent(); - --depth; - } + ++depth; + } return result.join(" "); } @@ -279,8 +276,6 @@ void LibraryTreeModel::createTracksTree() { pTree->setTrackCount(pTree->getTrackCount() + val); } } - - triggerRepaint(); } void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index b38f4f77352..1fc799294a4 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -23,13 +23,11 @@ class LibraryTreeModel : public TreeItemModel { UserSettingsPointer pConfig, QObject* parent = nullptr); - virtual QVariant data(const QModelIndex &index, int role) const; - - void setSortOrder(QStringList sortOrder); - QStringList getSortOrder(); + virtual QVariant data(const QModelIndex& index, int role) const; + virtual bool setData(const QModelIndex& index, const QVariant& value, int role); public slots: - void reloadTracksTree(); + void reloadTree() override; private: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index f11c4f1b532..0e8478ff51a 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -27,7 +27,6 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), kLibraryTitle(tr("Library")), - m_childModel(this, pTrackCollection, pConfig), m_trackDao(pTrackCollection->getTrackDAO()) { QStringList columns; columns << "library." + LIBRARYTABLE_ID @@ -101,12 +100,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); - connect(&m_trackDao, SIGNAL(trackChanged(TrackId)), - &m_childModel, SLOT(reloadTracksTree())); - connect(&m_trackDao, SIGNAL(tracksRemoved(QSet)), - &m_childModel, SLOT(reloadTracksTree())); - connect(&m_trackDao, SIGNAL(tracksAdded(QSet)), - &m_childModel, SLOT(reloadTracksTree())); + setChildModel(new LibraryTreeModel(this, m_pTrackCollection, m_pConfig)); m_pBaseTrackCache = QSharedPointer(pBaseTrackCache); @@ -118,6 +112,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, } MixxxLibraryFeature::~MixxxLibraryFeature() { + delete m_pChildModel; delete m_pLibraryTableModel; } @@ -130,13 +125,13 @@ QString MixxxLibraryFeature::getIconPath() { } TreeItemModel* MixxxLibraryFeature::getChildModel() { - return &m_childModel; + return m_pChildModel; } QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pSidebar = createLibrarySidebarWidget(pKeyboard); m_pSidebar->setIconSize(QSize(32, 32)); - m_childModel.reloadTracksTree(); + m_pChildModel->reloadTree(); return m_pSidebar; } @@ -157,6 +152,19 @@ void MixxxLibraryFeature::onSearch(const QString&) { m_pSidebar->clearSelection(); } +void MixxxLibraryFeature::setChildModel(TreeItemModel* pChild) { + if (!m_pChildModel.isNull()) { + delete m_pChildModel; + } + + m_pChildModel = pChild; + connect(&m_trackDao, SIGNAL(trackChanged(TrackId)), + m_pChildModel, SLOT(reloadTracksTree())); + connect(&m_trackDao, SIGNAL(tracksRemoved(QSet)), + m_pChildModel, SLOT(reloadTracksTree())); + connect(&m_trackDao, SIGNAL(tracksAdded(QSet)), + m_pChildModel, SLOT(reloadTracksTree())); +} void MixxxLibraryFeature::activate() { //qDebug() << "MixxxLibraryFeature::activate()"; @@ -179,16 +187,11 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, const QModelIndex&) { - bool recursive = m_childModel.getFolderRecursive(); // Create the sort menu - QMenu menu; - QAction* showRecursive = menu.addAction(tr("Show recursive view in folders")); - showRecursive->setCheckable(true); - showRecursive->setChecked(recursive); - - menu.addSeparator(); - QStringList currentSort = m_childModel.getSortOrder(); + QMenu menu; + QVariant varSort = m_pChildModel->data(QModelIndex(), TreeItemModel::RoleSettings); + QStringList currentSort = varSort.toStringList(); QStringList orderArtistAlbum, orderAlbum, orderGenreArtist, orderGenreAlbum; orderArtistAlbum << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; @@ -220,22 +223,19 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, QAction* selected = menu.exec(pos); - if (selected == showRecursive) { - recursive = showRecursive->isChecked(); - m_childModel.setFolderRecursive(recursive); - } else if (selected == artistAlbum) { - m_childModel.setSortOrder(orderArtistAlbum); + if (selected == artistAlbum) { + m_pChildModel->setData(QModelIndex(), orderArtistAlbum, TreeItemModel::RoleSettings); } else if (selected == album) { - m_childModel.setSortOrder(orderAlbum); + m_pChildModel->setData(QModelIndex(), orderAlbum, TreeItemModel::RoleSettings); } else if (selected == genreArtist) { - m_childModel.setSortOrder(orderGenreArtist); + m_pChildModel->setData(QModelIndex(), orderGenreArtist, TreeItemModel::RoleSettings); } else if (selected == genreAlbum) { - m_childModel.setSortOrder(orderGenreAlbum); + m_pChildModel->setData(QModelIndex(), orderGenreAlbum, TreeItemModel::RoleSettings); } else { // Menu rejected return; } - m_childModel.reloadTracksTree(); + m_pChildModel->reloadTree(); } bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { @@ -246,7 +246,7 @@ bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { // Adds track, does not insert duplicates, handles unremoving logic. QList trackIds = m_trackDao.addMultipleTracks(files, true); - m_childModel.reloadTracksTree(); + m_pChildModel->reloadTree(); return trackIds.size() > 0; } } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 3db1913f727..8c63ed532a7 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -32,7 +32,7 @@ class MissingTableModel; class MixxxLibraryFeature : public LibraryFeature { Q_OBJECT - + public: MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, @@ -42,26 +42,31 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - + bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); TreeItemModel* getChildModel(); - QWidget* createInnerSidebarWidget(KeyboardEventFilter *pKeyboard) override; + QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; public slots: void activate(); void activateChild(const QModelIndex& index); - void onRightClickChild(const QPoint& pos, const QModelIndex&); + void onRightClickChild(const QPoint& pos, const QModelIndex&) override; void refreshLibraryModels(); - + void selectAll(); void onSearch(const QString&) override; - + signals: void unhideHidden(); void purgeHidden(); void purgeMissing(); + protected: + void setChildModel(TreeItemModel* pChild); + + QPointer m_pChildModel; + private: enum Panes { MixxxLibrary = 1, @@ -69,11 +74,10 @@ class MixxxLibraryFeature : public LibraryFeature { Missing = 3 }; const QString kLibraryTitle; - + QSharedPointer m_pBaseTrackCache; QPointer m_pSidebar; LibraryTableModel* m_pLibraryTableModel; - LibraryTreeModel m_childModel; TrackDAO& m_trackDao; }; diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 060f63b3665..14eac971089 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -241,6 +241,10 @@ QString TreeItemModel::getBreadCrumbString(TreeItem* pTree) { return next % QLatin1String(" > ") % text; } +void TreeItemModel::reloadTree() { + triggerRepaint(); +} + bool TreeItemModel::dropAccept(const QModelIndex& index, QList urls, QObject* pSource) { //qDebug() << "TreeItemModel::dropAccept() index=" << index << urls; diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index 4bec30feddb..d71ae3331e7 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -18,7 +18,8 @@ class TreeItemModel : public QAbstractItemModel { RoleBold, RoleDivider, RoleQuery, - RoleBreadCrumb + RoleBreadCrumb, + RoleSettings }; TreeItemModel(QObject* parent = nullptr); @@ -48,6 +49,7 @@ class TreeItemModel : public QAbstractItemModel { static QString getBreadCrumbString(TreeItem* pTree); public slots: + virtual void reloadTree(); void triggerRepaint(); protected: From 17419f921d52b8c684c5ee57b69f5f6935a7b19d Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 20:29:01 +0200 Subject: [PATCH 352/552] Fix some bugs and coding style issues --- src/library/libraryfoldermodel.cpp | 39 +++++++++++++++------- src/library/libraryfoldermodel.h | 2 +- src/library/librarytreemodel.cpp | 53 +++++++++++++++++++----------- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index ce933eee6d3..7eeef7e9e9d 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -71,12 +71,15 @@ void LibraryFolderModel::reloadTree() { // Get the Library directories QStringList dirs(m_pTrackCollection->getDirectoryDAO().getDirs()); - QString queryStr = "SELECT DISTINCT %1 FROM %2 " - "WHERE %3=0 AND %1 LIKE :dir " - "ORDER BY %1 COLLATE localeAwareCompare"; + QString queryStr = "SELECT COUNT(%3),%1 " + "FROM track_locations INNER JOIN library ON %3=%4 " + "WHERE %2=0 AND %1 LIKE :dir " + "GROUP BY %1 " + "ORDER BY %1 COLLATE localeAwareCompare"; queryStr = queryStr.arg(TRACKLOCATIONSTABLE_DIRECTORY, - "track_locations", - TRACKLOCATIONSTABLE_FSDELETED); + "library." + LIBRARYTABLE_MIXXXDELETED, + "library." + LIBRARYTABLE_ID, + "track_locations." + TRACKLOCATIONSTABLE_ID); QSqlQuery query(m_pTrackCollection->getDatabase()); query.prepare(queryStr); @@ -90,23 +93,23 @@ void LibraryFolderModel::reloadTree() { } // For each source folder create the tree - createTreeFromSource(dir, query); + createTreeForLibraryDir(dir, query); } } -void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& query) { +void LibraryFolderModel::createTreeForLibraryDir(const QString& dir, QSqlQuery& query) { QStringList lastUsed; QList parent; parent.append(m_pRootItem); bool first = true; while (query.next()) { - QString value = query.value(0).toString(); - qDebug() << value; + QString location = query.value(1).toString(); + //qDebug() << location; // Remove the - QString dispValue = value.mid(dir.size()); + QString dispValue = location.mid(dir.size()); if (dispValue.startsWith("/")) { dispValue = dispValue.mid(1); } @@ -128,8 +131,10 @@ void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& que continue; } + // We always use Qt notation for folders "/" QStringList parts = dispValue.split("/"); - if (parts.size() > lastUsed.size()) { + int treeDepth = parts.size(); + if (treeDepth > lastUsed.size()) { for (int i = lastUsed.size(); i < parts.size(); ++i) { lastUsed.append(QString()); parent.append(nullptr); @@ -152,11 +157,23 @@ void LibraryFolderModel::createTreeFromSource(const QString& dir, QSqlQuery& que } TreeItem* pItem = new TreeItem(val, fullPath, m_pFeature, parent[i]); + pItem->setTrackCount(0); parent[i]->appendChild(pItem); parent[i + 1] = pItem; lastUsed[i] = val; } } + + // Set track count + int val = query.value(0).toInt(); + for (int i = 1; i < treeDepth + 1; ++i) { + TreeItem* pItem = parent[i]; + if (pItem == nullptr) { + continue; + } + + pItem->setTrackCount(pItem->getTrackCount() + val); + } } } diff --git a/src/library/libraryfoldermodel.h b/src/library/libraryfoldermodel.h index 7cb0eeb50ad..982e5ee916c 100644 --- a/src/library/libraryfoldermodel.h +++ b/src/library/libraryfoldermodel.h @@ -25,7 +25,7 @@ class LibraryFolderModel : public TreeItemModel private: - void createTreeFromSource(const QString& dir, QSqlQuery& query); + void createTreeForLibraryDir(const QString& dir, QSqlQuery& query); LibraryFeature* m_pFeature; TrackCollection* m_pTrackCollection; diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 99e74eb2ba0..1e323fac9ca 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -146,8 +146,15 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { TreeItem* pAux = pTree; QStringList result; - // Generate the query + // We need to know the depth before doing anything while (pAux->parent() != m_pRootItem && pAux->parent() != nullptr) { + pAux = pAux->parent(); + ++depth; + } + + // Generate the query + pAux = pTree; + while (depth >= 0) { QString value = pAux->dataPath().toString(); if (pAux->isDivider()) { value.append("*"); @@ -155,7 +162,7 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { result << param.arg(m_sortOrder[depth], value); pAux = pAux->parent(); - ++depth; + --depth; } return result.join(" "); @@ -176,7 +183,9 @@ void LibraryTreeModel::createTracksTree() { #else sortColumns = m_sortOrder; #endif - + + // Sorting is required to create the tree because the tree is sorted and + // in order to create a tree with levels it must be sorted too. QString queryStr = "SELECT COUNT(%3),%1,%2 " "FROM library LEFT JOIN track_locations " "ON (%3 = %4) " @@ -201,8 +210,8 @@ void LibraryTreeModel::createTracksTree() { } //qDebug() << "LibraryTreeModel::createTracksTree" << query.executedQuery(); - int size = columns.size(); - if (size <= 0) { + int treeDepth = columns.size(); + if (treeDepth <= 0) { return; } QSqlRecord record = query.record(); @@ -215,23 +224,26 @@ void LibraryTreeModel::createTracksTree() { cIndex.iCoverType = record.indexOf(LIBRARYTABLE_COVERART_TYPE); cIndex.iTrackLoc = record.indexOf(TRACKLOCATIONSTABLE_LOCATION); - int extraSize = m_coverQuery.size() + 1; - QVector lastUsed(size); + int treeStartQueryIndex = m_coverQuery.size() + 1; + QVector lastUsed(treeDepth); QChar lastHeader; - QVector parent(size + 1, nullptr); + // We add 1 to the total parents because the first parent is the root item + // with this we can always use parent[i] to get the parent of the element at + // depth i and to set the parent we avoid checking that i + 1 < treeDepth + QVector parent(treeDepth + 1, nullptr); parent[0] = m_pRootItem; while (query.next()) { - for (int i = 0; i < size; ++i) { - QString value = query.value(extraSize + i).toString(); - QString valueP = value; + for (int i = 0; i < treeDepth; ++i) { + QString treeItemLabel = query.value(treeStartQueryIndex + i).toString(); + QString dataPath = treeItemLabel; - bool unknown = valueP.isNull(); + bool unknown = dataPath.isNull(); if (unknown) { - valueP = ""; - value = tr("Unknown"); + dataPath = ""; + treeItemLabel = tr("Unknown"); } - if (!lastUsed[i].isNull() && valueP.localeAwareCompare(lastUsed[i]) == 0) { + if (!lastUsed[i].isNull() && dataPath.localeAwareCompare(lastUsed[i]) == 0) { continue; } @@ -241,7 +253,7 @@ void LibraryTreeModel::createTracksTree() { lastUsed.fill(QString()); // Check if a header must be added - QChar c = StringHelper::getFirstCharForGrouping(value); + QChar c = StringHelper::getFirstCharForGrouping(treeItemLabel); if (lastHeader != c) { lastHeader = c; TreeItem* pTree = new TreeItem(lastHeader, lastHeader, @@ -251,23 +263,24 @@ void LibraryTreeModel::createTracksTree() { } } - lastUsed[i] = valueP; + lastUsed[i] = dataPath; // We need to create a new item - TreeItem* pTree = new TreeItem(value, valueP, m_pFeature, parent[i]); + TreeItem* pTree = new TreeItem(treeItemLabel, dataPath, + m_pFeature, parent[i]); pTree->setTrackCount(0); parent[i]->appendChild(pTree); parent[i + 1] = pTree; // Add coverart info - if (extraSize + i == iAlbum && !unknown) { + if (treeStartQueryIndex + i == iAlbum && !unknown) { addCoverArt(cIndex, query, pTree); } } // Set track count int val = query.value(0).toInt(); - for (int i = 1; i < size + 1; ++i) { + for (int i = 1; i < treeDepth + 1; ++i) { TreeItem* pTree = parent[i]; if (pTree == nullptr) { continue; From a044c8bb9bcf96192796aca442e7d87b77bdf5ab Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 20:46:46 +0200 Subject: [PATCH 353/552] Added show all --- src/library/librarytreemodel.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 1e323fac9ca..a324f36cee8 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -105,10 +105,8 @@ void LibraryTreeModel::reloadTree() { // Create root item TreeItem* pRootItem = new TreeItem(); pRootItem->setLibraryFeature(m_pFeature); - QString title = m_pFeature->title().toString(); - m_pLibraryItem = new TreeItem(title, "", m_pFeature, pRootItem); - m_pLibraryItem->setIcon(m_pFeature->getIcon()); + m_pLibraryItem = new TreeItem(tr("Show all"), "", m_pFeature, pRootItem); pRootItem->appendChild(m_pLibraryItem); From 03a5fd5017db8eb65deef5db7e6191efeb1aebed Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 21:09:47 +0200 Subject: [PATCH 354/552] Center cross icon and add save icon --- res/mixxx.qrc | 1 + res/skins/cross.png | Bin 471 -> 447 bytes res/skins/save.png | Bin 0 -> 547 bytes src/widget/wsearchlineedit.cpp | 15 +++++++++++---- src/widget/wsearchlineedit.h | 1 + 5 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 res/skins/save.png diff --git a/res/mixxx.qrc b/res/mixxx.qrc index fc4b6ede103..8166ab264f6 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -110,5 +110,6 @@ translations/mixxx_zh_TW.qm images/library/ic_library_maintenance.png images/library/ic_library_folder.png + skins/save.png diff --git a/res/skins/cross.png b/res/skins/cross.png index 7cdc6e33788e0f0bab030968f2960c1ab8686fad..ea1424ff16f4beb90133bad1fa62e8456c27ae48 100644 GIT binary patch delta 400 zcmV;B0dM}-1HS{1Bo78+OGiWi{{a60|De66laVnPe+P6)O+^Rb2nrJk1Jm~HT>t<9 zOi4sRR5;76QZa7AKoFc=U6f_XS(Z(S=ncS7*C!Dl+~dpXxnzBC4q>HtE!qro)hnVT~*aYM8=^|ig{9z06-UmpyZD#58^8S_zOi* uoSUXGA~FN80q~_~BOTk}+<=KoCX$ zjB*86IfDyaQX#EEv8E+e8YDUnVQ~mLBpMn-i?;w-qN1}?_&~IW0!^Atxo91gDlwg5&C zE<6MHm`o<$zXTNi1d#mUx&tr>A{=b%%?W@t5xwhR4{2|$Gh1b@0$G;Lf^8x?=6Swn zW}_koZ06;`m&bicD+cL9ZW@D{wopY&(torQAgjWdL27ttS zUpeQDwYCKS=UnQ&ukQ9U>>WH)LEsYgy4ZFc2e*s8^a3Jsin1*N?7govPHL@fiD(h# z0>c2%G|dLrPXZAcmt{GPGAG{qsw~T?h>Vp#EAvku2{r( diff --git a/res/skins/save.png b/res/skins/save.png new file mode 100644 index 0000000000000000000000000000000000000000..bdcd0786e542f32ac423b514136c8085fa6f6037 GIT binary patch literal 547 zcmeAS@N?(olHy`uVBq!ia0vp^c_7Te1|*L~tNjL2Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPN2bVCL&j0;qPBSntZt!$*45_&F_U`VkLkrk?rt{;xO7*HWDo*Ip;NZq=%cGk=d%bEGf*Dy~2O)`oAtYkM}{-D6j% zr+3-x9;&5FA}`_6Z*?YDC`JOV4Zv!1X0a7Nv}t5^4x6ouY2@tq|9{p-SInKD|ed~?7i zTvmAh*oot2-ga)cUq8}puhzzI5@ml|sc9eN#biGJ{7Q@CoH8&=nArUuut4K7YSz<setIcon(QIcon(pixmap)); - m_clearButton->setIconSize(pixmap.size()); + QPixmap crossPixmap(":/skins/cross.png"); + m_clearButton->setIcon(QIcon(crossPixmap)); + m_clearButton->setIconSize(crossPixmap.size()); m_clearButton->setCursor(Qt::ArrowCursor); m_clearButton->setToolTip(tr("Clear input" , "Clear the search bar input field")); m_clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); m_clearButton->hide(); + + m_saveButton = new QToolButton(this); + QPixmap savePixmap(":/skins/save.png"); + m_saveButton->setIcon(QIcon(savePixmap)); + m_saveButton->setIconSize(QSize(height()/2, height()/2)); + m_saveButton->setCursor(Qt::ArrowCursor); + m_saveButton->setToolTip(tr("Save query", "Save the current query for later use")); m_place = true; showPlaceholder(); setFocusPolicy(Qt::ClickFocus); - QShortcut *setFocusShortcut = new QShortcut( + QShortcut* setFocusShortcut = new QShortcut( QKeySequence(tr("Ctrl+F", "Search|Focus")), this); connect(setFocusShortcut, SIGNAL(activated()), this, SLOT(setFocus())); diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 7f681ab8374..857eccbfe21 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -46,6 +46,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { QTimer m_searchTimer; QToolButton* m_clearButton; + QToolButton* m_saveButton; bool m_place; QColor m_fgc; //Foreground color }; From 12969021ffe4aaee7db3d83b073c31183b76972f Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 22:14:05 +0200 Subject: [PATCH 355/552] Add drop down button --- res/mixxx.qrc | 1 + res/skins/downArrow.png | Bin 0 -> 2363 bytes src/widget/wsearchlineedit.cpp | 94 ++++++++++++++++++++++++--------- src/widget/wsearchlineedit.h | 7 +-- 4 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 res/skins/downArrow.png diff --git a/res/mixxx.qrc b/res/mixxx.qrc index 8166ab264f6..ccae0f08c12 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -111,5 +111,6 @@ images/library/ic_library_maintenance.png images/library/ic_library_folder.png skins/save.png + skins/downArrow.png diff --git a/res/skins/downArrow.png b/res/skins/downArrow.png new file mode 100644 index 0000000000000000000000000000000000000000..ac35ac649885e6694d14fa7cd2bbd515bba06a6b GIT binary patch literal 2363 zcmZ8jdpy(o8~<#%MXg*Dg=WZYa;eR&i!9quRCb04xkVh8nZ*+69A%D6woaOBj%&U} z2N?=;j$1=2H9{s?Cbt;1kUBemp5N>9dOq*x^*o>F^?5zd^LjncJMFZq({_0cc>ut6 z0^ZS0f|37t@0-I|BYb>IXf3uG=8Ud@@^5 z*+y9#sCt#$6;SJGqL%(&&;tj&{j3fgIDOdOz7^j72txNid$tuckham~?x1~U2m1R{ za!k%zOuTrpv`FMw{$8D*pO*)@l)G_Y2Pz?D6pnPU0R}#GZ&$`|rk`;=#wU6I6_JE?0Xr(l}yu!lP2M|a9Y(@N%5i{tTlI|#nWT-3$< z-dI*S-i_pxX>JfV|Hgd5mQ1BmEm6j&%NUVu`OD-S+t@zSDCR2Eu1Va(NI3gLTBW))J zI`x#&Dp4FA>ng}C049VV09t8Jud~@~ZaaMo2t0{N_6AHZo4rMs6US_sS1EghNoX{a zNKOzhCSJ&}Mj}7`FVw42Ya;Dwm!v3KSTfj|=7@%7bq1TA8>K413O__gBa_eNHN>E6 z8XBk>0{@2}&oi9zoZavUhTYicsEw8<8T=XZp|>8OOYk1s)Ldw4KT);Xd8hYVvHHTN zapw{fH&I*;P&a*FOlg%}aZ0sj@5XH`ma? zNJjkiRkhSfWGLFFOqtsO282e=?-j_XgBqDh)zBtxXM`c302yN=qqg4gJ`#Np?aiLg zr0r$fWT=YqI&+xVs88y%Ag;4$f-rFP7(kK9~EB8YT|17Y#3+^+;(|75AweERQM-u)hh#N%xm+fcW-ny3xN0DI%Yvw?KB z3io?mU7c(`ChAgk6K;Njb9G3ak|LPumnndYsp$`Y*mEhSrlx^O_lzgDbHt0|w)na+ zO@Fm@050E^1mjULJ!YQ;eKaC=&*3uYlzc9ZW;UAYSZ1Jg^X6Idk>d#o8OmNR#{shjY zbp;G>dScqH5@S1VY_~_o==$9vlgh=keMp16{QLYCotgDv%|Q>;|vO+Crh#r5@+H|i9nb_!{G zVy{kDy47XPa|uSq#@aIFT5yA`vha-EDC?s!u#Y&`&8MH-%3gWvq7pPUH27X*YZL?j zZ9lRSw4l~ro@tz!pW$c(*2q>N;0aJ6l;k2Rfhv}k!!JoKNv3TtxxmmEy(5-NZ3WRR z0r5&_8jjzFXU^+dzZe{R??t8stcgBg@I?mJVucS?9$!4VSsnR@BJ$+CMz)yN)Yg)- zf*KoZ_ggZCc4X&FIvCx4>`Nq0N#ZK%>O=^xFY}dl%3mZtf_w6%RdM8DDtW@ctsa$&jY4(FVm z`%dmxu{kc{K7aPnuF42046J>#sdJ|})YahO!-t&h#U7-PWncJut6p&rKrf6o%w?(y zx41v>WXPv>^uX*^azgp1t_SmBO&2nnHCIJyyiYKcQd$Dv5J4EGx?D(U4lP^T%T3?A zcdyw4?A=N1fHwZHj~#ybyDPkDq3|ifcp&6aLxVk$_xyWEcVUrUM)v$jW7Nc-szM@? z@zk8zXmLdPM9eh-Rq>-)j)huzlVouyGE-muRdGXL40hSr+V(uaa(0~*SS647<^<`e zr574OBGvm%rrzufI9B*Mq9^VX-#)xcI+=Ih!z{(&4_(w%?=xp!?)X0{@Lyt3-nnM> YC}`WsetIcon(QIcon(crossPixmap)); - m_clearButton->setIconSize(crossPixmap.size()); - m_clearButton->setCursor(Qt::ArrowCursor); - m_clearButton->setToolTip(tr("Clear input" , "Clear the search bar input field")); - m_clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); - m_clearButton->hide(); - m_saveButton = new QToolButton(this); - QPixmap savePixmap(":/skins/save.png"); - m_saveButton->setIcon(QIcon(savePixmap)); - m_saveButton->setIconSize(QSize(height()/2, height()/2)); - m_saveButton->setCursor(Qt::ArrowCursor); - m_saveButton->setToolTip(tr("Save query", "Save the current query for later use")); + QSize iconSize(height()/2, height()/2); + + m_pClearButton = new QToolButton(this); + m_pClearButton->setIcon(QIcon(":/skins/cross.png")); + m_pClearButton->setIconSize(iconSize); + m_pClearButton->setCursor(Qt::ArrowCursor); + m_pClearButton->setToolTip(tr("Clear input" , "Clear the search bar input field")); + m_pClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + m_pClearButton->hide(); + + m_pSaveButton = new QToolButton(this); + m_pSaveButton->setIcon(QIcon(":/skins/save.png")); + m_pSaveButton->setIconSize(iconSize); + m_pSaveButton->setCursor(Qt::ArrowCursor); + m_pSaveButton->setToolTip(tr("Save query", "Save the current query for later use")); + m_pSaveButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + m_pSaveButton->hide(); + + m_pDropButton = new QToolButton(this); + m_pDropButton->setIcon(QIcon(":/skins/downArrow.png")); + m_pDropButton->setIconSize(iconSize); + m_pDropButton->setCursor(Qt::ArrowCursor); + m_pDropButton->setToolTip(tr("Restore query", + "Restore the search with one of the selected queries")); + m_pDropButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + m_pDropButton->hide(); m_place = true; showPlaceholder(); @@ -52,21 +64,21 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) connect(this, SIGNAL(returnPressed()), this, SLOT(triggerSearch())); - connect(m_clearButton, SIGNAL(clicked()), + connect(m_pClearButton, SIGNAL(clicked()), this, SLOT(onSearchTextCleared())); // Forces immediate update of tracktable - connect(m_clearButton, SIGNAL(clicked()), + connect(m_pClearButton, SIGNAL(clicked()), this, SLOT(triggerSearch())); connect(this, SIGNAL(textChanged(const QString&)), - this, SLOT(updateCloseButton(const QString&))); + this, SLOT(updateButtons(const QString&))); // The width of the frame for the widget based on the styling. int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); // Ensures the text does not obscure the clear image. setStyleSheet(QString("QLineEdit { padding-right: %1px; } "). - arg(m_clearButton->sizeHint().width() + frameWidth + 1)); + arg(m_pClearButton->sizeHint().width() + frameWidth + 1)); } void WSearchLineEdit::setup(const QDomNode& node, const SkinContext& context) { @@ -94,14 +106,39 @@ void WSearchLineEdit::setup(const QDomNode& node, const SkinContext& context) { void WSearchLineEdit::resizeEvent(QResizeEvent* e) { QLineEdit::resizeEvent(e); - QSize sz = m_clearButton->sizeHint(); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - int height = (rect().bottom() + 1 - sz.height())/2; + + QSize iconSize(height()/2, height()/2); + m_pDropButton->setIconSize(iconSize); + m_pSaveButton->setIconSize(iconSize); + m_pClearButton->setIconSize(iconSize); + + const QSize sizeDrop = m_pDropButton->sizeHint(); + const QSize sizeSave = m_pSaveButton->sizeHint(); + const QSize sizeClear = m_pClearButton->sizeHint(); + const int space = 1; // 1px of space between items + + int posXDrop = frameWidth + 1; + int posXSave = posXDrop + sizeDrop.width() + space; + int posXClear = posXSave + sizeSave.width() + space; + + int posYDrop = (height() - sizeDrop.height())/2; + int posYSave = (height() - sizeSave.height())/2; + int posYClear = (height() - sizeClear.height())/2; + if (layoutDirection() == Qt::LeftToRight) { - m_clearButton->move(rect().right() - frameWidth - sz.width() - 1, - height); + posXDrop += sizeDrop.width(); + posXSave += sizeDrop.width(); + posXClear += sizeDrop.width(); + + m_pDropButton->move(width() - posXDrop, posYDrop); + m_pSaveButton->move(width() - posXSave, posYSave); + m_pClearButton->move(width() - posXClear, posYClear); } else { - m_clearButton->move(frameWidth + 1, height); + m_pDropButton->move(posXDrop, posYDrop); + m_pSaveButton->move(posXSave, posYSave); + m_pClearButton->move(posXClear, posYClear); } } @@ -142,6 +179,8 @@ void WSearchLineEdit::restoreSearch(const QString& text) { blockSignals(true); setText("- - -"); blockSignals(false); + m_pSaveButton->hide(); + m_pDropButton->hide(); return; } setEnabled(true); @@ -158,7 +197,7 @@ void WSearchLineEdit::restoreSearch(const QString& text) { setPalette(pal); m_place = false; } - updateCloseButton(text); + updateButtons(text); } void WSearchLineEdit::slotSetupTimer(const QString& text) @@ -192,9 +231,12 @@ void WSearchLineEdit::showPlaceholder() { setPalette(pal); } -void WSearchLineEdit::updateCloseButton(const QString& text) +void WSearchLineEdit::updateButtons(const QString& text) { - m_clearButton->setVisible(!text.isEmpty() && !m_place); + bool visible = !text.isEmpty() && !m_place; + m_pDropButton->show(); + m_pSaveButton->setVisible(visible); + m_pClearButton->setVisible(visible); } bool WSearchLineEdit::event(QEvent* pEvent) { diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 857eccbfe21..68f51633fa8 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -36,7 +36,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void slotTextChanged(const QString& text); private slots: - void updateCloseButton(const QString& text); + void updateButtons(const QString& text); void slotSetupTimer(const QString& text); void triggerSearch(); void onSearchTextCleared(); @@ -45,8 +45,9 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void showPlaceholder(); QTimer m_searchTimer; - QToolButton* m_clearButton; - QToolButton* m_saveButton; + QToolButton* m_pClearButton; + QToolButton* m_pSaveButton; + QToolButton* m_pDropButton; bool m_place; QColor m_fgc; //Foreground color }; From e967f06f1dcf9ecc15faecdf9b34d49715dc205c Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 10 Aug 2016 23:10:45 +0200 Subject: [PATCH 356/552] First steps with saved queries --- src/library/libraryfeature.cpp | 14 ++++++++ src/library/libraryfeature.h | 15 +++++++++ src/library/librarypanemanager.cpp | 2 +- src/widget/wsearchlineedit.cpp | 54 ++++++++++++++++++++++++++++-- src/widget/wsearchlineedit.h | 19 +++++++---- 5 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index a4ac35691e6..12ef311078a 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -92,6 +92,20 @@ void LibraryFeature::setFocusedPane(int paneId) { m_focusedPane = paneId; } +void LibraryFeature::saveQuery(SavedSearchQuery& query) { + // A saved query goes the first in the list + m_savedQueries.prepend(query); +} + +void LibraryFeature::restoreQuery(int index) { + // Move the used query to the first item in the list + m_savedQueries.move(index, 0); +} + +const QList& LibraryFeature::getSavedQueries() const { + return m_savedQueries; +} + WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 2b5ca188362..0da3b73bf20 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -25,6 +25,15 @@ class WLibrary; class WLibrarySidebar; class WTrackTableView; +// This struct allows to save some data to allow interaction between +// the search bar and the library features +struct SavedSearchQuery { + QString query; + QString title; + QModelIndex selectedItem; + QString sortOrder; +}; + // pure virtual (abstract) class to provide an interface for libraryfeatures class LibraryFeature : public QObject { Q_OBJECT @@ -73,6 +82,10 @@ class LibraryFeature : public QObject { virtual int getFeatureFocus(); virtual void setFocusedPane(int paneId); + + virtual void saveQuery(SavedSearchQuery& query); + virtual void restoreQuery(int index); + virtual const QList &getSavedQueries() const; public slots: // called when you single click on the root item @@ -142,6 +155,8 @@ class LibraryFeature : public QObject { int m_featureFocus; int m_focusedPane; + QList m_savedQueries; + private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); QHash > m_trackTables; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index fc93e5c431a..01c644e8de0 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -114,7 +114,7 @@ void LibraryPaneManager::switchToFeature(LibraryFeature* pFeature) { void LibraryPaneManager::restoreSearch(const QString& text) { if (!m_pSearchBar.isNull()) { - m_pSearchBar->restoreSearch(text); + m_pSearchBar->restoreSearch(text, m_pCurrentFeature); } } diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index ebd81e845cf..d702ac71407 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -2,10 +2,12 @@ #include "wskincolor.h" #include "wsearchlineedit.h" -#include -#include +#include +#include #include +#include #include +#include WSearchLineEdit::WSearchLineEdit(QWidget* pParent) : QLineEdit(pParent), @@ -69,6 +71,11 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) // Forces immediate update of tracktable connect(m_pClearButton, SIGNAL(clicked()), this, SLOT(triggerSearch())); + + connect(m_pSaveButton, SIGNAL(clicked()), + this, SLOT(saveQuery())); + connect(m_pDropButton, SIGNAL(clicked()), + this, SLOT(restoreQuery())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateButtons(const QString&))); @@ -172,7 +179,7 @@ void WSearchLineEdit::focusOutEvent(QFocusEvent* event) { } // slot -void WSearchLineEdit::restoreSearch(const QString& text) { +void WSearchLineEdit::restoreSearch(const QString& text, QPointer pFeature) { if(text.isNull()) { // disable setEnabled(false); @@ -181,9 +188,11 @@ void WSearchLineEdit::restoreSearch(const QString& text) { blockSignals(false); m_pSaveButton->hide(); m_pDropButton->hide(); + m_pCurrentFeature = nullptr; return; } setEnabled(true); + m_pCurrentFeature = pFeature; qDebug() << "WSearchLineEdit::restoreSearch(" << text << ")"; blockSignals(true); setText(text); @@ -251,6 +260,45 @@ void WSearchLineEdit::onSearchTextCleared() { emit(searchCleared()); } +void WSearchLineEdit::saveQuery() { + SavedSearchQuery query; + query.title = query.query = text(); + if (!m_pCurrentFeature.isNull()) { + m_pCurrentFeature->saveQuery(query); + } + setText(""); +} + +void WSearchLineEdit::restoreQuery() { + const QList& savedQueries = m_pCurrentFeature->getSavedQueries(); + + QMenu menu; + + if (savedQueries.size() <= 0) { + QAction* action = menu.addAction(tr("No saved queries")); + action->setData(-1); + } + for (int i = 0; i < savedQueries.size(); ++i) { + QAction* action = menu.addAction(savedQueries[i].title); + action->setData(i); + } + QPoint position = m_pDropButton->pos(); + position += QPoint(0, m_pDropButton->height()); + + QAction* selected = menu.exec(mapToGlobal(position)); + if (selected == nullptr) { + return; + } + int index = selected->data().toInt(); + + if (index < 0) { + return; + } + m_pCurrentFeature->restoreQuery(index); + + setText(savedQueries.at(index).query); +} + void WSearchLineEdit::slotTextChanged(const QString& text) { if (text.isEmpty()) { triggerSearch(); diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 68f51633fa8..6d36f494389 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -1,14 +1,16 @@ #ifndef WSEARCHLINEEDIT_H #define WSEARCHLINEEDIT_H -#include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include +#include +#include "library/libraryfeature.h" #include "preferences/usersettings.h" #include "skin/skincontext.h" #include "widget/wbasewidget.h" @@ -16,6 +18,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { Q_OBJECT public: + explicit WSearchLineEdit(QWidget* pParent = nullptr); void setup(const QDomNode& node, const SkinContext& context); @@ -32,7 +35,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void searchStarting(); public slots: - void restoreSearch(const QString& text); + void restoreSearch(const QString& text, QPointer pFeature = nullptr); void slotTextChanged(const QString& text); private slots: @@ -40,10 +43,14 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void slotSetupTimer(const QString& text); void triggerSearch(); void onSearchTextCleared(); + + void saveQuery(); + void restoreQuery(); private: void showPlaceholder(); + QPointer m_pCurrentFeature; QTimer m_searchTimer; QToolButton* m_pClearButton; QToolButton* m_pSaveButton; From ea4750f116f4ee5fa817591f52896cc860dc8cd3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 11 Aug 2016 22:31:08 +0200 Subject: [PATCH 357/552] Add new icons and fix issue when replacing a query with another --- res/mixxx.qrc | 1 + res/skins/cross_2.png | Bin 0 -> 432 bytes res/skins/save.png | Bin 547 -> 394 bytes src/widget/wsearchlineedit.cpp | 7 ++++--- 4 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 res/skins/cross_2.png diff --git a/res/mixxx.qrc b/res/mixxx.qrc index ccae0f08c12..ef360e0d870 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -112,5 +112,6 @@ images/library/ic_library_folder.png skins/save.png skins/downArrow.png + skins/cross_2.png diff --git a/res/skins/cross_2.png b/res/skins/cross_2.png new file mode 100644 index 0000000000000000000000000000000000000000..41bee32108c4d26db6d724f8e14c25078f6bd0af GIT binary patch literal 432 zcmV;h0Z;ykP)<}Xb-vB9bh&Z z0PO(#BXnT~ARIF^Q|N&nd!Pxh4D14_^L~Ln=O=kil!LZ_GtUN6NePgc*(Y!dY)ZOw z>(athnAs6`v?OU1jGpEAZB z0vo^Fn|>`S{!8H6t!HAkGyT1{=4{uys)!YgXy}ISMoz!?weHU(XFmLE=l(oz?bp4L zYpzVr52)s6%3=`1juch|EOZhLSrNc0sukkc$`#6f`(NRUc>Cb&rA|N|Nb<_@oPX*2 zr)&;_DFF($Y610eX@#t4;u2l80F8U^(gn|~{Y)E!peBFKyRy7~Zh7g}YoC}N_lEHI T7Ojc}`kukl)z4*}Q$iB}wgZgp delta 509 zcmeBTUd*D{8Q|y6%O%Cdz`(%k>ERLtr1Ln+Z#VdCqOy-Ro9Qsm_XPuajK2YE{OWzelP$ z(wBY}*PnlD!?)kHJsa=tv8ylC(>ranZ}Z&sD-S-cwCkE`ZnRqVaP4gK4Li26L8%1d2S&-ElSR>BKLxQ=XsK{}z2v zrvG@w?z=u;n03Xvb2i^>Q7N#up6mCqZvX6pLus2Mx5cfOy{qDRso*!;iA6P2*B{Ff Q1;!|Yr>mdKI;Vst0I2@t#sB~S diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index d702ac71407..65a10a1e2fe 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -17,7 +17,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) QSize iconSize(height()/2, height()/2); m_pClearButton = new QToolButton(this); - m_pClearButton->setIcon(QIcon(":/skins/cross.png")); + m_pClearButton->setIcon(QIcon(":/skins/cross_2.png")); m_pClearButton->setIconSize(iconSize); m_pClearButton->setCursor(Qt::ArrowCursor); m_pClearButton->setToolTip(tr("Clear input" , "Clear the search bar input field")); @@ -294,9 +294,10 @@ void WSearchLineEdit::restoreQuery() { if (index < 0) { return; } - m_pCurrentFeature->restoreQuery(index); + QString text = savedQueries.at(index).query; - setText(savedQueries.at(index).query); + m_pCurrentFeature->restoreQuery(index); + setText(text); } void WSearchLineEdit::slotTextChanged(const QString& text) { From 4699e28677b813505acc0060acaf65de6db686dc Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 09:11:32 +0200 Subject: [PATCH 358/552] Change icon size --- res/skins/cross_2.png | Bin 432 -> 907 bytes res/skins/save.png | Bin 394 -> 398 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/res/skins/cross_2.png b/res/skins/cross_2.png index 41bee32108c4d26db6d724f8e14c25078f6bd0af..90ac557c96b2bbc80fa1aa5e9e2e0882953c7cfe 100644 GIT binary patch delta 837 zcmV-L1G@aM1B(ZcQ-2Hx2{cs?93lV!0~kp}K~y-)wN*`MTxAqJ=f1o#*p@mPX{%{c z1qG#Gv1%8UY>bOINi3z}Pec$D{J|_l$i^RZDP6gAD?|}Aki20S2SSAuAz*hRf{Qf% zR7@;^IOFtvdH1-;dooFrDG~Zs55D`Id+xdC-VeA*AG;maYJatRvMhUC($PHDCGC2L zqyYRAMbZ4OLG^n5?hwMHq_Y4HO4=Z)8v&Etkn}TmVR|Tp@EXaN0SrjmlMH6o?%9Fq zz7WC-0A7+b_&+6%t^-cf^qizuNge|LNg}x}X&pc>fZG5>Bq1pU@E1t}=#y07dDID- zB*~MKrT`o#8Gq%vZ2>XL~=QbqHh7T+`Z-QZ;<>Qzz2POec!LHuAX%Fc3#D%&Uv#Qlr%;1G|5ttOcErO z-2F(FW&1})My|$j`~}H(NPajrHg>VUzdx8+ndDtt9DkA|$#DRalAbS0*=8X~x@=~j z_V)IEHatB1OSM{MrBc!S{Cug^YMlZw>F(#YxI)snq-V@*-%hs5n>PsH*>=0Vw7k6h z<-owe1^~GGodBM4_p_Zc6jJm6h`Jd+PY?mHrKP3+;<7A@B$aZUEvyW{9LZTptuAB# zD}b*gU4I-J8VbdMyZ=eDMzXe@7y+PKtv;M(*+&3|N#4>~QtpheNxnZiI{HJsUOyZ{ zc+}n3$H&JnG#ZUknx<#6Ec?7LgPFAr04kNrB{Tcj%)XNpwlyx0ykcg}Mx${@2;n(N z=SjXdJ3D)-TrL~QKS=(Tlh_=+;%9n#`troY#D6M)`vDv-vgaFXjbsQRJOSVp0QX5c z0^r_evnh8!LGrYuTZ;kNqRZmqB3D*c&SY8kE`W#f!~)O+@Hc=GfP)=`u93W&4^%lf z0?e#^ofBqeW=e4!zX;%MNe@V}y>1{gOLw%`!otFVwY9Z3CB2@nP3;l5wX1iNBsuEt zZ$6QHTG9cM;YMEXSXw`I4V;^s8zlJ%fJ4QcxO=x31OU=FjxXG-w-o;ZZqb${Lm2QJ P00000NkvXXu0mjfj3I{Y delta 358 zcmV-s0h#`b2e1Q>Q-2E-3M}sV@+SZQ0X<1XK~y-)?Ulbv!%!53zr+l6)zQ_#%|Qp} zqU+IJM;CDuE7b}Xf1p_Z5!btjL`3KyC=ndRKS7+M;NbEaN_c6~(y?beH}A`P_nn)- zL{35317@}j%va?70r!%+Q3><}Xb-vB9bh&Z0PO(#BXnT~Ab%V)G*jq-9($k(ung=1 zsq=n;J?AHRPLzYTfHThqQb`GrnAsl1rpbJd* zJV`<5itPbVfEw^%X7wC&1$gX-=6hVLnE5Hs3!}ozlhg#RN`k*GDegBVJpmi8?oWlJ zL*TLi{L+J(*^%40@8;9q zM`eFby)fZ;;{FeB-=9%v;!A8sMbp1uyt?Yyiz7i7Z$KenPfDwtt~ozH~)d&`;yri5FwTYj<4DI zb<+1+m|g^`+~UwI29^Ob*mPmKfDA`&kapfE5aY%EHGhunzi%@WY&cNmwEA;>XTlFx b`x8`iuyQ+v4jA-bF?nX|(_qFcNBxgSSYv=wvZ|&E;k!!9@&JU>OXUbv_!$kEU zA%ztI3!OwmRs^t$YK1tqa)q+r{#W=S-aa^csS}U~lDu*}=U@8%DVu{}N`Qi`T0nhV zS|KZ%xI|YiK;z!Kbip%gKhwq_sL5aRt}L&gTVA^L+9#&Ry&?R)MXO?gLBh%4>FVdQ I&MBb@03+#nv;Y7A From fbd7080725fff86c259eafd36f004eff009a755b Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 10:44:14 +0200 Subject: [PATCH 359/552] Save selection with TrackModel instead of WTrackTableView --- src/library/basesqltablemodel.cpp | 18 +++++++++ src/library/basesqltablemodel.h | 4 ++ src/library/trackmodel.h | 8 ++++ src/widget/wtracktableview.cpp | 67 +++++++++++-------------------- src/widget/wtracktableview.h | 1 + 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index b234ee584af..37968c23bae 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -1026,6 +1026,24 @@ QMimeData* BaseSqlTableModel::mimeData(const QModelIndexList &indexes) const { return mimeData; } +void BaseSqlTableModel::saveSelection(const QModelIndexList& selection) { + m_savedSelectionIndices.clear(); + for (const QModelIndex& index : selection) { + m_savedSelectionIndices.insert(getTrackId(index)); + } +} + +QModelIndexList BaseSqlTableModel::getSavedSelection() { + QModelIndexList ret; + for (const TrackId& id : m_savedSelectionIndices) { + QLinkedList rows = getTrackRows(id); + for (const int row : rows) { + ret << index(row, 0); + } + } + return ret; +} + QAbstractItemDelegate* BaseSqlTableModel::delegateForColumn(const int i, QObject* pParent) { if (i == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_RATING)) { return new StarDelegate(pParent); diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 95ace56ccb3..178d4c1a3ca 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -74,6 +74,9 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const; virtual QMimeData* mimeData(const QModelIndexList &indexes) const; + + void saveSelection(const QModelIndexList& selection) override; + QModelIndexList getSavedSelection() override; public slots: void select(); @@ -152,6 +155,7 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { QList m_savedSortColumns; QVector > m_headerInfo; QString m_trackSourceOrderBy; + QSet m_savedSelectionIndices; DISALLOW_COPY_AND_ASSIGN(BaseSqlTableModel); }; diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index d8df9484625..369eb487ee6 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "track/track.h" @@ -145,6 +146,13 @@ class TrackModel { virtual void select() { } + + virtual void saveSelection(const QModelIndexList&) { + } + + virtual QModelIndexList getSavedSelection() { + return QModelIndexList(); + } private: QSqlDatabase m_db; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 707e22c7cdf..569365e5aa9 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1512,64 +1512,30 @@ void WTrackTableView::addSelectionToCrate(int iCrateId) { void WTrackTableView::doSortByColumn(int headerSection) { TrackModel* trackModel = getTrackModel(); - QAbstractItemModel* itemModel = model(); - if (trackModel == nullptr || itemModel == nullptr || !m_sorting) { + if (trackModel == nullptr || !m_sorting) { return; } - // Save the selection - QModelIndexList selection = selectionModel()->selectedRows(); - QSet trackIds; - for (const auto& index: selection) { - trackIds.insert(trackModel->getTrackId(index)); - } - + trackModel->saveSelection(selectionModel()->selectedRows()); sortByColumn(headerSection); QItemSelectionModel* currentSelection = selectionModel(); - - // Find a visible column - int visibleColumn = 0; - while (isColumnHidden(visibleColumn) && visibleColumn < itemModel->columnCount()) { - visibleColumn++; - } - currentSelection->reset(); // remove current selection - - QMap selectedRows; - for (const auto& trackId : trackIds) { - - // TODO(rryan) slowly fixing the issues with BaseSqlTableModel. This - // code is broken for playlists because it assumes each trackid is in - // the table once. This will erroneously select all instances of the - // track for playlists, but it works fine for every other view. The way - // to fix this that we should do is to delegate the selection saving to - // the TrackModel. This will allow the playlist table model to use the - // table index as the unique id instead of this code stupidly using - // trackid. - QLinkedList rows = trackModel->getTrackRows(trackId); - for (int row : rows) { - // Restore sort order by rows, so the following commands will act as expected - selectedRows.insert(row,0); - } - } - + + QModelIndexList savedSelection = trackModel->getSavedSelection(); QModelIndex first; - QMapIterator i(selectedRows); - while (i.hasNext()) { - i.next(); - QModelIndex tl = itemModel->index(i.key(), visibleColumn); - currentSelection->select(tl, QItemSelectionModel::Rows | QItemSelectionModel::Select); - + for (const QModelIndex& index : savedSelection) { + currentSelection->select(index, + QItemSelectionModel::Rows | + QItemSelectionModel::Select); if (!first.isValid()) { - first = tl; + first = index.sibling(index.row(), getVisibleColumn()); } } - + if (first.isValid()) { scrollTo(first, QAbstractItemView::EnsureVisible); - //scrollTo(first, QAbstractItemView::PositionAtCenter); } if (!m_pScrollBar.isNull()) { @@ -1619,6 +1585,19 @@ void WTrackTableView::lockBpm(bool lock) { } } +int WTrackTableView::getVisibleColumn() { + QAbstractItemModel* itemModel = model(); + if (itemModel == nullptr) { + return -1; + } + + int column = 0; + while (isColumnHidden(column) && column < itemModel->columnCount()) { + column++; + } + return column; +} + void WTrackTableView::slotClearBeats() { TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 804ee330588..e8ceb737f6f 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -89,6 +89,7 @@ class WTrackTableView : public WLibraryTableView { void dragEnterEvent(QDragEnterEvent * event) override; void dropEvent(QDropEvent * event) override; void lockBpm(bool lock); + int getVisibleColumn(); void enableCachedOnly(); void selectionChanged(const QItemSelection &selected, From 8f3fe68e08c619f55b6005bd3a535fe7110bdb85 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 10:44:37 +0200 Subject: [PATCH 360/552] Add getPosition function to get the Playlist track position --- src/library/playlisttablemodel.cpp | 44 ++++++++++++++---------------- src/library/playlisttablemodel.h | 7 +++++ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp index bac523823b7..2d3928875cc 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/playlisttablemodel.cpp @@ -96,9 +96,8 @@ int PlaylistTableModel::addTracks(const QModelIndex& index, if (locations.isEmpty()) { return 0; } - - const int positionColumn = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); - int position = index.sibling(index.row(), positionColumn).data().toInt(); + + int position = getPosition(index); // Handle weird cases like a drag and drop to an invalid index if (position <= 0) { @@ -138,9 +137,7 @@ void PlaylistTableModel::removeTrack(const QModelIndex& index) { return; } - const int positionColumnIndex = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); - int position = index.sibling(index.row(), positionColumnIndex).data().toInt(); - m_playlistDao.removeTrackFromPlaylist(m_iPlaylistId, position); + m_playlistDao.removeTrackFromPlaylist(m_iPlaylistId, getPosition(index)); } void PlaylistTableModel::removeTracks(const QModelIndexList& indices) { @@ -148,24 +145,18 @@ void PlaylistTableModel::removeTracks(const QModelIndexList& indices) { return; } - const int positionColumnIndex = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); - QList trackPositions; foreach (QModelIndex index, indices) { - int trackPosition = index.sibling(index.row(), positionColumnIndex).data().toInt(); - trackPositions.append(trackPosition); + trackPositions.append(getPosition(index)); } - m_playlistDao.removeTracksFromPlaylist(m_iPlaylistId,trackPositions); + m_playlistDao.removeTracksFromPlaylist(m_iPlaylistId, trackPositions); } void PlaylistTableModel::moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex) { - - int playlistPositionColumn = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); - - int newPosition = destIndex.sibling(destIndex.row(), playlistPositionColumn).data().toInt(); - int oldPosition = sourceIndex.sibling(sourceIndex.row(), playlistPositionColumn).data().toInt(); + int newPosition = getPosition(destIndex); + int oldPosition = getPosition(sourceIndex); if (newPosition > oldPosition) { // new position moves up due to closing the gap of the old position @@ -192,17 +183,15 @@ bool PlaylistTableModel::isLocked() { void PlaylistTableModel::shuffleTracks(const QModelIndexList& shuffle, const QModelIndex& exclude) { QList positions; QHash allIds; - const int positionColumn = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); - const int idColumn = fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ID); int excludePos = -1; if (exclude.row() > -1) { // this is used to exclude the already loaded track at pos #1 if used from running Auto-DJ - excludePos = exclude.sibling(exclude.row(), positionColumn).data().toInt(); + excludePos = getPosition(exclude); } if (shuffle.count() > 1) { // if there is more then one track selected, shuffle selection only foreach(QModelIndex shuffleIndex, shuffle) { - int oldPosition = shuffleIndex.sibling(shuffleIndex.row(), positionColumn).data().toInt(); + int oldPosition = getPosition(shuffleIndex); if (oldPosition != excludePos) { positions.append(oldPosition); } @@ -211,7 +200,7 @@ void PlaylistTableModel::shuffleTracks(const QModelIndexList& shuffle, const QMo // if there is only one track selected, shuffle all tracks int numOfTracks = rowCount(); for (int i = 0; i < numOfTracks; i++) { - int oldPosition = index(i, positionColumn).data().toInt(); + int oldPosition = getPosition(index(i, 0)); if (oldPosition != excludePos) { positions.append(oldPosition); } @@ -220,8 +209,8 @@ void PlaylistTableModel::shuffleTracks(const QModelIndexList& shuffle, const QMo // Set up list of all IDs int numOfTracks = rowCount(); for (int i = 0; i < numOfTracks; i++) { - int position = index(i, positionColumn).data().toInt(); - TrackId trackId(index(i, idColumn).data()); + int position = getPosition(index(i, 0)); + TrackId trackId(trackId(index(i, 0))); allIds.insert(position, trackId); } m_playlistDao.shuffleTracks(m_iPlaylistId, positions, allIds); @@ -282,8 +271,17 @@ TrackModel::CapabilitiesFlags PlaylistTableModel::getCapabilities() const { return caps; } +void PlaylistTableModel::saveSelection(const QModelIndexList& selection) { + +} + void PlaylistTableModel::playlistChanged(int playlistId) { if (playlistId == m_iPlaylistId) { select(); // Repopulate the data model. } } + +int PlaylistTableModel::getPosition(const QModelIndex& index) { + const int positionColumn = fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION); + return index.sibling(index.row(), positionColumn).data().toInt(); +} diff --git a/src/library/playlisttablemodel.h b/src/library/playlisttablemodel.h index bca10dc2d39..05b42287ac2 100644 --- a/src/library/playlisttablemodel.h +++ b/src/library/playlisttablemodel.h @@ -32,15 +32,22 @@ class PlaylistTableModel : public BaseSqlTableModel { bool isLocked(); void shuffleTracks(const QModelIndexList& shuffle, const QModelIndex& exclude); TrackModel::CapabilitiesFlags getCapabilities() const; + + void saveSelection(const QModelIndexList& selection); private slots: void playlistChanged(int playlistId); private: + + int getPosition(const QModelIndex& index); + PlaylistDAO& m_playlistDao; int m_iPlaylistId; QSet m_playlistIds; bool m_showAll; + + QSet m_savedSelection; }; #endif From 81fd66cdd73d35fd95c87c13dcf66c2cd26c8716 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 11:08:01 +0200 Subject: [PATCH 361/552] Fix selection on Playlist sorting --- src/library/playlisttablemodel.cpp | 27 ++++++++++++++++++++++++++- src/library/playlisttablemodel.h | 6 +++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp index 2d3928875cc..4c713e08d57 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/playlisttablemodel.cpp @@ -210,7 +210,7 @@ void PlaylistTableModel::shuffleTracks(const QModelIndexList& shuffle, const QMo int numOfTracks = rowCount(); for (int i = 0; i < numOfTracks; i++) { int position = getPosition(index(i, 0)); - TrackId trackId(trackId(index(i, 0))); + TrackId trackId(getTrackId(index(i, 0))); allIds.insert(position, trackId); } m_playlistDao.shuffleTracks(m_iPlaylistId, positions, allIds); @@ -272,7 +272,32 @@ TrackModel::CapabilitiesFlags PlaylistTableModel::getCapabilities() const { } void PlaylistTableModel::saveSelection(const QModelIndexList& selection) { + m_savedSelectionIndices.clear(); + for (const QModelIndex& index : selection) { + m_savedSelectionIndices.insert(getPosition(index)); + } +} + +QModelIndexList PlaylistTableModel::getSavedSelection() { + QModelIndexList ret; + for (const int& pos : m_savedSelectionIndices) { + auto it = m_positionToRow.find(pos); + if (it != m_positionToRow.constEnd()) { + ret << index(*it, 0); + } + } + return ret; +} + +void PlaylistTableModel::select() { + BaseSqlTableModel::select(); + + m_positionToRow.clear(); + for (int i = 0; i < rowCount(); ++i) { + int pos = getPosition(index(i, 0)); + m_positionToRow[pos] = i; + } } void PlaylistTableModel::playlistChanged(int playlistId) { diff --git a/src/library/playlisttablemodel.h b/src/library/playlisttablemodel.h index 05b42287ac2..3e0d929a7d1 100644 --- a/src/library/playlisttablemodel.h +++ b/src/library/playlisttablemodel.h @@ -34,6 +34,9 @@ class PlaylistTableModel : public BaseSqlTableModel { TrackModel::CapabilitiesFlags getCapabilities() const; void saveSelection(const QModelIndexList& selection); + QModelIndexList getSavedSelection(); + + void select() override; private slots: void playlistChanged(int playlistId); @@ -47,7 +50,8 @@ class PlaylistTableModel : public BaseSqlTableModel { QSet m_playlistIds; bool m_showAll; - QSet m_savedSelection; + QHash m_positionToRow; + QSet m_savedSelectionIndices; }; #endif From dc997901b3b9bae8e38228c5831c472d22c211aa Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 12:33:10 +0200 Subject: [PATCH 362/552] Rename saveSelection function --- src/library/basesqltablemodel.cpp | 2 +- src/library/basesqltablemodel.h | 2 +- src/library/playlisttablemodel.cpp | 2 +- src/library/playlisttablemodel.h | 2 +- src/library/trackmodel.h | 2 +- src/widget/wtracktableview.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 37968c23bae..b625a8e83b8 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -1033,7 +1033,7 @@ void BaseSqlTableModel::saveSelection(const QModelIndexList& selection) { } } -QModelIndexList BaseSqlTableModel::getSavedSelection() { +QModelIndexList BaseSqlTableModel::getSavedSelectionIndices() { QModelIndexList ret; for (const TrackId& id : m_savedSelectionIndices) { QLinkedList rows = getTrackRows(id); diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 178d4c1a3ca..7a5bebeb004 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -76,7 +76,7 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { virtual QMimeData* mimeData(const QModelIndexList &indexes) const; void saveSelection(const QModelIndexList& selection) override; - QModelIndexList getSavedSelection() override; + QModelIndexList getSavedSelectionIndices() override; public slots: void select(); diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp index 4c713e08d57..bcc06c447ee 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/playlisttablemodel.cpp @@ -279,7 +279,7 @@ void PlaylistTableModel::saveSelection(const QModelIndexList& selection) { } } -QModelIndexList PlaylistTableModel::getSavedSelection() { +QModelIndexList PlaylistTableModel::getSavedSelectionIndices() { QModelIndexList ret; for (const int& pos : m_savedSelectionIndices) { auto it = m_positionToRow.find(pos); diff --git a/src/library/playlisttablemodel.h b/src/library/playlisttablemodel.h index 3e0d929a7d1..a258c7708bd 100644 --- a/src/library/playlisttablemodel.h +++ b/src/library/playlisttablemodel.h @@ -34,7 +34,7 @@ class PlaylistTableModel : public BaseSqlTableModel { TrackModel::CapabilitiesFlags getCapabilities() const; void saveSelection(const QModelIndexList& selection); - QModelIndexList getSavedSelection(); + QModelIndexList getSavedSelectionIndices(); void select() override; diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index 369eb487ee6..77a4e29cf5e 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -150,7 +150,7 @@ class TrackModel { virtual void saveSelection(const QModelIndexList&) { } - virtual QModelIndexList getSavedSelection() { + virtual QModelIndexList getSavedSelectionIndices() { return QModelIndexList(); } diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 569365e5aa9..2777e573bb2 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1523,7 +1523,7 @@ void WTrackTableView::doSortByColumn(int headerSection) { QItemSelectionModel* currentSelection = selectionModel(); currentSelection->reset(); // remove current selection - QModelIndexList savedSelection = trackModel->getSavedSelection(); + QModelIndexList savedSelection = trackModel->getSavedSelectionIndices(); QModelIndex first; for (const QModelIndex& index : savedSelection) { currentSelection->select(index, From d6ebf4a97ebba4456850f15c06057ef57ef212eb Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 12:33:46 +0200 Subject: [PATCH 363/552] Add more save info to SavedSearchQuery --- src/library/libraryfeature.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 0da3b73bf20..6ca4800b09e 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -30,8 +30,15 @@ class WTrackTableView; struct SavedSearchQuery { QString query; QString title; - QModelIndex selectedItem; + QSet selectedItems; QString sortOrder; + + int vScrollBarPos; + int sortColumn; + bool sortAscendingOrder; + + // Used when saving and restoring from the DB + int id; }; // pure virtual (abstract) class to provide an interface for libraryfeatures From 0bfeff8f048675baaac9441f420e4150e6166c33 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 12:34:12 +0200 Subject: [PATCH 364/552] Begin implementing more save query functions --- src/library/trackmodel.h | 13 +++++++++++++ src/widget/wlibrarytableview.cpp | 12 ++++++++++++ src/widget/wlibrarytableview.h | 5 +++++ src/widget/wtracktableview.cpp | 26 +++++++++++++++++++++++++- src/widget/wtracktableview.h | 4 +++- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index 77a4e29cf5e..d7189912735 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -9,6 +9,7 @@ #include "track/track.h" #include "library/dao/settingsdao.h" +#include "library/libraryfeature.h" /** Pure virtual (abstract) class that provides an interface for data models which display track lists. */ @@ -154,6 +155,18 @@ class TrackModel { return QModelIndexList(); } + virtual void setSavedQuery(const SavedSearchQuery&) { + } + + virtual SavedSearchQuery getSavedQuery(const QModelIndexList& /* selected */, + SavedSearchQuery query = SavedSearchQuery()) { + return query; + } + + virtual SavedSearchQuery getSavedQuery(SavedSearchQuery = SavedSearchQuery()) { + return SavedSearchQuery(); + } + private: QSqlDatabase m_db; QString m_settingsNamespace; diff --git a/src/widget/wlibrarytableview.cpp b/src/widget/wlibrarytableview.cpp index 01b968f2885..63115b562c1 100644 --- a/src/widget/wlibrarytableview.cpp +++ b/src/widget/wlibrarytableview.cpp @@ -117,6 +117,18 @@ void WLibraryTableView::moveSelection(int delta) { } } +void WLibraryTableView::setSavedQuery(const SavedSearchQuery& query) { + +} + +SavedSearchQuery WLibraryTableView::getSavedQuery(SavedSearchQuery query) const { + query.vScrollBarPos = verticalScrollBar()->value(); + query.sortColumn = horizontalHeader()->sortIndicatorSection(); + query.sortAscendingOrder = + horizontalHeader()->sortIndicatorOrder() == Qt::AscendingOrder; + return query; +} + void WLibraryTableView::setTrackTableFont(const QFont& font) { setFont(font); setTrackTableRowHeight(verticalHeader()->defaultSectionSize()); diff --git a/src/widget/wlibrarytableview.h b/src/widget/wlibrarytableview.h index 25044c4d774..46046cc8b34 100644 --- a/src/widget/wlibrarytableview.h +++ b/src/widget/wlibrarytableview.h @@ -12,6 +12,7 @@ #include "library/libraryview.h" #include "track/track.h" #include "library/coverartcache.h" +#include "library/libraryfeature.h" class WLibraryTableView : public QTableView, public virtual LibraryView { @@ -24,6 +25,9 @@ class WLibraryTableView : public QTableView, public virtual LibraryView { ~WLibraryTableView() override; void moveSelection(int delta) override; + virtual void setSavedQuery(const SavedSearchQuery& query); + virtual SavedSearchQuery getSavedQuery(SavedSearchQuery query = SavedSearchQuery()) const; + signals: void loadTrack(TrackPointer pTrack); void loadTrackToPlayer(TrackPointer pTrack, QString group, @@ -31,6 +35,7 @@ class WLibraryTableView : public QTableView, public virtual LibraryView { void trackSelected(TrackPointer pTrack); void onlyCachedCoverArt(bool); void scrollValueChanged(int); + public slots: void saveView(); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 2777e573bb2..b62451de98e 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1262,7 +1262,7 @@ void WTrackTableView::dropEvent(QDropEvent * event) { restoreView(); } -TrackModel* WTrackTableView::getTrackModel() { +TrackModel* WTrackTableView::getTrackModel() const { TrackModel* trackModel = dynamic_cast(model()); return trackModel; } @@ -1304,6 +1304,30 @@ void WTrackTableView::setScrollBar(WMiniViewScrollBar *pScrollbar) { setVerticalScrollBar(pScrollbar); } +void WTrackTableView::setSavedQuery(const SavedSearchQuery& query) { + WLibraryTableView::setSavedQuery(query); + + TrackModel* trackModel = getTrackModel(); + if (trackModel == nullptr) { + return; + } + + trackModel->setSavedQuery(query); +} + +SavedSearchQuery WTrackTableView::getSavedQuery(SavedSearchQuery query) const { + query = WLibraryTableView::getSavedQuery(query); + + TrackModel* trackModel = getTrackModel(); + if (trackModel == nullptr) { + return query; + } + + QModelIndexList rowsSelected = selectionModel()->selectedRows(); + query = trackModel->getSavedQuery(rowsSelected, query); + return query; +} + void WTrackTableView::slotSendToAutoDJ() { // append to auto DJ sendToAutoDJ(false); // bTop = false diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index e8ceb737f6f..8fc0968d2f7 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -38,6 +38,8 @@ class WTrackTableView : public WLibraryTableView { void loadSelectedTrackToGroup(QString group, bool play) override; void setSorting(bool sorting); void setScrollBar(WMiniViewScrollBar* pScrollbar); + void setSavedQuery(const SavedSearchQuery& query) override; + SavedSearchQuery getSavedQuery(SavedSearchQuery query = SavedSearchQuery()) const override; public slots: void loadTrackModel(QAbstractItemModel* model); @@ -100,7 +102,7 @@ class WTrackTableView : public WLibraryTableView { void mouseMoveEvent(QMouseEvent *pEvent) override; // Returns the current TrackModel, or returns NULL if none is set. - TrackModel* getTrackModel(); + TrackModel* getTrackModel() const; bool modelHasCapabilities(TrackModel::CapabilitiesFlags capabilities); UserSettingsPointer m_pConfig; From 320b07a975a625d55017ee0d9287e0f9cfc6aeb3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 12:56:22 +0200 Subject: [PATCH 365/552] Fix broken function due to merge --- src/library/librarytreemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index a324f36cee8..1a2dae29051 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -73,7 +73,7 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { CoverArtCache* pCache = CoverArtCache::instance(); // Set a maximum size of 32px to not use many cache - QPixmap pixmap = pCache->requestCover(info, this, info.hash, 32); + QPixmap pixmap = pCache->requestCover(info, this, 32, false, true); if (pixmap.isNull()) { // The icon is not in the cache so we need to wait until the From 4d0c0c2f1343892a0bfb441058af82422f56eb1b Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 14:28:18 +0200 Subject: [PATCH 366/552] Separate some functions to allow load / save a sticky view --- src/library/basesqltablemodel.cpp | 98 +++++++++++++++++++------------ src/library/basesqltablemodel.h | 6 ++ src/library/libraryfeature.h | 2 +- src/library/trackmodel.h | 2 +- src/widget/wlibrarytableview.cpp | 9 +++ src/widget/wtracktableview.cpp | 10 ++-- 6 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index b625a8e83b8..5fab73db304 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -110,6 +110,14 @@ void BaseSqlTableModel::initHeaderData() { tr("ReplayGain"), 50); } +QSet BaseSqlTableModel::getTrackIdsFromIndices(const QModelIndexList& list) const { + QSet ret; + for (const QModelIndex& index : list) { + ret.insert(getTrackId(index)); + } + return ret; +} + QSqlDatabase BaseSqlTableModel::database() const { return m_database; } @@ -412,22 +420,7 @@ void BaseSqlTableModel::setSort(int column, Qt::SortOrder order) { // There's no item to sort already, load from Settings last sort if (m_sortColumns.isEmpty()) { QString val = getModelSetting(COLUMNS_SORTING); - QTextStream in(&val); - - while (!in.atEnd()) { - int ordI = -1; - QString name; - - in >> name >> ordI; - - int col = fieldIndex(name); - if (col < 0) continue; - - Qt::SortOrder ord; - ord = ordI > 0 ? Qt::AscendingOrder : Qt::DescendingOrder; - - m_sortColumns << SortColumn(col, ord); - } + deserialzeSortColumns(val); } if (m_sortColumns.size() > 0 && m_sortColumns.at(0).m_column == column) { // Only the order has changed @@ -451,23 +444,7 @@ void BaseSqlTableModel::setSort(int column, Qt::SortOrder order) { } // Write new sortColumns order to user settings - QString val; - QTextStream out(&val); - for (SortColumn& sc : m_sortColumns) { - - QString name; - if (sc.m_column > 0 && sc.m_column < m_tableColumns.size()) { - name = m_tableColumns[sc.m_column]; - } else { - // ccColumn between 1..x to skip the id column - int ccColumn = sc.m_column - m_tableColumns.size() + 1; - name = m_trackSource->columnNameForFieldIndex(ccColumn); - } - - out << name << " "; - out << (sc.m_order == Qt::AscendingOrder ? 1 : -1) << " "; - } - out.flush(); + QString val = serializedSortColumns(); setModelSetting(COLUMNS_SORTING, val); if (sDebug) { @@ -1027,10 +1004,7 @@ QMimeData* BaseSqlTableModel::mimeData(const QModelIndexList &indexes) const { } void BaseSqlTableModel::saveSelection(const QModelIndexList& selection) { - m_savedSelectionIndices.clear(); - for (const QModelIndex& index : selection) { - m_savedSelectionIndices.insert(getTrackId(index)); - } + m_savedSelectionIndices = getTrackIdsFromIndices(selection); } QModelIndexList BaseSqlTableModel::getSavedSelectionIndices() { @@ -1044,6 +1018,16 @@ QModelIndexList BaseSqlTableModel::getSavedSelectionIndices() { return ret; } +SavedSearchQuery BaseSqlTableModel::getSavedQuery(const QModelIndexList& indices, + SavedSearchQuery query) const { + query.selectedItems.clear(); + auto ids = getTrackIdsFromIndices(indices); + for (const TrackId& id : ids) { + query.selectedItems.insert(id); + } + return query; +} + QAbstractItemDelegate* BaseSqlTableModel::delegateForColumn(const int i, QObject* pParent) { if (i == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_RATING)) { return new StarDelegate(pParent); @@ -1078,3 +1062,43 @@ void BaseSqlTableModel::hideTracks(const QModelIndexList& indices) { // there. select(); //Repopulate the data model. } + +QString BaseSqlTableModel::serializedSortColumns() const { + QString val; + QTextStream out(&val); + for (const SortColumn& sc : m_sortColumns) { + + QString name; + if (sc.m_column > 0 && sc.m_column < m_tableColumns.size()) { + name = m_tableColumns[sc.m_column]; + } else { + // ccColumn between 1..x to skip the id column + int ccColumn = sc.m_column - m_tableColumns.size() + 1; + name = m_trackSource->columnNameForFieldIndex(ccColumn); + } + + out << name << " "; + out << (sc.m_order == Qt::AscendingOrder ? 1 : -1) << " "; + } + out.flush(); + return val; +} + +void BaseSqlTableModel::deserialzeSortColumns(QString serialized) { + QTextStream in(&serialized); + + while (!in.atEnd()) { + int ordI = -1; + QString name; + + in >> name >> ordI; + + int col = fieldIndex(name); + if (col < 0) continue; + + Qt::SortOrder ord; + ord = ordI > 0 ? Qt::AscendingOrder : Qt::DescendingOrder; + + m_sortColumns << SortColumn(col, ord); + } +} diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 7a5bebeb004..bdc788e529a 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -77,6 +77,8 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { void saveSelection(const QModelIndexList& selection) override; QModelIndexList getSavedSelectionIndices() override; + + SavedSearchQuery getSavedQuery(const QModelIndexList &indices, SavedSearchQuery query) const override; public slots: void select(); @@ -89,6 +91,8 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { const QStringList& tableColumns, QSharedPointer trackSource); void initHeaderData(); + + QSet getTrackIdsFromIndices(const QModelIndexList& list) const; // Use this if you want a model that is read-only. Qt::ItemFlags readOnlyFlags(const QModelIndex &index) const; @@ -120,6 +124,8 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { // called. QString orderByClause() const; QSqlDatabase database() const; + QString serializedSortColumns() const; + void deserialzeSortColumns(QString serialized); struct RowInfo { TrackId trackId; diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 6ca4800b09e..c1026a0c3f5 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -30,7 +30,7 @@ class WTrackTableView; struct SavedSearchQuery { QString query; QString title; - QSet selectedItems; + QSet selectedItems; QString sortOrder; int vScrollBarPos; diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index d7189912735..eedd86944df 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -159,7 +159,7 @@ class TrackModel { } virtual SavedSearchQuery getSavedQuery(const QModelIndexList& /* selected */, - SavedSearchQuery query = SavedSearchQuery()) { + SavedSearchQuery query = SavedSearchQuery()) const { return query; } diff --git a/src/widget/wlibrarytableview.cpp b/src/widget/wlibrarytableview.cpp index 63115b562c1..6f1160cc0b1 100644 --- a/src/widget/wlibrarytableview.cpp +++ b/src/widget/wlibrarytableview.cpp @@ -118,7 +118,16 @@ void WLibraryTableView::moveSelection(int delta) { } void WLibraryTableView::setSavedQuery(const SavedSearchQuery& query) { + verticalScrollBar()->setValue(query.vScrollBarPos); + Qt::SortOrder order; + if (query.sortAscendingOrder) { + order = Qt::AscendingOrder; + } else { + order = Qt::DescendingOrder; + } + + horizontalHeader()->setSortIndicator(query.sortColumn, order); } SavedSearchQuery WLibraryTableView::getSavedQuery(SavedSearchQuery query) const { diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 07c8f2effe1..d0b6ffc7097 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1305,14 +1305,16 @@ void WTrackTableView::setScrollBar(WMiniViewScrollBar *pScrollbar) { } void WTrackTableView::setSavedQuery(const SavedSearchQuery& query) { - WLibraryTableView::setSavedQuery(query); TrackModel* trackModel = getTrackModel(); - if (trackModel == nullptr) { - return; + if (trackModel != nullptr) { + trackModel->setSavedQuery(query); } - trackModel->setSavedQuery(query); + // First of all the track model must be set in order to get the correct + // table size for the WLibraryTableView parameters that are going to be + // restored + WLibraryTableView::setSavedQuery(query); } SavedSearchQuery WTrackTableView::getSavedQuery(SavedSearchQuery query) const { From a60a9a193c3e966e16d9eeb960e17413209db74a Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 14:51:31 +0200 Subject: [PATCH 367/552] Added save and restore query to Base SQL table model --- src/library/basesqltablemodel.cpp | 15 ++++++++++++++- src/library/basesqltablemodel.h | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 5fab73db304..2370be45daa 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -1018,13 +1018,26 @@ QModelIndexList BaseSqlTableModel::getSavedSelectionIndices() { return ret; } -SavedSearchQuery BaseSqlTableModel::getSavedQuery(const QModelIndexList& indices, +void BaseSqlTableModel::restoreQuery(const SavedSearchQuery& query) { + // Restore selection + m_savedSelectionIndices.clear(); + for (const DbId& id : query.selectedItems) { + m_savedSelectionIndices.insert(TrackId(id.toVariant())); + } + + deserialzeSortColumns(query.sortOrder); +} + +SavedSearchQuery BaseSqlTableModel::saveQuery(const QModelIndexList& indices, SavedSearchQuery query) const { query.selectedItems.clear(); auto ids = getTrackIdsFromIndices(indices); for (const TrackId& id : ids) { query.selectedItems.insert(id); } + + query.sortOrder = serializedSortColumns(); + return query; } diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index bdc788e529a..977e954f0ce 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -78,7 +78,8 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { void saveSelection(const QModelIndexList& selection) override; QModelIndexList getSavedSelectionIndices() override; - SavedSearchQuery getSavedQuery(const QModelIndexList &indices, SavedSearchQuery query) const override; + void restoreQuery(const SavedSearchQuery& query) override; + SavedSearchQuery saveQuery(const QModelIndexList &indices, SavedSearchQuery query) const override; public slots: void select(); From 7ea8d889efdc8a202317c85591716a9642e4214d Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 14:51:56 +0200 Subject: [PATCH 368/552] Renamed save and restore --- src/library/trackmodel.h | 8 ++++---- src/widget/wlibrarytableview.cpp | 4 ++-- src/widget/wlibrarytableview.h | 4 ++-- src/widget/wtracktableview.cpp | 23 ++++++++++++++++------- src/widget/wtracktableview.h | 4 ++-- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index eedd86944df..7d2135668f8 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -155,15 +155,15 @@ class TrackModel { return QModelIndexList(); } - virtual void setSavedQuery(const SavedSearchQuery&) { + virtual void restoreQuery(const SavedSearchQuery&) { } - virtual SavedSearchQuery getSavedQuery(const QModelIndexList& /* selected */, - SavedSearchQuery query = SavedSearchQuery()) const { + virtual SavedSearchQuery saveQuery(const QModelIndexList& /* selected */, + SavedSearchQuery query = SavedSearchQuery()) const { return query; } - virtual SavedSearchQuery getSavedQuery(SavedSearchQuery = SavedSearchQuery()) { + virtual SavedSearchQuery saveQuery(SavedSearchQuery = SavedSearchQuery()) { return SavedSearchQuery(); } diff --git a/src/widget/wlibrarytableview.cpp b/src/widget/wlibrarytableview.cpp index 6f1160cc0b1..d3794ec43f5 100644 --- a/src/widget/wlibrarytableview.cpp +++ b/src/widget/wlibrarytableview.cpp @@ -117,7 +117,7 @@ void WLibraryTableView::moveSelection(int delta) { } } -void WLibraryTableView::setSavedQuery(const SavedSearchQuery& query) { +void WLibraryTableView::restoreQuery(const SavedSearchQuery& query) { verticalScrollBar()->setValue(query.vScrollBarPos); Qt::SortOrder order; @@ -130,7 +130,7 @@ void WLibraryTableView::setSavedQuery(const SavedSearchQuery& query) { horizontalHeader()->setSortIndicator(query.sortColumn, order); } -SavedSearchQuery WLibraryTableView::getSavedQuery(SavedSearchQuery query) const { +SavedSearchQuery WLibraryTableView::saveQuery(SavedSearchQuery query) const { query.vScrollBarPos = verticalScrollBar()->value(); query.sortColumn = horizontalHeader()->sortIndicatorSection(); query.sortAscendingOrder = diff --git a/src/widget/wlibrarytableview.h b/src/widget/wlibrarytableview.h index 46046cc8b34..4c7ebb505b6 100644 --- a/src/widget/wlibrarytableview.h +++ b/src/widget/wlibrarytableview.h @@ -25,8 +25,8 @@ class WLibraryTableView : public QTableView, public virtual LibraryView { ~WLibraryTableView() override; void moveSelection(int delta) override; - virtual void setSavedQuery(const SavedSearchQuery& query); - virtual SavedSearchQuery getSavedQuery(SavedSearchQuery query = SavedSearchQuery()) const; + virtual void restoreQuery(const SavedSearchQuery& query); + virtual SavedSearchQuery saveQuery(SavedSearchQuery query = SavedSearchQuery()) const; signals: void loadTrack(TrackPointer pTrack); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d0b6ffc7097..50499f38213 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1304,21 +1304,30 @@ void WTrackTableView::setScrollBar(WMiniViewScrollBar *pScrollbar) { setVerticalScrollBar(pScrollbar); } -void WTrackTableView::setSavedQuery(const SavedSearchQuery& query) { +void WTrackTableView::restoreQuery(const SavedSearchQuery& query) { TrackModel* trackModel = getTrackModel(); - if (trackModel != nullptr) { - trackModel->setSavedQuery(query); + if (trackModel == nullptr) { + return; + } + + trackModel->restoreQuery(query); + QModelIndexList selectedIndeces = trackModel->getSavedSelectionIndices(); + QItemSelectionModel* selectionM = selectionModel(); + selectionM->clearSelection(); + for (const QModelIndex& index : selectedIndeces) { + selectionM->select(index, QItemSelectionModel::Rows | + QItemSelectionModel::Select); } // First of all the track model must be set in order to get the correct // table size for the WLibraryTableView parameters that are going to be // restored - WLibraryTableView::setSavedQuery(query); + WLibraryTableView::restoreQuery(query); } -SavedSearchQuery WTrackTableView::getSavedQuery(SavedSearchQuery query) const { - query = WLibraryTableView::getSavedQuery(query); +SavedSearchQuery WTrackTableView::saveQuery(SavedSearchQuery query) const { + query = WLibraryTableView::saveQuery(query); TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { @@ -1326,7 +1335,7 @@ SavedSearchQuery WTrackTableView::getSavedQuery(SavedSearchQuery query) const { } QModelIndexList rowsSelected = selectionModel()->selectedRows(); - query = trackModel->getSavedQuery(rowsSelected, query); + query = trackModel->saveQuery(rowsSelected, query); return query; } diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 8fc0968d2f7..b8d202c3c09 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -38,8 +38,8 @@ class WTrackTableView : public WLibraryTableView { void loadSelectedTrackToGroup(QString group, bool play) override; void setSorting(bool sorting); void setScrollBar(WMiniViewScrollBar* pScrollbar); - void setSavedQuery(const SavedSearchQuery& query) override; - SavedSearchQuery getSavedQuery(SavedSearchQuery query = SavedSearchQuery()) const override; + void restoreQuery(const SavedSearchQuery& query) override; + SavedSearchQuery saveQuery(SavedSearchQuery query = SavedSearchQuery()) const override; public slots: void loadTrackModel(QAbstractItemModel* model); From 8c1b6b06fe788848bfbe63990f75bee8ec1d30e8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 14:52:53 +0200 Subject: [PATCH 369/552] Implement save and restore in LibraryFeature --- src/library/libraryfeature.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 12ef311078a..9aea0f61fee 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -93,11 +93,24 @@ void LibraryFeature::setFocusedPane(int paneId) { } void LibraryFeature::saveQuery(SavedSearchQuery& query) { + WTrackTableView* pTable = getFocusedTable(); + if (pTable == nullptr) { + return; + } + + query = pTable->saveQuery(query); + // A saved query goes the first in the list m_savedQueries.prepend(query); } void LibraryFeature::restoreQuery(int index) { + WTrackTableView* pTable = getFocusedTable(); + if (pTable == nullptr) { + return; + } + + pTable->restoreQuery(m_savedQueries.at(index)); // Move the used query to the first item in the list m_savedQueries.move(index, 0); } From 3351d1ac0d14179004c977840d51ba7289d71bbb Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 16:51:31 +0200 Subject: [PATCH 370/552] Fix some bugs with sticky views not working properly --- src/library/basesqltablemodel.cpp | 1 + src/widget/wsearchlineedit.cpp | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 2370be45daa..9b2bbb49bc5 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -1026,6 +1026,7 @@ void BaseSqlTableModel::restoreQuery(const SavedSearchQuery& query) { } deserialzeSortColumns(query.sortOrder); + search(query.query); } SavedSearchQuery BaseSqlTableModel::saveQuery(const QModelIndexList& indices, diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 65a10a1e2fe..a8da662145f 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -289,15 +289,18 @@ void WSearchLineEdit::restoreQuery() { if (selected == nullptr) { return; } - int index = selected->data().toInt(); + int index = selected->data().toInt(); if (index < 0) { return; } - QString text = savedQueries.at(index).query; + QString text = savedQueries[index].query; + blockSignals(true); + setText(text); + updateButtons(text); + blockSignals(false); m_pCurrentFeature->restoreQuery(index); - setText(text); } void WSearchLineEdit::slotTextChanged(const QString& text) { From 4bfcff4965ac906aced7677c949711679f2719d9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 17:40:10 +0200 Subject: [PATCH 371/552] Added settings namespace to all features --- src/library/analysisfeature.cpp | 4 ++++ src/library/analysisfeature.h | 1 + src/library/autodj/autodjfeature.cpp | 4 ++++ src/library/autodj/autodjfeature.h | 1 + src/library/banshee/bansheefeature.cpp | 4 ++++ src/library/banshee/bansheefeature.h | 1 + src/library/browse/browsefeature.cpp | 4 ++++ src/library/browse/browsefeature.h | 1 + src/library/cratefeature.cpp | 4 ++++ src/library/cratefeature.h | 1 + src/library/historyfeature.cpp | 4 ++++ src/library/historyfeature.h | 1 + src/library/itunes/itunesfeature.cpp | 4 ++++ src/library/itunes/itunesfeature.h | 1 + src/library/libraryfeature.cpp | 15 +++++++++++++++ src/library/libraryfeature.h | 21 +++++---------------- src/library/libraryfoldersfeature.cpp | 4 ++++ src/library/libraryfoldersfeature.h | 1 + src/library/maintenancefeature.cpp | 4 ++++ src/library/maintenancefeature.h | 1 + src/library/mixxxlibraryfeature.cpp | 4 ++++ src/library/mixxxlibraryfeature.h | 1 + src/library/playlistfeature.cpp | 4 ++++ src/library/playlistfeature.h | 1 + src/library/recording/recordingfeature.cpp | 4 ++++ src/library/recording/recordingfeature.h | 1 + src/library/rhythmbox/rhythmboxfeature.cpp | 4 ++++ src/library/rhythmbox/rhythmboxfeature.h | 1 + src/library/traktor/traktorfeature.cpp | 4 ++++ src/library/traktor/traktorfeature.h | 1 + 30 files changed, 90 insertions(+), 16 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index b3cb46bbce1..68a6edfa4aa 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -60,6 +60,10 @@ QString AnalysisFeature::getIconPath() { return ":/images/library/ic_library_prepare.png"; } +QString AnalysisFeature::getSettingsName() { + return "AnalysisFeature"; +} + QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index b86db006bf2..67de87ac6b1 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -31,6 +31,7 @@ class AnalysisFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 01f12e06e03..89d4e5d8983 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -99,6 +99,10 @@ QString AutoDJFeature::getIconPath() { return ":/images/library/ic_library_autodj.png"; } +QString AutoDJFeature::getSettingsName() { + return "AutoDJFeature"; +} + QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { WTrackTableView* pTrackTableView = LibraryFeature::createTableWidget(pKeyboard, paneId); connect(pTrackTableView->selectionModel(), diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index e13c345576f..0a9e65e7f88 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -41,6 +41,7 @@ class AutoDJFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index decb6d8c875..4c3bf6ef385 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -62,6 +62,10 @@ QString BansheeFeature::getIconPath() { return ":/images/library/ic_library_banshee.png"; } +QString BansheeFeature::getSettingsName() { + return "BansheeFeature"; +} + void BansheeFeature::activate() { //qDebug("BansheeFeature::activate()"); diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index 04102070441..20f5e084c70 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -30,6 +30,7 @@ class BansheeFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; virtual TreeItemModel* getChildModel(); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 8d2880b939a..b497d09356e 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -145,6 +145,10 @@ QString BrowseFeature::getIconPath() { return ":/images/library/ic_library_browse.png"; } +QString BrowseFeature::getSettingsName() { + return "BrowseFeature"; +} + void BrowseFeature::slotAddQuickLink() { if (!m_pLastRightClickedItem) { return; diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index ad771cf1342..cfb835bdfe8 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,6 +38,7 @@ class BrowseFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId) override; diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 8f37a32e98d..457feb9745d 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -127,6 +127,10 @@ QString CrateFeature::getIconPath() { return ":/images/library/ic_library_crates.png"; } +QString CrateFeature::getSettingsName() { + return "CrateFeature"; +} + int CrateFeature::crateIdFromIndex(QModelIndex index) { TreeItem* item = static_cast(index.internalPointer()); if (item == nullptr) { diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index cd2758c656e..36bf090e027 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -33,6 +33,7 @@ class CrateFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; void onSearch(QString&) {} diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index b43342172df..a413536503e 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -57,6 +57,10 @@ QString HistoryFeature::getIconPath() { return ":/images/library/ic_library_history.png"; } +QString HistoryFeature::getSettingsName() { + return "HistoryFeature"; +} + void HistoryFeature::onRightClick(const QPoint&) { m_lastRightClickedIndex = QModelIndex(); diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index f75125fa21b..339773c036a 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -25,6 +25,7 @@ class HistoryFeature : public BasePlaylistFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; void decorateChild(TreeItem *pChild, int playlist_id) override; public slots: diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 54e6a827e91..ac0a24d5e2e 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -116,6 +116,10 @@ QString ITunesFeature::getIconPath() { return ":/images/library/ic_library_itunes.png"; } +QString ITunesFeature::getSettingsName() { + return "ITunesFeature"; +} + void ITunesFeature::activate() { activate(false); emit(enableCoverArtDisplay(false)); diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index 9b5ef9522ac..1481b425bbe 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -30,6 +30,7 @@ class ITunesFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; TreeItemModel* getChildModel(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 9aea0f61fee..6c26112b9da 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -34,12 +34,27 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), m_featureFocus(-1) { + + // Restore saved queries + QStringList queryColumns; + queryColumns << SAVEDQUERYTABLE_QUERY + << SAVEDQUERYTABLE_TITLE + << SAVEDQUERYTABLE_SELECTEDITEMS + << SAVEDQUERYTABLE_SORTORDER + << SAVEDQUERYTABLE_VSCROLLBARPOS + << SAVEDQUERYTABLE_SORTCOLUMN + << SAVEDQUERYTABLE_SORTASCENDINGORDER + << SAVEDQUERYTABLE_PINNED; } LibraryFeature::~LibraryFeature() { } +QString LibraryFeature::getSettingsName() { + return QString; +} + QIcon LibraryFeature::getIcon() { return WPixmapStore::getLibraryIcon(getIconPath()); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index c1026a0c3f5..72305316b36 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -12,6 +12,7 @@ #include #include "preferences/usersettings.h" +#include "library/savedsearchquery.h" #include "track/track.h" class Library; @@ -25,22 +26,6 @@ class WLibrary; class WLibrarySidebar; class WTrackTableView; -// This struct allows to save some data to allow interaction between -// the search bar and the library features -struct SavedSearchQuery { - QString query; - QString title; - QSet selectedItems; - QString sortOrder; - - int vScrollBarPos; - int sortColumn; - bool sortAscendingOrder; - - // Used when saving and restoring from the DB - int id; -}; - // pure virtual (abstract) class to provide an interface for libraryfeatures class LibraryFeature : public QObject { Q_OBJECT @@ -55,6 +40,10 @@ class LibraryFeature : public QObject { virtual QVariant title() = 0; virtual QString getIconPath() = 0; + + // This name must be unique for each feature + virtual QString getSettingsName(); + QIcon getIcon(); virtual bool dropAccept(QList /* urls */, diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp index 5623f6d9c4a..f5acb9d3817 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/libraryfoldersfeature.cpp @@ -23,6 +23,10 @@ QString LibraryFoldersFeature::getIconPath() { return ":/images/library/ic_library_folder.png"; } +QString LibraryFoldersFeature::getSettingsName() { + return "LibraryFoldersFeature"; +} + void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, const QModelIndex&) { diff --git a/src/library/libraryfoldersfeature.h b/src/library/libraryfoldersfeature.h index b0ab4e0b7eb..18f53646934 100644 --- a/src/library/libraryfoldersfeature.h +++ b/src/library/libraryfoldersfeature.h @@ -15,6 +15,7 @@ class LibraryFoldersFeature : public MixxxLibraryFeature QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; public slots: void onRightClickChild(const QPoint& pos, const QModelIndex&) override; diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 7e9c5cffe4e..568781c8bc3 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -31,6 +31,10 @@ QString MaintenanceFeature::getIconPath() { return ":/images/library/ic_library_maintenance.png"; } +QString MaintenanceFeature::getSettingsName() { + return "MaintenanceFeature"; +} + TreeItemModel* MaintenanceFeature::getChildModel() { return nullptr; } diff --git a/src/library/maintenancefeature.h b/src/library/maintenancefeature.h index 83a9d0a7fba..c4ee16347d7 100644 --- a/src/library/maintenancefeature.h +++ b/src/library/maintenancefeature.h @@ -22,6 +22,7 @@ class MaintenanceFeature : public LibraryFeature QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; TreeItemModel* getChildModel(); public slots: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 0e8478ff51a..f8274afc22c 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -124,6 +124,10 @@ QString MixxxLibraryFeature::getIconPath() { return ":/images/library/ic_library_library.png"; } +QString MixxxLibraryFeature::getSettingsName() { + return "MixxxLibraryFeature"; +} + TreeItemModel* MixxxLibraryFeature::getChildModel() { return m_pChildModel; } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 8c63ed532a7..ad570ea45d8 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -42,6 +42,7 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index a8f2f0b54ff..30f8596f858 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -41,6 +41,10 @@ QString PlaylistFeature::getIconPath() { return ":/images/library/ic_library_playlist.png"; } +QString PlaylistFeature::getSettingsName() { + return "PlaylistFeature"; +} + void PlaylistFeature::onRightClick(const QPoint& globalPos) { m_lastRightClickedIndex = QModelIndex(); diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index e894ed6ab78..1fcdead76a2 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -28,6 +28,7 @@ class PlaylistFeature : public BasePlaylistFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; bool dragMoveAccept(QUrl url); bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index cf13111361f..2015760ed48 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -40,6 +40,10 @@ QString RecordingFeature::getIconPath() { return ":/images/library/ic_library_recordings.png"; } +QString RecordingFeature::getSettingsName() { + return "RecordingFeature"; +} + TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 746d6d9ba18..6f186fa2bb5 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,6 +30,7 @@ class RecordingFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int paneId) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index bee2e47a1df..1f74ad1104e 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -107,6 +107,10 @@ QString RhythmboxFeature::getIconPath() { return ":/images/library/ic_library_rhythmbox.png"; } +QString RhythmboxFeature::getSettingsName() { + return "RhythmboxFeature"; +} + TreeItemModel* RhythmboxFeature::getChildModel() { return &m_childModel; } diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index dbd76c0f0a2..cd455efbe5e 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -30,6 +30,7 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { QVariant title(); QString getIconPath() override; + QString getSettingsName() override; TreeItemModel* getChildModel(); // processes the music collection diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 1100b7e62a6..00ce9e29fc0 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -126,6 +126,10 @@ QString TraktorFeature::getIconPath() { return ":/images/library/ic_library_traktor.png"; } +QString TraktorFeature::getSettingsName() { + return "TraktorFeature"; +} + bool TraktorFeature::isSupported() { return (QFile::exists(getTraktorMusicDatabase())); } diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index fc7d0755c84..1fb1f46afb7 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -46,6 +46,7 @@ class TraktorFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; + QString getSettingsName() override; static bool isSupported(); TreeItemModel* getChildModel(); From 04a7cc84917c3b57471b31f8599e290d8f6a03bb Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 18:19:19 +0200 Subject: [PATCH 372/552] Add SavedQueriesDAO --- res/schema.xml | 18 +++++ src/library/dao/savedqueriesdao.cpp | 105 ++++++++++++++++++++++++++++ src/library/dao/savedqueriesdao.h | 53 ++++++++++++++ src/library/libraryfeature.cpp | 11 +-- src/library/libraryfeature.h | 4 +- src/library/trackcollection.cpp | 8 ++- src/library/trackcollection.h | 3 + src/library/trackmodel.h | 2 +- src/widget/wlibrarytableview.h | 3 +- 9 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 src/library/dao/savedqueriesdao.cpp create mode 100644 src/library/dao/savedqueriesdao.h diff --git a/res/schema.xml b/res/schema.xml index e85570fb316..81f99cc1861 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -416,4 +416,22 @@ METADATA ALTER TABLE library ADD COLUMN tracktotal TEXT DEFAULT '//'; + + + Add new saved_queries table to store the saved queries for each + library feature + + + CREATE TABLE IF NOT EXISTS saved_queries ( + libraryFeature TEXT, + query TEXT, + title TEXT, + selectedItems TEXT, + sortOrder TEXT, + vScrollbarPos INTEGER, + sortColumn INTEGER, + sortAscendingOrder BOOLEAN, + pinned BOOLEAN + ); + diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp new file mode 100644 index 00000000000..85cb29ada00 --- /dev/null +++ b/src/library/dao/savedqueriesdao.cpp @@ -0,0 +1,105 @@ +#include + +#include "library/dao/savedqueriesdao.h" +#include "library/queryutil.h" + +SavedQueriesDAO::SavedQueriesDAO(QSqlDatabase& database) + : m_database(database) { + +} + +void SavedQueriesDAO::initialize() { +} + +void SavedQueriesDAO::setSavedQueries(LibraryFeature* pFeature, + const QList& queries) { + if (pFeature == nullptr) { + return; + } + + // First of all delete previous saved queries + QString queryStr = "DELETE FROM " SAVEDQUERYTABLE " WHERE libraryFeature = %1"; + queryStr = queryStr.arg(pFeature->getSettingsName()); + + QSqlQuery query(m_database); + if (!query.exec(queryStr)) { + LOG_FAILED_QUERY(query); + } + + + query.prepare("INSERT INTO " SAVEDQUERYTABLE + "(libraryFeature, query, title, selectedItems," + "sortOrder, vScrollbarPos, sortColumn, sortAscendingOrder, pinned) " + "VALUES (:libraryFeature, :query, :title, :selectedItems, " + ":sortOrder, :vScrollbarPos, :sortColumn, :sortAscendingOrder, :pinned)"); + + for (const SavedSearchQuery& sQuery : queries) { + query.bindValue(":libraryFeature", pFeature->getSettingsName()); + query.bindValue(":query", sQuery.query); + query.bindValue(":title", sQuery.title); + query.bindValue(":selectedItems", serializeItems(sQuery.selectedItems)); + query.bindValue(":sortOrder", sQuery.sortOrder); + query.bindValue(":vScrollbarPos", sQuery.vScrollBarPos); + query.bindValue(":sortColumn", sQuery.sortColumn); + query.bindValue(":sortAscendingOrder", sQuery.sortAscendingOrder); + query.bindValue(":pinned", sQuery.pinned); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + } +} + +QList SavedQueriesDAO::getSavedQueries(LibraryFeature* pFeature) { + + if (pFeature == nullptr) { + return QList(); + } + + QSqlQuery query(m_database); + QString queryStr = "SELECT query, title, selectedItems, sortOrder, " + "vScrollbarPos, sortColumn, sortAscendingOrder, pinned " + "FROM " SAVEDQUERYTABLE + " WHERE libraryFeature = %1"; + queryStr = queryStr.arg(pFeature->getSettingsName()); + + query.prepare(queryStr); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + + QList res; + while (query.next()) { + SavedSearchQuery q; + q.query = query.value(0).toString(); + q.title = query.value(1).toString(); + q.selectedItems = deserializeItems(query.value(2).toString()); + q.sortOrder = query.value(3).toString(); + q.vScrollBarPos = query.value(4).toInt(); + q.sortColumn = query.value(5).toInt(); + q.sortAscendingOrder = query.value(6).toBool(); + q.pinned = query.value(7).toBool(); + + res << q; + } + return res; +} + +QString SavedQueriesDAO::serializeItems(const QSet& items) const { + QStringList ret; + + for (const DbId& id : items) { + ret << id.toString(); + } + return ret.join(" "); +} + +QSet SavedQueriesDAO::deserializeItems(const QString& text) const { + QSet ret; + QStringList items = text.split(" "); + for (const QString& item : items) { + ret.insert(DbId(QVariant(item))); + } + return ret; +} diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h new file mode 100644 index 00000000000..e288887bac2 --- /dev/null +++ b/src/library/dao/savedqueriesdao.h @@ -0,0 +1,53 @@ +#ifndef SAVEDQUERIESDAO_H +#define SAVEDQUERIESDAO_H + +#include +#include +#include + +#include "library/dao/dao.h" +#include "library/libraryfeature.h" +#include "util/dbid.h" + +#define SAVEDQUERYTABLE "savedQueries" + +const QString SAVEDQUERYTABLE_QUERY = "query"; +const QString SAVEDQUERYTABLE_TITLE = "title"; +const QString SAVEDQUERYTABLE_SELECTEDITEMS = "selectedItems"; +const QString SAVEDQUERYTABLE_SORTORDER = "sortOrder"; +const QString SAVEDQUERYTABLE_VSCROLLBARPOS = "vScrollbarPos"; +const QString SAVEDQUERYTABLE_SORTCOLUMN = "sortColumn"; +const QString SAVEDQUERYTABLE_SORTASCENDINGORDER = "sortAscendingOrder"; +const QString SAVEDQUERYTABLE_PINNED = "pinned"; + +// This struct allows to save some data to allow interaction between +// the search bar and the library features +struct SavedSearchQuery { + QString query; + QString title; + QSet selectedItems; + QString sortOrder; + + int vScrollBarPos; + int sortColumn; + bool sortAscendingOrder; + bool pinned; +}; + +class SavedQueriesDAO : public DAO +{ + public: + SavedQueriesDAO(QSqlDatabase& database); + + void initialize(); + void setSavedQueries(LibraryFeature* pFeature, const QList& queries); + QList getSavedQueries(LibraryFeature* pFeature); + + private: + static QString serializeItems(const QSet& items) const; + static QSet deserializeItems(const QString& text) const; + + QSqlDatabase& m_database; +}; + +#endif // SAVEDQUERIESDAO_H diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 6c26112b9da..c038594ae2b 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -15,6 +15,7 @@ #include "controllers/keyboard/keyboardeventfilter.h" #include "library/library.h" #include "library/libraryfeature.h" +#include "library/trackcollection.h" #include "library/treeitemmodel.h" #include "widget/wbaselibrary.h" #include "widget/wlibrarysidebar.h" @@ -36,15 +37,7 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_featureFocus(-1) { // Restore saved queries - QStringList queryColumns; - queryColumns << SAVEDQUERYTABLE_QUERY - << SAVEDQUERYTABLE_TITLE - << SAVEDQUERYTABLE_SELECTEDITEMS - << SAVEDQUERYTABLE_SORTORDER - << SAVEDQUERYTABLE_VSCROLLBARPOS - << SAVEDQUERYTABLE_SORTCOLUMN - << SAVEDQUERYTABLE_SORTASCENDINGORDER - << SAVEDQUERYTABLE_PINNED; + m_savedQueries = m_pTrackCollection->getSavedQueriesDAO().getSavedQueries(this); } LibraryFeature::~LibraryFeature() { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 72305316b36..b29b433d05f 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -12,7 +12,7 @@ #include #include "preferences/usersettings.h" -#include "library/savedsearchquery.h" +#include "library/dao/savedqueriesdao.h" #include "track/track.h" class Library; @@ -33,7 +33,7 @@ class LibraryFeature : public QObject { // The parent does not necessary be the Library LibraryFeature(UserSettingsPointer pConfig, - Library* pLibrary, TrackCollection *pTrackCollection, + Library* pLibrary, TrackCollection* pTrackCollection, QObject* parent = nullptr); virtual ~LibraryFeature(); diff --git a/src/library/trackcollection.cpp b/src/library/trackcollection.cpp index 5406bfbf8f8..8155dfa07f5 100644 --- a/src/library/trackcollection.cpp +++ b/src/library/trackcollection.cpp @@ -14,7 +14,7 @@ #include "util/assert.h" // static -const int TrackCollection::kRequiredSchemaVersion = 26; +const int TrackCollection::kRequiredSchemaVersion = 27; TrackCollection::TrackCollection(UserSettingsPointer pConfig) : m_pConfig(pConfig), @@ -25,6 +25,7 @@ TrackCollection::TrackCollection(UserSettingsPointer pConfig) m_directoryDao(m_db), m_analysisDao(m_db, pConfig), m_libraryHashDao(m_db), + m_savedDao(m_db), m_trackDao(m_db, m_cueDao, m_playlistDao, m_crateDao, m_analysisDao, m_libraryHashDao, pConfig) { qDebug() << "Available QtSQL drivers:" << QSqlDatabase::drivers(); @@ -129,6 +130,7 @@ bool TrackCollection::checkForTables() { m_cueDao.initialize(); m_directoryDao.initialize(); m_libraryHashDao.initialize(); + m_savedDao.initialize(); return true; } @@ -152,6 +154,10 @@ DirectoryDAO& TrackCollection::getDirectoryDAO() { return m_directoryDao; } +SavedQueriesDAO &TrackCollection::getSavedQueriesDAO() { + return m_savedDao; +} + QSharedPointer TrackCollection::getTrackSource() { return m_defaultTrackSource; } diff --git a/src/library/trackcollection.h b/src/library/trackcollection.h index 936606802e1..87f551b0203 100644 --- a/src/library/trackcollection.h +++ b/src/library/trackcollection.h @@ -32,6 +32,7 @@ #include "library/dao/analysisdao.h" #include "library/dao/directorydao.h" #include "library/dao/libraryhashdao.h" +#include "library/dao/savedqueriesdao.h" #ifdef __SQLITE3__ typedef struct sqlite3_context sqlite3_context; @@ -63,6 +64,7 @@ class TrackCollection : public QObject { TrackDAO& getTrackDAO(); PlaylistDAO& getPlaylistDAO(); DirectoryDAO& getDirectoryDAO(); + SavedQueriesDAO& getSavedQueriesDAO(); AnalysisDao& getAnalysisDAO() { return m_analysisDao; } @@ -108,6 +110,7 @@ class TrackCollection : public QObject { DirectoryDAO m_directoryDao; AnalysisDao m_analysisDao; LibraryHashDAO m_libraryHashDao; + SavedQueriesDAO m_savedDao; TrackDAO m_trackDao; }; diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index 7d2135668f8..08c146c1ce2 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -8,8 +8,8 @@ #include #include "track/track.h" +#include "library/dao/savedqueriesdao.h" #include "library/dao/settingsdao.h" -#include "library/libraryfeature.h" /** Pure virtual (abstract) class that provides an interface for data models which display track lists. */ diff --git a/src/widget/wlibrarytableview.h b/src/widget/wlibrarytableview.h index 4c7ebb505b6..200df55847c 100644 --- a/src/widget/wlibrarytableview.h +++ b/src/widget/wlibrarytableview.h @@ -12,8 +12,7 @@ #include "library/libraryview.h" #include "track/track.h" #include "library/coverartcache.h" -#include "library/libraryfeature.h" - +#include "library/savedsearchquery.h" class WLibraryTableView : public QTableView, public virtual LibraryView { Q_OBJECT From 4ad426d9ce26391d615e0a4b209b718319af7f20 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 18:51:56 +0200 Subject: [PATCH 373/552] Finish storing queries in database --- build/depends.py | 1 + res/schema.xml | 5 +++-- src/library/basesqltablemodel.cpp | 1 + src/library/dao/savedqueriesdao.cpp | 19 +++++++++++-------- src/library/dao/savedqueriesdao.h | 16 ++++------------ src/library/libraryfeature.cpp | 5 +++-- src/widget/wlibrarytableview.h | 2 +- 7 files changed, 24 insertions(+), 25 deletions(-) diff --git a/build/depends.py b/build/depends.py index 31979d599cd..c78c7ab0186 100644 --- a/build/depends.py +++ b/build/depends.py @@ -887,6 +887,7 @@ def sources(self, build): "library/maintenancefeature.cpp", "library/historytreemodel.cpp", "library/libraryfoldermodel.cpp", + "library/dao/savedqueriesdao.cpp", "library/browse/browsetablemodel.cpp", "library/browse/browsethread.cpp", diff --git a/res/schema.xml b/res/schema.xml index 81f99cc1861..768d33ea16c 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -418,11 +418,11 @@ METADATA - Add new saved_queries table to store the saved queries for each + Add new savedQueries table to store the saved queries for each library feature - CREATE TABLE IF NOT EXISTS saved_queries ( + CREATE TABLE IF NOT EXISTS savedQueries ( libraryFeature TEXT, query TEXT, title TEXT, @@ -434,4 +434,5 @@ METADATA pinned BOOLEAN ); + diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 9b2bbb49bc5..0ca55fe8738 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -1100,6 +1100,7 @@ QString BaseSqlTableModel::serializedSortColumns() const { void BaseSqlTableModel::deserialzeSortColumns(QString serialized) { QTextStream in(&serialized); + m_sortColumns.clear(); while (!in.atEnd()) { int ordI = -1; diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 85cb29ada00..2457e71bce3 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -1,6 +1,7 @@ #include #include "library/dao/savedqueriesdao.h" +#include "library/libraryfeature.h" #include "library/queryutil.h" SavedQueriesDAO::SavedQueriesDAO(QSqlDatabase& database) @@ -18,11 +19,14 @@ void SavedQueriesDAO::setSavedQueries(LibraryFeature* pFeature, } // First of all delete previous saved queries - QString queryStr = "DELETE FROM " SAVEDQUERYTABLE " WHERE libraryFeature = %1"; - queryStr = queryStr.arg(pFeature->getSettingsName()); + QString queryStr = "DELETE FROM " SAVEDQUERYTABLE " WHERE libraryFeature = :featureName"; + + qDebug() << pFeature->getSettingsName(); QSqlQuery query(m_database); - if (!query.exec(queryStr)) { + query.prepare(queryStr); + query.bindValue(":featureName", pFeature->getSettingsName()); + if (!query.exec()) { LOG_FAILED_QUERY(query); } @@ -60,10 +64,9 @@ QList SavedQueriesDAO::getSavedQueries(LibraryFeature* pFeatur QString queryStr = "SELECT query, title, selectedItems, sortOrder, " "vScrollbarPos, sortColumn, sortAscendingOrder, pinned " "FROM " SAVEDQUERYTABLE - " WHERE libraryFeature = %1"; - queryStr = queryStr.arg(pFeature->getSettingsName()); - + " WHERE libraryFeature = :featureName"; query.prepare(queryStr); + query.bindValue(":featureName", pFeature->getSettingsName()); if (!query.exec()) { LOG_FAILED_QUERY(query); @@ -86,7 +89,7 @@ QList SavedQueriesDAO::getSavedQueries(LibraryFeature* pFeatur return res; } -QString SavedQueriesDAO::serializeItems(const QSet& items) const { +QString SavedQueriesDAO::serializeItems(const QSet& items) { QStringList ret; for (const DbId& id : items) { @@ -95,7 +98,7 @@ QString SavedQueriesDAO::serializeItems(const QSet& items) const { return ret.join(" "); } -QSet SavedQueriesDAO::deserializeItems(const QString& text) const { +QSet SavedQueriesDAO::deserializeItems(const QString& text) { QSet ret; QStringList items = text.split(" "); for (const QString& item : items) { diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index e288887bac2..4b126aaa335 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -6,20 +6,10 @@ #include #include "library/dao/dao.h" -#include "library/libraryfeature.h" #include "util/dbid.h" #define SAVEDQUERYTABLE "savedQueries" -const QString SAVEDQUERYTABLE_QUERY = "query"; -const QString SAVEDQUERYTABLE_TITLE = "title"; -const QString SAVEDQUERYTABLE_SELECTEDITEMS = "selectedItems"; -const QString SAVEDQUERYTABLE_SORTORDER = "sortOrder"; -const QString SAVEDQUERYTABLE_VSCROLLBARPOS = "vScrollbarPos"; -const QString SAVEDQUERYTABLE_SORTCOLUMN = "sortColumn"; -const QString SAVEDQUERYTABLE_SORTASCENDINGORDER = "sortAscendingOrder"; -const QString SAVEDQUERYTABLE_PINNED = "pinned"; - // This struct allows to save some data to allow interaction between // the search bar and the library features struct SavedSearchQuery { @@ -34,6 +24,8 @@ struct SavedSearchQuery { bool pinned; }; +class LibraryFeature; + class SavedQueriesDAO : public DAO { public: @@ -44,8 +36,8 @@ class SavedQueriesDAO : public DAO QList getSavedQueries(LibraryFeature* pFeature); private: - static QString serializeItems(const QSet& items) const; - static QSet deserializeItems(const QString& text) const; + static QString serializeItems(const QSet& items); + static QSet deserializeItems(const QString& text); QSqlDatabase& m_database; }; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index c038594ae2b..e518a11a2a5 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -41,11 +41,10 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, } LibraryFeature::~LibraryFeature() { - } QString LibraryFeature::getSettingsName() { - return QString; + return QString(""); } QIcon LibraryFeature::getIcon() { @@ -110,6 +109,7 @@ void LibraryFeature::saveQuery(SavedSearchQuery& query) { // A saved query goes the first in the list m_savedQueries.prepend(query); + m_pTrackCollection->getSavedQueriesDAO().setSavedQueries(this, m_savedQueries); } void LibraryFeature::restoreQuery(int index) { @@ -121,6 +121,7 @@ void LibraryFeature::restoreQuery(int index) { pTable->restoreQuery(m_savedQueries.at(index)); // Move the used query to the first item in the list m_savedQueries.move(index, 0); + m_pTrackCollection->getSavedQueriesDAO().setSavedQueries(this, m_savedQueries); } const QList& LibraryFeature::getSavedQueries() const { diff --git a/src/widget/wlibrarytableview.h b/src/widget/wlibrarytableview.h index 200df55847c..0dd67607a7a 100644 --- a/src/widget/wlibrarytableview.h +++ b/src/widget/wlibrarytableview.h @@ -12,7 +12,7 @@ #include "library/libraryview.h" #include "track/track.h" #include "library/coverartcache.h" -#include "library/savedsearchquery.h" +#include "library/dao/savedqueriesdao.h" class WLibraryTableView : public QTableView, public virtual LibraryView { Q_OBJECT From f877eaefd274dee3c9367044c592eaac0f7c807a Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 19:09:13 +0200 Subject: [PATCH 374/552] Fix some polymorphism issues with library feature and loading queries --- src/library/libraryfeature.cpp | 16 +++++++++++----- src/library/libraryfeature.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index e518a11a2a5..b7cb7eacbc1 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -34,10 +34,8 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pConfig(pConfig), m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), - m_featureFocus(-1) { - - // Restore saved queries - m_savedQueries = m_pTrackCollection->getSavedQueriesDAO().getSavedQueries(this); + m_featureFocus(-1), + m_queriesLoaded(false) { } LibraryFeature::~LibraryFeature() { @@ -124,7 +122,15 @@ void LibraryFeature::restoreQuery(int index) { m_pTrackCollection->getSavedQueriesDAO().setSavedQueries(this, m_savedQueries); } -const QList& LibraryFeature::getSavedQueries() const { +const QList& LibraryFeature::getSavedQueries() { + + if (!m_queriesLoaded) { + m_queriesLoaded = true; + + // Restore saved queries + m_savedQueries = m_pTrackCollection->getSavedQueriesDAO().getSavedQueries(this); + } + return m_savedQueries; } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index b29b433d05f..ad92e2ea546 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -81,7 +81,7 @@ class LibraryFeature : public QObject { virtual void saveQuery(SavedSearchQuery& query); virtual void restoreQuery(int index); - virtual const QList &getSavedQueries() const; + virtual const QList &getSavedQueries(); public slots: // called when you single click on the root item @@ -150,6 +150,7 @@ class LibraryFeature : public QObject { int m_featureFocus; int m_focusedPane; + bool m_queriesLoaded; QList m_savedQueries; From 1a5c72f7c6c004a59a6d9eaecfd51c3ca1de9a6c Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 19:17:56 +0200 Subject: [PATCH 375/552] Fix schema --- res/schema.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/schema.xml b/res/schema.xml index 768d33ea16c..a2ed82e0b47 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -423,6 +423,7 @@ METADATA CREATE TABLE IF NOT EXISTS savedQueries ( + id INTEGER PRIMARY KEY AUTOINCREMENT, libraryFeature TEXT, query TEXT, title TEXT, From 9c0b88e60abd17626fe181fbda2b5dfeaeebc70c Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 12 Aug 2016 20:10:52 +0200 Subject: [PATCH 376/552] Added id to SavedQueries and fix compilation issues --- src/library/analysisfeature.cpp | 2 +- src/library/analysisfeature.h | 2 +- src/library/autodj/autodjfeature.cpp | 2 +- src/library/autodj/autodjfeature.h | 2 +- src/library/banshee/bansheefeature.cpp | 2 +- src/library/banshee/bansheefeature.h | 2 +- src/library/browse/browsefeature.cpp | 2 +- src/library/browse/browsefeature.h | 2 +- src/library/cratefeature.cpp | 2 +- src/library/cratefeature.h | 2 +- src/library/dao/savedqueriesdao.cpp | 127 +++++++++++++++------ src/library/dao/savedqueriesdao.h | 15 ++- src/library/historyfeature.cpp | 2 +- src/library/historyfeature.h | 2 +- src/library/itunes/itunesfeature.cpp | 2 +- src/library/itunes/itunesfeature.h | 2 +- src/library/libraryfeature.cpp | 34 ++---- src/library/libraryfeature.h | 12 +- src/library/libraryfoldersfeature.cpp | 2 +- src/library/libraryfoldersfeature.h | 2 +- src/library/maintenancefeature.cpp | 2 +- src/library/maintenancefeature.h | 2 +- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/mixxxlibraryfeature.h | 2 +- src/library/playlistfeature.cpp | 2 +- src/library/playlistfeature.h | 2 +- src/library/recording/recordingfeature.cpp | 2 +- src/library/recording/recordingfeature.h | 2 +- src/library/rhythmbox/rhythmboxfeature.cpp | 2 +- src/library/rhythmbox/rhythmboxfeature.h | 2 +- src/library/traktor/traktorfeature.cpp | 2 +- src/library/traktor/traktorfeature.h | 2 +- 32 files changed, 149 insertions(+), 95 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 68a6edfa4aa..eb983787457 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -60,7 +60,7 @@ QString AnalysisFeature::getIconPath() { return ":/images/library/ic_library_prepare.png"; } -QString AnalysisFeature::getSettingsName() { +QString AnalysisFeature::getSettingsName() const { return "AnalysisFeature"; } diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 67de87ac6b1..14d972d0114 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -31,7 +31,7 @@ class AnalysisFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 89d4e5d8983..32fbcd89b23 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -99,7 +99,7 @@ QString AutoDJFeature::getIconPath() { return ":/images/library/ic_library_autodj.png"; } -QString AutoDJFeature::getSettingsName() { +QString AutoDJFeature::getSettingsName() const { return "AutoDJFeature"; } diff --git a/src/library/autodj/autodjfeature.h b/src/library/autodj/autodjfeature.h index 0a9e65e7f88..2b0d70d300c 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/autodj/autodjfeature.h @@ -41,7 +41,7 @@ class AutoDJFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 4c3bf6ef385..adbd826d7c3 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -62,7 +62,7 @@ QString BansheeFeature::getIconPath() { return ":/images/library/ic_library_banshee.png"; } -QString BansheeFeature::getSettingsName() { +QString BansheeFeature::getSettingsName() const { return "BansheeFeature"; } diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index 20f5e084c70..4306492d77f 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -30,7 +30,7 @@ class BansheeFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; virtual TreeItemModel* getChildModel(); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index b497d09356e..c83717f7b89 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -145,7 +145,7 @@ QString BrowseFeature::getIconPath() { return ":/images/library/ic_library_browse.png"; } -QString BrowseFeature::getSettingsName() { +QString BrowseFeature::getSettingsName() const { return "BrowseFeature"; } diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index cfb835bdfe8..92cdb75b9e2 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -38,7 +38,7 @@ class BrowseFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; QWidget* createPaneWidget(KeyboardEventFilter*pKeyboard, int paneId) override; diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 457feb9745d..26696d1da79 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -127,7 +127,7 @@ QString CrateFeature::getIconPath() { return ":/images/library/ic_library_crates.png"; } -QString CrateFeature::getSettingsName() { +QString CrateFeature::getSettingsName() const { return "CrateFeature"; } diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 36bf090e027..decb15a68d1 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -33,7 +33,7 @@ class CrateFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; void onSearch(QString&) {} diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 2457e71bce3..6ceda7d0468 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -4,6 +4,10 @@ #include "library/libraryfeature.h" #include "library/queryutil.h" +const QString SavedQueriesDAO::kSelectStart = + "SELECT query, title, selectedItems, sortOrder, " + "vScrollbarPos, sortColumn, sortAscendingOrder, pinned, id "; + SavedQueriesDAO::SavedQueriesDAO(QSqlDatabase& database) : m_database(database) { @@ -12,10 +16,10 @@ SavedQueriesDAO::SavedQueriesDAO(QSqlDatabase& database) void SavedQueriesDAO::initialize() { } -void SavedQueriesDAO::setSavedQueries(LibraryFeature* pFeature, - const QList& queries) { +SavedSearchQuery SavedQueriesDAO::saveQuery(LibraryFeature* pFeature, + SavedSearchQuery sQuery) { if (pFeature == nullptr) { - return; + return SavedSearchQuery(); } // First of all delete previous saved queries @@ -37,56 +41,92 @@ void SavedQueriesDAO::setSavedQueries(LibraryFeature* pFeature, "VALUES (:libraryFeature, :query, :title, :selectedItems, " ":sortOrder, :vScrollbarPos, :sortColumn, :sortAscendingOrder, :pinned)"); - for (const SavedSearchQuery& sQuery : queries) { - query.bindValue(":libraryFeature", pFeature->getSettingsName()); - query.bindValue(":query", sQuery.query); - query.bindValue(":title", sQuery.title); - query.bindValue(":selectedItems", serializeItems(sQuery.selectedItems)); - query.bindValue(":sortOrder", sQuery.sortOrder); - query.bindValue(":vScrollbarPos", sQuery.vScrollBarPos); - query.bindValue(":sortColumn", sQuery.sortColumn); - query.bindValue(":sortAscendingOrder", sQuery.sortAscendingOrder); - query.bindValue(":pinned", sQuery.pinned); - - if (!query.exec()) { - LOG_FAILED_QUERY(query); - } + query.bindValue(":libraryFeature", pFeature->getSettingsName()); + query.bindValue(":query", sQuery.query); + query.bindValue(":title", sQuery.title); + query.bindValue(":selectedItems", serializeItems(sQuery.selectedItems)); + query.bindValue(":sortOrder", sQuery.sortOrder); + query.bindValue(":vScrollbarPos", sQuery.vScrollBarPos); + query.bindValue(":sortColumn", sQuery.sortColumn); + query.bindValue(":sortAscendingOrder", sQuery.sortAscendingOrder); + query.bindValue(":pinned", sQuery.pinned); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + + if (!query.exec("SELECT id FROM " SAVEDQUERYTABLE + " WHERE ROWID=last_inserted_rowid()")) { + LOG_FAILED_QUERY(query); } + + query.next(); + sQuery.id = query.value(0).toInt(); + return sQuery; } -QList SavedQueriesDAO::getSavedQueries(LibraryFeature* pFeature) { +QList SavedQueriesDAO::getSavedQueries(const QString& settingsName) const { + QSqlQuery query(m_database); + QString queryStr = kSelectStart + + "FROM " SAVEDQUERYTABLE + " WHERE libraryFeature = :featureName " + "ORDER BY id DESC"; + query.prepare(queryStr); + query.bindValue(":featureName", settingsName); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + QList res; + while (query.next()) { + res << valueToQuery(query); + } + return res; +} + +QList SavedQueriesDAO::getSavedQueries(const LibraryFeature* pFeature) const { if (pFeature == nullptr) { return QList(); } + return getSavedQueries(pFeature->getSettingsName()); +} + +SavedSearchQuery SavedQueriesDAO::getSavedQuery(int id) const { QSqlQuery query(m_database); - QString queryStr = "SELECT query, title, selectedItems, sortOrder, " - "vScrollbarPos, sortColumn, sortAscendingOrder, pinned " + QString queryStr = kSelectStart + "FROM " SAVEDQUERYTABLE - " WHERE libraryFeature = :featureName"; + " WHERE id = :id " + "ORDER BY id DESC"; query.prepare(queryStr); - query.bindValue(":featureName", pFeature->getSettingsName()); + query.bindValue(":id", id); if (!query.exec()) { LOG_FAILED_QUERY(query); } - QList res; - while (query.next()) { - SavedSearchQuery q; - q.query = query.value(0).toString(); - q.title = query.value(1).toString(); - q.selectedItems = deserializeItems(query.value(2).toString()); - q.sortOrder = query.value(3).toString(); - q.vScrollBarPos = query.value(4).toInt(); - q.sortColumn = query.value(5).toInt(); - q.sortAscendingOrder = query.value(6).toBool(); - q.pinned = query.value(7).toBool(); - - res << q; + query.next(); + return valueToQuery(query); +} + +SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, + const SavedSearchQuery& sQuery) { + // To move to the first item we delete the item and insert againt it + // to assign it a new ID + QSqlQuery query(m_database); + query.prepare("DELETE FROM " SAVEDQUERYTABLE " WHERE id=:id"); + query.bindValue(":id", sQuery.id); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); } - return res; + + return saveQuery(pFeature, sQuery); +} + +SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) { + return moveToFirst(pFeature, getSavedQuery(id)); } QString SavedQueriesDAO::serializeItems(const QSet& items) { @@ -106,3 +146,18 @@ QSet SavedQueriesDAO::deserializeItems(const QString& text) { } return ret; } + +SavedSearchQuery SavedQueriesDAO::valueToQuery(const QSqlQuery& query) { + SavedSearchQuery q; + q.query = query.value(0).toString(); + q.title = query.value(1).toString(); + q.selectedItems = deserializeItems(query.value(2).toString()); + q.sortOrder = query.value(3).toString(); + q.vScrollBarPos = query.value(4).toInt(); + q.sortColumn = query.value(5).toInt(); + q.sortAscendingOrder = query.value(6).toBool(); + q.pinned = query.value(7).toBool(); + q.id = query.value(8).toInt(); + + return q; +} diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 4b126aaa335..6d75bc85ab0 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -13,6 +13,9 @@ // This struct allows to save some data to allow interaction between // the search bar and the library features struct SavedSearchQuery { + + SavedSearchQuery() : id(-1) {} + QString query; QString title; QSet selectedItems; @@ -22,6 +25,7 @@ struct SavedSearchQuery { int sortColumn; bool sortAscendingOrder; bool pinned; + int id; }; class LibraryFeature; @@ -32,12 +36,19 @@ class SavedQueriesDAO : public DAO SavedQueriesDAO(QSqlDatabase& database); void initialize(); - void setSavedQueries(LibraryFeature* pFeature, const QList& queries); - QList getSavedQueries(LibraryFeature* pFeature); + SavedSearchQuery saveQuery(LibraryFeature* pFeature, SavedSearchQuery sQuery); + QList getSavedQueries(const QString& settingsName) const; + QList getSavedQueries(const LibraryFeature *pFeature) const; + SavedSearchQuery getSavedQuery(int id) const; + SavedSearchQuery moveToFirst(LibraryFeature* pFeature, const SavedSearchQuery& sQuery); + SavedSearchQuery moveToFirst(LibraryFeature* pFeature, int id); private: static QString serializeItems(const QSet& items); static QSet deserializeItems(const QString& text); + static SavedSearchQuery valueToQuery(const QSqlQuery& query); + + static const QString kSelectStart; QSqlDatabase& m_database; }; diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index a413536503e..71cacabf6cb 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -57,7 +57,7 @@ QString HistoryFeature::getIconPath() { return ":/images/library/ic_library_history.png"; } -QString HistoryFeature::getSettingsName() { +QString HistoryFeature::getSettingsName() const { return "HistoryFeature"; } diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index 339773c036a..f0ea5475e84 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -25,7 +25,7 @@ class HistoryFeature : public BasePlaylistFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; void decorateChild(TreeItem *pChild, int playlist_id) override; public slots: diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index ac0a24d5e2e..9cb1ec6a8ad 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -116,7 +116,7 @@ QString ITunesFeature::getIconPath() { return ":/images/library/ic_library_itunes.png"; } -QString ITunesFeature::getSettingsName() { +QString ITunesFeature::getSettingsName() const { return "ITunesFeature"; } diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index 1481b425bbe..8a00fec60d3 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -30,7 +30,7 @@ class ITunesFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; TreeItemModel* getChildModel(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index b7cb7eacbc1..e025b743fd7 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -34,14 +34,14 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pConfig(pConfig), m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), - m_featureFocus(-1), - m_queriesLoaded(false) { + m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), + m_featureFocus(-1) { } LibraryFeature::~LibraryFeature() { } -QString LibraryFeature::getSettingsName() { +QString LibraryFeature::getSettingsName() const { return QString(""); } @@ -97,41 +97,31 @@ void LibraryFeature::setFocusedPane(int paneId) { m_focusedPane = paneId; } -void LibraryFeature::saveQuery(SavedSearchQuery& query) { +SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery query) { WTrackTableView* pTable = getFocusedTable(); if (pTable == nullptr) { - return; + return SavedSearchQuery(); } query = pTable->saveQuery(query); // A saved query goes the first in the list - m_savedQueries.prepend(query); - m_pTrackCollection->getSavedQueriesDAO().setSavedQueries(this, m_savedQueries); + return m_savedDAO.saveQuery(this, query); } -void LibraryFeature::restoreQuery(int index) { +void LibraryFeature::restoreQuery(int id) { WTrackTableView* pTable = getFocusedTable(); if (pTable == nullptr) { return; } - pTable->restoreQuery(m_savedQueries.at(index)); - // Move the used query to the first item in the list - m_savedQueries.move(index, 0); - m_pTrackCollection->getSavedQueriesDAO().setSavedQueries(this, m_savedQueries); + // Move the query to the first position to be reused later by the user + const SavedSearchQuery& sQuery = m_savedDAO.moveToFirst(this, id); + pTable->restoreQuery(sQuery); } -const QList& LibraryFeature::getSavedQueries() { - - if (!m_queriesLoaded) { - m_queriesLoaded = true; - - // Restore saved queries - m_savedQueries = m_pTrackCollection->getSavedQueriesDAO().getSavedQueries(this); - } - - return m_savedQueries; +QList LibraryFeature::getSavedQueries() const { + return m_savedDAO.getSavedQueries(this); } WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index ad92e2ea546..db04954fcd9 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -42,7 +42,7 @@ class LibraryFeature : public QObject { virtual QString getIconPath() = 0; // This name must be unique for each feature - virtual QString getSettingsName(); + virtual QString getSettingsName() const; QIcon getIcon(); @@ -79,9 +79,9 @@ class LibraryFeature : public QObject { virtual void setFocusedPane(int paneId); - virtual void saveQuery(SavedSearchQuery& query); - virtual void restoreQuery(int index); - virtual const QList &getSavedQueries(); + virtual SavedSearchQuery saveQuery(SavedSearchQuery query); + virtual void restoreQuery(int id); + virtual QList getSavedQueries() const; public slots: // called when you single click on the root item @@ -147,12 +147,10 @@ class LibraryFeature : public QObject { UserSettingsPointer m_pConfig; Library* m_pLibrary; TrackCollection* m_pTrackCollection; + SavedQueriesDAO& m_savedDAO; int m_featureFocus; int m_focusedPane; - bool m_queriesLoaded; - - QList m_savedQueries; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp index f5acb9d3817..6d8d4a62215 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/libraryfoldersfeature.cpp @@ -23,7 +23,7 @@ QString LibraryFoldersFeature::getIconPath() { return ":/images/library/ic_library_folder.png"; } -QString LibraryFoldersFeature::getSettingsName() { +QString LibraryFoldersFeature::getSettingsName() const { return "LibraryFoldersFeature"; } diff --git a/src/library/libraryfoldersfeature.h b/src/library/libraryfoldersfeature.h index 18f53646934..97b5732eee0 100644 --- a/src/library/libraryfoldersfeature.h +++ b/src/library/libraryfoldersfeature.h @@ -15,7 +15,7 @@ class LibraryFoldersFeature : public MixxxLibraryFeature QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; public slots: void onRightClickChild(const QPoint& pos, const QModelIndex&) override; diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 568781c8bc3..c093d4a3c01 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -31,7 +31,7 @@ QString MaintenanceFeature::getIconPath() { return ":/images/library/ic_library_maintenance.png"; } -QString MaintenanceFeature::getSettingsName() { +QString MaintenanceFeature::getSettingsName() const { return "MaintenanceFeature"; } diff --git a/src/library/maintenancefeature.h b/src/library/maintenancefeature.h index c4ee16347d7..c4a79423517 100644 --- a/src/library/maintenancefeature.h +++ b/src/library/maintenancefeature.h @@ -22,7 +22,7 @@ class MaintenanceFeature : public LibraryFeature QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; TreeItemModel* getChildModel(); public slots: diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index f8274afc22c..722009f8832 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -124,7 +124,7 @@ QString MixxxLibraryFeature::getIconPath() { return ":/images/library/ic_library_library.png"; } -QString MixxxLibraryFeature::getSettingsName() { +QString MixxxLibraryFeature::getSettingsName() const { return "MixxxLibraryFeature"; } diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index ad570ea45d8..4a606399c1d 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -42,7 +42,7 @@ class MixxxLibraryFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 30f8596f858..a343843178a 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -41,7 +41,7 @@ QString PlaylistFeature::getIconPath() { return ":/images/library/ic_library_playlist.png"; } -QString PlaylistFeature::getSettingsName() { +QString PlaylistFeature::getSettingsName() const { return "PlaylistFeature"; } diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 1fcdead76a2..9d5cabce963 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -28,7 +28,7 @@ class PlaylistFeature : public BasePlaylistFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; bool dragMoveAccept(QUrl url); bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 2015760ed48..52bbb8b42e5 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -40,7 +40,7 @@ QString RecordingFeature::getIconPath() { return ":/images/library/ic_library_recordings.png"; } -QString RecordingFeature::getSettingsName() { +QString RecordingFeature::getSettingsName() const { return "RecordingFeature"; } diff --git a/src/library/recording/recordingfeature.h b/src/library/recording/recordingfeature.h index 6f186fa2bb5..de1a32c96bf 100644 --- a/src/library/recording/recordingfeature.h +++ b/src/library/recording/recordingfeature.h @@ -30,7 +30,7 @@ class RecordingFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; QWidget* createPaneWidget(KeyboardEventFilter *pKeyboard, int paneId) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 1f74ad1104e..cf68a11a677 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -107,7 +107,7 @@ QString RhythmboxFeature::getIconPath() { return ":/images/library/ic_library_rhythmbox.png"; } -QString RhythmboxFeature::getSettingsName() { +QString RhythmboxFeature::getSettingsName() const { return "RhythmboxFeature"; } diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/rhythmbox/rhythmboxfeature.h index cd455efbe5e..c7a638c9e5b 100644 --- a/src/library/rhythmbox/rhythmboxfeature.h +++ b/src/library/rhythmbox/rhythmboxfeature.h @@ -30,7 +30,7 @@ class RhythmboxFeature : public BaseExternalLibraryFeature { QVariant title(); QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; TreeItemModel* getChildModel(); // processes the music collection diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 00ce9e29fc0..fcd40768415 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -126,7 +126,7 @@ QString TraktorFeature::getIconPath() { return ":/images/library/ic_library_traktor.png"; } -QString TraktorFeature::getSettingsName() { +QString TraktorFeature::getSettingsName() const { return "TraktorFeature"; } diff --git a/src/library/traktor/traktorfeature.h b/src/library/traktor/traktorfeature.h index 1fb1f46afb7..9f5475c87a3 100644 --- a/src/library/traktor/traktorfeature.h +++ b/src/library/traktor/traktorfeature.h @@ -46,7 +46,7 @@ class TraktorFeature : public BaseExternalLibraryFeature { QVariant title() override; QString getIconPath() override; - QString getSettingsName() override; + QString getSettingsName() const override; static bool isSupported(); TreeItemModel* getChildModel(); From a01639a7da46e8f41cea2f20ae3a5489e3b313b1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 13 Aug 2016 09:28:33 +0200 Subject: [PATCH 377/552] Some improvements to StringHelper --- src/util/stringhelper.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp index 09859cafd4c..9d4d6f2634e 100644 --- a/src/util/stringhelper.cpp +++ b/src/util/stringhelper.cpp @@ -18,18 +18,18 @@ QChar StringHelper::getFirstCharForGrouping(const QString& text) { } c = c.toUpper(); QString letter(c); - QString limmit("Z"); - if (QString::localeAwareCompare(limmit, letter) < 0) { - // The letter is above z so we must not change it this is due to - // Chinese letters or Finnish sorting. In Finnish the correct sorting - // is a-z, å, ä, ö and the user will expect these letters at the - // end and not like this a, ä, å, b-o, ö, p-z - return c; - } // This removes the accents of the characters QString s1 = letter.normalized(QString::NormalizationForm_KD); if (s1.size() > 0) { + if (QString::localeAwareCompare(s1, letter) != 0) { + // The letter does not sort together with it's normalized form, + // it is due to Chinese letters or Finnish sorting. In Finnish the + // correct sorting is a-z, å, ä, ö and the user will expect these + // letters at the end and not like this a, ä, å, b-o, ö, p-z + return c; + } + c = s1.at(0).toUpper(); } return c; From d8b54fc24cd401f88ae7ebc983c8dacb6f5fe1d3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 13 Aug 2016 10:04:52 +0200 Subject: [PATCH 378/552] Fix crash in search bar --- src/widget/wsearchlineedit.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 65a10a1e2fe..0d809be8a2a 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -270,6 +270,10 @@ void WSearchLineEdit::saveQuery() { } void WSearchLineEdit::restoreQuery() { + if (m_pCurrentFeature.isNull()) { + return; + } + const QList& savedQueries = m_pCurrentFeature->getSavedQueries(); QMenu menu; From 18545979dba6d279c57b0bc9b75b4f6141523d4b Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 13 Aug 2016 10:05:18 +0200 Subject: [PATCH 379/552] Removed changed function --- src/util/stringhelper.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp index 9d4d6f2634e..09859cafd4c 100644 --- a/src/util/stringhelper.cpp +++ b/src/util/stringhelper.cpp @@ -18,18 +18,18 @@ QChar StringHelper::getFirstCharForGrouping(const QString& text) { } c = c.toUpper(); QString letter(c); + QString limmit("Z"); + if (QString::localeAwareCompare(limmit, letter) < 0) { + // The letter is above z so we must not change it this is due to + // Chinese letters or Finnish sorting. In Finnish the correct sorting + // is a-z, å, ä, ö and the user will expect these letters at the + // end and not like this a, ä, å, b-o, ö, p-z + return c; + } // This removes the accents of the characters QString s1 = letter.normalized(QString::NormalizationForm_KD); if (s1.size() > 0) { - if (QString::localeAwareCompare(s1, letter) != 0) { - // The letter does not sort together with it's normalized form, - // it is due to Chinese letters or Finnish sorting. In Finnish the - // correct sorting is a-z, å, ä, ö and the user will expect these - // letters at the end and not like this a, ä, å, b-o, ö, p-z - return c; - } - c = s1.at(0).toUpper(); } return c; From dee390f4ebb1a5938170f8edab8f896f2628a9a5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 13 Aug 2016 10:46:36 +0200 Subject: [PATCH 380/552] Fix some issues --- src/skin/legacyskinparser.cpp | 22 +++++++++++----------- src/widget/wfeatureclickbutton.cpp | 6 +++++- src/widget/wlibrarybreadcrumb.cpp | 4 +++- src/widget/wminiviewscrollbar.cpp | 19 ++++++++++++++++++- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 5fa21d0f563..79cc02a9d99 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1162,16 +1162,16 @@ QWidget* LegacySkinParser::parseSpinny(const QDomElement& node) { } QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { - WSearchLineEdit* pSearchLineEdit = new WSearchLineEdit(m_pParent); int id = -1; - if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { - //qDebug() << "SearchBox ID:" << id; - m_pLibrary->bindSearchBar(pSearchLineEdit, id); - } - else { + if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { SKIN_WARNING(node, *m_pContext) << "SearchBox Id not found"; + return nullptr; } + //qDebug() << "SearchBox ID:" << id; + + WSearchLineEdit* pSearchLineEdit = new WSearchLineEdit(m_pParent); + m_pLibrary->bindSearchBar(pSearchLineEdit, id); pSearchLineEdit->setup(node, *m_pContext); commonWidgetSetup(node, pSearchLineEdit, false); @@ -1286,17 +1286,17 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { QFrame* pContainer = new QFrame(m_pParent); QVBoxLayout* pLayout = new QVBoxLayout(pContainer); pContainer->setLayout(pLayout); + + WLibraryBreadCrumb* pBreadCrumb = new WLibraryBreadCrumb(pContainer); + m_pLibrary->bindBreadCrumb(pBreadCrumb, m_paneId); + setupWidget(node, pBreadCrumb); + pLayout->addWidget(pBreadCrumb); WSearchLineEdit* pSearchBox = new WSearchLineEdit(pContainer); pSearchBox->setup(node, *m_pContext); m_pLibrary->bindSearchBar(pSearchBox, m_paneId); commonWidgetSetup(node, pSearchBox); pLayout->addWidget(pSearchBox); - - WLibraryBreadCrumb* pBreadCrumb = new WLibraryBreadCrumb(pContainer); - m_pLibrary->bindBreadCrumb(pBreadCrumb, m_paneId); - setupWidget(node, pBreadCrumb); - pLayout->addWidget(pBreadCrumb); WLibrary* pLibraryWidget = new WLibrary(pContainer); pLibraryWidget->installEventFilter(m_pKeyboard); diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index edbe8abb1d0..2d5df12b1a5 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -19,7 +19,11 @@ WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* pare setIcon(m_pFeature->getIcon()); m_textControl.connectValueChanged(SLOT(slotTextDisplayChanged(double))); - slotTextDisplayChanged(m_textControl.get()); + if (m_textControl.valid()) { + slotTextDisplayChanged(m_textControl.get()); + } else { + slotTextDisplayChanged(1.0); + } } void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index f8cef22a9e3..ec97532b0b0 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -13,8 +13,10 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) layout->addWidget(m_pIcon); layout->addWidget(m_pText); layout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding)); - layout->setSpacing(0); + layout->setSpacing(2); layout->setContentsMargins(0,0,0,0); + layout->setAlignment(Qt::AlignVCenter); + setContentsMargins(0,0,0,0); setLayout(layout); } diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 49b8730b14e..33c22494e5d 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -236,9 +236,26 @@ void WMiniViewScrollBar::computeLettersSize() { m_computedPosition[i].character = m_letters[i].character; } + QStyleOptionSlider opt; + opt.init(this); + opt.maximum = maximum(); + opt.minimum = minimum(); + opt.orientation = orientation(); + opt.pageStep = pageStep(); + opt.singleStep = singleStep(); + opt.sliderPosition = sliderPosition(); + opt.sliderValue = value(); + + const int addLineSize = + style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarAddLine, this).height(); + const int subLineSize = + style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarSubLine, this).height(); + // Height of a letter const int letterSize = fontMetrics().height(); - const int totalLinearSize = rect().height(); + const int totalLinearSize = rect().height() - addLineSize - subLineSize; float nextAvailableScrollPosition = 0.0; float optimalScrollPosition = 0.0; From a4fcf3ea64afed096edbad85dc803a713fdc5f7d Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 13 Aug 2016 13:22:38 +0200 Subject: [PATCH 381/552] Fix addLine subLine controls not showing in WMiniViewScrollBar --- src/widget/wminiviewscrollbar.cpp | 40 +++++++++++++++---------------- src/widget/wminiviewscrollbar.h | 1 + 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 33c22494e5d..d33d7cfc4e8 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -67,17 +67,7 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { } QStylePainter painter(this); - QStyleOptionSlider opt; - opt.init(this); - opt.subControls = QStyle::SC_None; - opt.activeSubControls = QStyle::SC_None; - opt.orientation = orientation(); - opt.minimum = minimum(); - opt.maximum = maximum(); - opt.sliderPosition = sliderPosition(); - opt.sliderValue = value(); - opt.singleStep = singleStep(); - opt.pageStep = pageStep(); + QStyleOptionSlider opt(getStyleOptions()); painter.drawComplexControl(QStyle::CC_ScrollBar, opt); painter.setBrush(palette().color(QPalette::Text)); @@ -106,6 +96,8 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { opt.subControls = QStyle::SC_ScrollBarSlider; opt.activeSubControls = QStyle::SC_ScrollBarSlider; painter.drawControl(QStyle::CE_ScrollBarSlider, opt); + painter.drawControl(QStyle::CE_ScrollBarAddLine, opt); + painter.drawControl(QStyle::CE_ScrollBarSubLine, opt); } void WMiniViewScrollBar::resizeEvent(QResizeEvent* pEvent) { @@ -236,15 +228,7 @@ void WMiniViewScrollBar::computeLettersSize() { m_computedPosition[i].character = m_letters[i].character; } - QStyleOptionSlider opt; - opt.init(this); - opt.maximum = maximum(); - opt.minimum = minimum(); - opt.orientation = orientation(); - opt.pageStep = pageStep(); - opt.singleStep = singleStep(); - opt.sliderPosition = sliderPosition(); - opt.sliderValue = value(); + QStyleOptionSlider opt(getStyleOptions()); const int addLineSize = style()->subControlRect(QStyle::CC_ScrollBar, &opt, @@ -290,3 +274,19 @@ void WMiniViewScrollBar::triggerUpdate() { computeLettersSize(); update(); } + +QStyleOptionSlider WMiniViewScrollBar::getStyleOptions() { + QStyleOptionSlider opt; + opt.init(this); + opt.subControls = QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine; + opt.activeSubControls = QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine; + opt.orientation = orientation(); + opt.minimum = minimum(); + opt.maximum = maximum(); + opt.sliderPosition = sliderPosition(); + opt.sliderValue = value(); + opt.singleStep = singleStep(); + opt.pageStep = pageStep(); + + return opt; +} diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index abb00732e68..df1e2e41166 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -48,6 +48,7 @@ class WMiniViewScrollBar : public QScrollBar // paintEvent function which can block the GUI thread void computeLettersSize(); void triggerUpdate(); + QStyleOptionSlider getStyleOptions(); int m_sortColumn; int m_dataRole; From b963173a5658dccca4881687e8a2cfd0f849c3c4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 09:23:35 +0200 Subject: [PATCH 382/552] Fix purge not working in maintenance feature --- src/library/dlghidden.cpp | 1 - src/library/dlgmissing.cpp | 1 - src/library/maintenancefeature.cpp | 4 ++++ src/widget/wtracktableview.cpp | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 7adcc47323d..54f8a46030f 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -10,7 +10,6 @@ DlgHidden::DlgHidden(QWidget* parent) Ui::DlgHidden() { setupUi(this); - connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); connect(btnPurge, SIGNAL(clicked()), this, SIGNAL(purge())); connect(btnUnhide, SIGNAL(clicked()), this, SIGNAL(unhide())); diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 4eb22b2bcac..72e17b67aa4 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -9,7 +9,6 @@ DlgMissing::DlgMissing(QWidget* parent) Ui::DlgMissing() { setupUi(this); - connect(btnPurge, SIGNAL(clicked()), this, SLOT(onShow())); connect(btnPurge, SIGNAL(clicked()), this, SIGNAL(purge())); connect(btnSelect, SIGNAL(clicked()), this, SIGNAL(selectAll())); } diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index c093d4a3c01..031e1ce3023 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -68,6 +68,7 @@ void MaintenanceFeature::selectionChanged(const QItemSelection&, } else if (*it == Pane::Missing) { m_pMissingView->setSelectedIndexes(selection); } + const QModelIndexList& selection2 = pTable->selectionModel()->selectedRows(); } void MaintenanceFeature::selectAll() { @@ -171,6 +172,9 @@ void MaintenanceFeature::slotPurge() { return; } pTable->slotPurge(); + + m_pMissingView->onShow(); + m_pHiddenView->onShow(); } HiddenTableModel* MaintenanceFeature::getHiddenTableModel() { diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 50499f38213..f26efb29bbd 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -510,6 +510,7 @@ void WTrackTableView::slotRemove() { void WTrackTableView::slotPurge() { QModelIndexList indices = selectionModel()->selectedRows(); + indices = selectionModel()->selectedIndexes(); if (indices.size() > 0) { TrackModel* trackModel = getTrackModel(); if (trackModel) { From de2d982e0a58cf54e55b3a9f35eaf58b7b72368c Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 10:16:19 +0200 Subject: [PATCH 383/552] Fix coverart deactivated when activating some features --- src/library/banshee/bansheefeature.cpp | 4 ++-- src/library/browse/browsefeature.cpp | 2 +- src/library/itunes/itunesfeature.cpp | 6 +++--- src/library/recording/recordingfeature.cpp | 2 +- src/library/rhythmbox/rhythmboxfeature.cpp | 4 ++-- src/library/traktor/traktorfeature.cpp | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index adbd826d7c3..fbb243f3485 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -127,7 +127,7 @@ void BansheeFeature::activate() { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } void BansheeFeature::activateChild(const QModelIndex& index) { @@ -141,7 +141,7 @@ void BansheeFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(item); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index c83717f7b89..d820048b5b1 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -244,7 +244,7 @@ void BrowseFeature::activate() { m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->restoreSearch(QString()); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } // Note: This is executed whenever you single click on an child item diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 9cb1ec6a8ad..f727c5ba548 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -122,7 +122,7 @@ QString ITunesFeature::getSettingsName() const { void ITunesFeature::activate() { activate(false); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } void ITunesFeature::activate(bool forceReload) { @@ -184,7 +184,7 @@ void ITunesFeature::activate(bool forceReload) { showTrackModel(m_pITunesTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } void ITunesFeature::activateChild(const QModelIndex& index) { @@ -195,7 +195,7 @@ void ITunesFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pITunesPlaylistModel); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } TreeItemModel* ITunesFeature::getChildModel() { diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 52bbb8b42e5..1941eb46a6b 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -76,7 +76,7 @@ void RecordingFeature::activate() { showBreadCrumb(); restoreSearch(""); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } BrowseTableModel* RecordingFeature::getBrowseTableModel() { diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index cf68a11a677..7b0e07b22f7 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,7 +138,7 @@ void RhythmboxFeature::activate() { showTrackModel(m_pRhythmboxTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } void RhythmboxFeature::activateChild(const QModelIndex& index) { @@ -149,7 +149,7 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pRhythmboxPlaylistModel); m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } TreeItem* RhythmboxFeature::importMusicCollection() { diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index fcd40768415..85cc31c8bbb 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -161,12 +161,12 @@ void TraktorFeature::activate() { m_future_watcher.setFuture(m_future); m_title = tr("(loading) Traktor"); //calls a slot in the sidebar model such that 'iTunes (isLoading)' is displayed. - emit (featureIsLoading(this, true)); + emit(featureIsLoading(this, true)); } showTrackModel(m_pTraktorTableModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } void TraktorFeature::activateChild(const QModelIndex& index) { @@ -182,7 +182,7 @@ void TraktorFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pTraktorPlaylistModel); m_pLibrary->showBreadCrumb(item); - emit(enableCoverArtDisplay(false)); + enableCoverArtDisplay(true); } } From 8fd7205abc2744cf745be4b17dc3023c7d64eb3c Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 10:27:27 +0200 Subject: [PATCH 384/552] Disable 26 column (directory) added for FoldersFeature --- src/library/columncache.cpp | 1 + src/library/columncache.h | 1 + src/library/librarytablemodel.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/library/columncache.cpp b/src/library/columncache.cpp index dfac4176d37..59bd5f1f84b 100644 --- a/src/library/columncache.cpp +++ b/src/library/columncache.cpp @@ -57,6 +57,7 @@ void ColumnCache::setColumns(const QStringList& columns) { m_columnIndexByEnum[COLUMN_LIBRARYTABLE_COVERART_HASH] = fieldIndex(LIBRARYTABLE_COVERART_HASH); m_columnIndexByEnum[COLUMN_TRACKLOCATIONSTABLE_FSDELETED] = fieldIndex(TRACKLOCATIONSTABLE_FSDELETED); + m_columnIndexByEnum[COLUMN_TRACKLOCATIONSTABLE_DIRECTORY] = fieldIndex(TRACKLOCATIONSTABLE_DIRECTORY); m_columnIndexByEnum[COLUMN_PLAYLISTTRACKSTABLE_TRACKID] = fieldIndex(PLAYLISTTRACKSTABLE_TRACKID); m_columnIndexByEnum[COLUMN_PLAYLISTTRACKSTABLE_POSITION] = fieldIndex(PLAYLISTTRACKSTABLE_POSITION); diff --git a/src/library/columncache.h b/src/library/columncache.h index 0a0878aef60..134ebab0084 100644 --- a/src/library/columncache.h +++ b/src/library/columncache.h @@ -50,6 +50,7 @@ class ColumnCache { COLUMN_LIBRARYTABLE_COVERART_HASH, COLUMN_TRACKLOCATIONSTABLE_FSDELETED, + COLUMN_TRACKLOCATIONSTABLE_DIRECTORY, COLUMN_PLAYLISTTRACKSTABLE_TRACKID, COLUMN_PLAYLISTTRACKSTABLE_POSITION, diff --git a/src/library/librarytablemodel.cpp b/src/library/librarytablemodel.cpp index 38f259b4388..9b8ec12cf50 100644 --- a/src/library/librarytablemodel.cpp +++ b/src/library/librarytablemodel.cpp @@ -78,6 +78,7 @@ bool LibraryTableModel::isColumnInternal(int column) { (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK)) || (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_CHANNELS)) || (column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_FSDELETED)) || + (column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_DIRECTORY)) || (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) || (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE)) || From e5a4e700652043984498b944e52ad9db48e3b5ec Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 10:52:40 +0200 Subject: [PATCH 385/552] Disable save icon instead of removing the text --- res/mixxx.qrc | 1 + res/skins/save_disabled.png | Bin 0 -> 398 bytes src/widget/wsearchlineedit.cpp | 11 +++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 res/skins/save_disabled.png diff --git a/res/mixxx.qrc b/res/mixxx.qrc index ef360e0d870..456856e6200 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -113,5 +113,6 @@ skins/save.png skins/downArrow.png skins/cross_2.png + skins/save_disabled.png diff --git a/res/skins/save_disabled.png b/res/skins/save_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..0e0de61d7904131c6520a42cd85e82252edd092d GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^Q6S901|%(3I5Gh#wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pIsgO9_Q;e-3m2%wN;iEBiObAE1aYF-J0b5UwyNotBh zd1gt5g1e`0KzJjcI8f0yPZ!6Kid%2*8uB$82)H_SSZw8gklk)KQGol0_Jm5+sgm0^ zs0v(G@qGI1Jon!3=F{FsWq(e+FyVOO{ts{8pHXPyOKe6()4yN5y7$S8y+7xDmD#yo z`Src1?#_K53O0Q$aA@D)2uJ+K*kpm|5EyZpWL#k4l`>(vuz*#{B%_gSZPDqw`49Bo zm(0$92(c`1e9g|UlfK`=^deB@7KdgrundsFrVG;rWH@qzwDU%R7%%p(`EzXleVdtJ m!+|QN)t~D-6MncVPrF~*@1xM6{T9FwVDNPHb6Mw<&;$V5{gg%k literal 0 HcmV?d00001 diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 14d71cd7f6d..2b40ac6ce31 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -25,7 +25,13 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) m_pClearButton->hide(); m_pSaveButton = new QToolButton(this); - m_pSaveButton->setIcon(QIcon(":/skins/save.png")); + QIcon saveIcon; + saveIcon.addPixmap(QPixmap(":/skins/save.png"), QIcon::Active, QIcon::Off); + saveIcon.addPixmap(QPixmap(":/skins/save_disabled.png"), QIcon::Disabled, QIcon::Off); + saveIcon.addPixmap(QPixmap(":/skins/save.png"), QIcon::Active, QIcon::On); + saveIcon.addPixmap(QPixmap(":/skins/save_disabled.png"), QIcon::Disabled, QIcon::On); + + m_pSaveButton->setIcon(saveIcon); m_pSaveButton->setIconSize(iconSize); m_pSaveButton->setCursor(Qt::ArrowCursor); m_pSaveButton->setToolTip(tr("Save query", "Save the current query for later use")); @@ -245,6 +251,7 @@ void WSearchLineEdit::updateButtons(const QString& text) bool visible = !text.isEmpty() && !m_place; m_pDropButton->show(); m_pSaveButton->setVisible(visible); + m_pSaveButton->setEnabled(visible); m_pClearButton->setVisible(visible); } @@ -266,7 +273,7 @@ void WSearchLineEdit::saveQuery() { if (!m_pCurrentFeature.isNull()) { m_pCurrentFeature->saveQuery(query); } - setText(""); + m_pSaveButton->setEnabled(false); } void WSearchLineEdit::restoreQuery() { From 9824bbaf852509bf34c7eb940593550bfba672ee Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 14:35:47 +0200 Subject: [PATCH 386/552] Fix show always save button to allow saving sorting/scrolling only --- res/skins/cross_2.png | Bin 907 -> 916 bytes src/library/library.cpp | 56 ++++++++++++++++++++--------- src/library/library.h | 3 +- src/library/libraryfeature.cpp | 6 ++++ src/library/libraryfeature.h | 3 ++ src/library/librarypanemanager.cpp | 10 ++++++ src/library/librarypanemanager.h | 5 ++- src/widget/wsearchlineedit.cpp | 16 ++++++--- src/widget/wsearchlineedit.h | 1 + src/widget/wtracktableview.cpp | 7 +++- src/widget/wtracktableview.h | 3 ++ 11 files changed, 85 insertions(+), 25 deletions(-) diff --git a/res/skins/cross_2.png b/res/skins/cross_2.png index 90ac557c96b2bbc80fa1aa5e9e2e0882953c7cfe..ef516f72adfa6a71009a9a147ce5449e5e5b0d58 100644 GIT binary patch delta 846 zcmV-U1F`&z2b2epQ-2N&2LMcD;&T8110hL7K~y-)wN*`MoK+M(=YE-KFqJwQvDGxG zf`U?Lv1k{SY>bOINhqb_PedrR;16aYLN@-OOUcTmTOo>|fn&$xR#d&QQ{S+O3IG)eLt$zq;N5+oJf z{aB3g@bK{PjY6UDImx$4elR*ZdbO{wFPK@0t^;z zcX#)vLqkJ9SF2T)%Vo{a&lg**)>!}(?tXEbDlos z`uqDg0l?kw1@Nr9U+9z}m!b z$#-XGXU~>OB_sI<$zL-PTdkLGrl+T`kB^V90)Kb}z|lN=HnG-7h7iKj04@V~Skf^7 z4>g-jx%+97=Oo>cH^??!78e(}va)hM#`q3^Q(0mGXad*(Py}$KgV0TqH?oE*Wk!IR zwQq64%*;%&P$;|%;4MjyO0t7aATvvMwb;VK!kuetYi~$;EgPFUAaH9>?^Y_6@u znn$Kr02K0G>HKxvy_nTNJ3L?5w<+f4<_0!4Hl|4S07x@{v?JtDHsv~33?ZDlU4JS5 Y0mv7jz>UbOINi3z}Pec$D{J|_l$i^RZDP6gAD?|}Aki20S2SSAuAz*hRf{Qf% zR7@;^IOFtvdH1-;dooFrDG~Zs55D`Id+xdC-VeA*AG;maYJatRvMhUC($PHDCGC2L zqyYRAMbZ4OLG^n5?hwMHq_Y4HO4=Z)8v&Etkn}TmVR|Tp@EXaN0SrjmlMH6o?%9Fq zz7WC-0A7+b_&+6%t^-cf^qizuNge|LNg}x}X&pc>fZG5>Bq1pU@E1t}=#y07dDID- zB*~MKrT`o#8Gq%vZ2>XL~=QbqHh7T+`Z-QZ;<>Qzz2POec!LHuAX%Fc3#D%&Uv#Qlr%;1G|5ttOcErO z-2F(FW&1})My|$j`~}H(NPajrHg>VUzdx8+ndDtt9DkA|$#DRalAbS0*=8X~x@=~j z_V)IEHatB1OSM{MrBc!S{Cug^YMlZw>F(#YxI)snq-V@*-%hs5n>PsH*>=0Vw7k6h z<-owe1^~GGodBM4_p_Zc6jJm6h`Jd+PY?mHrKP3+;<7A@B$aZUEvyW{9LZTptuAB# zD}b*gU4I-J8VbdMyZ=eDMzXe@7y+PKtv;M(*+&3|N#4>~QtpheNxnZiI{HJsUOyZ{ zc+}n3$H&JnG#ZUknx<#6Ec?7LgPFAr04kNrB{Tcj%)XNpwlyx0ykcg}Mx${@2;n(N z=SjXdJ3D)-TrL~QKS=(Tlh_=+;%9n#`troY#D6M)`vDv-vgaFXjbsQRJOSVp0QX5c z0^r_evnh8!LGrYuTZ;kNqRZmqB3D*c&SY8kE`W#f!~)O+@Hc=GfP)=`u93W&4^%lf z0?e#^ofBqeW=e4!zX;%MNe@V}y>1{gOLw%`!otFVwY9Z3CB2@nP3;l5wX1iNBsuEt zZ$6QHTG9cM;YMEXSXw`I4V;^s8zlJ%fJ4QcxO=x31OU=FjxXG-w-o;ZZqb${Lm2QJ P00000NkvXXu0mjfJ*9@# diff --git a/src/library/library.cpp b/src/library/library.cpp index 0c425d99544..2d652fad3d2 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -164,7 +164,7 @@ void Library::destroyInterface() { m_panes.clear(); } -LibraryView *Library::getActiveView() { +LibraryView* Library::getActiveView() { WBaseLibrary* pPane = m_panes[m_focusedPane]->getPaneWidget(); WLibrary* pLibrary = qobject_cast(pPane); DEBUG_ASSERT_AND_HANDLE(pLibrary) { @@ -196,21 +196,36 @@ void Library::switchToFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->switchToFeature(pFeature); slotUpdateFocus(pFeature); - WBaseLibrary* pWLibrary = m_panes[m_focusedPane]->getPaneWidget(); + LibraryPaneManager* pPane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pPane) { + return; + } + + WBaseLibrary* pWLibrary = pPane->getPaneWidget(); // Only change the current pane if it's not shown already if (pWLibrary->getCurrentFeature() != pFeature) { - m_panes[m_focusedPane]->switchToFeature(pFeature); + pPane->switchToFeature(pFeature); } handleFocus(); } void Library::showBreadCrumb(TreeItem *pTree) { - m_panes[m_focusedPane]->showBreadCrumb(pTree); + LibraryPaneManager* pPane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pPane) { + return; + } + + pPane->showBreadCrumb(pTree); } void Library::showBreadCrumb(const QString &text, const QIcon &icon) { - m_panes[m_focusedPane]->showBreadCrumb(text, icon); + LibraryPaneManager* pPane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pPane) { + return; + } + + pPane->showBreadCrumb(text, icon); } void Library::slotLoadTrack(TrackPointer pTrack) { @@ -230,13 +245,23 @@ void Library::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool pla } void Library::restoreSearch(const QString& text) { - LibraryPaneManager* pane = getFocusedPane(); - DEBUG_ASSERT_AND_HANDLE(pane) { + LibraryPaneManager* pPane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pPane) { return; } - pane->restoreSearch(text); + pPane->restoreSearch(text); } + +void Library::restoreSaveButton() { + LibraryPaneManager* pPane = getFocusedPane(); + DEBUG_ASSERT_AND_HANDLE(pPane) { + return; + } + pPane->restoreSaveButton(); +} + + void Library::slotRefreshLibraryModels() { m_pMixxxLibraryFeature->refreshLibraryModels(); m_pAnalysisFeature->refreshLibraryModels(); @@ -396,7 +421,7 @@ void Library::paneUncollapsed(int paneId) { } } -void Library::slotActivateFeature(LibraryFeature *pFeature) { +void Library::slotActivateFeature(LibraryFeature* pFeature) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { m_pSidebarExpanded->switchToFeature(pFeature); @@ -487,15 +512,14 @@ LibraryPaneManager* Library::getPane(int paneId) { return pPane; } -LibraryPaneManager *Library::getFocusedPane() { +LibraryPaneManager* Library::getFocusedPane() { //qDebug() << "Focused" << m_focusedPane; - if (m_focusedPane == -1) { - return m_pSidebarExpanded; - } - else if (m_panes.contains(m_focusedPane)) { - return m_panes[m_focusedPane]; + auto it = m_panes.find(m_focusedPane); + if (it == m_panes.end()) { + return nullptr; } - return nullptr; + + return *it; } void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { diff --git a/src/library/library.h b/src/library/library.h index 6490cc24f38..3cdfc4b079d 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -95,6 +95,7 @@ class Library : public QObject { void showBreadCrumb(TreeItem* pTree); void showBreadCrumb(const QString& text, const QIcon& icon); void restoreSearch(const QString& text); + void restoreSaveButton(); public slots: @@ -141,7 +142,7 @@ class Library : public QObject { private: // If the pane exists returns it, otherwise it creates the pane - LibraryPaneManager *getPane(int paneId); + LibraryPaneManager* getPane(int paneId); LibraryPaneManager* getFocusedPane(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index e025b743fd7..1a1277c1bb1 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -140,6 +140,8 @@ WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboar this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); connect(pTrackTableView, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); + connect(pTrackTableView, SIGNAL(tableChanged()), + this, SLOT(restoreSaveButton())); connect(m_pLibrary, SIGNAL(setTrackTableFont(QFont)), pTrackTableView, SLOT(setTrackTableFont(QFont))); @@ -195,6 +197,10 @@ void LibraryFeature::restoreSearch(const QString& search) { m_pLibrary->restoreSearch(search); } +void LibraryFeature::restoreSaveButton() { + m_pLibrary->restoreSaveButton(); +} + void LibraryFeature::showBreadCrumb(TreeItem *pTree) { m_pLibrary->showBreadCrumb(pTree); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index db04954fcd9..ce50114293f 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -119,6 +119,9 @@ class LibraryFeature : public QObject { void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); + protected slots: + void restoreSaveButton(); + protected: inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 01c644e8de0..6cf9083cba6 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -118,6 +118,12 @@ void LibraryPaneManager::restoreSearch(const QString& text) { } } +void LibraryPaneManager::restoreSaveButton() { + if (!m_pSearchBar.isNull()) { + m_pSearchBar->slotRestoreSaveButton(); + } +} + void LibraryPaneManager::showBreadCrumb(TreeItem *pTree) { DEBUG_ASSERT_AND_HANDLE(!m_pBreadCrumb.isNull()) { return; @@ -133,6 +139,10 @@ void LibraryPaneManager::showBreadCrumb(const QString &text, const QIcon& icon) m_pBreadCrumb->showBreadCrumb(text, icon); } +int LibraryPaneManager::getPaneId() { + return m_paneId; +} + void LibraryPaneManager::slotPaneCollapsed() { m_pLibrary->paneCollapsed(m_paneId); } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 8ba27cd9d1e..20756b81c5a 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -43,13 +43,12 @@ class LibraryPaneManager : public QObject { void clearFocus(); void restoreSearch(const QString& text); + void restoreSaveButton(); void switchToFeature(LibraryFeature* pFeature); void showBreadCrumb(TreeItem* pTree); void showBreadCrumb(const QString& text, const QIcon &icon); - inline int getPaneId() { - return m_paneId; - } + int getPaneId(); signals: diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 2b40ac6ce31..2ba94302b65 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -117,12 +117,20 @@ void WSearchLineEdit::setup(const QDomNode& node, const SkinContext& context) { setPalette(pal); } +void WSearchLineEdit::slotRestoreSaveButton() { + m_pSaveButton->setEnabled(true); +} + void WSearchLineEdit::resizeEvent(QResizeEvent* e) { QLineEdit::resizeEvent(e); + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - QSize iconSize(height()/2, height()/2); + const int size = fontMetrics().height(); + QSize iconSize(size, size); m_pDropButton->setIconSize(iconSize); m_pSaveButton->setIconSize(iconSize); m_pClearButton->setIconSize(iconSize); @@ -249,9 +257,9 @@ void WSearchLineEdit::showPlaceholder() { void WSearchLineEdit::updateButtons(const QString& text) { bool visible = !text.isEmpty() && !m_place; - m_pDropButton->show(); - m_pSaveButton->setVisible(visible); - m_pSaveButton->setEnabled(visible); + m_pDropButton->setVisible(true); + m_pSaveButton->setVisible(true); + m_pSaveButton->setEnabled(true); m_pClearButton->setVisible(visible); } diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 6d36f494389..746f831950b 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -37,6 +37,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { public slots: void restoreSearch(const QString& text, QPointer pFeature = nullptr); void slotTextChanged(const QString& text); + void slotRestoreSaveButton(); private slots: void updateButtons(const QString& text); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index f26efb29bbd..a670c9e1871 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -78,7 +78,6 @@ WTrackTableView::WTrackTableView(QWidget * parent, connect(m_pCoverMenu, SIGNAL(reloadCoverArt()), this, SLOT(slotReloadCoverArt())); - // Disable editing //setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -105,6 +104,9 @@ WTrackTableView::WTrackTableView(QWidget * parent, QKeySequence(tr("ESC", "Focus")), this); connect(setFocusShortcut, SIGNAL(activated()), this, SLOT(setFocus())); + + QScrollBar* pScroll = verticalScrollBar(); + connect(pScroll, SIGNAL(valueChanged(int)), this, SIGNAL(tableChanged())); } WTrackTableView::~WTrackTableView() { @@ -1302,6 +1304,7 @@ void WTrackTableView::setSorting(bool sorting) { void WTrackTableView::setScrollBar(WMiniViewScrollBar *pScrollbar) { m_pScrollBar = pScrollbar; + connect(pScrollbar, SIGNAL(valueChanged(int)), this, SIGNAL(tableChanged())); setVerticalScrollBar(pScrollbar); } @@ -1577,6 +1580,8 @@ void WTrackTableView::doSortByColumn(int headerSection) { if (!m_pScrollBar.isNull()) { m_pScrollBar->setSortColumn(headerSection); } + + emit(tableChanged()); } void WTrackTableView::slotLockBpm() { diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index b8d202c3c09..ee72f81b1df 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -50,6 +50,9 @@ class WTrackTableView : public WLibraryTableView { void onSearchCleared() override; void slotSendToAutoDJ() override; void slotSendToAutoDJTop() override; + + signals: + void tableChanged(); private slots: void slotRemove(); From 49d196969365ee8f1b585496e947710ea717deeb Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 15:05:31 +0200 Subject: [PATCH 387/552] Fix StringHelper issue with correct sorting --- src/test/stringhelpertest.cpp | 6 ++++++ src/util/stringhelper.cpp | 27 +++++++++++++++++---------- src/util/stringhelper.h | 2 ++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/test/stringhelpertest.cpp b/src/test/stringhelpertest.cpp index afe4de2cbae..8c49ce0fc71 100644 --- a/src/test/stringhelpertest.cpp +++ b/src/test/stringhelpertest.cpp @@ -20,21 +20,27 @@ TEST(StringHelperTest, Null) { } TEST(StringHelperTest, Change) { + QLocale prev; + QLocale::setDefault(QLocale::Catalan); QString s1 = QString::fromUtf8("ç"); QString s2 = QString::fromUtf8("C"); QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); + QLocale::setDefault(prev); } TEST(StringHelperTest, RemoveAccent) { + QLocale prev; + QLocale::setDefault(QLocale::Catalan); QString s1 = QString::fromUtf8("à"); QString s2 = QString::fromUtf8("A"); QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); + QLocale::setDefault(prev); } TEST(StringHelperTest, Finnish) { diff --git a/src/util/stringhelper.cpp b/src/util/stringhelper.cpp index 09859cafd4c..55d0fd59a41 100644 --- a/src/util/stringhelper.cpp +++ b/src/util/stringhelper.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -18,19 +19,25 @@ QChar StringHelper::getFirstCharForGrouping(const QString& text) { } c = c.toUpper(); QString letter(c); - QString limmit("Z"); - if (QString::localeAwareCompare(limmit, letter) < 0) { - // The letter is above z so we must not change it this is due to - // Chinese letters or Finnish sorting. In Finnish the correct sorting - // is a-z, å, ä, ö and the user will expect these letters at the - // end and not like this a, ä, å, b-o, ö, p-z - return c; - } // This removes the accents of the characters - QString s1 = letter.normalized(QString::NormalizationForm_KD); + QString s1 = letter.normalized(QString::NormalizationForm_KD); + QString normChar(s1.at(0)); + QString s1_1 = normChar + "d"; + QString s1_2 = normChar + "f"; + QString letter_1 = s1 + "e"; if (s1.size() > 0) { - c = s1.at(0).toUpper(); + // We do the following checking: Ad < Äe < Af + // because locale aware compare takes in account the next character. + // This is due to Chinese letters or Finnish sorting. In Finnish the + // correct sorting is a-z, å, ä, ö and the user will expect these + // letters at the end and not like this a, ä, å, b-o, ö, p-z + + //qDebug() << "Checking " << s1_1 << "<" << letter_1 << "<" << s1_2; + if (s1_1.localeAwareCompare(letter_1) < 0 && + letter_1.localeAwareCompare(s1_2) < 0) { + c = s1.at(0).toUpper(); + } } return c; } diff --git a/src/util/stringhelper.h b/src/util/stringhelper.h index f014882cccc..cdca88edd1f 100644 --- a/src/util/stringhelper.h +++ b/src/util/stringhelper.h @@ -1,6 +1,8 @@ #ifndef STRINGHELPER_H #define STRINGHELPER_H +#include + class StringHelper { public: From 454b344bfe791d544ef5869e20aaed0e158c6a76 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 20:15:35 +0200 Subject: [PATCH 388/552] Fix create Show Text CO in Legacy skins --- src/skin/legacyskinparser.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 79cc02a9d99..f993752adec 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1312,23 +1312,25 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { } -QWidget *LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { +QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { // We must create both LibrarySidebarButtons and LibrarySidebarExpanded - // to allow support for old skins + // to allow support for old skins QFrame* pContainer = new QFrame(m_pParent); QHBoxLayout* pLayout = new QHBoxLayout(pContainer); pContainer->setLayout(pLayout); - QScrollArea* scroll = new QScrollArea(pContainer); - scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + // Create config object for WButtonBar + ConfigKey confKey("[Library]", "show_icon_text"); + controlFromConfigKey(confKey, true, nullptr); + m_pConfig->set(confKey, QString::number(1.0)); + + WVerticalScrollArea* scroll = new WVerticalScrollArea(pContainer); + pLayout->addWidget(scroll); - WButtonBar* pLibrarySidebar = new WButtonBar(pContainer); + WButtonBar* pLibrarySidebar = new WButtonBar(scroll); pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarWidget(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); - pLayout->addWidget(scroll); WBaseLibrary* pLibrarySidebarExpanded = new WBaseLibrary(pContainer); pLibrarySidebarExpanded->installEventFilter(m_pKeyboard); @@ -1337,7 +1339,7 @@ QWidget *LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { pLayout->addWidget(pLibrarySidebarExpanded); setupWidget(node, pLibrarySidebar); - commonWidgetSetup(node, pLibrarySidebarExpanded, false); + commonWidgetSetup(node, pLibrarySidebarExpanded, false); return pContainer; } From f29b2819ab714df57d4160de4e5cb5084c4063e8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 20:25:08 +0200 Subject: [PATCH 389/552] Add tooltip to BreadCrumb / SearchBar for the shrinked pane case --- src/widget/wlibrarybreadcrumb.cpp | 1 + src/widget/wsearchlineedit.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index ec97532b0b0..b4b0b483ee5 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -53,6 +53,7 @@ void WLibraryBreadCrumb::resizeEvent(QResizeEvent* pEvent) { void WLibraryBreadCrumb::setText(const QString &text) { m_longText = text; + setToolTip(m_longText); refreshWidth(); } diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 2ba94302b65..07194db34ac 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -323,6 +323,7 @@ void WSearchLineEdit::restoreQuery() { } void WSearchLineEdit::slotTextChanged(const QString& text) { + setToolTip(text); if (text.isEmpty()) { triggerSearch(); emit(searchCleared()); From 81378c2851db4de6d6e4863bdf0cd26cb7f72b58 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 20:58:51 +0200 Subject: [PATCH 390/552] Fix icons in LibraryTree and remove "Show All" breadcrumb In Library Tree all album icons have now a default icon --- src/library/libraryfoldermodel.cpp | 30 +++++++------ src/library/librarytreemodel.cpp | 67 +++++++++++++++++------------- 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index 7eeef7e9e9d..9c13ab99d72 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -40,24 +40,30 @@ QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { return m_folderRecursive; } - if (role != TreeItemModel::RoleQuery) { - return TreeItemModel::data(index, role); - } - - // Role is Get query TreeItem* pTree = static_cast(index.internalPointer()); DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { - return QVariant(); + return TreeItemModel::data(index, role); } - - // User has clicked the show all item - if (pTree == m_pShowAllItem) { - return ""; + + if (role == TreeItemModel::RoleBreadCrumb) { + if (pTree == m_pShowAllItem) { + return m_pFeature->title(); + } else { + return TreeItemModel::data(index, role); + } } - const QString param("%1:=\"%2\""); + if (role == TreeItemModel::RoleQuery) { + // User has clicked the show all item + if (pTree == m_pShowAllItem) { + return ""; + } + + const QString param("%1:=\"%2\""); + return param.arg("folder", pTree->dataPath().toString()); + } - return param.arg("folder", pTree->dataPath().toString()); + return TreeItemModel::data(index, role); } void LibraryFolderModel::reloadTree() { diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 1a2dae29051..8b809abf754 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -43,49 +43,59 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, reloadTree(); } + QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { - if (role == TreeItemModel::RoleSettings) { return m_sortOrder; } - // The decoration role contains the icon in QTreeView - if (role != Qt::DecorationRole && role != TreeItemModel::RoleQuery) { + TreeItem* pTree = static_cast(index.internalPointer()); + DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { return TreeItemModel::data(index, role); } - - TreeItem* pTree = static_cast(index.internalPointer()); - DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { - return QVariant(); + if (role == TreeItemModel::RoleBreadCrumb) { + if (pTree == m_pLibraryItem) { + return m_pFeature->title(); + } else { + return TreeItemModel::data(index, role); + } } + if (role == TreeItemModel::RoleQuery) { return getQuery(pTree); } - // Role is decoration role, we need to show the cover art - const CoverInfo& info = pTree->getCoverInfo(); - - // Currently we only support this two types of cover info - if (info.type != CoverInfo::METADATA && info.type != CoverInfo::FILE) { - return TreeItemModel::data(index, role); + // The decoration role contains the icon in QTreeView + if (role == Qt::DecorationRole) { + // Role is decoration role, we need to show the cover art + const CoverInfo& info = pTree->getCoverInfo(); + + // Currently we only support this two types of cover info + if (info.type != CoverInfo::METADATA && info.type != CoverInfo::FILE) { + return TreeItemModel::data(index, role); + } + + CoverArtCache* pCache = CoverArtCache::instance(); + // Set a maximum size of 32px to not use many cache + QPixmap pixmap = pCache->requestCover(info, this, 32, false, true); + + if (pixmap.isNull()) { + // The icon is not in the cache so we need to wait until the + // coverFound slot is called. Since the data function is const + // and we cannot change that we use m_hashToIndex in an anonymous + // namespace to store the future value that we will get + m_hashToIndex.insert(info.type, index); + + // Return a temporary icon + return QIcon(":/images/library/cover_default.png"); + } else { + // Good luck icon found + return QIcon(pixmap); + } } - CoverArtCache* pCache = CoverArtCache::instance(); - // Set a maximum size of 32px to not use many cache - QPixmap pixmap = pCache->requestCover(info, this, 32, false, true); - - if (pixmap.isNull()) { - // The icon is not in the cache so we need to wait until the - // coverFound slot is called. Since the data function is const - // and we cannot change that we use m_hashToIndex in an anonymous - // namespace to store the future value that we will get - m_hashToIndex.insert(info.type, index); - } else { - // Good luck icon found - return QIcon(pixmap); - } - return QVariant(); + return TreeItemModel::data(index, role); } bool LibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { @@ -301,4 +311,5 @@ void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, c.source = static_cast(source); c.type = static_cast(type); pTree->setCoverInfo(c); + pTree->setIcon(QIcon(":/images/library/cover_default.png")); } From 89c6dd10a5e5c04d5b206cff07f9b01403ff88a4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 14 Aug 2016 22:43:28 +0200 Subject: [PATCH 391/552] Change breadcrumb / search bar position improve Deere skin colors too --- res/skins/Deere/library.xml | 12 +++++------ res/skins/Deere/style.qss | 37 +++++++++++++-------------------- res/skins/LateNight/library.xml | 12 +++++------ res/skins/LateNight/style.qss | 21 ++++++++++++++----- res/skins/Shade/skin.xml | 12 +++++------ src/widget/wsearchlineedit.cpp | 33 ++++++++++++++++++----------- 6 files changed, 70 insertions(+), 57 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index e572a467fd6..0079c568fc9 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -175,13 +175,13 @@ vertical - - 1 - LibraryBreadCrumb 1 + + 1 + 1 @@ -192,13 +192,13 @@ vertical - - 2 - LibraryBreadCrumb 2 + + 2 + 2 diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 76fab25076a..d1efff029a6 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -1,3 +1,5 @@ + + /* Deere , Skin for Mixxx 1.12.x www.mixxx.org @@ -123,7 +125,7 @@ QTableView { color: #d2d2d2; background-color: #1F1F1F; alternate-background-color: #1A1A1A; - selection-background-color: #006596; + selection-background-color: #006596 !important; selection-color: #D6D6D6; border: 1px solid #1A1A1A; gridline-color: red; @@ -144,13 +146,13 @@ QTableView::indicator:unchecked { } WBaseLibrary[showFocus="0"] { - padding: 1px 0 0 0; + padding: 2px 0 0 0; border: none; } WBaseLibrary[showFocus="1"] { - padding: 1px 1px 1px 1px; - border-top: 1px solid #DE6B0F; + padding: 2px 0 0 0; + border-top: 2px solid #0080BE; } /* BPM lock icon in the library "BPM" column. */ @@ -217,15 +219,13 @@ WBaseLibrary QLabel { #LibraryCoverArtSplitter QTabBar::tab { padding: 4px; border: none; - color: #cfb32c; + color: #006596; background-color: #191919; border-top-left-radius: 2px; border-top-right-radius: 2px; color: #D2D2D2; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #4B4B4B, - stop: 1 #4B4B4B); + background-color: #4B4B4B; border: 0px solid #4B4B4B; outline: none; } @@ -305,7 +305,7 @@ QHeaderView::down-arrow { /* library search bar */ WSearchLineEdit { - margin: 0px 0px 0px 1px; + margin: 0px 0px 5px 0px; padding: 2px; border: 1px solid #1A1A1A; background-color: #4B4B4B; @@ -313,9 +313,8 @@ WSearchLineEdit { } WSearchLineEdit:focus { - margin: 2px 0px 0px 1px; padding: 2px; - border: 1px solid #FF6600; + border: 2px solid #006596; background-color: #4B4B4B; color: #D6D6D6; selection-color: #222222; @@ -464,27 +463,21 @@ WBaseLibrary QPushButton:hover { WBaseLibrary QPushButton:checked { /* checkbuttons in active state */ color: #FDFDFD; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #006596, - stop: 1 #006596); + background-color: #006596; border: 0px solid #006596; } WBaseLibrary QPushButton:checked:hover { /* checkbuttons hovered over in "active" state */ color: #FDFDFD; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #0080BE, - stop: 1 #0080BE); + background-color: #0080BE; border: 0px solid #0080BE; } WBaseLibrary QPushButton:pressed { /* pushbuttons in "down" state */ color: #FDFDFD; - background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #006596, - stop: 1 #006596); + background-color: #006596; border: 0px solid #006596; } @@ -730,13 +723,13 @@ WWidget { /* Start editable widgets in decks */ #BpmEditRow:hover, #KeyEditRow:hover, #PositionGutter:hover, #StarratingGutter:hover { /* emphasize editable widgets on hover */ - border: 1px solid #FF6600; + border: 1px solid #0080BE; background-color: rgba(255, 102, 0, 128); } #BpmEditRowExpanded, #KeyEditRowExpanded { /* emphasize active widget */ - border: 1px solid #FF6600; + border: 1px solid #006596; background: rgba(255, 102, 0, 64); color: #D6D6D6; } diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index aeedf94cc3d..8fbf1419962 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -55,12 +55,12 @@ vertical - - 1 - 1 + + 1 + 1 @@ -69,12 +69,12 @@ vertical - - 2 - 2 + + 2 + 2 diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 190eaf5bc99..4280c097782 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1366,8 +1366,19 @@ QSpinBox:editable { background: transparent; color: #cfb32c; } QSpinBox { min-height: 20px; max-height: 20px;min-width: 40px; max-width: 40px;} /* library search bar */ -WSearchLineEdit { padding: 2px; border: 1px solid #656565; background: #181818; color: #cfb32c; } -WSearchLineEdit:focus { padding: 2px; border: 2px solid #FF6600; background: #0f0f0f; color: #eece33;} +WSearchLineEdit { + margin-bottom: 2px; + padding: 2px; + border: 1px solid #656565; + background: #181818; + color: #cfb32c; +} + +WSearchLineEdit:focus { + border: 2px solid #FF6600; + background: #0f0f0f; + color: #eece33; +} /* cover art */ WCoverArt { background: transparent; color: #ACACAC; } @@ -1420,11 +1431,11 @@ QTreeView::item:selected { } WLibrary[showFocus="0"] { - padding: 1px 0 0 0; + padding: 2px 0 0 0; border: none; } WLibrary[showFocus="1"] { - padding: 1px 0 0 0; - border-top: 1px solid #FF7100 !important; + padding: 2px 0 0 0; + border-top: 2px solid #FF7100 !important; } \ No newline at end of file diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 010d9e4e1ec..887a80f9bc7 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -860,12 +860,12 @@ vertical - - 1 - 1 + + 1 + 1 @@ -874,12 +874,12 @@ vertical - - 2 - 2 + + 2 + 2 diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 07194db34ac..f4fd7b5ddbf 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -8,6 +8,7 @@ #include #include #include +#include WSearchLineEdit::WSearchLineEdit(QWidget* pParent) : QLineEdit(pParent), @@ -124,29 +125,37 @@ void WSearchLineEdit::slotRestoreSaveButton() { void WSearchLineEdit::resizeEvent(QResizeEvent* e) { QLineEdit::resizeEvent(e); - int left, top, right, bottom; - getContentsMargins(&left, &top, &right, &bottom); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - const int size = fontMetrics().height(); - QSize iconSize(size, size); + QStyleOption option; + option.initFrom(this); + const QRect contentsRect = + style()->subElementRect(QStyle::SE_LineEditContents, &option, this); + + const int Ydeviation = contentsRect.top(); + const int height = contentsRect.height(); + const int fontHeight = fontMetrics().height(); + QSize iconSize(fontHeight, fontHeight); + m_pDropButton->resize(iconSize); + m_pSaveButton->resize(iconSize); + m_pClearButton->resize(iconSize); + m_pDropButton->setIconSize(iconSize); m_pSaveButton->setIconSize(iconSize); m_pClearButton->setIconSize(iconSize); - const QSize sizeDrop = m_pDropButton->sizeHint(); - const QSize sizeSave = m_pSaveButton->sizeHint(); - const QSize sizeClear = m_pClearButton->sizeHint(); - const int space = 1; // 1px of space between items + const QSize sizeDrop = m_pDropButton->size(); + const QSize sizeSave = m_pSaveButton->size(); + const QSize sizeClear = m_pClearButton->size(); + const int space = 2; // 1px of space between items int posXDrop = frameWidth + 1; int posXSave = posXDrop + sizeDrop.width() + space; int posXClear = posXSave + sizeSave.width() + space; - int posYDrop = (height() - sizeDrop.height())/2; - int posYSave = (height() - sizeSave.height())/2; - int posYClear = (height() - sizeClear.height())/2; + int posYDrop = (height - sizeDrop.height())/2 + Ydeviation; + int posYSave = (height - sizeSave.height())/2 + Ydeviation; + int posYClear = (height - sizeClear.height())/2 + Ydeviation; if (layoutDirection() == Qt::LeftToRight) { posXDrop += sizeDrop.width(); From 891e75178b6d6b7f819051f6dae7bbcb23696125 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 15 Aug 2016 21:51:18 +0200 Subject: [PATCH 392/552] Allow adding tracks to empty area of playlists' tree --- src/library/baseplaylistfeature.cpp | 71 ++++++++++++++++------------- src/library/baseplaylistfeature.h | 1 + src/library/playlistfeature.cpp | 12 ++++- src/library/treeitemmodel.cpp | 49 ++++++++------------ src/library/treeitemmodel.h | 3 ++ 5 files changed, 74 insertions(+), 62 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 0af4f8436a9..3825478c0e5 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -296,35 +296,11 @@ void BasePlaylistFeature::slotCreatePlaylist() { return; } - QString name; - bool validNameGiven = false; - - while (!validNameGiven) { - bool ok = false; - name = QInputDialog::getText(NULL, - tr("Create New Playlist"), - tr("Enter name for new playlist:"), - QLineEdit::Normal, - tr("New Playlist"), - &ok).trimmed(); - if (!ok) - return; - - int existingId = m_playlistDao.getPlaylistIdFromName(name); - - if (existingId != -1) { - QMessageBox::warning(NULL, - tr("Playlist Creation Failed"), - tr("A playlist by that name already exists.")); - } else if (name.isEmpty()) { - QMessageBox::warning(NULL, - tr("Playlist Creation Failed"), - tr("A playlist cannot have a blank name.")); - } else { - validNameGiven = true; - } + QString name = getValidPlaylistName(); + if (name.isNull()) { + // The user has canceled + return; } - int playlistId = m_playlistDao.createPlaylist(name); if (playlistId != -1) { @@ -611,10 +587,43 @@ void BasePlaylistFeature::addToAutoDJ(bool bTop) { } } +QString BasePlaylistFeature::getValidPlaylistName() const { + QString name; + bool validNameGiven = false; + + while (!validNameGiven) { + bool ok = false; + name = QInputDialog::getText(nullptr, + tr("Create New Playlist"), + tr("Enter name for new playlist:"), + QLineEdit::Normal, + tr("New Playlist"), + &ok).trimmed(); + if (!ok) { + // Cancel button clicked + return QString(); + } + + int existingId = m_playlistDao.getPlaylistIdFromName(name); + + if (existingId != -1) { + QMessageBox::warning(NULL, + tr("Playlist Creation Failed"), + tr("A playlist by that name already exists.")); + } else if (name.isEmpty()) { + QMessageBox::warning(NULL, + tr("Playlist Creation Failed"), + tr("A playlist cannot have a blank name.")); + } else { + validNameGiven = true; + } + } + return name; +} + QSet BasePlaylistFeature::playlistIdsFromIndex(const QModelIndex &index) const { - QString dataPath = index.data(TreeItemModel::RoleDataPath).toString(); bool ok = false; - int playlistId = dataPath.toInt(&ok); + int playlistId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); if (!ok) { return QSet(); } @@ -627,7 +636,7 @@ int BasePlaylistFeature::playlistIdFromIndex(const QModelIndex& index) const { QSet playlistIds = playlistIdsFromIndex(index); if (playlistIds.empty() || playlistIds.size() > 1) { return -1; - } + } return *playlistIds.begin(); } diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 8c0a0f53a6c..6a7357055e7 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -73,6 +73,7 @@ class BasePlaylistFeature : public LibraryFeature { virtual void buildPlaylistList() = 0; virtual void decorateChild(TreeItem *pChild, int playlist_id) = 0; virtual void addToAutoDJ(bool bTop); + QString getValidPlaylistName() const; QPointer getPlaylistTableModel(int paneId); virtual PlaylistTableModel* constructTableModel() = 0; diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index a343843178a..18f6377726b 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -120,11 +120,21 @@ bool PlaylistFeature::dropAcceptChild(const QModelIndex& index, QList urls } } + // Request a name for the playlist if it's a new playlist + if (playlistId < 0) { + QString name = getValidPlaylistName(); + if (name.isNull()) { + // The user has canceled + return false; + } + playlistId = m_playlistDao.createPlaylist(name); + } + // Return whether appendTracksToPlaylist succeeded. return m_playlistDao.appendTracksToPlaylist(trackIds, playlistId); } -bool PlaylistFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { +bool PlaylistFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { int playlistId = playlistIdFromIndex(index); bool locked = m_playlistDao.isPlaylistLocked(playlistId); diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 14eac971089..02d114c4979 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -248,39 +248,28 @@ void TreeItemModel::reloadTree() { bool TreeItemModel::dropAccept(const QModelIndex& index, QList urls, QObject* pSource) { //qDebug() << "TreeItemModel::dropAccept() index=" << index << urls; - bool result = false; - if (index.isValid()) { - LibraryFeature* pFeature; - if (index.internalPointer() == this) { - pFeature = m_pRootItem->getFeature(); - } else { - TreeItem* treeItem = (TreeItem*) index.internalPointer(); - if (!treeItem) { - return false; - } - pFeature = treeItem->getFeature(); - } - - result = pFeature->dropAcceptChild(index, urls, pSource); + LibraryFeature* pFeature = getFeatureFromIndex(index); + if (pFeature == nullptr) { + return false; } - return result; + + return pFeature->dropAcceptChild(index, urls, pSource); } bool TreeItemModel::dragMoveAccept(const QModelIndex& index, QUrl url) { - //qDebug() << "TreeItemModel::dragMoveAccept() index=" << index << url; - bool result = false; - if (index.isValid()) { - LibraryFeature* pFeature; - if (index.internalPointer() == this) { - pFeature = m_pRootItem->getFeature(); - } else { - TreeItem* treeItem = (TreeItem*) index.internalPointer(); - if (treeItem) { - pFeature = treeItem->getFeature(); - } - } - - result = pFeature->dragMoveAcceptChild(index, url); + //qDebug() << "TreeItemModel::dragMoveAccept() index=" << index << url; + LibraryFeature* pFeature = getFeatureFromIndex(index); + if (pFeature == nullptr) { + return false; + } + + return pFeature->dragMoveAcceptChild(index, url); +} + +LibraryFeature* TreeItemModel::getFeatureFromIndex(const QModelIndex& index) const { + TreeItem* pTree = getItem(index); + if (pTree == nullptr) { + return nullptr; } - return result; + return pTree->getFeature(); } diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index d71ae3331e7..b2a593f8319 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -8,6 +8,7 @@ #include class TreeItem; +class LibraryFeature; class TreeItemModel : public QAbstractItemModel { Q_OBJECT @@ -53,6 +54,8 @@ class TreeItemModel : public QAbstractItemModel { void triggerRepaint(); protected: + LibraryFeature* getFeatureFromIndex(const QModelIndex& index) const; + TreeItem* m_pRootItem; }; From bcaf892eb3ac2d296866bd2aae6cb9110a7b3925 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 09:34:52 +0200 Subject: [PATCH 393/552] Allow adding tracks to empty area of crates' tree --- src/library/cratefeature.cpp | 92 ++++++++++++++++++++------------- src/library/cratefeature.h | 1 + src/library/playlistfeature.cpp | 5 ++ 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 26696d1da79..aaf3bb32d9f 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -155,9 +155,7 @@ bool CrateFeature::dragMoveAccept(QUrl url) { bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource) { int crateId = crateIdFromIndex(index); - if (crateId == -1) { - return false; - } + QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); QList trackIds; if (pSource) { @@ -167,23 +165,35 @@ bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList urls, // Adds track, does not insert duplicates, handles unremoving logic. trackIds = m_pTrackCollection->getTrackDAO().addMultipleTracks(files, true); } - qDebug() << "CrateFeature::dropAcceptChild adding tracks" - << trackIds.size() << " to crate "<< crateId; + //qDebug() << "CrateFeature::dropAcceptChild adding tracks" + // << trackIds.size() << " to crate "<< crateId; // remove tracks that could not be added for (int trackIdIndex = 0; trackIdIndex < trackIds.size(); ++trackIdIndex) { if (!trackIds.at(trackIdIndex).isValid()) { trackIds.removeAt(trackIdIndex--); } } + + // Request a name for the crate if it's a new crate + if (crateId < 0) { + QString name = getValidCrateName(); + if (name.isNull()) { + return false; + } + + crateId = m_crateDao.createCrate(name); + // An error happened + if (crateId < 0) { + return false; + } + } + m_crateDao.addTracksToCrate(crateId, &trackIds); return true; } bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { int crateId = crateIdFromIndex(index); - if (crateId == -1) { - return false; - } bool locked = m_crateDao.isCrateLocked(crateId); bool formatSupported = SoundSourceProxy::isUrlSupported(url) || Parser::isPlaylistFilenameSupported(url.toLocalFile()); @@ -320,33 +330,10 @@ void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) } void CrateFeature::slotCreateCrate() { - QString name; - bool validNameGiven = false; - - while (!validNameGiven) { - bool ok = false; - name = QInputDialog::getText(NULL, - tr("Create New Crate"), - tr("Enter name for new crate:"), - QLineEdit::Normal, tr("New Crate"), - &ok).trimmed(); - - if (!ok) - return; - - int existingId = m_crateDao.getCrateIdByName(name); - - if (existingId != -1) { - QMessageBox::warning(NULL, - tr("Creating Crate Failed"), - tr("A crate by that name already exists.")); - } else if (name.isEmpty()) { - QMessageBox::warning(NULL, - tr("Creating Crate Failed"), - tr("A crate cannot have a blank name.")); - } else { - validNameGiven = true; - } + QString name = getValidCrateName(); + if (name.isNull()) { + // The user canceled + return; } int crateId = m_crateDao.createCrate(name); @@ -354,7 +341,7 @@ void CrateFeature::slotCreateCrate() { activateCrate(crateId); } else { qDebug() << "Error creating crate with name " << name; - QMessageBox::warning(NULL, + QMessageBox::warning(nullptr, tr("Creating Crate Failed"), tr("An unknown error occurred while creating crate: ") + name); @@ -899,6 +886,39 @@ void CrateFeature::slotResetSelectedTrack() { slotTrackSelected(TrackPointer()); } +QString CrateFeature::getValidCrateName() { + QString name; + bool validNameGiven = false; + + while (!validNameGiven) { + bool ok = false; + name = QInputDialog::getText(nullptr, + tr("Create New Crate"), + tr("Enter name for new crate:"), + QLineEdit::Normal, tr("New Crate"), + &ok).trimmed(); + + if (!ok) { + return QString(); + } + + int existingId = m_crateDao.getCrateIdByName(name); + + if (existingId != -1) { + QMessageBox::warning(nullptr, + tr("Creating Crate Failed"), + tr("A crate by that name already exists.")); + } else if (name.isEmpty()) { + QMessageBox::warning(nullptr, + tr("Creating Crate Failed"), + tr("A crate cannot have a blank name.")); + } else { + validNameGiven = true; + } + } + return name; +} + QModelIndex CrateFeature::indexFromCrateId(int crateId) { int row = 0; for (QList >::const_iterator it = m_crateList.begin(); diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index decb15a68d1..ed4b3c203a4 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -79,6 +79,7 @@ class CrateFeature : public LibraryFeature { void slotResetSelectedTrack(); private: + QString getValidCrateName(); QString getRootViewHtml() const; QModelIndex constructChildModel(int selected_id); void updateChildModel(int selected_id); diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 18f6377726b..29e7e03e312 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -127,7 +127,12 @@ bool PlaylistFeature::dropAcceptChild(const QModelIndex& index, QList urls // The user has canceled return false; } + playlistId = m_playlistDao.createPlaylist(name); + // An error happened + if (playlistId < 0) { + return false; + } } // Return whether appendTracksToPlaylist succeeded. From 8b1379cebb19b25d77150b9dc8fb84a52385e170 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 10:44:12 +0200 Subject: [PATCH 394/552] Fix playlist items not get updated when adding tracks Improved some code too --- src/library/baseplaylistfeature.cpp | 57 +++++++++++------------ src/library/baseplaylistfeature.h | 18 +++++++- src/library/cratefeature.h | 22 ++++----- src/library/historyfeature.cpp | 2 +- src/library/playlistfeature.cpp | 70 ++++++++++++----------------- src/library/treeitem.cpp | 19 +++++--- src/library/treeitem.h | 6 ++- 7 files changed, 103 insertions(+), 91 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 3825478c0e5..07b4bd79e53 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -689,42 +689,40 @@ void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) { * we require the sidebar model not to reset. * This method queries the database and does dynamic insertion */ -QModelIndex BasePlaylistFeature::constructChildModel(int selected_id) { +QModelIndex BasePlaylistFeature::constructChildModel(int selectedId) { buildPlaylistList(); + m_childModel->setRootItem(new TreeItem("$root", "$root", this, nullptr)); QList data_list; - int selected_row = -1; + int selectedRow = -1; // Access the invisible root item TreeItem* root = m_childModel->getItem(QModelIndex()); int row = 0; - for (const QPair& p : m_playlistList) { - int playlist_id = p.first; - QString playlist_name = p.second; - - if (selected_id == playlist_id) { + for (const PlaylistItem& p : m_playlistList) { + if (selectedId == p.id) { // save index for selection - selected_row = row; + selectedRow = row; } // Create the TreeItem whose parent is the invisible root item - TreeItem* item = new TreeItem(playlist_name, QString::number(playlist_id), this, root); - item->setBold(m_playlistsSelectedTrackIsIn.contains(playlist_id)); + TreeItem* item = new TreeItem(p.name, QString::number(p.id), this, root); + item->setBold(m_playlistsSelectedTrackIsIn.contains(p.id)); - decorateChild(item, playlist_id); + decorateChild(item, p.id); data_list.append(item); ++row; } // Append all the newly created TreeItems in a dynamic way to the childmodel m_childModel->insertRows(data_list, 0, m_playlistList.size()); - return m_childModel->index(selected_row, 0); + return m_childModel->index(selectedRow, 0); } -void BasePlaylistFeature::updateChildModel(int selected_id) { +void BasePlaylistFeature::updateChildModel(int selectedId) { buildPlaylistList(); - QModelIndex index = indexFromPlaylistId(selected_id); + QModelIndex index = indexFromPlaylistId(selectedId); if (!index.isValid()) { return; } @@ -733,19 +731,23 @@ void BasePlaylistFeature::updateChildModel(int selected_id) { DEBUG_ASSERT_AND_HANDLE(item) { return; } - decorateChild(item, selected_id); + // Update the name + int pos = m_playlistList.indexOf(PlaylistItem(selectedId)); + if (pos < 0) { + return; + } + item->setData(m_playlistList[pos].name); + + decorateChild(item, selectedId); } QModelIndex BasePlaylistFeature::indexFromPlaylistId(int playlistId) const { - int row = 0; - for (QList >::const_iterator it = m_playlistList.begin(); - it != m_playlistList.end(); ++it, ++row) { - int current_id = it->first; - if (playlistId == current_id) { - return m_childModel->index(row, 0); - } + int row = m_playlistList.indexOf(PlaylistItem(playlistId)); + if (row < 0) { + return QModelIndex(); } - return QModelIndex(); + + return m_childModel->index(row, 0); } void BasePlaylistFeature::slotTrackSelected(TrackPointer pTrack) { @@ -764,16 +766,15 @@ void BasePlaylistFeature::slotTrackSelected(TrackPointer pTrack) { // Set all playlists the track is in bold (or if there is no track selected, // clear all the bolding). int row = 0; - for (QList >::const_iterator it = m_playlistList.begin(); - it != m_playlistList.end(); ++it, ++row) { + for (const PlaylistItem& p : m_playlistList) { TreeItem* playlist = rootItem->child(row); if (playlist == nullptr) { continue; } - - int playlistId = it->first; - bool shouldBold = m_playlistsSelectedTrackIsIn.contains(playlistId); + + bool shouldBold = m_playlistsSelectedTrackIsIn.contains(p.id); playlist->setBold(shouldBold); + ++row; } m_childModel->triggerRepaint(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 6a7357055e7..a5da9bafc51 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -68,8 +68,22 @@ class BasePlaylistFeature : public LibraryFeature { void slotAnalyzePlaylist(); protected: + + struct PlaylistItem { + PlaylistItem() : id(-1) {} + PlaylistItem(int id) : id(id) {} + PlaylistItem(int id, QString name) : id(id), name(name) {} + + int id; + QString name; + + bool operator==(const PlaylistItem& other) { + return this->id == other.id; + } + }; + virtual QModelIndex constructChildModel(int selected_id); - virtual void updateChildModel(int selected_id); + virtual void updateChildModel(int selectedId); virtual void buildPlaylistList() = 0; virtual void decorateChild(TreeItem *pChild, int playlist_id) = 0; virtual void addToAutoDJ(bool bTop); @@ -101,7 +115,7 @@ class BasePlaylistFeature : public LibraryFeature { QAction *m_pExportTrackFilesAction; QAction *m_pDuplicatePlaylistAction; QAction *m_pAnalyzePlaylistAction; - QList > m_playlistList; + QList m_playlistList; QModelIndex m_lastRightClickedIndex; TreeItemModel* m_childModel; TrackPointer m_pSelectedTrack; diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index ed4b3c203a4..5ef25aac3e6 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -94,17 +94,17 @@ class CrateFeature : public LibraryFeature { TrackCollection* m_pTrackCollection; CrateDAO& m_crateDao; - QAction *m_pCreateCrateAction; - QAction *m_pDeleteCrateAction; - QAction *m_pRenameCrateAction; - QAction *m_pLockCrateAction; - QAction *m_pDuplicateCrateAction; - QAction *m_pAutoDjTrackSource; - QAction *m_pImportPlaylistAction; - QAction *m_pCreateImportPlaylistAction; - QAction *m_pExportPlaylistAction; - QAction *m_pExportTrackFilesAction; - QAction *m_pAnalyzeCrateAction; + QAction* m_pCreateCrateAction; + QAction* m_pDeleteCrateAction; + QAction* m_pRenameCrateAction; + QAction* m_pLockCrateAction; + QAction* m_pDuplicateCrateAction; + QAction* m_pAutoDjTrackSource; + QAction* m_pImportPlaylistAction; + QAction* m_pCreateImportPlaylistAction; + QAction* m_pExportPlaylistAction; + QAction* m_pExportTrackFilesAction; + QAction* m_pAnalyzeCrateAction; QList > m_crateList; QHash > m_crateTableModel; CrateTableModel* m_pCrateTableModel; diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 71cacabf6cb..b1b72eacc04 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -126,7 +126,7 @@ void HistoryFeature::buildPlaylistList() { while (query.next()) { int id = query.value(iId).toInt(); QString name = query.value(iName).toString(); - m_playlistList.append(qMakePair(id, name)); + m_playlistList << PlaylistItem(id, name); } } diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 29e7e03e312..ca9bff28034 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -151,54 +151,42 @@ bool PlaylistFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { void PlaylistFeature::buildPlaylistList() { m_playlistList.clear(); - QString queryString = QString( - "CREATE TEMPORARY VIEW IF NOT EXISTS PlaylistsCountsDurations " - "AS SELECT " - " Playlists.id as id, " - " Playlists.name as name, " - " COUNT(library.id) as count, " - " SUM(library.duration) as durationSeconds " - "FROM Playlists " - "LEFT JOIN PlaylistTracks ON PlaylistTracks.playlist_id = Playlists.id " - "LEFT JOIN library ON PlaylistTracks.track_id = library.id " - "WHERE Playlists.hidden = 0 " - "GROUP BY Playlists.id;"); + QString queryString = "SELECT " + "Playlists.id as id, " + "Playlists.name as name, " + "COUNT(library.id) as count, " + "SUM(library.duration) as durationSeconds " + "FROM Playlists " + "LEFT JOIN PlaylistTracks ON PlaylistTracks.playlist_id = Playlists.id " + "LEFT JOIN library ON PlaylistTracks.track_id = library.id " + "WHERE Playlists.hidden = 0 " + "GROUP BY Playlists.id " + "ORDER BY name"; QSqlQuery query(m_pTrackCollection->getDatabase()); if (!query.exec(queryString)) { LOG_FAILED_QUERY(query); } - - // Setup the sidebar playlist model - QSqlTableModel playlistTableModel(this, m_pTrackCollection->getDatabase()); - playlistTableModel.setTable("PlaylistsCountsDurations"); - playlistTableModel.setSort(playlistTableModel.fieldIndex("name"), - Qt::AscendingOrder); - playlistTableModel.select(); - while (playlistTableModel.canFetchMore()) { - playlistTableModel.fetchMore(); - } - QSqlRecord record = playlistTableModel.record(); - int nameColumn = record.indexOf("name"); - int idColumn = record.indexOf("id"); - int countColumn = record.indexOf("count"); - int durationColumn = record.indexOf("durationSeconds"); - - for (int row = 0; row < playlistTableModel.rowCount(); ++row) { - int id = playlistTableModel.data( - playlistTableModel.index(row, idColumn)).toInt(); - QString name = playlistTableModel.data( - playlistTableModel.index(row, nameColumn)).toString(); - int count = playlistTableModel.data( - playlistTableModel.index(row, countColumn)).toInt(); - int duration = playlistTableModel.data( - playlistTableModel.index(row, durationColumn)).toInt(); - m_playlistList.append(qMakePair(id, QString("%1 (%2) %3") - .arg(name, QString::number(count), - mixxx::Duration::formatSeconds(duration)))); + + QSqlRecord record = query.record(); + int iName = record.indexOf("name"); + int iId = record.indexOf("id"); + int iCount = record.indexOf("count"); + int iDuration = record.indexOf("durationSeconds"); + + while (query.next()) { + int id = query.value(iId).toInt(); + QString name = query.value(iName).toString(); + int count = query.value(iCount).toInt(); + int duration = query.value(iDuration).toInt(); + QString itemName = "%1 (%2) %3"; + itemName = itemName.arg(name, + QString::number(count), + mixxx::Duration::formatSeconds(duration)); + m_playlistList << PlaylistItem(id, itemName); } } -void PlaylistFeature::decorateChild(TreeItem* item, int playlist_id) { +void PlaylistFeature::decorateChild(TreeItem* item, int playlist_id) { if (m_playlistDao.isPlaylistLocked(playlist_id)) { item->setIcon(QIcon(":/images/library/ic_library_locked.png")); } else { diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index 96ab76a12af..a3ff61a528e 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -31,10 +31,10 @@ * - cratefeature.cpp * - *feature.cpp */ -TreeItem::TreeItem(const QVariant& data, const QVariant& data_path, +TreeItem::TreeItem(const QVariant& data, const QVariant& dataPath, LibraryFeature* pFeature, TreeItem* parent) : m_data(data), - m_dataPath(data_path), + m_dataPath(dataPath), m_pFeature(pFeature), m_bold(false), m_divider(false), @@ -182,10 +182,17 @@ bool TreeItem::removeChildren(int position, int count) { return true; } -bool TreeItem::setData(const QVariant& data, const QVariant& data_path) { - m_data = data.toString(); - m_dataPath = data_path.toString(); - return true; +void TreeItem::setData(const QVariant& data) { + m_data = data; +} + +void TreeItem::setData(const QVariant& data, const QVariant& dataPath) { + m_data = data; + m_dataPath = dataPath; +} + +void TreeItem::setDataPath(const QVariant& dataPath) { + m_dataPath = dataPath; } QIcon TreeItem::getIcon() const { diff --git a/src/library/treeitem.h b/src/library/treeitem.h index 5a7d51b0aeb..d77baaed4b7 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -17,7 +17,7 @@ class TreeItem { public: TreeItem(); //creates an invisible root item for the tree TreeItem(const QVariant &data, - const QVariant &data_path, + const QVariant &dataPath, LibraryFeature* pFeature, TreeItem* parent); TreeItem(LibraryFeature* pFeature); @@ -44,7 +44,9 @@ class TreeItem { bool removeChildren(int position, int count); /** sets data **/ - bool setData(const QVariant& data, const QVariant& data_path); + void setData(const QVariant& data); + void setData(const QVariant& data, const QVariant& dataPath); + void setDataPath(const QVariant& dataPath); /** simple name of the playlist **/ QVariant data() const; /** Full path of the playlist **/ From 22ab4197600e624b47cae1fca3770b380bba1cc4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 11:45:04 +0200 Subject: [PATCH 395/552] Fix orange colors in Deere skin --- res/skins/Deere/image/style_sort_down.svg | 63 +++++++++++++++++++++-- res/skins/Deere/image/style_sort_up.svg | 63 +++++++++++++++++++++-- res/skins/Deere/style.qss | 10 ++-- 3 files changed, 124 insertions(+), 12 deletions(-) diff --git a/res/skins/Deere/image/style_sort_down.svg b/res/skins/Deere/image/style_sort_down.svg index dcfc197e736..96d0b84931d 100644 --- a/res/skins/Deere/image/style_sort_down.svg +++ b/res/skins/Deere/image/style_sort_down.svg @@ -1,5 +1,60 @@ - - - - + + + + + + image/svg+xml + + + + + + + + + diff --git a/res/skins/Deere/image/style_sort_up.svg b/res/skins/Deere/image/style_sort_up.svg index 08ca2a566af..8a69a90ca93 100644 --- a/res/skins/Deere/image/style_sort_up.svg +++ b/res/skins/Deere/image/style_sort_up.svg @@ -1,5 +1,60 @@ - - - - + + + + + + image/svg+xml + + + + + + + + + diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index d1efff029a6..fb8ebae3352 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -121,14 +121,16 @@ *******************************************************************************/ /* library table */ -QTableView { +QTableView, QTreeView { color: #d2d2d2; background-color: #1F1F1F; alternate-background-color: #1A1A1A; - selection-background-color: #006596 !important; - selection-color: #D6D6D6; + selection-background-color: #006596; border: 1px solid #1A1A1A; - gridline-color: red; +} + +QTreeView::branch:selected, QTableView::item:selected, QTreeView::item:selected { + background-color: #006596; } /* checkbox in library "Played" column */ From ce07cacccb14cd82e7e5878cc820ff57e5a47633 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 12:53:40 +0200 Subject: [PATCH 396/552] Fix icon height and horizontal line position --- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/treeitemmodel.cpp | 16 +++++++++++++++- src/library/treeitemmodel.h | 1 + src/widget/wlibrarysidebar.cpp | 7 +++---- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 722009f8832..968e38a9728 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -134,7 +134,7 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { m_pSidebar = createLibrarySidebarWidget(pKeyboard); - m_pSidebar->setIconSize(QSize(32, 32)); + m_pSidebar->setIconSize(m_pChildModel->getDefaultIconSize()); m_pChildModel->reloadTree(); return m_pSidebar; } diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 02d114c4979..bbada9627a9 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -55,7 +55,17 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const { // We use Qt::UserRole to ask for the datapath. switch(role) { case Qt::DisplayRole: - return item->data(); + return item->data(); + case Qt::SizeHintRole: + { + QIcon icon(item->getIcon()); + if (icon.isNull()) { + return QVariant(); + } + QSize size(getDefaultIconSize()); + size.setHeight(size.height() + 2); + return size; + } case Qt::DecorationRole: return item->getIcon(); case Role::RoleDataPath: @@ -241,6 +251,10 @@ QString TreeItemModel::getBreadCrumbString(TreeItem* pTree) { return next % QLatin1String(" > ") % text; } +QSize TreeItemModel::getDefaultIconSize() { + return QSize(32, 32); +} + void TreeItemModel::reloadTree() { triggerRepaint(); } diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index b2a593f8319..0389ed116a1 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -48,6 +48,7 @@ class TreeItemModel : public QAbstractItemModel { bool dragMoveAccept(const QModelIndex& index, QUrl url); static QString getBreadCrumbString(TreeItem* pTree); + static QSize getDefaultIconSize(); public slots: virtual void reloadTree(); diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 5919e25d562..50b63c5dbcd 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -1,10 +1,10 @@ #include "widget/wlibrarysidebar.h" +#include #include #include #include #include -#include #include #include "library/treeitemmodel.h" @@ -31,7 +31,7 @@ void WSidebarItemDelegate::paint(QPainter* painter, QString text = index.data().toString(); QRect rect(option.rect); // Set small padding left - rect.setLeft(rect.left() + 20); + rect.setLeft(rect.left() + 2); // Draw the text painter->setPen(option.palette.color(QPalette::Text)); @@ -59,8 +59,7 @@ WLibrarySidebar::WLibrarySidebar(QWidget* parent) setAutoScroll(true); setAttribute(Qt::WA_MacShowFocusRect, false); header()->setStretchLastSection(false); - header()->setResizeMode(QHeaderView::ResizeToContents); - header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + header()->setResizeMode(QHeaderView::Stretch); } void WLibrarySidebar::contextMenuEvent(QContextMenuEvent *event) { From 0e9d60f56157ddbf05338f5fbb4f50bd39a3edf3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 12:59:55 +0200 Subject: [PATCH 397/552] Fix coverart in unknown albums --- src/library/librarytreemodel.cpp | 2 +- src/widget/wlibrarysidebar.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 8b809abf754..629794ca3fe 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -281,7 +281,7 @@ void LibraryTreeModel::createTracksTree() { parent[i + 1] = pTree; // Add coverart info - if (treeStartQueryIndex + i == iAlbum && !unknown) { + if (treeStartQueryIndex + i == iAlbum) { addCoverArt(cIndex, query, pTree); } } diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 50b63c5dbcd..087b4a3711c 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -30,12 +30,14 @@ void WSidebarItemDelegate::paint(QPainter* painter, QString text = index.data().toString(); QRect rect(option.rect); + QFont font(option.font); + font.setBold(true); // Set small padding left - rect.setLeft(rect.left() + 2); + rect.setLeft(rect.left() + 3); // Draw the text painter->setPen(option.palette.color(QPalette::Text)); - painter->setFont(option.font); + painter->setFont(font); painter->drawText(rect, text); // Draw line under text From 83f434c93091be92eae3339875e10ff3dd618c3f Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 13:38:47 +0200 Subject: [PATCH 398/552] Fix divider text in sidebar not eliding --- src/widget/wlibrarysidebar.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 087b4a3711c..75e0021da01 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -35,10 +35,13 @@ void WSidebarItemDelegate::paint(QPainter* painter, // Set small padding left rect.setLeft(rect.left() + 3); + QFontMetrics fontMetrics(font); + QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, rect.width() - 3); + // Draw the text painter->setPen(option.palette.color(QPalette::Text)); painter->setFont(font); - painter->drawText(rect, text); + painter->drawText(rect, elidedText); // Draw line under text painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); From bbc1166b4fae1c1e29d67f1043a2bf8042e62d20 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 14:23:56 +0200 Subject: [PATCH 399/552] Fix analysis button not working and refactor includes --- src/library/analysisfeature.cpp | 9 ++--- src/library/analysisfeature.h | 4 +-- src/library/autodj/autodjfeature.cpp | 1 - src/library/banshee/bansheefeature.h | 1 - src/library/baseplaylistfeature.cpp | 3 +- src/library/browse/browsefeature.cpp | 4 --- src/library/browse/foldertreemodel.cpp | 1 - src/library/browse/foldertreemodel.h | 2 -- src/library/cratefeature.cpp | 1 - src/library/dlganalysis.cpp | 4 +-- src/library/historyfeature.cpp | 1 - src/library/historytreemodel.cpp | 1 - src/library/itunes/itunesfeature.h | 1 - src/library/libraryfeature.cpp | 16 +++++++++ src/library/libraryfeature.h | 40 +++++++++------------- src/library/libraryfoldermodel.cpp | 1 - src/library/librarytreemodel.cpp | 5 ++- src/library/playlistfeature.cpp | 1 - src/library/recording/recordingfeature.cpp | 1 - src/library/rhythmbox/rhythmboxfeature.cpp | 1 - src/library/traktor/traktorfeature.cpp | 1 - src/library/treeitemmodel.cpp | 5 ++- src/library/treeitemmodel.h | 3 +- src/widget/wlibrarybreadcrumb.cpp | 1 - 24 files changed, 47 insertions(+), 61 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index eb983787457..1d11c99b7aa 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -11,7 +11,6 @@ #include "library/library.h" #include "library/librarytablemodel.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "sources/soundsourceproxy.h" #include "util/debug.h" #include "util/dnd.h" @@ -33,8 +32,6 @@ AnalysisFeature::AnalysisFeature(UserSettingsPointer pConfig, } AnalysisFeature::~AnalysisFeature() { - // TODO(XXX) delete these - //delete m_pLibraryTableModel; cleanupAnalyzer(); } @@ -64,9 +61,9 @@ QString AnalysisFeature::getSettingsName() const { return "AnalysisFeature"; } -QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, - int paneId) { - WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); +QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { + WTrackTableView* pTable = createTableWidget(pKeyboard, paneId); + pTable->loadTrackModel(getAnalysisTableModel()); connect(pTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index 14d972d0114..6ec1dd25d38 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -13,9 +13,9 @@ #include #include "library/libraryfeature.h" -#include "preferences/usersettings.h" -#include "treeitemmodel.h" #include "library/dlganalysis.h" +#include "library/treeitemmodel.h" +#include "preferences/usersettings.h" class AnalyzerQueue; class TrackCollection; diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 32fbcd89b23..7b550bb4d2b 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -15,7 +15,6 @@ #include "library/autodj/autodjprocessor.h" #include "library/trackcollection.h" #include "library/autodj/dlgautodj.h" -#include "library/treeitem.h" #include "mixer/playermanager.h" #include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index 4306492d77f..a9bd24e9fe3 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -11,7 +11,6 @@ #include "library/baseexternallibraryfeature.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" -#include "library/treeitem.h" #include "library/banshee/bansheedbconnection.h" diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 07b4bd79e53..bb508a0f92e 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -13,7 +13,6 @@ #include "library/parsercsv.h" #include "library/playlisttablemodel.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "library/treeitemmodel.h" #include "controllers/keyboard/keyboardeventfilter.h" #include "widget/wlibrary.h" @@ -167,7 +166,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { m_featureFocus = -1; restoreSearch(""); - showBreadCrumb(static_cast(index.internalPointer())); + showBreadCrumb(index); emit(enableCoverArtDisplay(true)); } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index d820048b5b1..ed6209b03dd 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -8,15 +8,11 @@ #include #include #include -#include -#include #include "controllers/keyboard/keyboardeventfilter.h" #include "library/browse/browsefeature.h" #include "library/library.h" #include "library/trackcollection.h" -#include "library/treeitem.h" -#include "track/track.h" #include "util/sandbox.h" #include "widget/wlibrary.h" #include "widget/wlibrarystack.h" diff --git a/src/library/browse/foldertreemodel.cpp b/src/library/browse/foldertreemodel.cpp index 6776e394ecf..0dfdc3b74e1 100644 --- a/src/library/browse/foldertreemodel.cpp +++ b/src/library/browse/foldertreemodel.cpp @@ -12,7 +12,6 @@ #include -#include "library/treeitem.h" #include "library/browse/foldertreemodel.h" #include "library/browse/browsefeature.h" #include "util/file.h" diff --git a/src/library/browse/foldertreemodel.h b/src/library/browse/foldertreemodel.h index 240e26b4472..6bac312ce0e 100644 --- a/src/library/browse/foldertreemodel.h +++ b/src/library/browse/foldertreemodel.h @@ -8,9 +8,7 @@ #include #include "library/treeitemmodel.h" -#include "library/treeitem.h" -class TreeItem; // This class represents a folder item within the Browse Feature // The class is derived from TreeItemModel to support lazy model // initialization. diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index aaf3bb32d9f..637af60cb85 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -19,7 +19,6 @@ #include "library/parserpls.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "sources/soundsourceproxy.h" #include "util/dnd.h" #include "util/duration.h" diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index e552827aaad..cc2fe5ff18a 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -102,10 +102,10 @@ void DlgAnalysis::setSelectedIndexes(const QModelIndexList& selectedIndexes) { //qDebug() << "DlgAnalysis::setSelectedIndexes" << selectedIndexes; m_selectedIndexes = selectedIndexes; pushButtonAnalyze->setEnabled(m_selectedIndexes.size() > 0 || - m_bAnalysisActive); + !m_bAnalysisActive); } -void DlgAnalysis::setTableModel(AnalysisLibraryTableModel *pTableModel) { +void DlgAnalysis::setTableModel(AnalysisLibraryTableModel* pTableModel) { m_pAnalysisLibraryTableModel = pTableModel; connect(radioButtonRecentlyAdded, SIGNAL(clicked()), diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index b1b72eacc04..2bc57899caf 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -9,7 +9,6 @@ #include "library/playlisttablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "mixer/playerinfo.h" #include "mixer/playermanager.h" #include "widget/wlibrarysidebar.h" diff --git a/src/library/historytreemodel.cpp b/src/library/historytreemodel.cpp index 795b94ce574..368aea9af98 100644 --- a/src/library/historytreemodel.cpp +++ b/src/library/historytreemodel.cpp @@ -3,7 +3,6 @@ #include "library/historyfeature.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "library/historytreemodel.h" diff --git a/src/library/itunes/itunesfeature.h b/src/library/itunes/itunesfeature.h index 8a00fec60d3..320e476e372 100644 --- a/src/library/itunes/itunesfeature.h +++ b/src/library/itunes/itunesfeature.h @@ -13,7 +13,6 @@ #include "library/baseexternallibraryfeature.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" -#include "library/treeitem.h" class BaseExternalTrackModel; class BaseExternalPlaylistModel; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 1a1277c1bb1..8c25e41f813 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -49,6 +49,18 @@ QIcon LibraryFeature::getIcon() { return WPixmapStore::getLibraryIcon(getIconPath()); } +bool LibraryFeature::dropAcceptChild(const QModelIndex&, QList, QObject*) { + return false; +} + +bool LibraryFeature::dragMoveAccept(QUrl) { + return false; +} + +bool LibraryFeature::dragMoveAcceptChild(const QModelIndex &, QUrl) { + return false; +} + QWidget* LibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { return createTableWidget(pKeyboard, paneId); @@ -205,6 +217,10 @@ void LibraryFeature::showBreadCrumb(TreeItem *pTree) { m_pLibrary->showBreadCrumb(pTree); } +void LibraryFeature::showBreadCrumb(const QModelIndex &index) { + showBreadCrumb(static_cast(index.internalPointer())); +} + void LibraryFeature::showBreadCrumb(const QString &text, const QIcon& icon) { m_pLibrary->showBreadCrumb(text, icon); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index ce50114293f..3b2b0996141 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -52,16 +52,10 @@ class LibraryFeature : public QObject { } virtual bool dropAcceptChild(const QModelIndex& /* index */, QList /* urls */, - QObject* /* pSource */) { - return false; - } - virtual bool dragMoveAccept(QUrl /* url */) { - return false; - } + QObject* /* pSource */); + virtual bool dragMoveAccept(QUrl /* url */); virtual bool dragMoveAcceptChild(const QModelIndex& /* index */, - QUrl /* url */) { - return false; - } + QUrl /* url */); // Reimplement this to register custom views with the library widget // at the right pane. @@ -87,22 +81,17 @@ class LibraryFeature : public QObject { // called when you single click on the root item virtual void activate() = 0; // called when you single click on a child item, e.g., a concrete playlist or crate - virtual void activateChild(const QModelIndex&) { - } + virtual void activateChild(const QModelIndex&) {} // called when you right click on the root item - virtual void onRightClick(const QPoint&) { - } + virtual void onRightClick(const QPoint&) {} // called when you right click on a child item, e.g., a concrete playlist or crate virtual void onRightClickChild(const QPoint& /* globalPos */, - const QModelIndex& /* index */) { - } + const QModelIndex& /* index */) {} // Only implement this, if using incremental or lazy childmodels, see BrowseFeature. // This method is executed whenever you **double** click child items - virtual void onLazyChildExpandation(const QModelIndex&) { - } + virtual void onLazyChildExpandation(const QModelIndex&) {} - virtual void onSearch(const QString&) { - } + virtual void onSearch(const QString&) {} signals: @@ -123,11 +112,15 @@ class LibraryFeature : public QObject { void restoreSaveButton(); protected: - inline QStringList getPlaylistFiles() { return getPlaylistFiles(QFileDialog::ExistingFiles); } - inline QString getPlaylistFile() { return getPlaylistFiles(QFileDialog::ExistingFile).first(); } + inline QStringList getPlaylistFiles() { + return getPlaylistFiles(QFileDialog::ExistingFiles); + } + inline QString getPlaylistFile() { + return getPlaylistFiles(QFileDialog::ExistingFile).first(); + } // Creates a table widget with no model - virtual WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, + WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, int paneId); // Creates a WLibrarySidebar widget with the getChildModel() function as @@ -138,10 +131,11 @@ class LibraryFeature : public QObject { // the default widget is a WLibrarySidebar widget virtual QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard); - void showTrackModel(QAbstractItemModel *model); + void showTrackModel(QAbstractItemModel* model); void switchToFeature(); void restoreSearch(const QString& search); void showBreadCrumb(TreeItem* pTree); + void showBreadCrumb(const QModelIndex& index); void showBreadCrumb(const QString& text, const QIcon &icon); void showBreadCrumb(); diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index 9c13ab99d72..de03763f9d4 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -5,7 +5,6 @@ #include "library/libraryfeature.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, TrackCollection* pTrackCollection, diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 629794ca3fe..836a0384604 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -1,15 +1,14 @@ #include #include "library/coverartcache.h" -#include "library/librarytreemodel.h" #include "library/libraryfeature.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" - #include "util/stringhelper.h" #include "widget/wpixmapstore.h" +#include "library/librarytreemodel.h" + namespace { QHash m_hashToIndex; } diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index ca9bff28034..99d4b10f98a 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -10,7 +10,6 @@ #include "widget/wlibrarytextbrowser.h" #include "library/trackcollection.h" #include "library/playlisttablemodel.h" -#include "library/treeitem.h" #include "library/treeitemmodel.h" #include "library/queryutil.h" #include "library/parser.h" diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 1941eb46a6b..36046aae222 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -4,7 +4,6 @@ #include "controllers/keyboard/keyboardeventfilter.h" #include "library/recording/dlgrecording.h" #include "track/track.h" -#include "library/treeitem.h" #include "library/recording/recordingfeature.h" #include "library/library.h" #include "library/trackcollection.h" diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 7b0e07b22f7..64fb5086356 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -9,7 +9,6 @@ #include "library/baseexternalplaylistmodel.h" #include "library/library.h" #include "library/queryutil.h" -#include "library/treeitem.h" RhythmboxFeature::RhythmboxFeature(UserSettingsPointer pConfig, Library* pLibrary, diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 85cc31c8bbb..64325e8bfad 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -15,7 +15,6 @@ #include "library/missingtablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/treeitem.h" #include "util/sandbox.h" TraktorTrackModel::TraktorTrackModel(QObject* parent, diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index bbada9627a9..38f3a72f62d 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -1,8 +1,7 @@ -#include "library/treeitemmodel.h" - #include #include -#include "library/treeitem.h" + +#include "library/treeitemmodel.h" /* * Just a word about how the TreeItem objects and TreeItemModels are used in general: diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index 0389ed116a1..bc4286b3e5a 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -7,7 +7,8 @@ #include #include -class TreeItem; +#include "library/treeitem.h" + class LibraryFeature; class TreeItemModel : public QAbstractItemModel { diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index b4b0b483ee5..17c17231729 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -3,7 +3,6 @@ #include "widget/wlibrarybreadcrumb.h" #include "library/treeitemmodel.h" -#include "library/treeitem.h" WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) : QWidget(parent) { From e158b808adfff300b97e8a3255f27c3f06e08168 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 14:41:41 +0200 Subject: [PATCH 400/552] Fix focus change in Search Bar --- src/library/librarypanemanager.cpp | 6 ++++-- src/widget/wsearchlineedit.cpp | 2 ++ src/widget/wsearchlineedit.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 6cf9083cba6..8b4c9cf8afe 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -57,6 +57,8 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { this, SLOT(slotSearchCleared())); connect(pSearchBar, SIGNAL(searchStarting()), this, SLOT(slotSearchStarting())); + connect(pSearchBar, SIGNAL(focused()), + this, SLOT(slotPaneFocused())); m_pSearchBar = pSearchBar; } @@ -176,12 +178,12 @@ void LibraryPaneManager::slotSearchCleared() { } bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { - if (m_pPaneWidget.isNull()) { + if (m_pPaneWidget.isNull() || m_pSearchBar.isNull()) { return false; } if (event->type() == QEvent::MouseButtonPress && - m_pPaneWidget->underMouse()) { + (m_pPaneWidget->underMouse() || m_pSearchBar->underMouse())) { m_pLibrary->slotPaneFocused(this); } diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index f4fd7b5ddbf..4eee626129a 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -275,6 +275,8 @@ void WSearchLineEdit::updateButtons(const QString& text) bool WSearchLineEdit::event(QEvent* pEvent) { if (pEvent->type() == QEvent::ToolTip) { updateTooltip(); + } else if (pEvent->type() == QEvent::FocusIn) { + emit(focused()); } return QLineEdit::event(pEvent); } diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 746f831950b..64379abfe0c 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -33,6 +33,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void search(const QString& text); void searchCleared(); void searchStarting(); + void focused(); public slots: void restoreSearch(const QString& text, QPointer pFeature = nullptr); From 15c8ee26b465448dd1299c636dea52a4356adff2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 17:40:33 +0200 Subject: [PATCH 401/552] Add clicking a breadcrumb changes the focus --- src/library/librarypanemanager.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 8b4c9cf8afe..8de55e1d2a6 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -63,8 +63,9 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { m_pSearchBar = pSearchBar; } -void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb *pBreadCrumb) { +void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb* pBreadCrumb) { m_pBreadCrumb = pBreadCrumb; + pBreadCrumb->installEventFilter(this); } void LibraryPaneManager::addFeature(LibraryFeature* feature) { @@ -178,12 +179,15 @@ void LibraryPaneManager::slotSearchCleared() { } bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { - if (m_pPaneWidget.isNull() || m_pSearchBar.isNull()) { + if (m_pPaneWidget.isNull() || m_pSearchBar.isNull() || + m_pBreadCrumb.isNull()) { return false; } if (event->type() == QEvent::MouseButtonPress && - (m_pPaneWidget->underMouse() || m_pSearchBar->underMouse())) { + (m_pPaneWidget->underMouse() || + m_pSearchBar->underMouse() || + m_pBreadCrumb->underMouse())) { m_pLibrary->slotPaneFocused(this); } From 7405400df4de81af6489718dfdadd0db65320b2e Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 18:48:41 +0200 Subject: [PATCH 402/552] Fix crash caused by having more panes than features --- src/library/library.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/library/library.cpp b/src/library/library.cpp index 2d652fad3d2..8dc977e2513 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -129,6 +129,9 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, // Get the value once to avoid searching again in the hash LibraryPaneManager* pPane = getPane(paneId); + if (pPane == nullptr) { + return; + } pPane->bindPaneWidget(pLibraryWidget, pKeyboard); // Set the current font and row height on all the WTrackTableViews that were @@ -503,6 +506,12 @@ LibraryPaneManager* Library::getPane(int paneId) { return *it; } + // Create a new pane only if there are more features than panes + if (m_panes.size() >= m_features.size()) { + qWarning() << "Library: there are more panes declared than features"; + return nullptr; + } + LibraryPaneManager* pPane = new LibraryPaneManager(paneId, this); pPane->addFeatures(m_features); m_panes.insert(paneId, pPane); From bd058091b10e31e2d03c94654193cac440217971 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 19:15:53 +0200 Subject: [PATCH 403/552] Vertical scroll area, show scrollbar when needed --- src/widget/wverticalscrollarea.cpp | 20 +++++++++++--------- src/widget/wverticalscrollarea.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index 5e5406f5858..e712ea91b1f 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -1,12 +1,12 @@ -#include #include +#include #include #include "wverticalscrollarea.h" WVerticalScrollArea::WVerticalScrollArea(QWidget* parent) : QScrollArea(parent) { - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setAlignment(Qt::AlignTop); setWidgetResizable(true); @@ -17,12 +17,14 @@ void WVerticalScrollArea::setWidget(QWidget* widget) { QScrollArea::setWidget(widget); } -bool WVerticalScrollArea::eventFilter(QObject* o, QEvent* e) { - if (o == widget() && e->type() == QEvent::Resize) { - int width = widget()->minimumSizeHint().width(); - int vScrollWidth = verticalScrollBar()->width(); - // + 2 for a Gap between scroll area and bar - setFixedWidth(width + vScrollWidth); +void WVerticalScrollArea::resizeEvent(QResizeEvent *e) { + QScrollArea::resizeEvent(e); + + int width = widget()->minimumSizeHint().width(); + int vScrollWidth = 0; + + if (e->size().height() <= widget()->minimumSizeHint().height()) { + vScrollWidth = verticalScrollBar()->width(); } - return false; + setFixedWidth(width + vScrollWidth); } diff --git a/src/widget/wverticalscrollarea.h b/src/widget/wverticalscrollarea.h index d49c39f5062..92f6795848c 100644 --- a/src/widget/wverticalscrollarea.h +++ b/src/widget/wverticalscrollarea.h @@ -11,7 +11,7 @@ class WVerticalScrollArea : public QScrollArea void setWidget(QWidget* widget); protected: - virtual bool eventFilter(QObject* o, QEvent* e); + virtual void resizeEvent(QResizeEvent* e); }; #endif // WVERTICALSCROLLAREA_H From 225ce988a0ad66bf4ba8f49c4108325a04cb5fd2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 21:02:04 +0200 Subject: [PATCH 404/552] Fix some miniview issues - Now the items do not overlap Add Line / Sub Line buttons - Item is only displayed in special columns --- src/library/libraryfeature.cpp | 3 +- src/widget/wminiviewscrollbar.cpp | 145 ++++++++++++++++++------------ src/widget/wminiviewscrollbar.h | 16 +++- 3 files changed, 102 insertions(+), 62 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 8c25e41f813..65bb699780c 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -176,8 +176,9 @@ WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter // Set sidebar mini view WMiniViewScrollBar* pMiniView = new WMiniViewScrollBar(pSidebar); + pMiniView->setTreeView(pSidebar); pMiniView->setSortColumn(0); - pMiniView->setRole(TreeItemModel::RoleDataPath); + pMiniView->setRole(Qt::DisplayRole); pMiniView->setModel(pModel); pSidebar->setVerticalScrollBar(pMiniView); diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index d33d7cfc4e8..3701232d213 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -41,6 +41,14 @@ int WMiniViewScrollBar::sortColumn() const { return m_sortColumn; } +void WMiniViewScrollBar::setTreeView(QPointer pTreeView) { + m_pTreeView = pTreeView; +} + +QPointer WMiniViewScrollBar::getTreeView() { + return m_pTreeView; +} + void WMiniViewScrollBar::setRole(int role) { m_dataRole = role; triggerUpdate(); @@ -53,8 +61,8 @@ int WMiniViewScrollBar::role() const { void WMiniViewScrollBar::setModel(QAbstractItemModel* model) { m_pModel = model; if (!m_pModel.isNull()) { - connect(m_pModel.data(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(refreshCharMap())); + connect(m_pModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(triggerUpdate())); triggerUpdate(); } @@ -76,10 +84,11 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { // Get total size int letterSize = fontMetrics().height(); int w = width(); + const QPoint bottom(w, letterSize); // Draw each letter in its position for (const CharPosition& p : m_computedPosition) { - if (p.position < 0) { + if (p.position < 0 || p.character.isNull()) { continue; } QFont f(font()); @@ -87,8 +96,7 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { painter.setFont(f); QPoint topLeft = QPoint(0, p.position); - QPoint bottomRight = topLeft + QPoint(w, letterSize); - painter.drawText(QRect(topLeft, bottomRight), flags, p.character); + painter.drawText(QRect(topLeft, topLeft + bottom), flags, p.character); } opt.rect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, @@ -164,58 +172,24 @@ void WMiniViewScrollBar::refreshCharMap() { setMaximum(size); const QModelIndex& rootIndex = m_pModel->index(0, 0); - int digits = 0; - bool isNumber; - rootIndex.sibling(0, m_sortColumn).data(m_dataRole).toString().toInt(&isNumber); - if (isNumber) { - // Search the max number of digits, since we know that the model is - // sorted then we search the first and the last element for the number - // of digits - const QModelIndex& firstIndex = rootIndex.sibling(0, m_sortColumn); - QString first = firstIndex.data(m_dataRole).toString(); - const QModelIndex& lastIndex = rootIndex.sibling(size - 1, m_sortColumn); - QString last = lastIndex.data(m_dataRole).toString(); - - digits = qMax(first.length(), last.length()); + m_letters.clear(); + if (!isValidColumn()) { + return; } - bool isYear = false; - QPointer pModel = qobject_cast(m_pModel); - if (!pModel.isNull()) { - int index = pModel->fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR); - isYear = index == m_sortColumn; - } - - m_letters.clear(); for (int i = 0; i < size; ++i) { const QModelIndex& index = rootIndex.sibling(i, m_sortColumn); + int count = getVisibleChildCount(index); QString text = index.data(m_dataRole).toString(); QChar c; - if (isNumber) { - if (text.length() == digits) { - c = text.at(0); - } else { - c = '0'; - } - } else if (isYear && text.size() >= 3) { - // 4 digits year, we take the decade which is the most - // representative in one single digit show + + if (m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) && + text.size() >= 3) { c = text.at(2); } else { c = StringHelper::getFirstCharForGrouping(text); } - - if (m_letters.size() <= 0) { - m_letters.append({c, 1}); - } else { - CharCount& last = m_letters.last(); - - if (last.character == c) { - ++last.count; - } else { - m_letters.append({c, 1}); - } - } + addToLastCharCount(c, count); } } @@ -229,19 +203,15 @@ void WMiniViewScrollBar::computeLettersSize() { } QStyleOptionSlider opt(getStyleOptions()); - - const int addLineSize = - style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarAddLine, this).height(); - const int subLineSize = - style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarSubLine, this).height(); + QRect grooveRect = + style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarGroove, this); // Height of a letter const int letterSize = fontMetrics().height(); - const int totalLinearSize = rect().height() - addLineSize - subLineSize; - float nextAvailableScrollPosition = 0.0; - float optimalScrollPosition = 0.0; + const int totalLinearSize = grooveRect.bottom(); + float nextAvailableScrollPosition = grooveRect.top(); + float optimalScrollPosition = grooveRect.top(); int totalCount = 0; // Get the total count of letters appearance to make a linear interpolation @@ -254,8 +224,9 @@ void WMiniViewScrollBar::computeLettersSize() { float size = interpolSize(p.position, totalCount, totalLinearSize); float percentage = 100.0*p.position/float(totalCount); - if ((optimalScrollPosition + size) < (nextAvailableScrollPosition + letterSize) - || percentage < 1.0) { + if ((optimalScrollPosition + size) < (nextAvailableScrollPosition + letterSize) || + percentage < 1.0 || + (optimalScrollPosition + letterSize) > totalLinearSize) { // If a very small percentage letter takes the space for a letter // with more high ocupacy percentage this can be annoying @@ -290,3 +261,59 @@ QStyleOptionSlider WMiniViewScrollBar::getStyleOptions() { return opt; } + +int WMiniViewScrollBar::getFieldIndex(ColumnCache::Column col) { + QPointer pModel = qobject_cast(m_pModel); + if (pModel.isNull()) { + return -1; + } + + return pModel->fieldIndex(col); +} + +bool WMiniViewScrollBar::isValidColumn() { + return m_sortColumn == 0 || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ARTIST) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GENRE) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TITLE) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_ARTIST) || + m_sortColumn == getFieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_TITLE); +} + +void WMiniViewScrollBar::addToLastCharCount(const QChar& c, int sum) { + if (m_letters.size() <= 0) { + m_letters.append({c, sum}); + } else { + CharCount& lastC = m_letters.last(); + if (lastC.character == c) { + ++lastC.count; + } else { + m_letters.append({c, sum}); + } + } +} + +int WMiniViewScrollBar::getVisibleChildCount(const QModelIndex& index) { + if (!index.isValid()) { + return 0; + } + + if (m_pTreeView.isNull()) { + return 1; + } + + if (!m_pTreeView->isExpanded(index)) { + return 1; + } + + int total = 1; + int rowCount = m_pModel->rowCount(index); + for (int i = 0; i < rowCount; ++i) { + total += getVisibleChildCount(index.child(i, m_sortColumn)); + } + return total; +} diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index df1e2e41166..fd5f248573f 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -4,9 +4,13 @@ #include #include #include +#include + +#include "library/columncache.h" class WMiniViewScrollBar : public QScrollBar { + Q_OBJECT public: WMiniViewScrollBar(QWidget* parent = nullptr); @@ -16,6 +20,9 @@ class WMiniViewScrollBar : public QScrollBar void setSortColumn(int column); int sortColumn() const; + void setTreeView(QPointer pTreeView); + QPointer getTreeView(); + void setRole(int role); int role() const; @@ -41,14 +48,18 @@ class WMiniViewScrollBar : public QScrollBar }; private slots: - void refreshCharMap(); + void triggerUpdate(); private: // The purpose of this function is to avoid computing all the sizes in the // paintEvent function which can block the GUI thread + void refreshCharMap(); void computeLettersSize(); - void triggerUpdate(); QStyleOptionSlider getStyleOptions(); + int getFieldIndex(ColumnCache::Column col); + bool isValidColumn(); + void addToLastCharCount(const QChar& c, int sum = 1); + int getVisibleChildCount(const QModelIndex &index); int m_sortColumn; int m_dataRole; @@ -60,6 +71,7 @@ class WMiniViewScrollBar : public QScrollBar // Contains each character's vertical position QVector m_computedPosition; QPointer m_pModel; + QPointer m_pTreeView; }; #endif // WMINIVIEWSCROLLBAR_H From 33c37b899cbcaa55c0f40fa61dd91744676b5353 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 21:15:50 +0200 Subject: [PATCH 405/552] Scrollbar helper now changes its size when expanding tree item --- src/widget/wminiviewscrollbar.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 3701232d213..52761214c91 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -22,6 +22,9 @@ WMiniViewScrollBar::WMiniViewScrollBar(QWidget* parent) m_dataRole(Qt::DisplayRole), m_showLetters(true) { setMouseTracking(true); + + connect(this, SIGNAL(rangeChanged(int,int)), + this, SLOT(triggerUpdate())); } void WMiniViewScrollBar::setShowLetters(bool show) { @@ -179,8 +182,8 @@ void WMiniViewScrollBar::refreshCharMap() { for (int i = 0; i < size; ++i) { const QModelIndex& index = rootIndex.sibling(i, m_sortColumn); - int count = getVisibleChildCount(index); QString text = index.data(m_dataRole).toString(); + int count = getVisibleChildCount(index); QChar c; if (m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) && @@ -290,7 +293,7 @@ void WMiniViewScrollBar::addToLastCharCount(const QChar& c, int sum) { } else { CharCount& lastC = m_letters.last(); if (lastC.character == c) { - ++lastC.count; + lastC.count += sum; } else { m_letters.append({c, sum}); } From a6a29d893e3446b09a74eef94df78bb8aee9b7a4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 21:50:26 +0200 Subject: [PATCH 406/552] Add Finnish test only for linux --- src/test/stringhelpertest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/stringhelpertest.cpp b/src/test/stringhelpertest.cpp index 8c49ce0fc71..4d909b575ad 100644 --- a/src/test/stringhelpertest.cpp +++ b/src/test/stringhelpertest.cpp @@ -51,9 +51,10 @@ TEST(StringHelperTest, Finnish) { QString s2 = QString::fromUtf8("Å"); QChar c1 = StringHelper::getFirstCharForGrouping(s1); QChar c2 = s2.at(0); +#if __LINUX__ ASSERT_EQ(QString::localeAwareCompare(c1, c2), 0) << qPrintable(c1) << " " << qPrintable(c2); - +#endif QLocale::setDefault(prev); } From ee49111e107f54a3e8a9415032318502011f5da1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 21:55:43 +0200 Subject: [PATCH 407/552] Fix only one query was saved --- src/library/dao/savedqueriesdao.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 6ceda7d0468..0bc16ec4cd4 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -22,19 +22,7 @@ SavedSearchQuery SavedQueriesDAO::saveQuery(LibraryFeature* pFeature, return SavedSearchQuery(); } - // First of all delete previous saved queries - QString queryStr = "DELETE FROM " SAVEDQUERYTABLE " WHERE libraryFeature = :featureName"; - - qDebug() << pFeature->getSettingsName(); - - QSqlQuery query(m_database); - query.prepare(queryStr); - query.bindValue(":featureName", pFeature->getSettingsName()); - if (!query.exec()) { - LOG_FAILED_QUERY(query); - } - - + QSqlQuery query(m_database); query.prepare("INSERT INTO " SAVEDQUERYTABLE "(libraryFeature, query, title, selectedItems," "sortOrder, vScrollbarPos, sortColumn, sortAscendingOrder, pinned) " From 743a92dfc16367dcd6dc82faab10ef664e52744d Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 22:45:59 +0200 Subject: [PATCH 408/552] Fix icons overlaping text in search bar --- src/widget/wsearchlineedit.cpp | 14 ++++---------- src/widget/wsearchlineedit.h | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 4eee626129a..84bd7850fd7 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -86,13 +86,6 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateButtons(const QString&))); - - // The width of the frame for the widget based on the styling. - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - - // Ensures the text does not obscure the clear image. - setStyleSheet(QString("QLineEdit { padding-right: %1px; } "). - arg(m_pClearButton->sizeHint().width() + frameWidth + 1)); } void WSearchLineEdit::setup(const QDomNode& node, const SkinContext& context) { @@ -170,6 +163,9 @@ void WSearchLineEdit::resizeEvent(QResizeEvent* e) { m_pSaveButton->move(posXSave, posYSave); m_pClearButton->move(posXClear, posYClear); } + + // Ensures the text does not obscure the clear image. + setStyleSheet(QString("QLineEdit { padding-right: %1px; }").arg(posXClear)); } void WSearchLineEdit::focusInEvent(QFocusEvent* event) { @@ -232,9 +228,7 @@ void WSearchLineEdit::restoreSearch(const QString& text, QPointer Date: Tue, 16 Aug 2016 22:46:12 +0200 Subject: [PATCH 409/552] Fix only one query was saved --- src/library/dao/savedqueriesdao.h | 10 +++++++++- src/library/libraryfeature.cpp | 1 + src/widget/wsearchlineedit.cpp | 13 +++++-------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 6d75bc85ab0..baa6754ae69 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -14,7 +14,15 @@ // the search bar and the library features struct SavedSearchQuery { - SavedSearchQuery() : id(-1) {} + SavedSearchQuery() : + vScrollBarPos(-1), + sortColumn(-1), + sortAscendingOrder(false), + pinned(false), + id(-1) {} + + SavedSearchQuery(const SavedSearchQuery& other) = default; + SavedSearchQuery& operator=(const SavedSearchQuery& other) = default; QString query; QString title; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 65bb699780c..97424e6f0b8 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -130,6 +130,7 @@ void LibraryFeature::restoreQuery(int id) { // Move the query to the first position to be reused later by the user const SavedSearchQuery& sQuery = m_savedDAO.moveToFirst(this, id); pTable->restoreQuery(sQuery); + restoreSearch(sQuery.query.isNull() ? "" : sQuery.query); } QList LibraryFeature::getSavedQueries() const { diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 84bd7850fd7..19ddb72005f 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -302,10 +302,12 @@ void WSearchLineEdit::restoreQuery() { QAction* action = menu.addAction(tr("No saved queries")); action->setData(-1); } - for (int i = 0; i < savedQueries.size(); ++i) { - QAction* action = menu.addAction(savedQueries[i].title); - action->setData(i); + + for (const SavedSearchQuery& query : savedQueries) { + QAction* action = menu.addAction(query.title); + action->setData(query.id); } + QPoint position = m_pDropButton->pos(); position += QPoint(0, m_pDropButton->height()); @@ -318,11 +320,6 @@ void WSearchLineEdit::restoreQuery() { if (index < 0) { return; } - QString text = savedQueries[index].query; - blockSignals(true); - setText(text); - updateButtons(text); - blockSignals(false); m_pCurrentFeature->restoreQuery(index); } From fd1ba9746cf325058a881c0899d749e19a6c67be Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 23:09:21 +0200 Subject: [PATCH 410/552] Fix restoring empty queries --- src/library/dao/savedqueriesdao.cpp | 12 +++++++----- src/library/dao/savedqueriesdao.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 0bc16ec4cd4..90a93fdf45f 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -126,12 +126,14 @@ QString SavedQueriesDAO::serializeItems(const QSet& items) { return ret.join(" "); } -QSet SavedQueriesDAO::deserializeItems(const QString& text) { +QSet SavedQueriesDAO::deserializeItems(QString text) { QSet ret; - QStringList items = text.split(" "); - for (const QString& item : items) { - ret.insert(DbId(QVariant(item))); - } + QTextStream ss(&text); + while (!ss.atEnd()) { + int value; + ss >> value; + ret.insert(DbId(QVariant(value))); + } return ret; } diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index baa6754ae69..53eeb08465c 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -53,7 +53,7 @@ class SavedQueriesDAO : public DAO private: static QString serializeItems(const QSet& items); - static QSet deserializeItems(const QString& text); + static QSet deserializeItems(QString text); static SavedSearchQuery valueToQuery(const QSqlQuery& query); static const QString kSelectStart; From 466ce6966a7f90b9ed97f7c5e8ef641afe4ff311 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 16 Aug 2016 23:10:18 +0200 Subject: [PATCH 411/552] Add set title for saving empty queries --- src/widget/wsearchlineedit.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 19ddb72005f..6f3962cd132 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -284,6 +286,21 @@ void WSearchLineEdit::saveQuery() { SavedSearchQuery query; query.title = query.query = text(); if (!m_pCurrentFeature.isNull()) { + if (query.title.isEmpty()) { + // Request a title + bool ok = false; + query.title = + QInputDialog::getText(nullptr, + tr("Create search query"), + tr("Enter name for empty search query"), + QLineEdit::Normal, + tr("New query"), + &ok).trimmed(); + if (ok == false) { + return; + } + } + m_pCurrentFeature->saveQuery(query); } m_pSaveButton->setEnabled(false); From 37ee9569985b3c216bc0f7f178073f7ff249de58 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 17 Aug 2016 10:22:48 +0200 Subject: [PATCH 412/552] Apply focus patch --- src/library/analysisfeature.cpp | 1 + src/library/autodj/autodjfeature.cpp | 1 + src/library/banshee/bansheefeature.cpp | 2 ++ src/library/baseplaylistfeature.cpp | 3 ++ src/library/browse/browsefeature.cpp | 1 + src/library/cratefeature.cpp | 1 + src/library/itunes/itunesfeature.cpp | 2 ++ src/library/library.cpp | 38 +++++++++++++--------- src/library/libraryfeature.cpp | 12 ++++++- src/library/libraryfeature.h | 3 ++ src/library/maintenancefeature.cpp | 1 + src/library/mixxxlibraryfeature.cpp | 1 + src/library/recording/recordingfeature.cpp | 1 + src/library/rhythmbox/rhythmboxfeature.cpp | 1 + src/library/traktor/traktorfeature.cpp | 1 + 15 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 1d11c99b7aa..50ca6ce7239 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -118,6 +118,7 @@ void AnalysisFeature::activate() { restoreSearch(m_pAnalysisView->currentSearch()); } emit(enableCoverArtDisplay(true)); + m_active = true; } void AnalysisFeature::analyzeTracks(QList trackIds) { diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 7b550bb4d2b..c55475e3cc0 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -155,6 +155,7 @@ void AutoDJFeature::activate() { restoreSearch(QString()); //Null String disables search box emit(enableCoverArtDisplay(true)); + m_active = true; } bool AutoDJFeature::dropAccept(QList urls, QObject* pSource) { diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index fbb243f3485..1cebaea4691 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -128,6 +128,7 @@ void BansheeFeature::activate() { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); + m_active = true; } void BansheeFeature::activateChild(const QModelIndex& index) { @@ -142,6 +143,7 @@ void BansheeFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(item); enableCoverArtDisplay(true); + m_active = true; } } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index bb508a0f92e..6305ace746d 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -141,6 +141,7 @@ void BasePlaylistFeature::activate() { restoreSearch(QString()); // Null String disables search box emit(enableCoverArtDisplay(true)); m_featureFocus = -1; + m_active = true; } void BasePlaylistFeature::activateChild(const QModelIndex& index) { @@ -169,6 +170,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { showBreadCrumb(index); emit(enableCoverArtDisplay(true)); + m_active = true; } } @@ -182,6 +184,7 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); activateChild(m_lastRightClickedIndex); + m_active = true; } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index ed6209b03dd..e77403b1be2 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -241,6 +241,7 @@ void BrowseFeature::activate() { m_pLibrary->restoreSearch(QString()); enableCoverArtDisplay(true); + m_active = true; } // Note: This is executed whenever you single click on an child item diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 637af60cb85..5579af85916 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -237,6 +237,7 @@ void CrateFeature::activate() { restoreSearch(QString()); //disable search on crate home m_featureFocus = -1; emit(enableCoverArtDisplay(true)); + m_active = true; } void CrateFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index f727c5ba548..634e8b52f1e 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -123,6 +123,7 @@ QString ITunesFeature::getSettingsName() const { void ITunesFeature::activate() { activate(false); enableCoverArtDisplay(true); + m_active = true; } void ITunesFeature::activate(bool forceReload) { @@ -185,6 +186,7 @@ void ITunesFeature::activate(bool forceReload) { showTrackModel(m_pITunesTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); + m_active = true; } void ITunesFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/library.cpp b/src/library/library.cpp index 8dc977e2513..85cae9dc26d 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -431,23 +431,31 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { handleFocus(); return; } - int featureFocus = pFeature->getFeatureFocus(); - - // The feature is not focused anywhere - if (featureFocus < 0 || m_collapsedPanes.contains(featureFocus)) { - // Remove the previous focused feature in this pane - for (LibraryFeature* f : m_features) { - if (f->getFeatureFocus() == m_focusedPane) { - f->setFeatureFocus(-1); + + if (m_pSidebarExpanded->getCurrentFeature() != pFeature) { + // If the feature is not already shown, follow restore in old pane + int featureFocus = pFeature->getFeatureFocus(); + if (featureFocus >= 0 && !m_collapsedPanes.contains(featureFocus)) { + // The feature is shown in some not collapsed pane + m_focusedPane = featureFocus; + setFocusedPane(); + + /* + if (pFeature->getActive()) { + m_pSidebarExpanded->switchToFeature(pFeature); + handleFocus(); + return; } + */ + } + } + + // Set all features in this pane inactive + for (LibraryFeature* f : m_features) { + if (f->getFeatureFocus() == m_focusedPane && + pFeature->getActive()) { + f->setInactive(); } - } else { - // The feature is shown in some not collapsed pane - m_focusedPane = featureFocus; - setFocusedPane(); - m_pSidebarExpanded->switchToFeature(pFeature); - handleFocus(); - return; } m_panes[m_focusedPane]->setCurrentFeature(pFeature); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 97424e6f0b8..5bdafcccd11 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -35,7 +35,9 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), - m_featureFocus(-1) { + m_featureFocus(-1), + m_focusedPane(-1), + m_active(false) { } LibraryFeature::~LibraryFeature() { @@ -105,6 +107,14 @@ int LibraryFeature::getFeatureFocus() { return m_featureFocus; } +bool LibraryFeature::getActive() const { + return m_active; +} + +void LibraryFeature::setInactive() { + m_active = false; +} + void LibraryFeature::setFocusedPane(int paneId) { m_focusedPane = paneId; } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 3b2b0996141..62d6350d505 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -70,6 +70,8 @@ class LibraryFeature : public QObject { virtual void setFeatureFocus(int focus); virtual int getFeatureFocus(); + virtual bool getActive() const; + virtual void setInactive(); virtual void setFocusedPane(int paneId); @@ -148,6 +150,7 @@ class LibraryFeature : public QObject { int m_featureFocus; int m_focusedPane; + bool m_active; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 031e1ce3023..1d86a16d429 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -48,6 +48,7 @@ void MaintenanceFeature::activate() { switchToFeature(); emit(enableCoverArtDisplay(true)); + m_active = true; } void MaintenanceFeature::selectionChanged(const QItemSelection&, diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 968e38a9728..b01599e881f 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -177,6 +177,7 @@ void MixxxLibraryFeature::activate() { showBreadCrumb(); emit(enableCoverArtDisplay(true)); + m_active = true; } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 36046aae222..ef83eba0d8e 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -76,6 +76,7 @@ void RecordingFeature::activate() { restoreSearch(""); enableCoverArtDisplay(true); + m_active = true; } BrowseTableModel* RecordingFeature::getBrowseTableModel() { diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 64fb5086356..9e17d37a1a6 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,6 +138,7 @@ void RhythmboxFeature::activate() { showTrackModel(m_pRhythmboxTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); + m_active = true; } void RhythmboxFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 64325e8bfad..81b9de149c7 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -166,6 +166,7 @@ void TraktorFeature::activate() { showTrackModel(m_pTraktorTableModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); + m_active = true; } void TraktorFeature::activateChild(const QModelIndex& index) { From f7e061e99cba1a6b76a319f305be59408d7bd83d Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 17 Aug 2016 11:32:46 +0200 Subject: [PATCH 413/552] Change focus change behavior --- src/library/library.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 85cae9dc26d..100620797f2 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -427,6 +427,7 @@ void Library::paneUncollapsed(int paneId) { void Library::slotActivateFeature(LibraryFeature* pFeature) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { + pFeature->setFeatureFocus(m_focusedPane); m_pSidebarExpanded->switchToFeature(pFeature); handleFocus(); return; @@ -451,11 +452,23 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { } // Set all features in this pane inactive - for (LibraryFeature* f : m_features) { + /*for (LibraryFeature* f : m_features) { if (f->getFeatureFocus() == m_focusedPane && pFeature->getActive()) { f->setInactive(); } + } */ + + LibraryFeature* pCurrentFeature = m_panes[m_focusedPane]->getCurrentFeature(); + if (pCurrentFeature != pFeature && + pCurrentFeature->getFeatureFocus() == m_focusedPane) { + // If this feature it's still shown in another pane change the feature + // focus to the other pane + for (LibraryPaneManager* p : m_panes) { + if (p->getCurrentFeature() == pCurrentFeature) { + pCurrentFeature->setFeatureFocus(p->getPaneId()); + } + } } m_panes[m_focusedPane]->setCurrentFeature(pFeature); @@ -487,7 +500,6 @@ void Library::slotPaneFocused(LibraryPaneManager* pPane) { if (pPane != m_pSidebarExpanded) { m_focusedPane = pPane->getPaneId(); - pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } @@ -498,7 +510,7 @@ void Library::slotPaneFocused(LibraryPaneManager* pPane) { //qDebug() << "Library::slotPaneFocused" << m_focusedPane; } -void Library::slotUpdateFocus(LibraryFeature *pFeature) { +void Library::slotUpdateFocus(LibraryFeature* pFeature) { if (pFeature->getFeatureFocus() >= 0) { m_focusedPane = pFeature->getFeatureFocus(); setFocusedPane(); From 777b2b38f42f21e2d5ec48aef82ee41989b63004 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 15:19:54 +0200 Subject: [PATCH 414/552] Remove m_active and add savedPane --- src/library/analysisfeature.cpp | 1 - src/library/autodj/autodjfeature.cpp | 1 - src/library/banshee/bansheefeature.cpp | 2 -- src/library/baseplaylistfeature.cpp | 6 ----- src/library/browse/browsefeature.cpp | 1 - src/library/cratefeature.cpp | 5 +++- src/library/cratefeature.h | 1 + src/library/itunes/itunesfeature.cpp | 2 -- src/library/library.cpp | 30 ++++++---------------- src/library/libraryfeature.cpp | 23 ++++++++++++----- src/library/libraryfeature.h | 13 ++++++---- src/library/maintenancefeature.cpp | 1 - src/library/mixxxlibraryfeature.cpp | 1 - src/library/playlistfeature.cpp | 4 +++ src/library/playlistfeature.h | 1 + src/library/recording/recordingfeature.cpp | 1 - src/library/rhythmbox/rhythmboxfeature.cpp | 1 - src/library/traktor/traktorfeature.cpp | 1 - 18 files changed, 42 insertions(+), 53 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 50ca6ce7239..1d11c99b7aa 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -118,7 +118,6 @@ void AnalysisFeature::activate() { restoreSearch(m_pAnalysisView->currentSearch()); } emit(enableCoverArtDisplay(true)); - m_active = true; } void AnalysisFeature::analyzeTracks(QList trackIds) { diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index c55475e3cc0..7b550bb4d2b 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -155,7 +155,6 @@ void AutoDJFeature::activate() { restoreSearch(QString()); //Null String disables search box emit(enableCoverArtDisplay(true)); - m_active = true; } bool AutoDJFeature::dropAccept(QList urls, QObject* pSource) { diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 1cebaea4691..fbb243f3485 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -128,7 +128,6 @@ void BansheeFeature::activate() { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); - m_active = true; } void BansheeFeature::activateChild(const QModelIndex& index) { @@ -143,7 +142,6 @@ void BansheeFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pBansheePlaylistModel); m_pLibrary->showBreadCrumb(item); enableCoverArtDisplay(true); - m_active = true; } } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 6305ace746d..bd6f7d1653e 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -140,8 +140,6 @@ void BasePlaylistFeature::activate() { restoreSearch(QString()); // Null String disables search box emit(enableCoverArtDisplay(true)); - m_featureFocus = -1; - m_active = true; } void BasePlaylistFeature::activateChild(const QModelIndex& index) { @@ -162,15 +160,12 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { // Set the feature Focus for a moment to allow the LibraryFeature class // to find the focused WTrackTable - m_featureFocus = m_focusedPane; showTrackModel(m_pPlaylistTableModel); - m_featureFocus = -1; restoreSearch(""); showBreadCrumb(index); emit(enableCoverArtDisplay(true)); - m_active = true; } } @@ -184,7 +179,6 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); activateChild(m_lastRightClickedIndex); - m_active = true; } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index e77403b1be2..ed6209b03dd 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -241,7 +241,6 @@ void BrowseFeature::activate() { m_pLibrary->restoreSearch(QString()); enableCoverArtDisplay(true); - m_active = true; } // Note: This is executed whenever you single click on an child item diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 5579af85916..4c1a32690bd 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -130,6 +130,10 @@ QString CrateFeature::getSettingsName() const { return "CrateFeature"; } +bool CrateFeature::isSinglePane() const { + return false; +} + int CrateFeature::crateIdFromIndex(QModelIndex index) { TreeItem* item = static_cast(index.internalPointer()); if (item == nullptr) { @@ -237,7 +241,6 @@ void CrateFeature::activate() { restoreSearch(QString()); //disable search on crate home m_featureFocus = -1; emit(enableCoverArtDisplay(true)); - m_active = true; } void CrateFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 5ef25aac3e6..4b50221e967 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -34,6 +34,7 @@ class CrateFeature : public LibraryFeature { QVariant title() override; QString getIconPath() override; QString getSettingsName() const override; + bool isSinglePane() const override; void onSearch(QString&) {} diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 634e8b52f1e..f727c5ba548 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -123,7 +123,6 @@ QString ITunesFeature::getSettingsName() const { void ITunesFeature::activate() { activate(false); enableCoverArtDisplay(true); - m_active = true; } void ITunesFeature::activate(bool forceReload) { @@ -186,7 +185,6 @@ void ITunesFeature::activate(bool forceReload) { showTrackModel(m_pITunesTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); - m_active = true; } void ITunesFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/library.cpp b/src/library/library.cpp index 100620797f2..e6e4f2358ee 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -291,9 +291,10 @@ void Library::onSkinLoadFinished() { while (itP != m_panes.end() && itF != m_features.end()) { m_focusedPane = itP.key(); - (*itF)->setFeatureFocus(itP.key()); + (*itF)->setFeatureFocus(m_focusedPane); + (*itF)->setSavedPane(m_focusedPane); (*itF)->activate(); - m_savedFeatures[itP.key()] = *itF; + m_savedFeatures[m_focusedPane] = *itF; ++itP; ++itF; @@ -427,7 +428,7 @@ void Library::paneUncollapsed(int paneId) { void Library::slotActivateFeature(LibraryFeature* pFeature) { // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { - pFeature->setFeatureFocus(m_focusedPane); + pFeature->setSavedPane(m_focusedPane); m_pSidebarExpanded->switchToFeature(pFeature); handleFocus(); return; @@ -435,29 +436,13 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { if (m_pSidebarExpanded->getCurrentFeature() != pFeature) { // If the feature is not already shown, follow restore in old pane - int featureFocus = pFeature->getFeatureFocus(); + int featureFocus = pFeature->getSavedPane(); if (featureFocus >= 0 && !m_collapsedPanes.contains(featureFocus)) { // The feature is shown in some not collapsed pane m_focusedPane = featureFocus; setFocusedPane(); - - /* - if (pFeature->getActive()) { - m_pSidebarExpanded->switchToFeature(pFeature); - handleFocus(); - return; - } - */ } } - - // Set all features in this pane inactive - /*for (LibraryFeature* f : m_features) { - if (f->getFeatureFocus() == m_focusedPane && - pFeature->getActive()) { - f->setInactive(); - } - } */ LibraryFeature* pCurrentFeature = m_panes[m_focusedPane]->getCurrentFeature(); if (pCurrentFeature != pFeature && @@ -466,13 +451,13 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { // focus to the other pane for (LibraryPaneManager* p : m_panes) { if (p->getCurrentFeature() == pCurrentFeature) { - pCurrentFeature->setFeatureFocus(p->getPaneId()); + pCurrentFeature->setSavedPane(p->getPaneId()); } } } m_panes[m_focusedPane]->setCurrentFeature(pFeature); - pFeature->setFeatureFocus(m_focusedPane); + pFeature->setSavedPane(m_focusedPane); pFeature->activate(); handleFocus(); } @@ -500,6 +485,7 @@ void Library::slotPaneFocused(LibraryPaneManager* pPane) { if (pPane != m_pSidebarExpanded) { m_focusedPane = pPane->getPaneId(); + pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 5bdafcccd11..5d3da550f3e 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -37,7 +37,7 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), m_featureFocus(-1), m_focusedPane(-1), - m_active(false) { + m_savedPane(-1) { } LibraryFeature::~LibraryFeature() { @@ -47,6 +47,10 @@ QString LibraryFeature::getSettingsName() const { return QString(""); } +bool LibraryFeature::isSinglePane() const { + return true; +} + QIcon LibraryFeature::getIcon() { return WPixmapStore::getLibraryIcon(getIconPath()); } @@ -107,16 +111,21 @@ int LibraryFeature::getFeatureFocus() { return m_featureFocus; } -bool LibraryFeature::getActive() const { - return m_active; +void LibraryFeature::setFocusedPane(int paneId) { + m_focusedPane = paneId; +} + +int LibraryFeature::getFocusedPane() { + return m_focusedPane; } -void LibraryFeature::setInactive() { - m_active = false; +void LibraryFeature::setSavedPane(int paneId) { + m_savedPane = paneId; + setFocusedPane(m_savedPane); } -void LibraryFeature::setFocusedPane(int paneId) { - m_focusedPane = paneId; +int LibraryFeature::getSavedPane() { + return m_savedPane; } SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery query) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 62d6350d505..eb6e9c87e79 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -43,6 +43,7 @@ class LibraryFeature : public QObject { // This name must be unique for each feature virtual QString getSettingsName() const; + virtual bool isSinglePane() const; QIcon getIcon(); @@ -69,11 +70,13 @@ class LibraryFeature : public QObject { virtual TreeItemModel* getChildModel() = 0; virtual void setFeatureFocus(int focus); - virtual int getFeatureFocus(); - virtual bool getActive() const; - virtual void setInactive(); + int getFeatureFocus(); - virtual void setFocusedPane(int paneId); + void setFocusedPane(int paneId); + int getFocusedPane(); + + void setSavedPane(int paneId); + int getSavedPane(); virtual SavedSearchQuery saveQuery(SavedSearchQuery query); virtual void restoreQuery(int id); @@ -150,7 +153,7 @@ class LibraryFeature : public QObject { int m_featureFocus; int m_focusedPane; - bool m_active; + int m_savedPane; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 1d86a16d429..031e1ce3023 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -48,7 +48,6 @@ void MaintenanceFeature::activate() { switchToFeature(); emit(enableCoverArtDisplay(true)); - m_active = true; } void MaintenanceFeature::selectionChanged(const QItemSelection&, diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index b01599e881f..968e38a9728 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -177,7 +177,6 @@ void MixxxLibraryFeature::activate() { showBreadCrumb(); emit(enableCoverArtDisplay(true)); - m_active = true; } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 99d4b10f98a..cf729346e67 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -44,6 +44,10 @@ QString PlaylistFeature::getSettingsName() const { return "PlaylistFeature"; } +bool PlaylistFeature::isSinglePane() const { + return false; +} + void PlaylistFeature::onRightClick(const QPoint& globalPos) { m_lastRightClickedIndex = QModelIndex(); diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 9d5cabce963..23ae5f98623 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -29,6 +29,7 @@ class PlaylistFeature : public BasePlaylistFeature { QVariant title() override; QString getIconPath() override; QString getSettingsName() const override; + bool isSinglePane() const override; bool dragMoveAccept(QUrl url); bool dropAcceptChild(const QModelIndex& index, QList urls, QObject* pSource); diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index ef83eba0d8e..36046aae222 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -76,7 +76,6 @@ void RecordingFeature::activate() { restoreSearch(""); enableCoverArtDisplay(true); - m_active = true; } BrowseTableModel* RecordingFeature::getBrowseTableModel() { diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 9e17d37a1a6..64fb5086356 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -138,7 +138,6 @@ void RhythmboxFeature::activate() { showTrackModel(m_pRhythmboxTrackModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); - m_active = true; } void RhythmboxFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 81b9de149c7..64325e8bfad 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -166,7 +166,6 @@ void TraktorFeature::activate() { showTrackModel(m_pTraktorTableModel); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); enableCoverArtDisplay(true); - m_active = true; } void TraktorFeature::activateChild(const QModelIndex& index) { From 72aca73da98b714cf937fa5c84ef511f0a8b66ee Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 16:49:44 +0200 Subject: [PATCH 415/552] Fix small issues --- src/library/baseplaylistfeature.cpp | 5 +++++ src/library/baseplaylistfeature.h | 1 + src/library/library.cpp | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index bd6f7d1653e..d154fa9ae85 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -128,6 +128,10 @@ QPointer BasePlaylistFeature::getPlaylistTableModel(int pane } void BasePlaylistFeature::activate() { + if (m_lastChildClicked.isValid()) { + activateChild(m_lastChildClicked); + } + auto it = m_panes.find(m_featureFocus); auto itId = m_idBrowse.find(m_featureFocus); if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { @@ -143,6 +147,7 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { + m_lastChildClicked = index; //qDebug() << "BasePlaylistFeature::activateChild()" << index; QSet playlistIds = playlistIdsFromIndex(index); m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index a5da9bafc51..f17d8218bb1 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -119,6 +119,7 @@ class BasePlaylistFeature : public LibraryFeature { QModelIndex m_lastRightClickedIndex; TreeItemModel* m_childModel; TrackPointer m_pSelectedTrack; + QModelIndex m_lastChildClicked; private slots: void slotTrackSelected(TrackPointer pTrack); diff --git a/src/library/library.cpp b/src/library/library.cpp index e6e4f2358ee..e6ff33f3eec 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -446,7 +446,7 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { LibraryFeature* pCurrentFeature = m_panes[m_focusedPane]->getCurrentFeature(); if (pCurrentFeature != pFeature && - pCurrentFeature->getFeatureFocus() == m_focusedPane) { + pCurrentFeature->getSavedPane() == m_focusedPane) { // If this feature it's still shown in another pane change the feature // focus to the other pane for (LibraryPaneManager* p : m_panes) { From 2b4cebe552280bb2439b5d473ae3360169b31c41 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 19:38:49 +0200 Subject: [PATCH 416/552] Fix header arro issue --- res/skins/Deere/style.qss | 12 +++- res/skins/LateNight/image/style_sort_down.svg | 60 +++++++++++++++++++ res/skins/LateNight/image/style_sort_up.svg | 60 +++++++++++++++++++ res/skins/LateNight/style.qss | 20 ++++++- 4 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 res/skins/LateNight/image/style_sort_down.svg create mode 100644 res/skins/LateNight/image/style_sort_up.svg diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index fb8ebae3352..7bd0fabd05a 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -297,12 +297,20 @@ QHeaderView::section:selected { border-right: none; } +QHeaderView::up-arrow, +QHeaderView::down-arrow { + background: #1A1A1A; + width: 12px; + padding-left: 3px; + padding-right: 3px; +} + QHeaderView::up-arrow { - image: url(skin:/image/style_sort_up.svg) + image: url(skin:/image/style_sort_up.svg); } QHeaderView::down-arrow { - image: url(skin:/image/style_sort_down.svg) + image: url(skin:/image/style_sort_down.svg); } /* library search bar */ diff --git a/res/skins/LateNight/image/style_sort_down.svg b/res/skins/LateNight/image/style_sort_down.svg new file mode 100644 index 00000000000..f60ad295e75 --- /dev/null +++ b/res/skins/LateNight/image/style_sort_down.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/skins/LateNight/image/style_sort_up.svg b/res/skins/LateNight/image/style_sort_up.svg new file mode 100644 index 00000000000..e92f24780d7 --- /dev/null +++ b/res/skins/LateNight/image/style_sort_up.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 4280c097782..b8b949f9a0b 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1319,9 +1319,27 @@ QHeaderView::section { height: 18px; border: 1px solid #585858; border-left: 0px; - background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); +} + +QHeaderView::up-arrow, +QHeaderView::down-arrow { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); + width: 12px; + padding-left: 3px; + padding-right: 3px; + border-bottom: 1px solid #585858; } +QHeaderView::up-arrow { + image: url(skin:/image/style_sort_up.svg); +} + +QHeaderView::down-arrow { + image: url(skin:/image/style_sort_down.svg); +} + + /* QScrollbar styling is even harder */ QScrollBar { border: 1px solid #585858; From 4cc9dc5b31b491ed5c3cfede0b3cac17e841025c Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 20:22:58 +0200 Subject: [PATCH 417/552] Fix Library/Folders tree not getting updated when adding new tracks --- src/library/libraryfoldermodel.cpp | 9 +++++++++ src/library/librarytreemodel.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index de03763f9d4..ad083133aa1 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -19,6 +19,15 @@ LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, QString recursive = m_pConfig->getValueString(ConfigKey("[Library]", "FolderRecursive")); m_folderRecursive = recursive.toInt() == 1; + + TrackDAO& trackDAO(pTrackCollection->getTrackDAO()); + connect(&trackDAO, SIGNAL(forceModelUpdate()), this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(tracksAdded(QSet)), + this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(tracksRemoved(QSet)), + this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(trackChanged(TrackId)), + this, SLOT(reloadTree())); reloadTree(); } diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 836a0384604..2a85b2671e7 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -30,6 +30,15 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, m_sortOrder = sort.split(","); } + TrackDAO& trackDAO(pTrackCollection->getTrackDAO()); + connect(&trackDAO, SIGNAL(forceModelUpdate()), this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(tracksAdded(QSet)), + this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(tracksRemoved(QSet)), + this, SLOT(reloadTree())); + connect(&trackDAO, SIGNAL(trackChanged(TrackId)), + this, SLOT(reloadTree())); + m_coverQuery << LIBRARYTABLE_COVERART_HASH << LIBRARYTABLE_COVERART_LOCATION << LIBRARYTABLE_COVERART_SOURCE From dad1c63d4d84b0170b4e10587faa393d129352df Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 21:21:28 +0200 Subject: [PATCH 418/552] Fix some features not saving last clicked item when activating --- src/library/baseplaylistfeature.cpp | 9 +++++++++ src/library/baseplaylistfeature.h | 1 + src/library/cratefeature.cpp | 6 ++++++ src/library/cratefeature.h | 1 + src/library/library.cpp | 10 ++++++---- src/library/libraryfeature.cpp | 2 +- src/library/libraryview.h | 1 + src/library/mixxxlibraryfeature.cpp | 6 ++++++ src/library/mixxxlibraryfeature.h | 1 + 9 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index d154fa9ae85..093298d89f3 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -130,6 +130,7 @@ QPointer BasePlaylistFeature::getPlaylistTableModel(int pane void BasePlaylistFeature::activate() { if (m_lastChildClicked.isValid()) { activateChild(m_lastChildClicked); + return; } auto it = m_panes.find(m_featureFocus); @@ -147,7 +148,15 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { + if (index == m_lastChildClicked && m_lastClickedFocus == m_featureFocus) { + restoreSearch(""); + showBreadCrumb(index); + switchToFeature(); + return; + } + m_lastChildClicked = index; + m_lastClickedFocus = m_featureFocus; //qDebug() << "BasePlaylistFeature::activateChild()" << index; QSet playlistIds = playlistIdsFromIndex(index); m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index f17d8218bb1..dfe955c8a23 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -120,6 +120,7 @@ class BasePlaylistFeature : public LibraryFeature { TreeItemModel* m_childModel; TrackPointer m_pSelectedTrack; QModelIndex m_lastChildClicked; + int m_lastClickedFocus; private slots: void slotTrackSelected(TrackPointer pTrack); diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 4c1a32690bd..94bb187f1ee 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -228,6 +228,11 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { + if (m_lastClickedIndex.isValid()) { + activateChild(m_lastClickedIndex); + return; + } + auto it = m_panes.find(m_featureFocus); auto itId = m_idBrowse.find(m_featureFocus); if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { @@ -244,6 +249,7 @@ void CrateFeature::activate() { } void CrateFeature::activateChild(const QModelIndex& index) { + m_lastClickedIndex = index; if (!index.isValid()) { return; } diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 4b50221e967..6b3651087f5 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -116,6 +116,7 @@ class CrateFeature : public LibraryFeature { QHash > m_panes; QHash m_idBrowse; QHash m_idTable; + QModelIndex m_lastClickedIndex; }; #endif /* CRATEFEATURE_H */ diff --git a/src/library/library.cpp b/src/library/library.cpp index e6ff33f3eec..c28b66124a1 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -436,10 +436,10 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { if (m_pSidebarExpanded->getCurrentFeature() != pFeature) { // If the feature is not already shown, follow restore in old pane - int featureFocus = pFeature->getSavedPane(); - if (featureFocus >= 0 && !m_collapsedPanes.contains(featureFocus)) { + int savedPane = pFeature->getSavedPane(); + if (savedPane >= 0 && !m_collapsedPanes.contains(savedPane)) { // The feature is shown in some not collapsed pane - m_focusedPane = featureFocus; + m_focusedPane = savedPane; setFocusedPane(); } } @@ -450,8 +450,10 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { // If this feature it's still shown in another pane change the feature // focus to the other pane for (LibraryPaneManager* p : m_panes) { - if (p->getCurrentFeature() == pCurrentFeature) { + if (!m_collapsedPanes.contains(p->getPaneId()) && + p->getCurrentFeature() == pCurrentFeature) { pCurrentFeature->setSavedPane(p->getPaneId()); + break; } } } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 5d3da550f3e..3cf942cc196 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -121,7 +121,7 @@ int LibraryFeature::getFocusedPane() { void LibraryFeature::setSavedPane(int paneId) { m_savedPane = paneId; - setFocusedPane(m_savedPane); + setFeatureFocus(m_savedPane); } int LibraryFeature::getSavedPane() { diff --git a/src/library/libraryview.h b/src/library/libraryview.h index 7e589b322e8..c40e6d8009d 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -7,6 +7,7 @@ #ifndef LIBRARYVIEW_H #define LIBRARYVIEW_H +#include #include class LibraryView { diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 968e38a9728..2cab596055e 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -171,6 +171,11 @@ void MixxxLibraryFeature::setChildModel(TreeItemModel* pChild) { } void MixxxLibraryFeature::activate() { + if (m_lastClickedIndex.isValid()) { + activateChild(m_lastClickedIndex); + return; + } + //qDebug() << "MixxxLibraryFeature::activate()"; showTrackModel(m_pLibraryTableModel); restoreSearch(""); @@ -180,6 +185,7 @@ void MixxxLibraryFeature::activate() { } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { + m_lastClickedIndex = index; QString query = index.data(TreeItemModel::RoleQuery).toString(); //qDebug() << "MixxxLibraryFeature::activateChild" << query; diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 4a606399c1d..6d9e3284f80 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -80,6 +80,7 @@ class MixxxLibraryFeature : public LibraryFeature { QPointer m_pSidebar; LibraryTableModel* m_pLibraryTableModel; TrackDAO& m_trackDao; + QModelIndex m_lastClickedIndex; }; #endif /* MIXXXLIBRARYFEATURE_H */ From fbc6eab4988599cef8c4c7eafe82a0cb8f7f00fd Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 18 Aug 2016 21:21:58 +0200 Subject: [PATCH 419/552] Fix WLibraryStack not passing focus events --- src/widget/wbaselibrary.cpp | 2 ++ src/widget/wlibrarystack.cpp | 30 +++++++++++++++++++++--------- src/widget/wlibrarystack.h | 3 +++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index ec14f9293d7..fd6527e876f 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -65,6 +65,8 @@ bool WBaseLibrary::eventFilter(QObject*, QEvent* pEvent) { bool WBaseLibrary::event(QEvent* pEvent) { if (pEvent->type() == QEvent::ToolTip) { updateTooltip(); + } else if (pEvent->type() == QEvent::FocusIn) { + emit(focused()); } return QStackedWidget::event(pEvent); diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp index 1a7c431990a..b83e5c2d2db 100644 --- a/src/widget/wlibrarystack.cpp +++ b/src/widget/wlibrarystack.cpp @@ -15,50 +15,58 @@ WLibraryStack::~WLibraryStack() { int WLibraryStack::addWidget(QWidget* w) { //qDebug() << "WLibraryStack::addWidget" << w; checkAndWarning(w); + w->installEventFilter(this); return QStackedWidget::addWidget(w); } int WLibraryStack::insertWidget(int index, QWidget* w) { checkAndWarning(w); + w->installEventFilter(this); return QStackedWidget::insertWidget(index, w); } void WLibraryStack::onShow() { - + LibraryView* pView = getCurrentView(); + if (pView) { + pView->onShow(); + } } void WLibraryStack::onSearch(const QString& text) { - LibraryView* pView = dynamic_cast(currentWidget()); - + LibraryView* pView = getCurrentView(); if (pView) { pView->onSearch(text); } } void WLibraryStack::loadSelectedTrack() { - LibraryView* pView = dynamic_cast(currentWidget()); - + LibraryView* pView = getCurrentView(); if (pView) { pView->loadSelectedTrack(); } } void WLibraryStack::slotSendToAutoDJ() { - LibraryView* pView = dynamic_cast(currentWidget()); - + LibraryView* pView = getCurrentView(); if (pView) { pView->slotSendToAutoDJ(); } } void WLibraryStack::slotSendToAutoDJTop() { - LibraryView* pView = dynamic_cast(currentWidget()); - + LibraryView* pView = getCurrentView(); if (pView) { pView->slotSendToAutoDJTop(); } } +bool WLibraryStack::eventFilter(QObject* o, QEvent* e) { + if (e->type() == QEvent::FocusIn) { + parent()->event(e); + } + return QStackedWidget::eventFilter(o, e); +} + bool WLibraryStack::checkAndWarning(QWidget* w) { if (!dynamic_cast(w)) { qDebug() << "WARNING: Attempted to register a view with WLibraryStack" @@ -67,3 +75,7 @@ bool WLibraryStack::checkAndWarning(QWidget* w) { } return true; } + +LibraryView *WLibraryStack::getCurrentView() { + return dynamic_cast(currentWidget()); +} diff --git a/src/widget/wlibrarystack.h b/src/widget/wlibrarystack.h index d37a1d62ecf..c8a7166bd7a 100644 --- a/src/widget/wlibrarystack.h +++ b/src/widget/wlibrarystack.h @@ -25,10 +25,13 @@ class WLibraryStack : public QStackedWidget, public LibraryView { void loadSelectedTrack(); void slotSendToAutoDJ(); void slotSendToAutoDJTop(); + + bool eventFilter(QObject*o, QEvent* e); private: bool checkAndWarning(QWidget *w); + LibraryView* getCurrentView(); }; #endif /* WLIBRARYSTACK_H */ From 35270f55b151114a707e93fcedb344630d42ad6c Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 10:06:21 +0200 Subject: [PATCH 420/552] Apply Danie'ls patch --- res/skins/Deere/style.qss | 10 ++++++++-- res/skins/LateNight/style.qss | 14 +++++++++++--- res/skins/Shade/skin.xml | 9 +++++---- src/widget/wlibrarybreadcrumb.cpp | 8 ++++++-- src/widget/wlibrarybreadcrumb.h | 1 - src/widget/wlibrarystack.cpp | 1 + src/widget/wverticalscrollarea.cpp | 14 ++++++++++++-- src/widget/wverticalscrollarea.h | 6 +++++- 8 files changed, 48 insertions(+), 15 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 7bd0fabd05a..7ebf109d16a 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -174,14 +174,20 @@ WBaseLibrary[showFocus="1"] { background-color: #4B4B4B; } -WLibraryBreadCrumb QLabel, -WBaseLibrary QLabel { +WLibraryBreadCrumb QLabel { margin: 4px 4px; font-size: 12px; font-weight: bold; color: #B3B3B3; } +WBaseLibrary QLabel { + margin: 4px 4px 0px 4px; + font-size: 12px; + font-weight: bold; + color: #B3B3B3; +} + #LibraryCoverArtSplitter QTabWidget { border: none; } diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index b8b949f9a0b..2fa63c0b7ce 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1226,7 +1226,7 @@ } #LibrarySidebarExpanded { - margin-left: 5px; + margin: -5px 0px 0px 5px; } #LibrarySidebarExpanded QPushButton { @@ -1262,6 +1262,7 @@ #LibrarySidebarButtons WButtonBar { background-color: #191919; + margin: 0px 2px 0px 0px; } #LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { @@ -1276,7 +1277,14 @@ } WLibraryBreadCrumb QLabel { - margin: 4px 2px; + margin: 4px 0px 6px 3px; +} + +WBaseLibrary QLabel { + padding: 0px 0px 0px 0px; + margin: 100px 100px 100px 100px; + background-color: blue; + border: 0px solid blue; } /* checkbox in library "Played" column */ @@ -1456,4 +1464,4 @@ WLibrary[showFocus="0"] { WLibrary[showFocus="1"] { padding: 2px 0 0 0; border-top: 2px solid #FF7100 !important; -} \ No newline at end of file +} diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 887a80f9bc7..67dced43d27 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -427,8 +427,8 @@ WSearchLineEdit { - margin: 0px 0px 5px 5px; - padding: 2px; + margin: 3px 0px 3px 0px; + padding: 1px; border: 1px solid #656565; font: 12px/14px sans-serif; font-family: "Open Sans"; @@ -577,7 +577,7 @@ } WLibraryBreadCrumb QLabel { - margin: 2px 4px; + margin: 2px 0px 2px 3px; } WBaseLibrary QLabel { @@ -838,14 +838,15 @@ vertical 8,2 me,me + 30,30 LibrarySidebarExpanded + 100,100 30,30 - me,me [Library],show_coverart visible diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 17c17231729..46eefa9fce1 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -20,6 +20,9 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) setLayout(layout); } +// Do not remove this, if the minimum size hint is not 0 width then when +// the user resizes a panel with the breadcrumb it never shows elided text and +// the minimum size becomes the text lenght QSize WLibraryBreadCrumb::minimumSizeHint() const { return QSize(0, height()); } @@ -60,9 +63,10 @@ void WLibraryBreadCrumb::refreshWidth() { QFontMetrics metrics(fontMetrics()); // Measure the text for the label width - int mLText, mRText; + int mLText, mRText, mLIcon, mRIcon; m_pText->getContentsMargins(&mLText, nullptr, &mRText, nullptr); - int margins = mLText + mRText; + m_pIcon->getContentsMargins(&mLIcon, nullptr, &mRIcon, nullptr); + int margins = mLText + mRText + layout()->spacing() + mLIcon + mRIcon; int newSize = width() - m_pIcon->width() - margins; QString elidedText = metrics.elidedText(m_longText, Qt::ElideRight, newSize); diff --git a/src/widget/wlibrarybreadcrumb.h b/src/widget/wlibrarybreadcrumb.h index 3aff6c98ebb..f5a996a156a 100644 --- a/src/widget/wlibrarybreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -13,7 +13,6 @@ class WLibraryBreadCrumb : public QWidget { WLibraryBreadCrumb(QWidget* parent = nullptr); - virtual QSize minimumSizeHint() const; public slots: diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp index b83e5c2d2db..141bad38e87 100644 --- a/src/widget/wlibrarystack.cpp +++ b/src/widget/wlibrarystack.cpp @@ -1,4 +1,5 @@ #include +#include #include "widget/wlibrarystack.h" diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index e712ea91b1f..174eca43406 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -17,13 +17,23 @@ void WVerticalScrollArea::setWidget(QWidget* widget) { QScrollArea::setWidget(widget); } +bool WVerticalScrollArea::eventFilter(QObject* o, QEvent* e) { + if (o == widget() && e->type() == QEvent::Resize) { + calcSize(); + } + return false; +} + void WVerticalScrollArea::resizeEvent(QResizeEvent *e) { QScrollArea::resizeEvent(e); - + calcSize(); +} + +void WVerticalScrollArea::calcSize() { int width = widget()->minimumSizeHint().width(); int vScrollWidth = 0; - if (e->size().height() <= widget()->minimumSizeHint().height()) { + if (height() <= widget()->minimumSizeHint().height()) { vScrollWidth = verticalScrollBar()->width(); } setFixedWidth(width + vScrollWidth); diff --git a/src/widget/wverticalscrollarea.h b/src/widget/wverticalscrollarea.h index 92f6795848c..74ab5ca49d2 100644 --- a/src/widget/wverticalscrollarea.h +++ b/src/widget/wverticalscrollarea.h @@ -11,7 +11,11 @@ class WVerticalScrollArea : public QScrollArea void setWidget(QWidget* widget); protected: - virtual void resizeEvent(QResizeEvent* e); + bool eventFilter(QObject* o, QEvent* e) override; + void resizeEvent(QResizeEvent* e) override; + + private: + void calcSize(); }; #endif // WVERTICALSCROLLAREA_H From 03cbcf98b59455abab7263f29cfe52c7b2fd69c0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 10:17:49 +0200 Subject: [PATCH 421/552] Add new Focus change behavior --- src/library/library.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index c28b66124a1..74a59385a57 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -285,11 +285,19 @@ void Library::onSkinLoadFinished() { auto itF = m_features.begin(); auto itP = m_panes.begin(); + bool first = true; // Assign a feature to show on each pane unless there are more panes // than features while (itP != m_panes.end() && itF != m_features.end()) { m_focusedPane = itP.key(); + if (first) { + first = false; + // Set the first pane as saved pane to all features + for (LibraryFeature* pFeature : m_features) { + pFeature->setSavedPane(m_focusedPane); + } + } (*itF)->setFeatureFocus(m_focusedPane); (*itF)->setSavedPane(m_focusedPane); @@ -432,7 +440,7 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->switchToFeature(pFeature); handleFocus(); return; - } + } if (m_pSidebarExpanded->getCurrentFeature() != pFeature) { // If the feature is not already shown, follow restore in old pane @@ -442,16 +450,25 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { m_focusedPane = savedPane; setFocusedPane(); } + } else if (pFeature->isSinglePane()) { + // Swap panes in case of a single Pane feature + LibraryFeature* pOldFeature = m_panes[m_focusedPane]->getCurrentFeature(); + int newFocusPane = m_focusedPane; + m_focusedPane = pFeature->getSavedPane(); + m_panes[m_focusedPane]->setCurrentFeature(pOldFeature); + pOldFeature->setSavedPane(m_focusedPane); + pOldFeature->activate(); + m_focusedPane = newFocusPane; } LibraryFeature* pCurrentFeature = m_panes[m_focusedPane]->getCurrentFeature(); if (pCurrentFeature != pFeature && - pCurrentFeature->getSavedPane() == m_focusedPane) { + pCurrentFeature->getSavedPane() == m_focusedPane) { // If this feature it's still shown in another pane change the feature // focus to the other pane for (LibraryPaneManager* p : m_panes) { if (!m_collapsedPanes.contains(p->getPaneId()) && - p->getCurrentFeature() == pCurrentFeature) { + p->getCurrentFeature() == pCurrentFeature) { pCurrentFeature->setSavedPane(p->getPaneId()); break; } From e2558e5822ad47726310057ba9e44c43a8223bb3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 13:34:31 +0200 Subject: [PATCH 422/552] Fix enter key not acting as click in sidebar --- src/library/libraryfeature.cpp | 5 ++--- src/library/libraryfeature.h | 2 +- src/widget/wlibrarysidebar.cpp | 20 ++++---------------- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 3cf942cc196..3014e8b4e1a 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -188,9 +188,8 @@ QWidget* LibraryFeature::createInnerSidebarWidget(KeyboardEventFilter *pKeyboard return createLibrarySidebarWidget(pKeyboard); } -WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter *pKeyboard) { +WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter*) { WLibrarySidebar* pSidebar = new WLibrarySidebar(nullptr); - pSidebar->installEventFilter(pKeyboard); QAbstractItemModel* pModel = getChildModel(); pSidebar->setModel(pModel); @@ -202,7 +201,7 @@ WLibrarySidebar *LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter pMiniView->setModel(pModel); pSidebar->setVerticalScrollBar(pMiniView); - connect(pSidebar, SIGNAL(clicked(const QModelIndex&)), + connect(pSidebar, SIGNAL(pressed(const QModelIndex&)), this, SLOT(activateChild(const QModelIndex&))); connect(pSidebar, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onLazyChildExpandation(const QModelIndex&))); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index eb6e9c87e79..09679f00c50 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -130,7 +130,7 @@ class LibraryFeature : public QObject { // Creates a WLibrarySidebar widget with the getChildModel() function as // model - WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter* pKeyboard); + WLibrarySidebar* createLibrarySidebarWidget(KeyboardEventFilter*); // Override this function to create a custom inner widget for the sidebar, // the default widget is a WLibrarySidebar widget diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 75e0021da01..b6eff73812a 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -227,28 +227,16 @@ void WLibrarySidebar::toggleSelectedItem() { emit(pressed(index)); // Expand or collapse the item as necessary. setExpanded(index, !isExpanded(index)); + } } void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Return) { + qDebug() << event->text() << (bool) (event->key() == Qt::Key_Return); + + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { toggleSelectedItem(); return; - } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Up) { - // Let the tree view move up and down for us. - QTreeView::keyPressEvent(event); - - // But force the index to be activated/clicked after the selection - // changes. (Saves you from having to push "enter" after changing the - // selection.) - QModelIndexList selectedIndices = this->selectionModel()->selectedRows(); - - //Note: have to get the selected indices _after_ QTreeView::keyPressEvent() - if (selectedIndices.size() > 0) { - QModelIndex index = selectedIndices.at(0); - emit(pressed(index)); - } - return; } // Fall through to deafult handler. From e624d6de6b2a891ebeeeb3aef98003b43089d316 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 13:47:15 +0200 Subject: [PATCH 423/552] Fix not clearing breadcrumb on query change --- src/library/mixxxlibraryfeature.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 2cab596055e..613221fcd98 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -153,6 +153,7 @@ void MixxxLibraryFeature::selectAll() { } void MixxxLibraryFeature::onSearch(const QString&) { + showBreadCrumb(); m_pSidebar->clearSelection(); } From cccb89212f658431d035445c787889492d0fac55 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 13:58:14 +0200 Subject: [PATCH 424/552] Fix slider showing empty area some times --- src/widget/wminiviewscrollbar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 52761214c91..1696adac0c9 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -171,8 +171,6 @@ void WMiniViewScrollBar::refreshCharMap() { } int size = m_pModel->rowCount(); - setMinimum(0); - setMaximum(size); const QModelIndex& rootIndex = m_pModel->index(0, 0); m_letters.clear(); From 92e55523a38d2cbd0993b79daa00d9d0e7e65141 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 19 Aug 2016 17:02:10 +0200 Subject: [PATCH 425/552] Fix issue with WLibraryBreadcrumb height --- src/widget/wlibrarybreadcrumb.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 46eefa9fce1..9a676de01d3 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -7,7 +7,7 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) : QWidget(parent) { QHBoxLayout* layout = new QHBoxLayout(this); - m_pIcon = new QLabel(this); + m_pIcon = new QLabel(this); m_pText = new QLabel(this); layout->addWidget(m_pIcon); layout->addWidget(m_pText); @@ -24,7 +24,7 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) // the user resizes a panel with the breadcrumb it never shows elided text and // the minimum size becomes the text lenght QSize WLibraryBreadCrumb::minimumSizeHint() const { - return QSize(0, height()); + return QSize(0, m_pText->height()); } void WLibraryBreadCrumb::showBreadCrumb(TreeItem* pTree) { @@ -44,7 +44,7 @@ void WLibraryBreadCrumb::showBreadCrumb(const QString& text, const QIcon& icon) void WLibraryBreadCrumb::setBreadIcon(const QIcon& icon) { // Get font height - int height = fontMetrics().height(); + int height = m_pText->fontMetrics().height(); m_pIcon->setPixmap(icon.pixmap(height)); } From 90728c8e3e75d6ec6e8aafe559822fc853b3d861 Mon Sep 17 00:00:00 2001 From: jmigual Date: Sun, 21 Aug 2016 14:30:03 +0200 Subject: [PATCH 426/552] Fix issue with WMiniViewScrollBar and legacy skins --- src/widget/wminiviewscrollbar.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 1696adac0c9..4238cf81145 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -79,6 +79,8 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { QStylePainter painter(this); QStyleOptionSlider opt(getStyleOptions()); + opt.subControls &= ~(QStyle::SC_ScrollBarSlider); + painter.drawComplexControl(QStyle::CC_ScrollBar, opt); painter.setBrush(palette().color(QPalette::Text)); @@ -102,13 +104,11 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { painter.drawText(QRect(topLeft, topLeft + bottom), flags, p.character); } + opt.subControls = QStyle::SC_ScrollBarSlider; opt.rect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this); - opt.subControls = QStyle::SC_ScrollBarSlider; - opt.activeSubControls = QStyle::SC_ScrollBarSlider; + //painter.drawComplexControl(QStyle::CC_ScrollBar, opt); painter.drawControl(QStyle::CE_ScrollBarSlider, opt); - painter.drawControl(QStyle::CE_ScrollBarAddLine, opt); - painter.drawControl(QStyle::CE_ScrollBarSubLine, opt); } void WMiniViewScrollBar::resizeEvent(QResizeEvent* pEvent) { @@ -250,8 +250,9 @@ void WMiniViewScrollBar::triggerUpdate() { QStyleOptionSlider WMiniViewScrollBar::getStyleOptions() { QStyleOptionSlider opt; opt.init(this); - opt.subControls = QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine; - opt.activeSubControls = QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine; + opt.subControls = QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine | + QStyle::SC_ScrollBarFirst | QStyle::SC_ScrollBarLast | + QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarSlider; opt.orientation = orientation(); opt.minimum = minimum(); opt.maximum = maximum(); From 0aa96a2084cc9531eeb7308bc8d77649231a83c7 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 09:51:16 +0200 Subject: [PATCH 427/552] Fix Browse Feature not remembering clicked items --- src/library/browse/browsefeature.cpp | 6 ++++++ src/library/browse/browsefeature.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index ed6209b03dd..591523a55c3 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -229,6 +229,11 @@ QWidget* BrowseFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, } void BrowseFeature::activate() { + if (m_lastClickedChild.isValid()) { + activateChild(m_lastClickedChild); + return; + } + auto it = m_panes.find(m_featureFocus); auto itId = m_idBrowse.find(m_featureFocus); if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { @@ -246,6 +251,7 @@ void BrowseFeature::activate() { // Note: This is executed whenever you single click on an child item // Single clicks will not populate sub folders void BrowseFeature::activateChild(const QModelIndex& index) { + m_lastClickedChild = index; QString data = index.data().toString(); QString dataPath = index.data(TreeItemModel::RoleDataPath).toString(); qDebug() << "BrowseFeature::activateChild " << data << dataPath; diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 92cdb75b9e2..1eb46ca97b9 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -77,6 +77,7 @@ class BrowseFeature : public LibraryFeature { TreeItem* m_pLastRightClickedItem; TreeItem* m_pQuickLinkItem; QStringList m_quickLinkList; + QModelIndex m_lastClickedChild; QHash > m_panes; QHash m_idBrowse; From e1779e8d40167c076c325a13ae8f58c7c210caee Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 11:17:06 +0200 Subject: [PATCH 428/552] Fix Crates/Playlists showing all the menu when right clicking empty area --- src/library/cratefeature.cpp | 28 ++++++++++++++++------------ src/library/playlistfeature.cpp | 30 +++++++++++++++++------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 94bb187f1ee..b353f2a1eb0 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -320,21 +320,25 @@ void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) m_pLockCrateAction->setText(locked ? tr("Unlock") : tr("Lock")); - QMenu menu(NULL); + QMenu menu(nullptr); menu.addAction(m_pCreateCrateAction); menu.addSeparator(); - menu.addAction(m_pRenameCrateAction); - menu.addAction(m_pDuplicateCrateAction); - menu.addAction(m_pDeleteCrateAction); - menu.addAction(m_pLockCrateAction); - menu.addSeparator(); - menu.addAction(m_pAutoDjTrackSource); - menu.addSeparator(); - menu.addAction(m_pAnalyzeCrateAction); - menu.addSeparator(); + if (crateId >= 0) { + menu.addAction(m_pRenameCrateAction); + menu.addAction(m_pDuplicateCrateAction); + menu.addAction(m_pDeleteCrateAction); + menu.addAction(m_pLockCrateAction); + menu.addSeparator(); + menu.addAction(m_pAutoDjTrackSource); + menu.addSeparator(); + menu.addAction(m_pAnalyzeCrateAction); + menu.addSeparator(); + } menu.addAction(m_pImportPlaylistAction); - menu.addAction(m_pExportPlaylistAction); - menu.addAction(m_pExportTrackFilesAction); + if (crateId >= 0) { + menu.addAction(m_pExportPlaylistAction); + menu.addAction(m_pExportTrackFilesAction); + } menu.exec(globalPos); } diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index cf729346e67..1861774c21a 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -71,22 +71,26 @@ void PlaylistFeature::onRightClickChild(const QPoint& globalPos, QModelIndex ind m_pLockPlaylistAction->setText(locked ? tr("Unlock") : tr("Lock")); //Create the right-click menu - QMenu menu(NULL); + QMenu menu(nullptr); menu.addAction(m_pCreatePlaylistAction); menu.addSeparator(); - menu.addAction(m_pAddToAutoDJAction); - menu.addAction(m_pAddToAutoDJTopAction); - menu.addSeparator(); - menu.addAction(m_pRenamePlaylistAction); - menu.addAction(m_pDuplicatePlaylistAction); - menu.addAction(m_pDeletePlaylistAction); - menu.addAction(m_pLockPlaylistAction); - menu.addSeparator(); - menu.addAction(m_pAnalyzePlaylistAction); - menu.addSeparator(); + if (playlistId >= 0) { + menu.addAction(m_pAddToAutoDJAction); + menu.addAction(m_pAddToAutoDJTopAction); + menu.addSeparator(); + menu.addAction(m_pRenamePlaylistAction); + menu.addAction(m_pDuplicatePlaylistAction); + menu.addAction(m_pDeletePlaylistAction); + menu.addAction(m_pLockPlaylistAction); + menu.addSeparator(); + menu.addAction(m_pAnalyzePlaylistAction); + menu.addSeparator(); + } menu.addAction(m_pImportPlaylistAction); - menu.addAction(m_pExportPlaylistAction); - menu.addAction(m_pExportTrackFilesAction); + if (playlistId >= 0) { + menu.addAction(m_pExportPlaylistAction); + menu.addAction(m_pExportTrackFilesAction); + } menu.exec(globalPos); } From 4df6c07b0d94e5d45e5dd32d2533d17fd54b149e Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 11:17:18 +0200 Subject: [PATCH 429/552] Fix playlists not being able to export --- src/library/baseplaylistfeature.cpp | 6 ++++-- src/library/baseplaylistfeature.h | 2 +- src/library/playlisttablemodel.cpp | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 093298d89f3..1928d6890dd 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -459,9 +459,11 @@ void BasePlaylistFeature::slotCreateImportPlaylist() { } void BasePlaylistFeature::slotExportPlaylist() { - if (!m_pPlaylistTableModel) { + QPointer pTableModel = getPlaylistTableModel(); + if (pTableModel.isNull()) { return; } + int playlistId = playlistIdFromIndex(m_lastRightClickedIndex); if (playlistId == -1) { return; @@ -512,7 +514,7 @@ void BasePlaylistFeature::slotExportPlaylist() { new PlaylistTableModel(this, m_pTrackCollection, "mixxx.db.model.playlist_export")); - pPlaylistTableModel->setTableModel(m_pPlaylistTableModel->getPlaylist()); + pPlaylistTableModel->setTableModel(pTableModel->getPlaylist()); pPlaylistTableModel->setSort(pPlaylistTableModel->fieldIndex( ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION), Qt::AscendingOrder); pPlaylistTableModel->select(); diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index dfe955c8a23..54ed01f5b1b 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -89,7 +89,7 @@ class BasePlaylistFeature : public LibraryFeature { virtual void addToAutoDJ(bool bTop); QString getValidPlaylistName() const; - QPointer getPlaylistTableModel(int paneId); + QPointer getPlaylistTableModel(int paneId = -1); virtual PlaylistTableModel* constructTableModel() = 0; virtual QSet playlistIdsFromIndex(const QModelIndex& index) const; diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp index bcc06c447ee..4c702cfbb41 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/playlisttablemodel.cpp @@ -33,6 +33,8 @@ void PlaylistTableModel::setTableModel(const QSet &playlistIds) { if (playlistIds.size() > 1) { // If we are showing many playlist at once this is not a real playlist m_iPlaylistId = -1; + } else { + m_iPlaylistId = *playlistIds.begin(); } m_playlistIds = playlistIds; From ddcd423e29f589969631a2a57f9d23168225384c Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 11:34:06 +0200 Subject: [PATCH 430/552] Fix height in WLibraryBreadcrumb --- src/widget/wlibrarybreadcrumb.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 9a676de01d3..2c02a1efcad 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -24,7 +24,8 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) // the user resizes a panel with the breadcrumb it never shows elided text and // the minimum size becomes the text lenght QSize WLibraryBreadCrumb::minimumSizeHint() const { - return QSize(0, m_pText->height()); + QSize min = m_pText->minimumSizeHint(); + return QSize(0, min.height()); } void WLibraryBreadCrumb::showBreadCrumb(TreeItem* pTree) { @@ -44,8 +45,10 @@ void WLibraryBreadCrumb::showBreadCrumb(const QString& text, const QIcon& icon) void WLibraryBreadCrumb::setBreadIcon(const QIcon& icon) { // Get font height - int height = m_pText->fontMetrics().height(); - m_pIcon->setPixmap(icon.pixmap(height)); + int height = m_pText->fontMetrics().height(); + QPixmap pix = icon.pixmap(height); + m_pIcon->setContentsMargins(0, 0, 0, 0); + m_pIcon->setPixmap(pix); } void WLibraryBreadCrumb::resizeEvent(QResizeEvent* pEvent) { From c56b0d87180c980eb1488ac14305051efab90414 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 11:38:36 +0200 Subject: [PATCH 431/552] Fix crash when canceling a playlist import --- src/library/cratefeature.cpp | 10 ++++++---- src/library/libraryfeature.h | 6 +++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index b353f2a1eb0..5754a0614ad 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -622,15 +622,17 @@ void CrateFeature::clearChildModel() { void CrateFeature::slotImportPlaylist() { //qDebug() << "slotImportPlaylist() row:" ; //<< m_lastRightClickedIndex.data(); - QString playlist_file = getPlaylistFile(); - if (playlist_file.isEmpty()) return; + QString playlistFile = getPlaylistFile(); + if (playlistFile.isEmpty()) { + return; + } // Update the import/export crate directory - QFileInfo fileName(playlist_file); + QFileInfo fileName(playlistFile); m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), ConfigValue(fileName.dir().absolutePath())); - slotImportPlaylistFile(playlist_file); + slotImportPlaylistFile(playlistFile); activateChild(m_lastRightClickedIndex); } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 09679f00c50..e5ab1b66fd6 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -121,7 +121,11 @@ class LibraryFeature : public QObject { return getPlaylistFiles(QFileDialog::ExistingFiles); } inline QString getPlaylistFile() { - return getPlaylistFiles(QFileDialog::ExistingFile).first(); + QStringList files(getPlaylistFiles(QFileDialog::ExistingFile)); + if (files.isEmpty()) { + return QString(); + } + return files.first(); } // Creates a table widget with no model From 9d6f838525b00599d473940197c8a838e75d25c2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 17:42:15 +0200 Subject: [PATCH 432/552] Fix that it was possible to store repeated queries in the database --- src/library/dao/savedqueriesdao.cpp | 19 ++++++++++++++++ src/library/dao/savedqueriesdao.h | 5 +++++ src/library/libraryfeature.cpp | 16 ++++++++++--- src/library/libraryfeature.h | 2 +- src/widget/wsearchlineedit.cpp | 35 ++++++++++++++++------------- 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 90a93fdf45f..23192dd03be 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -117,6 +117,25 @@ SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) return moveToFirst(pFeature, getSavedQuery(id)); } +bool SavedQueriesDAO::exists(const SavedSearchQuery& sQuery) { + return getQueryId(sQuery) >= 0; +} + +int SavedQueriesDAO::getQueryId(const SavedSearchQuery& sQuery) { + QSqlQuery query(m_database); + query.prepare("SELECT id FROM " SAVEDQUERYTABLE " " + "WHERE query=:query AND title=:title"); + query.bindValue(":query", sQuery.query); + query.bindValue(":title", sQuery.title); + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + if (query.next()) { + return query.value(0).toInt(); + } + return -1; +} + QString SavedQueriesDAO::serializeItems(const QSet& items) { QStringList ret; diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 53eeb08465c..37f741932de 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -23,6 +23,9 @@ struct SavedSearchQuery { SavedSearchQuery(const SavedSearchQuery& other) = default; SavedSearchQuery& operator=(const SavedSearchQuery& other) = default; + bool operator==(const SavedSearchQuery& other) const { + return other.title == this->title && other.query == this->query; + } QString query; QString title; @@ -50,6 +53,8 @@ class SavedQueriesDAO : public DAO SavedSearchQuery getSavedQuery(int id) const; SavedSearchQuery moveToFirst(LibraryFeature* pFeature, const SavedSearchQuery& sQuery); SavedSearchQuery moveToFirst(LibraryFeature* pFeature, int id); + bool exists(const SavedSearchQuery& sQuery); + int getQueryId(const SavedSearchQuery& sQuery); private: static QString serializeItems(const QSet& items); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 3014e8b4e1a..73c988d6b06 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -128,16 +129,25 @@ int LibraryFeature::getSavedPane() { return m_savedPane; } -SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery query) { +SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery sQuery) { WTrackTableView* pTable = getFocusedTable(); if (pTable == nullptr) { return SavedSearchQuery(); } - query = pTable->saveQuery(query); + sQuery = pTable->saveQuery(sQuery); + if (m_savedDAO.exists(sQuery)) { + QMessageBox::warning(nullptr, + tr("Query already exists"), + tr("The query with title: \"%1\" and query: \"%2\"" + " already exists in the database") + .arg(sQuery.title, sQuery.query)); + m_savedDAO.moveToFirst(this, m_savedDAO.getQueryId(sQuery)); + return sQuery; + } // A saved query goes the first in the list - return m_savedDAO.saveQuery(this, query); + return m_savedDAO.saveQuery(this, sQuery); } void LibraryFeature::restoreQuery(int id) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index e5ab1b66fd6..8299e9392d9 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -78,7 +78,7 @@ class LibraryFeature : public QObject { void setSavedPane(int paneId); int getSavedPane(); - virtual SavedSearchQuery saveQuery(SavedSearchQuery query); + virtual SavedSearchQuery saveQuery(SavedSearchQuery sQuery); virtual void restoreQuery(int id); virtual QList getSavedQueries() const; diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 6f3962cd132..624c74d3fd4 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -283,26 +283,29 @@ void WSearchLineEdit::onSearchTextCleared() { } void WSearchLineEdit::saveQuery() { + if (m_pCurrentFeature.isNull()) { + return; + } + SavedSearchQuery query; query.title = query.query = text(); - if (!m_pCurrentFeature.isNull()) { - if (query.title.isEmpty()) { - // Request a title - bool ok = false; - query.title = - QInputDialog::getText(nullptr, - tr("Create search query"), - tr("Enter name for empty search query"), - QLineEdit::Normal, - tr("New query"), - &ok).trimmed(); - if (ok == false) { - return; - } + + if (query.title.isEmpty()) { + // Request a title + bool ok = false; + query.title = + QInputDialog::getText(nullptr, + tr("Create search query"), + tr("Enter name for empty search query"), + QLineEdit::Normal, + tr("New query"), + &ok).trimmed(); + if (ok == false) { + return; } - - m_pCurrentFeature->saveQuery(query); } + + m_pCurrentFeature->saveQuery(query); m_pSaveButton->setEnabled(false); } From 8aecde159519bac12bda921d18402553e1cfedbd Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 17:54:34 +0200 Subject: [PATCH 433/552] Fix clicking on scroll helper blank space would not do as expected --- src/widget/wminiviewscrollbar.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 4238cf81145..f6565e99c52 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -148,14 +148,22 @@ void WMiniViewScrollBar::mousePressEvent(QMouseEvent* pEvent) { // In this scrollbar maximum = model.size(), minimum = 0 while (!found && itL != m_letters.end() && itC != m_computedPosition.end()) { if (itC->bold) { - found = true; setSliderPosition(totalSum); - } else { - totalSum += itL->count; + return; } + totalSum += itL->count; ++itL; ++itC; } + + // If we haven't found any bold letter it means that the user is clicking + // on the blank space so take the relative position. + int posVert = pEvent->pos().y(); + QStyleOptionSlider opt(getStyleOptions()); + int maxHeight = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarGroove, this).height(); + float size = interpolSize(posVert, maxHeight, totalSum); + setSliderPosition(size); } void WMiniViewScrollBar::leaveEvent(QEvent* pEvent) { From 00ad712ddceec7ee93ef9bf4a22a33c2a5e5329f Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 19:24:23 +0200 Subject: [PATCH 434/552] Fix crash when removing playlist --- src/library/baseplaylistfeature.cpp | 6 ++++++ src/library/historyfeature.cpp | 6 +++--- src/library/libraryfeature.cpp | 2 +- src/library/playlistfeature.cpp | 6 +++--- src/widget/wlibrarybreadcrumb.cpp | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 1928d6890dd..d00166be271 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -345,6 +345,12 @@ void BasePlaylistFeature::slotDeletePlaylist() { DEBUG_ASSERT_AND_HANDLE(playlistId >= 0) { return; } + + // This avoids a bug where the m_lastChildClicked index is still a valid + // index but it's not true since we just deleted it + if (m_lastChildClicked == m_lastRightClickedIndex) { + m_lastChildClicked = QModelIndex(); + } m_playlistDao.deletePlaylist(playlistId); activate(); diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 2bc57899caf..aa6a1861656 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -72,7 +72,7 @@ void HistoryFeature::onRightClick(const QPoint&) { void HistoryFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex &index) { //Save the model index so we can get it in the action slots... - m_lastRightClickedIndex = index; + m_lastChildClicked = m_lastRightClickedIndex = index; bool ok; int playlistId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); if (!ok || playlistId < 0) { @@ -322,7 +322,7 @@ void HistoryFeature::slotPlaylistTableChanged(int playlistId) { PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_SET_LOG || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); } } @@ -349,7 +349,7 @@ void HistoryFeature::slotPlaylistTableRenamed(int playlistId, enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_SET_LOG || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); if (type != PlaylistDAO::PLHT_UNKNOWN) { activatePlaylist(playlistId); } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 73c988d6b06..cdbd2113a6f 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -247,7 +247,7 @@ void LibraryFeature::showBreadCrumb(TreeItem *pTree) { m_pLibrary->showBreadCrumb(pTree); } -void LibraryFeature::showBreadCrumb(const QModelIndex &index) { +void LibraryFeature::showBreadCrumb(const QModelIndex& index) { showBreadCrumb(static_cast(index.internalPointer())); } diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 1861774c21a..3184493a5b1 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -61,7 +61,7 @@ void PlaylistFeature::onRightClick(const QPoint& globalPos) { void PlaylistFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { //Save the model index so we can get it in the action slots... - m_lastRightClickedIndex = index; + m_lastChildClicked = m_lastRightClickedIndex = index; int playlistId = playlistIdFromIndex(index); bool locked = m_playlistDao.isPlaylistLocked(playlistId); @@ -214,7 +214,7 @@ void PlaylistFeature::slotPlaylistTableChanged(int playlistId) { enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_NOT_HIDDEN || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); } } @@ -243,7 +243,7 @@ void PlaylistFeature::slotPlaylistTableRenamed(int playlistId, enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_NOT_HIDDEN || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); if (type != PlaylistDAO::PLHT_UNKNOWN) { activatePlaylist(playlistId); } diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 2c02a1efcad..755d8440869 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -30,7 +30,7 @@ QSize WLibraryBreadCrumb::minimumSizeHint() const { void WLibraryBreadCrumb::showBreadCrumb(TreeItem* pTree) { LibraryFeature* pFeature = pTree->getFeature(); - DEBUG_ASSERT_AND_HANDLE(pFeature) { + DEBUG_ASSERT_AND_HANDLE(pFeature != nullptr) { return; } From 62bab6653778f332571f27c421abda52394ebce1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 19:47:57 +0200 Subject: [PATCH 435/552] Fixed playlist not activating properly --- src/library/baseplaylistfeature.cpp | 39 ++++++++++++++++++----------- src/library/baseplaylistfeature.h | 2 ++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index d00166be271..136fdb2825f 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -133,13 +133,7 @@ void BasePlaylistFeature::activate() { return; } - auto it = m_panes.find(m_featureFocus); - auto itId = m_idBrowse.find(m_featureFocus); - if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { - return; - } - - (*it)->setCurrentIndex(*itId); + showBrowse(m_featureFocus); switchToFeature(); showBreadCrumb(); @@ -150,6 +144,8 @@ void BasePlaylistFeature::activate() { void BasePlaylistFeature::activateChild(const QModelIndex& index) { if (index == m_lastChildClicked && m_lastClickedFocus == m_featureFocus) { restoreSearch(""); + + showTable(m_lastClickedFocus); showBreadCrumb(index); switchToFeature(); return; @@ -163,14 +159,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { if (!playlistIds.isEmpty() && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistIds); - - auto it = m_panes.find(m_focusedPane); - auto itId = m_idTable.find(m_focusedPane); - if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { - return; - } - - (*it)->setCurrentIndex(*itId); + showTable(m_focusedPane); // Set the feature Focus for a moment to allow the LibraryFeature class // to find the focused WTrackTable @@ -659,6 +648,26 @@ int BasePlaylistFeature::playlistIdFromIndex(const QModelIndex& index) const { return *playlistIds.begin(); } +void BasePlaylistFeature::showTable(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idTable.find(paneId); + if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); +} + +void BasePlaylistFeature::showBrowse(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idBrowse.find(paneId); + if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { + return; + } + + (*it)->setCurrentIndex(*itId); +} + void BasePlaylistFeature::slotAnalyzePlaylist() { if (m_lastRightClickedIndex.isValid()) { diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 54ed01f5b1b..d8de941b37f 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -94,6 +94,8 @@ class BasePlaylistFeature : public LibraryFeature { virtual QSet playlistIdsFromIndex(const QModelIndex& index) const; int playlistIdFromIndex(const QModelIndex& index) const; + void showTable(int paneId); + void showBrowse(int paneId); // Get the QModelIndex of a playlist based on its id. Returns QModelIndex() // on failure. From 3fa058245077dd09ada1bd37835d4126f17a2abc Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 22 Aug 2016 20:45:07 +0200 Subject: [PATCH 436/552] Add combo box for selecting grouping options (still needs styling) --- src/library/libraryfoldersfeature.cpp | 5 ++ src/library/libraryfoldersfeature.h | 1 + src/library/mixxxlibraryfeature.cpp | 103 ++++++++++++++++---------- src/library/mixxxlibraryfeature.h | 24 ++++-- 4 files changed, 87 insertions(+), 46 deletions(-) diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp index 6d8d4a62215..9a3377ae1e7 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/libraryfoldersfeature.cpp @@ -5,6 +5,7 @@ #include "library/libraryfoldersfeature.h" #include "library/libraryfoldermodel.h" +#include "widget/wlibrarysidebar.h" LibraryFoldersFeature::LibraryFoldersFeature(UserSettingsPointer pConfig, Library* pLibrary, @@ -27,6 +28,10 @@ QString LibraryFoldersFeature::getSettingsName() const { return "LibraryFoldersFeature"; } +QWidget* LibraryFoldersFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { + return createLibrarySidebarWidget(pKeyboard); +} + void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, const QModelIndex&) { diff --git a/src/library/libraryfoldersfeature.h b/src/library/libraryfoldersfeature.h index 97b5732eee0..7e2d367a958 100644 --- a/src/library/libraryfoldersfeature.h +++ b/src/library/libraryfoldersfeature.h @@ -16,6 +16,7 @@ class LibraryFoldersFeature : public MixxxLibraryFeature QVariant title() override; QString getIconPath() override; QString getSettingsName() const override; + QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; public slots: void onRightClickChild(const QPoint& pos, const QModelIndex&) override; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 613221fcd98..86cf751f18d 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include "library/mixxxlibraryfeature.h" @@ -21,6 +23,21 @@ #include "widget/wlibrarystack.h" #include "widget/wtracktableview.h" +const QStringList MixxxLibraryFeature::kGroupingText = { + tr("Artist > Album"), + tr("Album"), + tr("Genre > Artist > Album"), + tr("Genre > Album") +}; + +const QList MixxxLibraryFeature::kGroupingOptions = { + { LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }, + { LIBRARYTABLE_ALBUM }, + { LIBRARYTABLE_GENRE, LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }, + { LIBRARYTABLE_GENRE, LIBRARYTABLE_ALBUM } +}; + + MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, @@ -133,10 +150,29 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { } QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { + QWidget* pContainer = new QWidget; + QLayout* pLayout = new QVBoxLayout(pContainer); + m_pGroupingCombo = new QComboBox(pContainer); + for (int i = 0; i < kGroupingOptions.size(); ++i) { + m_pGroupingCombo->addItem(kGroupingText.at(i), kGroupingOptions.at(i)); + } + + QVariant varData = m_pChildModel->data(QModelIndex(), TreeItemModel::RoleSettings); + m_pGroupingCombo->setCurrentIndex(kGroupingOptions.indexOf(varData.toStringList())); + + connect(m_pGroupingCombo.data(), SIGNAL(activated(int)), + this, SLOT(slotComboActivated(int))); + + pLayout->addWidget(m_pGroupingCombo); + m_pSidebar = createLibrarySidebarWidget(pKeyboard); + m_pSidebar->setParent(pContainer); m_pSidebar->setIconSize(m_pChildModel->getDefaultIconSize()); + pLayout->addWidget(m_pSidebar); + pContainer->setLayout(pLayout); + m_pChildModel->reloadTree(); - return m_pSidebar; + return pContainer; } void MixxxLibraryFeature::refreshLibraryModels() { @@ -204,49 +240,23 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, QVariant varSort = m_pChildModel->data(QModelIndex(), TreeItemModel::RoleSettings); QStringList currentSort = varSort.toStringList(); - QStringList orderArtistAlbum, orderAlbum, orderGenreArtist, orderGenreAlbum; - orderArtistAlbum << LIBRARYTABLE_ARTIST << LIBRARYTABLE_ALBUM; - orderAlbum << LIBRARYTABLE_ALBUM; - orderGenreArtist << LIBRARYTABLE_GENRE << LIBRARYTABLE_ARTIST - << LIBRARYTABLE_ALBUM; - orderGenreAlbum << LIBRARYTABLE_GENRE << LIBRARYTABLE_ALBUM; - - QAction* artistAlbum = menu.addAction(tr("Artist > Album")); - QAction* album = menu.addAction(tr("Album")); - QAction* genreArtist = menu.addAction(tr("Genre > Artist > Album")); - QAction* genreAlbum = menu.addAction(tr("Genre > Album")); - QActionGroup* orderGroup = new QActionGroup(&menu); - artistAlbum->setActionGroup(orderGroup); - album->setActionGroup(orderGroup); - genreArtist->setActionGroup(orderGroup); - genreAlbum->setActionGroup(orderGroup); - - artistAlbum->setCheckable(true); - album->setCheckable(true); - genreArtist->setCheckable(true); - genreAlbum->setCheckable(true); - - artistAlbum->setChecked(currentSort == orderArtistAlbum); - album->setChecked(currentSort == orderAlbum); - genreArtist->setChecked(currentSort == orderGenreArtist); - genreAlbum->setChecked(currentSort == orderGenreAlbum); + for (int i = 0; i < kGroupingOptions.size(); ++i) { + QAction* action = menu.addAction(kGroupingText.at(i)); + action->setActionGroup(orderGroup); + action->setData(kGroupingOptions.at(i)); + action->setCheckable(true); + action->setChecked(currentSort == kGroupingOptions.at(i)); + } QAction* selected = menu.exec(pos); - - if (selected == artistAlbum) { - m_pChildModel->setData(QModelIndex(), orderArtistAlbum, TreeItemModel::RoleSettings); - } else if (selected == album) { - m_pChildModel->setData(QModelIndex(), orderAlbum, TreeItemModel::RoleSettings); - } else if (selected == genreArtist) { - m_pChildModel->setData(QModelIndex(), orderGenreArtist, TreeItemModel::RoleSettings); - } else if (selected == genreAlbum) { - m_pChildModel->setData(QModelIndex(), orderGenreAlbum, TreeItemModel::RoleSettings); - } else { - // Menu rejected + if (selected == nullptr) { return; } - m_pChildModel->reloadTree(); + if (!m_pGroupingCombo.isNull()) { + m_pGroupingCombo->setCurrentIndex(kGroupingOptions.indexOf(selected->data().toStringList())); + } + setTreeSettings(selected->data()); } bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { @@ -266,3 +276,18 @@ bool MixxxLibraryFeature::dragMoveAccept(QUrl url) { return SoundSourceProxy::isUrlSupported(url) || Parser::isPlaylistFilenameSupported(url.toLocalFile()); } + +void MixxxLibraryFeature::setTreeSettings(const QVariant& settings) { + if (m_pChildModel.isNull()) { + return; + } + m_pChildModel->setData(QModelIndex(), settings, TreeItemModel::RoleSettings); + m_pChildModel->reloadTree(); +} + +void MixxxLibraryFeature::slotComboActivated(int index) { + if (m_pGroupingCombo.isNull()) { + return; + } + setTreeSettings(m_pGroupingCombo->itemData(index)); +} diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 6d9e3284f80..6987b5a3e51 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -4,16 +4,17 @@ #ifndef MIXXXLIBRARYFEATURE_H #define MIXXXLIBRARYFEATURE_H -#include -#include -#include +#include #include -#include #include +#include +#include #include -#include #include -#include +#include +#include +#include +#include #include "library/libraryfeature.h" #include "library/librarytreemodel.h" @@ -75,12 +76,21 @@ class MixxxLibraryFeature : public LibraryFeature { Missing = 3 }; const QString kLibraryTitle; - + + private slots: + void setTreeSettings(const QVariant &settings); + void slotComboActivated(int index); + + private: + QPointer m_pGroupingCombo; QSharedPointer m_pBaseTrackCache; QPointer m_pSidebar; LibraryTableModel* m_pLibraryTableModel; TrackDAO& m_trackDao; QModelIndex m_lastClickedIndex; + + static const QList kGroupingOptions; + static const QStringList kGroupingText; }; #endif /* MIXXXLIBRARYFEATURE_H */ From 244fa19af08a719d83de37f0c21a2cf61e4bdb4a Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 23 Aug 2016 09:38:45 +0200 Subject: [PATCH 437/552] Fix crash when searching "*" in Folders Feature --- src/library/libraryfoldersfeature.cpp | 3 ++- src/library/mixxxlibraryfeature.cpp | 17 +++++++++++------ src/library/mixxxlibraryfeature.h | 13 ++++--------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp index 9a3377ae1e7..824d245936a 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/libraryfoldersfeature.cpp @@ -29,7 +29,8 @@ QString LibraryFoldersFeature::getSettingsName() const { } QWidget* LibraryFoldersFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { - return createLibrarySidebarWidget(pKeyboard); + m_pSidebar = createLibrarySidebarWidget(pKeyboard); + return m_pSidebar; } void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 86cf751f18d..ffe480721a5 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -23,6 +23,8 @@ #include "widget/wlibrarystack.h" #include "widget/wtracktableview.h" +const QString MixxxLibraryFeature::kLibraryTitle = tr("Library"); + const QStringList MixxxLibraryFeature::kGroupingText = { tr("Artist > Album"), tr("Album"), @@ -36,14 +38,12 @@ const QList MixxxLibraryFeature::kGroupingOptions = { { LIBRARYTABLE_GENRE, LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }, { LIBRARYTABLE_GENRE, LIBRARYTABLE_ALBUM } }; - MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), - kLibraryTitle(tr("Library")), m_trackDao(pTrackCollection->getTrackDAO()) { QStringList columns; columns << "library." + LIBRARYTABLE_ID @@ -190,7 +190,9 @@ void MixxxLibraryFeature::selectAll() { void MixxxLibraryFeature::onSearch(const QString&) { showBreadCrumb(); - m_pSidebar->clearSelection(); + if (!m_pSidebar.isNull()) { + m_pSidebar->clearSelection(); + } } void MixxxLibraryFeature::setChildModel(TreeItemModel* pChild) { @@ -237,7 +239,8 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, // Create the sort menu QMenu menu; - QVariant varSort = m_pChildModel->data(QModelIndex(), TreeItemModel::RoleSettings); + QVariant varSort = m_pChildModel->data(QModelIndex(), + TreeItemModel::RoleSettings); QStringList currentSort = varSort.toStringList(); QActionGroup* orderGroup = new QActionGroup(&menu); @@ -254,7 +257,8 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, return; } if (!m_pGroupingCombo.isNull()) { - m_pGroupingCombo->setCurrentIndex(kGroupingOptions.indexOf(selected->data().toStringList())); + int index = kGroupingOptions.indexOf(selected->data().toStringList()); + m_pGroupingCombo->setCurrentIndex(index); } setTreeSettings(selected->data()); } @@ -263,7 +267,8 @@ bool MixxxLibraryFeature::dropAccept(QList urls, QObject* pSource) { if (pSource) { return false; } else { - QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); + QList files = + DragAndDropHelper::supportedTracksFromUrls(urls, false, true); // Adds track, does not insert duplicates, handles unremoving logic. QList trackIds = m_trackDao.addMultipleTracks(files, true); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 6987b5a3e51..9c5eb7c40e5 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -68,14 +68,12 @@ class MixxxLibraryFeature : public LibraryFeature { void setChildModel(TreeItemModel* pChild); QPointer m_pChildModel; + QPointer m_pSidebar; private: - enum Panes { - MixxxLibrary = 1, - Hidden = 2, - Missing = 3 - }; - const QString kLibraryTitle; + static const QString kLibraryTitle; + static const QList kGroupingOptions; + static const QStringList kGroupingText; private slots: void setTreeSettings(const QVariant &settings); @@ -84,13 +82,10 @@ class MixxxLibraryFeature : public LibraryFeature { private: QPointer m_pGroupingCombo; QSharedPointer m_pBaseTrackCache; - QPointer m_pSidebar; LibraryTableModel* m_pLibraryTableModel; TrackDAO& m_trackDao; QModelIndex m_lastClickedIndex; - static const QList kGroupingOptions; - static const QStringList kGroupingText; }; #endif /* MIXXXLIBRARYFEATURE_H */ From 71e80677cf437accde237b013b1ebfd16bcbd6e6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 23 Aug 2016 10:45:10 +0200 Subject: [PATCH 438/552] Allow overwritting saved queries --- src/library/dao/savedqueriesdao.cpp | 19 +++++++++++------- src/library/dao/savedqueriesdao.h | 1 + src/library/libraryfeature.cpp | 30 +++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 23192dd03be..2240bfbed7d 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -102,19 +102,24 @@ SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, const SavedSearchQuery& sQuery) { // To move to the first item we delete the item and insert againt it // to assign it a new ID + deleteSavedQuery(sQuery.id); + return saveQuery(pFeature, sQuery); +} + +SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) { + return moveToFirst(pFeature, getSavedQuery(id)); +} + +bool SavedQueriesDAO::deleteSavedQuery(int id) { QSqlQuery query(m_database); query.prepare("DELETE FROM " SAVEDQUERYTABLE " WHERE id=:id"); - query.bindValue(":id", sQuery.id); + query.bindValue(":id", id); if (!query.exec()) { LOG_FAILED_QUERY(query); + return false; } - - return saveQuery(pFeature, sQuery); -} - -SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) { - return moveToFirst(pFeature, getSavedQuery(id)); + return true; } bool SavedQueriesDAO::exists(const SavedSearchQuery& sQuery) { diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 37f741932de..840d1229a64 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -53,6 +53,7 @@ class SavedQueriesDAO : public DAO SavedSearchQuery getSavedQuery(int id) const; SavedSearchQuery moveToFirst(LibraryFeature* pFeature, const SavedSearchQuery& sQuery); SavedSearchQuery moveToFirst(LibraryFeature* pFeature, int id); + bool deleteSavedQuery(int id); bool exists(const SavedSearchQuery& sQuery); int getQueryId(const SavedSearchQuery& sQuery); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index cdbd2113a6f..3d1e18a7cec 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -136,14 +136,28 @@ SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery sQuery) { } sQuery = pTable->saveQuery(sQuery); - if (m_savedDAO.exists(sQuery)) { - QMessageBox::warning(nullptr, - tr("Query already exists"), - tr("The query with title: \"%1\" and query: \"%2\"" - " already exists in the database") - .arg(sQuery.title, sQuery.query)); - m_savedDAO.moveToFirst(this, m_savedDAO.getQueryId(sQuery)); - return sQuery; + int qId = m_savedDAO.getQueryId(sQuery); + if (qId >= 0) { + QMessageBox box; + box.setWindowTitle(tr("Query already exists")); + box.setText(tr("The query already exists in the database. Do you want " + "to overwrite it?")); + box.setDetailedText(tr("The query has title: \"%1\" and query: \"%2\"") + .arg(sQuery.title, sQuery.query)); + box.setIcon(QMessageBox::Warning); + box.addButton(QMessageBox::Yes); + box.addButton(QMessageBox::No); + box.setDefaultButton(QMessageBox::Yes); + box.setEscapeButton(QMessageBox::No); + + if (box.exec() == QMessageBox::No) { + // No pressed + m_savedDAO.moveToFirst(this, qId); + return sQuery; + } else { + // Yes pressed + m_savedDAO.deleteSavedQuery(qId); + } } // A saved query goes the first in the list From 9fb09a20df6cc9adf23270cf8df222e0424a7a10 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 23 Aug 2016 11:28:59 +0200 Subject: [PATCH 439/552] Style combo box in Deere skin --- .../Deere/image/style_sort_down_white.svg | 60 +++++++++++++++++++ res/skins/Deere/style.qss | 40 +++++++++++++ src/library/mixxxlibraryfeature.cpp | 1 + 3 files changed, 101 insertions(+) create mode 100644 res/skins/Deere/image/style_sort_down_white.svg diff --git a/res/skins/Deere/image/style_sort_down_white.svg b/res/skins/Deere/image/style_sort_down_white.svg new file mode 100644 index 00000000000..c0ecfd00add --- /dev/null +++ b/res/skins/Deere/image/style_sort_down_white.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 7ebf109d16a..e6cc23cb2f5 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -497,6 +497,46 @@ WBaseLibrary QPushButton:pressed { border: 0px solid #006596; } +QComboBox { + border: 1px solid #4B4B4B; + padding: 0px 5px 0px 5px; + border-radius: 3px; + background: #4B4B4B; + color: #d2d2d2; +} + +QComboBox::drop-down { + border: none; +} + +QComboBox::down-arrow { + image: url(skin:/image/style_sort_down_white.svg); + width: 12px; + margin-right: 2px; + padding-left: 3px; + padding-right: 3px; +} + +QComboBox:hover { + border: 1px solid #0080BE; +} + +QComboBox:focus { + border: 1px solid #006596; + background-color: #006596; +} + +QComboBox:focus:hover { + border: 1px solid #0080BE; + background-color: #0080BE; +} + +QComboBox QAbstractItemView { + background: #4B4B4B; + selection-background-color: #006596; + color: #d2d2d2; +} + /* Scroll bars */ QScrollBar { color: #d2d2d2; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index ffe480721a5..a883a6b9cce 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -152,6 +152,7 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { QWidget* pContainer = new QWidget; QLayout* pLayout = new QVBoxLayout(pContainer); + pLayout->setContentsMargins(0, 0, 0, 0); m_pGroupingCombo = new QComboBox(pContainer); for (int i = 0; i < kGroupingOptions.size(); ++i) { m_pGroupingCombo->addItem(kGroupingText.at(i), kGroupingOptions.at(i)); From ed2fd28e04e4930bb28c1a618be382a21778791b Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 23 Aug 2016 20:14:17 +0200 Subject: [PATCH 440/552] Add sorting options to Library Tree instead of combo box --- .../Deere/image/style_sort_down_white.svg | 60 ------------------- res/skins/Deere/style.qss | 40 ------------- src/library/librarytreemodel.cpp | 10 +++- src/library/librarytreemodel.h | 2 +- src/library/mixxxlibraryfeature.cpp | 35 +++-------- src/library/mixxxlibraryfeature.h | 1 - 6 files changed, 16 insertions(+), 132 deletions(-) delete mode 100644 res/skins/Deere/image/style_sort_down_white.svg diff --git a/res/skins/Deere/image/style_sort_down_white.svg b/res/skins/Deere/image/style_sort_down_white.svg deleted file mode 100644 index c0ecfd00add..00000000000 --- a/res/skins/Deere/image/style_sort_down_white.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index e6cc23cb2f5..7ebf109d16a 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -497,46 +497,6 @@ WBaseLibrary QPushButton:pressed { border: 0px solid #006596; } -QComboBox { - border: 1px solid #4B4B4B; - padding: 0px 5px 0px 5px; - border-radius: 3px; - background: #4B4B4B; - color: #d2d2d2; -} - -QComboBox::drop-down { - border: none; -} - -QComboBox::down-arrow { - image: url(skin:/image/style_sort_down_white.svg); - width: 12px; - margin-right: 2px; - padding-left: 3px; - padding-right: 3px; -} - -QComboBox:hover { - border: 1px solid #0080BE; -} - -QComboBox:focus { - border: 1px solid #006596; - background-color: #006596; -} - -QComboBox:focus:hover { - border: 1px solid #0080BE; - background-color: #0080BE; -} - -QComboBox QAbstractItemView { - background: #4B4B4B; - selection-background-color: #006596; - color: #d2d2d2; -} - /* Scroll bars */ QScrollBar { color: #d2d2d2; diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index 2a85b2671e7..afa0506dbd7 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -125,8 +125,11 @@ void LibraryTreeModel::reloadTree() { pRootItem->setLibraryFeature(m_pFeature); m_pLibraryItem = new TreeItem(tr("Show all"), "", m_pFeature, pRootItem); - pRootItem->appendChild(m_pLibraryItem); + + QString groupTitle = tr("Grouping Options (%1)").arg(m_sortOrder.join(" > ")); + m_pSettings = new TreeItem(groupTitle, "", m_pFeature, pRootItem); + pRootItem->appendChild(m_pSettings); // Deletes the old root item if the previous root item was not null setRootItem(pRootItem); @@ -153,9 +156,12 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { return ""; } - if (pTree == m_pLibraryItem || pTree == m_pFoldersRoot) { + if (pTree == m_pLibraryItem) { return ""; + } else if (pTree == m_pSettings) { + return "$groupingSettings$"; } + const QString param("%1:=\"%2\""); int depth = 0; diff --git a/src/library/librarytreemodel.h b/src/library/librarytreemodel.h index 1fc799294a4..41e751ee59c 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/librarytreemodel.h @@ -55,8 +55,8 @@ class LibraryTreeModel : public TreeItemModel { QStringList m_sortOrder; QStringList m_coverQuery; + TreeItem* m_pSettings; TreeItem* m_pLibraryItem; - TreeItem* m_pFoldersRoot; bool m_folderRecursive; }; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index a883a6b9cce..6c3a04da78e 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -150,28 +150,8 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { } QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { - QWidget* pContainer = new QWidget; - QLayout* pLayout = new QVBoxLayout(pContainer); - pLayout->setContentsMargins(0, 0, 0, 0); - m_pGroupingCombo = new QComboBox(pContainer); - for (int i = 0; i < kGroupingOptions.size(); ++i) { - m_pGroupingCombo->addItem(kGroupingText.at(i), kGroupingOptions.at(i)); - } - - QVariant varData = m_pChildModel->data(QModelIndex(), TreeItemModel::RoleSettings); - m_pGroupingCombo->setCurrentIndex(kGroupingOptions.indexOf(varData.toStringList())); - - connect(m_pGroupingCombo.data(), SIGNAL(activated(int)), - this, SLOT(slotComboActivated(int))); - - pLayout->addWidget(m_pGroupingCombo); - m_pSidebar = createLibrarySidebarWidget(pKeyboard); - m_pSidebar->setParent(pContainer); - m_pSidebar->setIconSize(m_pChildModel->getDefaultIconSize()); - pLayout->addWidget(m_pSidebar); - pContainer->setLayout(pLayout); - + m_pSidebar->setIconSize(m_pChildModel->getDefaultIconSize()); m_pChildModel->reloadTree(); return pContainer; } @@ -229,6 +209,12 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString query = index.data(TreeItemModel::RoleQuery).toString(); //qDebug() << "MixxxLibraryFeature::activateChild" << query; + if (query == "$groupingSettings$") { + // Act as right click + onRightClickChild(QCursor::pos(), QModelIndex()); + return; + } + m_pLibraryTableModel->search(query); switchToFeature(); showBreadCrumb(index.data(TreeItemModel::RoleBreadCrumb).toString(), getIcon()); @@ -290,10 +276,3 @@ void MixxxLibraryFeature::setTreeSettings(const QVariant& settings) { m_pChildModel->setData(QModelIndex(), settings, TreeItemModel::RoleSettings); m_pChildModel->reloadTree(); } - -void MixxxLibraryFeature::slotComboActivated(int index) { - if (m_pGroupingCombo.isNull()) { - return; - } - setTreeSettings(m_pGroupingCombo->itemData(index)); -} diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index 9c5eb7c40e5..db81afce09a 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -77,7 +77,6 @@ class MixxxLibraryFeature : public LibraryFeature { private slots: void setTreeSettings(const QVariant &settings); - void slotComboActivated(int index); private: QPointer m_pGroupingCombo; From 043b52296c7b0e9a837fb9d07f30034068864b48 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 09:12:16 +0200 Subject: [PATCH 441/552] Fix build --- src/library/mixxxlibraryfeature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 6c3a04da78e..2f3dd021868 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -153,7 +153,7 @@ QWidget* MixxxLibraryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKey m_pSidebar = createLibrarySidebarWidget(pKeyboard); m_pSidebar->setIconSize(m_pChildModel->getDefaultIconSize()); m_pChildModel->reloadTree(); - return pContainer; + return m_pSidebar; } void MixxxLibraryFeature::refreshLibraryModels() { From 7f5e0b2b3a28e85515dd53ed257b92277039b230 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 11:47:50 +0200 Subject: [PATCH 442/552] Fix selected items in AutoDJ not getting handled --- src/library/autodj/autodjfeature.cpp | 6 ++++-- src/library/autodj/dlgautodj.cpp | 10 ++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 7b550bb4d2b..71e244d967a 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -103,7 +103,9 @@ QString AutoDJFeature::getSettingsName() const { } QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTableView = LibraryFeature::createTableWidget(pKeyboard, paneId); + WTrackTableView* pTrackTableView = createTableWidget(pKeyboard, paneId); + pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); + connect(pTrackTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, @@ -150,7 +152,7 @@ void AutoDJFeature::activate() { m_pAutoDJView->onShow(); - showTrackModel(m_pAutoDJProcessor->getTableModel()); + switchToFeature(); showBreadCrumb(); restoreSearch(QString()); //Null String disables search box diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 30a449dc430..98fa7186129 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -61,14 +61,8 @@ void DlgAutoDJ::setSelectedRows(const QModelIndexList& selectedRows) { } void DlgAutoDJ::shufflePlaylistButton(bool) { - LibraryView* pView = m_pLibrary->getActiveView(); - WTrackTableView* pTrackTable = dynamic_cast(pView); - - if (pView) { - QModelIndexList indexList = pTrackTable->selectionModel()->selectedRows(); - // Activate regardless of button being checked - m_pAutoDJProcessor->shufflePlaylist(indexList); - } + // Activate regardless of button being checked + m_pAutoDJProcessor->shufflePlaylist(m_selectedRows); } void DlgAutoDJ::skipNextButton(bool) { From ec949330033b949210c12d4e92c65e195bb744f1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 11:48:25 +0200 Subject: [PATCH 443/552] Add preselect icons --- res/images/library/ic_library_notpreselect.png | Bin 0 -> 1627 bytes res/images/library/ic_library_preselect.png | Bin 0 -> 2104 bytes res/mixxx.qrc | 2 ++ 3 files changed, 2 insertions(+) create mode 100644 res/images/library/ic_library_notpreselect.png create mode 100644 res/images/library/ic_library_preselect.png diff --git a/res/images/library/ic_library_notpreselect.png b/res/images/library/ic_library_notpreselect.png new file mode 100644 index 0000000000000000000000000000000000000000..9d99db31755beb57ca238625870068c4300ae193 GIT binary patch literal 1627 zcmai#Yd8}M7{@pFx#Th&4AnI9pe4%XklHi18kS3!E#@9mb7^Cmp+#qel9b8iAaW^+ zq+^(fmANcdgfUL7Lt&EUSU7w<=gWDX|Ns5H&;NNp{J*^!XirxaMLk6T0HEUThV*4EbcIx;fS+}wQe;>EnYJX>2^iA1uzygWEKxVX5;U@*jD zF^NPH3Wd43xi}mS0)e1VD1ksQHa3RAU>X}6>+0%QELL@OHHAV!B9T2kJqQHi(4j+g zI^D#?BqJjO3We(E=%CSPH8r)curOkET%K(59c*j6MVUf;u zC{J|vaF!P+Xn{0La0(TP0Dx?aJMy?Md3>Sx#_e)@wd-IaeNyu{S|*zOVRZv1;teut zFW(g?TMefez1x!3ajMNDCfG+-+H-twa88LEsM@x8z&F)GG#mO+&fNNGjut$yYK|2A zQAw;B_an1Ri-GXgsbZq1T>ihgIgyP3qLRlVkXu$ihd2 z#}i()CT{g{;o+^bMc37XjrYLiAFGeXKN=#-6h_KrOr7YsLJgtv)q+hEbb`|DXwUUq z^unvuUz>Tp=;y`h*67#LIH-1ECk*d{;3v0sJM?B<7_m9r&iU~gWn^en$rRYN^jn8o zdUqjlUAH;hPA+jE)`o@Xz0?s-|85j&*>qp;AS23<3; z)0)ZHmHp8`Sk|0@OVfqN%mD6ZyinP$+G{q6rV`sD`FhE7t6r2gut4Cefv;Ero#L0c z;Hh)>yv-n=ey|{}ZC-qvn`!f#s&IlR6KEaOMNx@#iLL}K6??Ad_r7Qo$2rDzJ#i`B zNbWFTR~S7IkDHsxf(`##N$NMtK3R%zCo?SpePtmLew=&mP+DctXcQK3U`~I`d;L z_~=iT{F~y7$7+jDH0dApNNtx2A!dk6S1s_stXSMicEONp=YrwF)BSLVK^q@(MW=ME zEA!_lG57QR0b|^B6WhNW1SdbjT>oN8|HeFw*k`euj+M(=&kV_$0NsjD#5U*Xeh)rU z6+(%aH5Wdn^5%qde-6KEgzO>VXO?~K!o{l+XfC{p)j_SYWF~xdInnM!B2;eH@a@AY zU`gYD05?v*t;3ov4h?#2%1}6wtGUsKJ-O{n8!7Itw26F2?oY@d81qKIs5mh!1tjOt6m11Q_La>IJ;i8%v&1CV|M;saI0w^ zB;kS9wPqwOn^X1X{u^0@HJdah;RZEgw*YrF*{g)7*7id1l7iD#4L$p&zW+eW$b;Dm z$(RJJ(J@`3ms5n@O8tORIT86}DZinfC%U5@8=aJ{S38W4YxQr86ZiAXl_~;`O)Ztq z_}=c_Cbe61`?X*a?Y*fm@73S!x*C6DZ*T7TaGb4t|$p}&6VYjVx&)UEHhT$ zazu{!U^?tOA(Jbs_R&A^`Qdq<_xt(b{d#_SUhgcl(}lyLa-sqP0*8@y2-kgG`~wld zJ_93^?e>L;cD!iA=kxc+@$vDFj*jr~a1x0GgTZ(_9+%4<9v)s>TO*UnJ3BjgJbr0u zDK9V2-``(eUf$8sk;P(7PfvS!d9}5*H8nNSXtaig1_FVAKp+MN2HE zD4Rnp5h)-@x^Pm|d*4AJ5$7+)&a7616+bc)%kYkVo+^U~5VT>wS?BXv9wX%)!PvZK zqcyF2#LA;5%ASRm3c^c*g6=w;zdfb2eI0S2^MaO(&GI!s-Nm*$Vlt=dHt_Jz-^Gu? z9SqND*Pjw?6=5HJbFk0#+DO<6GYl?Br&#$*V&JF-pbtXf|5c&gs!tlGI>nliRdGb;UGY` zo%m{>$jHQ=wgcTdMI8YOm9uZ01(w}R*FTl)Qh;Z$_x2KVP+G>7NO6= z`V})M0gh4jpOB}_GvwaZ} zM)~3<*&Wwqt770pf>n976;UOTgR&|NkajPl@6}{e%T7QHidH~>d29&3TN#OUsWKT} ziU2*W%$8n4(H9!ql9;=5Ul{=`d5*XK7W2~T=^O_eIT#*)!@$P++HV=OYDpi>lotGU zU`;NpoE%kc7#j#nSoLB^JJqIf=%wkhvJRtaSFE; znANp%t{Y4CtSZX;4U6`j(~L7_F8jHFr2_FCgWnnTi+K%7GzF1&Xv(<%n@4*@Y@ns7 zM@650Swr=Z_oc$Nt-s852FlmhP@$tsx=_r4k;B7^mf_Frrn(}2lphemR z?V>|;kgBRJ;cAAhh$mgy9qC}ezPHX~>DEsk(CM$?=VK*5Y+FlRMO$W2%^O2g7q*Mu zD6whEX9{p#v+i3=?A;x!qC1ivBS7|WS=miP2hIqlA0?|1)64dTbg>r?Yj_81nEsRY zl^cHhp40WWD41LM=%=BMza53D(H88j;qRm*+g{$6i90bt2xzv%lek6fp+bxYroTmD zDnAh;`;+RsQn*BG=?)Ca{_&=0@)d=_KlJ5Q0p+u(kB7cm;H^yXn6`u9iU!!Ye|v_A zYPR^O2rnvMSGj4&e^7hv-RY(!W&KFIJpJc%nkuF?tV#fb_RLqpxsk$z1-2=cV%S!HPVY<|XJLd2K zu0WavmXrCx*`^@(s~%BB)6!2}DLDP3MAZ|_W%zvlw&bMDD#T>Eu`)Zd{<=t`{TH{|YxoN40A>3mcy zwg*2uK4tFR+tF;C4}8!mMQm%35gCd}Ebb8>j6=_i0sTcQ-hNNHq9_Q}#|nGCxAJ7i zs|~X1d1OI2Zl2yjG(^bhx!b*e!iIhIJK)6-i zk3`a$u=v|ql4q61zc7IQ1?1=#z8@2NE43C|(z%4?G)7Ln)9wxDVK->PE{@$ODWN^* zT)qzRvh;;I?OG&60kB4)^x~cjd3LSmXFYY~Zj{9jLp+_C8#%OpG?=ZYSBKhFc>Rj& z#M6}Q{fw$yxBib7)j~cmQJ^r%?hm%#(wWeeM^0w#RN*-rVcy-XtNnP$H8JXpIJI z-m9Q}3NammG%ebR%=#e{`HsdevXO0L3N;B3w>tF0rD7vRIvE^bYpd!k(5hN3kuA9-;F$@e=;&K#WgHSnNHoe>UX*vlI5 zVglc{b%`?AdXTP%F=hODCAU%a5b6X>#VxO=XX4~1Lse3~)LQp!&u-mQjgM|-q+70g Y0BSD=`c?SPiy$C?v~fZ_fnQ1a7xEV2(*OVf literal 0 HcmV?d00001 diff --git a/res/mixxx.qrc b/res/mixxx.qrc index 456856e6200..a6cd8ef3d50 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -114,5 +114,7 @@ skins/downArrow.png skins/cross_2.png skins/save_disabled.png + images/library/ic_library_preselect.png + images/library/ic_library_notpreselect.png From d04ec82dc313c51d0171e3690ad3d5ab93fadec9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 13:25:11 +0200 Subject: [PATCH 444/552] Add some styling to icons --- .../library/ic_library_notpreselect.png | Bin 1627 -> 3520 bytes res/images/library/ic_library_preselect.png | Bin 2104 -> 7579 bytes res/skins/Deere/style.qss | 10 ++++ res/skins/LateNight/style.qss | 8 ++- res/skins/Shade/skin.xml | 11 ++-- src/widget/wlibrarybreadcrumb.cpp | 51 +++++++++++++++--- src/widget/wlibrarybreadcrumb.h | 13 +++++ src/widget/wpixmapstore.cpp | 13 +++-- src/widget/wpixmapstore.h | 3 +- 9 files changed, 91 insertions(+), 18 deletions(-) diff --git a/res/images/library/ic_library_notpreselect.png b/res/images/library/ic_library_notpreselect.png index 9d99db31755beb57ca238625870068c4300ae193..f5cac3aa6615b460876a33043f4b0bab7237177d 100644 GIT binary patch literal 3520 zcmcIn`8S)}8jd-XHZfOAB{~s`syXI};S@D%IjP|oS~VQ%G&PqX5<^u{MHJPlc~&ZQ zYF0JZ6oeRJsv$x(Xx+Hy{sH&?aKF9w-s^eackkzUzP;D_))#-v+=!1yj0XS!@R=AR zte7+9qyssbqjt@3FmvK`{mlpgusmsrQ1nTf+u!(hAOLVm;H0wvUS^9jgIo_y%nZ5a zfTE{3#U>-HruNmqH7We^k+_WgP0UQFD zt_0GeB7rOl`B)GD%nE?A>tX;*41xe8^#KSV;J*y(vSl4Z|Ca^u!Nvbty&aO(GIV{>Dv`4-x+e7+dNFF0cW>Hx4nA# z3qNHz_C?~4uZ-hV`F9NIPDbHlV)dt*)lL@CJC8l*-jx&oI2VPd%)r}Rh;bdUO z(L3_@L#js)ubP{J&R&62ru}Q{7JXLGD%-dV!NrQVEbdO+hFqqF!-xJr+?H9mF7wUK zIel3+k;Qs}DAYD3yj++5cXuLnqpYhsVB@(9?PJ!H^Wxwn^b3`Q;k_7N17q0!s&)%i z-+W8WjH>*yJLpbDRqzZy#vdtU*P(jj{$h(y(1h4f)6$2V=&&GO^FI(cusS%YU-rw5 z=+82*9PaM&+W^Xzb5*ck`yKQ1O=;|Y*iun)vs^RUP|!!_Q;N%^W8WU{Gf%bYHSa2e z!NE!j=b2qhlY|$Z1j(~y*$v1dj>0#%$Foj@rj*_(dC4V@#(vHGT<*K;k(J=(+*1lf zj+XxjKCtRluzZmT(=P#yoPNy@r#`-}<@%K4LVF2&`m2L+v6K$lD~skb>z`@n;cC&S zK#WLrR%~IW{(U}sc_(Bfm$1kEfk3-TY4ezh#Zxc?HuG-`xV+yGrs^zrgmMboJ?Dh# zSZ}=E&YMKiQ=(Ch8L0k^@+l569@~d-IE0ps&O37pWRb^Ca zJ0aSUl`Y@3VZ^ZDPn#d}ORrF9uNaaYq*sC6a>+h*fGri_CFDTTzxn2w>f)2HnbtNR zWZovt*^Wcp*TrjBZ{9m458KMm(eHmUBYU=LEcK{NuWD!7`m{H-$F|)qY}QUkL2^N#n#kSxP3wpRWCUn8^AlR`TMXE+C5eX=MKD$kILPhECcevTPLR&?=; zvQ{kml_4!l7>?r{f+KT9TRxW*XKa$QR72B9Uuv`cJ-jG=>xSa8FL`Z4F40wv5-w+% zRa{(Oo(;KIDnSCXy)tjN%56}ilp`iJv!nWlS34fO z1=@9p)H$w{nmThAht}L#MkXYR74N)3mn!24mTQkMuRb{ADikPNk(KzAY^?1iHrRKx z4?E1pe7IIYkFb`_S&&U0QBpu%Q=!w7Q261V$>3aNdIK*i7hFJpQvqqk3ws2sKgG>t z`k4ub#PEyXP?ABqbim%>bEOh7X?Ch6my1_|vSpE<5ZTja(QeA1g@h(RV6;82(FbVS zo+-Xws-t>`$~y9W0%305(nSvG6U+8$lKKF#5e&e&iIxs3@@f_OJ@lY^G|wp#6l9*) zM)!H+tD785{hIU+)J<+Eh`eU4Gm zuj|}Rl4?cu=jpjCd``s)RHvD5Uav`w7?26=RWR&?EhvVZDh%nY4T}ijvOk>pxU`OL zU1hRi(c*ikeye9)A?`;-n$)6jb89uSx7rlcw9*34DG;!>8&IC`lF9?iWc1J5ns)dN zY8#&S`^m`)H^=meR5_$iR#y9{d6_Acv~#2;Jn?_Ddpcl};CUu+dJZ1g=0@9hkxrt} zn!~=vUg2K2vGaR~V~oSdO@Dti8R*WIe2zun<8yL?ko0CKoillCC^7&;9}fsRm#eGQ(i@DMvt~4DQRCn|Y_|?781BBr+bYHB_=e}) z*(Y)Y-HT*9#iqf`q_j3J-DPB{W81hDf*b>=5J^J1d|vVC^N7iy&~nN^1@)?a0#{+B z-#4#4AV_tcD{JzvCdpVuyNNGY>HP9#M~7Klh3@RjXM11!5V~>=bNi**Tl=exyPh)v zZRW7^-$~=w2~~nA`=RGp$lMlQcWnJwicr5!my^eSl8OApe3KM({L|5&{KQgXbU(Lx{H9xC< zZD)>nG=}3L?~AjeuNX4rjEf{{Q{(ruSA^7&t-}fSIG$_d&{<0g`i<+liUSv=@KLrs zElh{Cc?v2BX7ox$a2=Jtt!l=qqVvaBY*~pCL#16}d=(*GiR4>K_Y-RpVvL=nzw@Tz zy172$e{3cK4H3VNidv}t4+q^FFd5FEq*A3X-+~Hyx;*13nfVDK9wB`TmPLtxt-O=c zU9Zr9{D+8F@qtDG1aeH{3Y@SzwOmh4cC;@K-44NSq43NjP0nrT8ZnO7%BtDDoGTVrv6qp*ArPa!Jm|?`%v|&J~(BT=>PG^ zM3Z9g(erfq6Y>qO$5MEKR)%Hw%+y4W=65L_T_>!Q`T*#s04=#n2XqJa@<$alXq@|4mfGND;KaWV79%JGj&0XKN z13OLkx+~E-j%<61?Qy{5Mf)>}Q@ecVirZPFwK)!no<~Y~b$i(tjv?~~m`6^f88YRF zj%VNKdm0XFT{<+Gljw_aiSqFqsOuRu%{dRy&3lo#2sCzEo7T&X`qNLx8&$MpElSMh0URKY@Cm`0(591AK}eo4pFbMwF-@0C4BgH@(W* z;)I|=2Qu@rT1aW@V${PABtK@F`6cb_9(sm*4EbcIx;fS+}wQe;>EnYJX>2^iA1uzygWEKxVX5;U@*jD zF^NPH3Wd43xi}mS0)e1VD1ksQHa3RAU>X}6>+0%QELL@OHHAV!B9T2kJqQHi(4j+g zI^D#?BqJjO3We(E=%CSPH8r)curOkET%K(59c*j6MVUf;u zC{J|vaF!P+Xn{0La0(TP0Dx?aJMy?Md3>Sx#_e)@wd-IaeNyu{S|*zOVRZv1;teut zFW(g?TMefez1x!3ajMNDCfG+-+H-twa88LEsM@x8z&F)GG#mO+&fNNGjut$yYK|2A zQAw;B_an1Ri-GXgsbZq1T>ihgIgyP3qLRlVkXu$ihd2 z#}i()CT{g{;o+^bMc37XjrYLiAFGeXKN=#-6h_KrOr7YsLJgtv)q+hEbb`|DXwUUq z^unvuUz>Tp=;y`h*67#LIH-1ECk*d{;3v0sJM?B<7_m9r&iU~gWn^en$rRYN^jn8o zdUqjlUAH;hPA+jE)`o@Xz0?s-|85j&*>qp;AS23<3; z)0)ZHmHp8`Sk|0@OVfqN%mD6ZyinP$+G{q6rV`sD`FhE7t6r2gut4Cefv;Ero#L0c z;Hh)>yv-n=ey|{}ZC-qvn`!f#s&IlR6KEaOMNx@#iLL}K6??Ad_r7Qo$2rDzJ#i`B zNbWFTR~S7IkDHsxf(`##N$NMtK3R%zCo?SpePtmLew=&mP+DctXcQK3U`~I`d;L z_~=iT{F~y7$7+jDH0dApNNtx2A!dk6S1s_stXSMicEONp=YrwF)BSLVK^q@(MW=ME zEA!_lG57QR0b|^B6WhNW1SdbjT>oN8|HeFw*k`euj+M(=&kV_$0NsjD#5U*Xeh)rU z6+(%aH5Wdn^5%qde-6KEgzO>VXO?~K!o{l+XfC{p)j_SYWF~xdInnM!B2;eH@a@AY zU`gYD05?v*t;3ov4h?#2%1}6wtGUsKJ-O{n8!7Itw26F2?oY@d81qKIs5mh!1tjOt6m11Q_La>IJ;i8%v&1CV|M;saI0w^ zB;kS9wPqwOn^X1X{u^0@HJdah;RZEgw*YrF*{g)7*7id1l7iD#4L$p&zW+eW$b;Dm z$(RJJ(J@`3ms5n@O8tORIT86}DZinfC%U5@8=aJ{S38W4YxQr86ZiAXl_~;`O)Ztq z_}=c_Cbe61`?XFDrv?c=pnn&s$RDX+{qv&x1J^T0sb$ton6xpe` zS(=u^24Dl0;d!e=KBIE}Ux&U=f1kmkcPyPa=dFK}QBqZdi*&(Z)YE!PU>Sw(+sXwi z>5UZvD4BXiHKkne@tKJalboAy77;spDtX~k0L(&wGXnP&MScWW0TA1ir9p@v!B)lA zz^|#8cXRN>=aVELE`kmpC+3m;b zoB60erGAJcaa^?LozJq48jc1b0Q?F7_!I#E+^Ycozu5al{%1FY68C@Y{$Ex!OkV8~ zuL2PcKx38wvy8qm62$>2-S1=8{i0*QA#CIU+VFJ(F8c!^qkH8#YK_@2?mGueB)L2_ z1*?VwkM--^9jcX6p|}V@2(3UWc?jDpqR0Qfuc5htemrc?*|?PpL)dYjtKy&o@*@D$ z6m$bjD(nDdWo+ZS;N6_Wr@pcrp$Kw1B5Bg667)j0_co5bPKWgfnZVM2iT!n6P~y_v zBLZ->dT)rN6VbrFlwfoNo5(krW)vzGca-;b)loGe2|6)GT@^DN1 zy7P^ARh(oC#jc07=StXJ&_9#(DJ{!>wP-zZ)Ausoop~PxZ%6#|{?nNyuEs-%-$OzN zp{JrI2lN?%w5A_)^oJ9I?qzU8CNGYPLfeeQ>$K&eop~RF0mz;6&D6QmrN-LPcH!F7 zz|pJaAHGz&5=to?bw)D#@u093JKQj>p%h1-sXS!i6! zcy5a|T3!2-1>1J>0OK<752(2`9B)vTNGX02or_f)P;ck(*nn+quLx0La2|Ya!v|v+ zlkpAVWj07Z!d@J-w)Lg}!WB^T2zj}wmm~+vK0imkl)Ap{eIy*t`v*Vq_Hf_h1-kCV zYI=K}+nrW7;kn%&ly4uiIFb$#>^^DfRc+Q#1UjCF z388vk*CyvrQ7b7k2%GTRG%OhAlr}&PtJ&T-P0P1+|6BTD43!V+qMD-zmbyN5q^<~l zWAByL1RYW0fWA&>V0sFypwRmgo-RKX5c6G_AEq3Nu<#!(r;@giNltjFU)O~yJhFrJ z=)=pp@0!PI%do#}g(ck`Qx9Uyg|MrW6yQ7cQT%~SJ$71X*>KyOxfEMMpxrMt2PVI} zFTzLr-`xA3rX?$J1EY1hvV5dj(Y$@hjbnvWi_w6o7@hKH1B(*B?%_Eutv1&nlD~yV5|g=t)8_ zCoV${{?+UYwiyxnx$NFHKeC_2gF&*oYz6xX?-E`v9Fh_o%Ea2v9?sPq4je-Dm6#=d z#+1Oe`3T;lgPZR|iGWY|qo1)XEY`1}(%-YZv?(dd%ax|hX*VU_s{|gn0lFF$cI$fj ztQm*otc|WxLD+9wz7rZy3VeN3f!>jVan5ryGR?)2>-%oX&@B91 zcSw%*XOr);@{lO%IL`W6(xnTPyh`{EIdYdtss8Lz71=(>H=VbWS&`BjOoj7$ezQ}S*COBH0XXUCCn)%F`` zJJUSg&58D!Hg0-K#cAMlk8@@aifCO}$gvCZtj-uzU`j6oQQ7+nTff;G_?F0T9?r?; zU56`M;K9H1X{wylmxHt5>Fr5?pXj+-|LDRm5h9J-{9dB}%E07y#wVt15bN}eMD4h-{({DhHE7Ry zC^Di=Kl{tTr$;o*HVj-x_CI-Jqs#s_W1Z?m`7qCWwb_RlH}LnSnF|BBOfdGnGPZx@ z%8u=TE~JYq%~u0zA}O-_AZk=Yje`PB3H2U$=Ps>EkzMb~ggde05m;tF7klYzg}936u0!*)=i4D$mU$au(LvBGiF&TJ zLKg4{<96oK9p(<5aQ78k2!Ii&|?M{}zRsujY8dPlbWWzb>c^_tb8ggBZcd74c|APFU&4Tt4@> z7ihKEOrAD#`sbeaw#2P|iC?jY1}@oWGoVdldXDyrXa$8`xRqN774mN9TEs_EJ;F7u z_JyQTuaXLx}#K793v{ zA?8yXRyVLf3~lBfbQHzaB^Kv63s0)NuJ?!<6eEyNy{M@tQJ~!B8(^Dn3&h2k!wXKG zpWc3U2c?(mFN#0UqHLHQQ_{)vzvTR3tKDZVbjqWNQrMTn)URqLG_MWtbj_GwRGXBl zS=DO&kqccq{r6E3%(pz(R@KE%!jU6e;K>Qj(=cg_p!w;e)W^%z`v6Vm)%qZZomDuEuLZ>`J>(9 zTxx^rmlP0424C}5ZwKIPL|H%~caD@beY|YuK;4ONs)cugB3CSwgFq)b@5K6`g<|&Z zh+ISBeDLaqJ13}rp4jaQvQVOMQ~-zSx_*q|U$vJVilu$t!dqQ`idsVqY0M)=f?Hi^ zi*|vvp1NNCs+G5^sgkwzHovSqP9?MQW(d^E+NYpq!SrF{BOfQoZYi0y6w?E&pp9zZ z-X%{)tvniNP1k-Wu*TT3DBzhCxWiuT-e>9c@UbGHW5=$5)b%i-v*7MKV_%)gzVpQ? z1i)ed-^JZD=G*}-*rkW|8%fn8tl93*yb=gYz?+@fyH0onS&uNwM#4pU-y6AUTe6U0o(koN%tO5W_a*QE@cy`TBUm6I&`9llJeboC|z>Glyaz_Ss2<= z>4cA6nwSSo?+0=(n^V`i-VEOHQtU2!%mWKtAB|Qg;S?5JKB~#3XMpIR~u1#v%2m=YH4OimGynsOAdzPYe^NfwSm@M1ZHA zRM`ZpJr46f$)u&tkKlfk_H)X$`6N|@tUZ7er-Q2}0mHwSRH;Z6bo=XvmBX=)pub(I zPnM1s!p^pKW+-?`9cxV5Ez6k2XuBax`(n#H;DNwRAz6Ce_~F^;uS0sNsOU2x4WdTU zOjE~kHO2NXGkVYEi%$LOC5yG&lAm8PLPS(Kn37%%D!Wq-o4eF59QR44oL2N3ip_D7 zl~Jj^2ux5%!YnZ@fohptgQ3hAQ3JG+cae8l>~N7xEzpNca+g*|VwZeOoTelsJTXGq zYj5WKXB&_G0jYo7o)VQi0K!s(6vYw>=#zPh?F45E@dqgpp5^GdYF~7V z`RSKqx&6Fe)M<5c^JJ*t0=t zCtpwxUKxceXv4w5Cgr-!;-~Y)G$Ng2Lz{L@M(=hey&SX;QHD(ODM)wKWBV)jEgVqI z_QY4z+utzl_BT4x%e5h*=jsH3$oKLj1dhT!WbHYU4*C*a->#ucDQTad?Ecn^SwK3z zC3r{48x=~kWoxhMXgp{+BT_f&G8t|fc{ksx@0WWLDFugBEJ4fbX|AVg6gV1uMpjABzTS$!2^Naxh#-Vw$8+DqHGGu%=B~~^RY^e!*2V*7UQO)5Z!_>qilf-zChzYT$+(Y z1}!b(3=3m=e(~UMGL<+4W6YH6zg}0OZ&&jMRA`s$&b*Y@_3RVZ@D>}rv2Cb!Y{%u0 zjkiDmVcUvq`t{{hRQpx_<|0CzmNv7LElY@@=ePipyFlgeQCPLfdUNu1lsrW7lp>E# z&$e8K_Lq3}s(RBJc8hn}uHTgr|Aq{`bAT2lo%Gi6KznbT4Vp_QQobCd+8a z$uNwHX9k>h=Zhl7S#?l($T-V3aFDvv;3PBmy!qx}b~;S=7FQOwdz4E#Hi~tyKm0e& z`-?|I!l(z{1hINId+s(Q$JCIfdfKXLb}36u`_CY~zcZUgunk37`MjaR1hlsB&Q2~m zPT;i3KhSPL@~n}-w&D0i<3FmuYCDp{Eokq#A`iW^hX^1UtV+z&M@~B#XmmN^%-7%W z4+7Uoaj#m}ue=hubYjVmAnE8mH+UvpHu)P?Xpi){IBPO4>o~RbV}1@^LN%8M@bkoZ zIcOPkt=9u^Xtw9!hi>P^N`oW?NTaG-wBJlEO7HAhwIWF>_(?S>4XZ2|pwUEn5rgGz zt%fZ$YT#!&vU2(rwUtuAx-BD9*fhU6B(`+hvNI^f7Q6;(*N_?(>-yP#H0|5=G!EK9 zKR4|+Pl`-UC;~&^yl-9fR687|JD%BSnO`S=wa~SKBoZIt=9zym9i2YnSCT9~x?Z*K zB>K^1QrhJM&+Qh7{&zgQr))Pw>GMl&l2s| zOnRQsPb1gXWarP|^^i%*#YKi3IosdO4JhI|*-Y1gE)vqjfQD7BdU}d67!}VSP&Z6j zIoR)J)apBz{HYw@=E8yrmyMswUv6{b&_?GEi?xLoUg8Hd$9as>U@uwQ8|hTHr+sm*xU zmO&$pU@XE-?BL=F8Q9N#sKGVe^EHIz@C&H5S~&(h1fs`T&cw?7#h*VuxNhHnPBu_aNaQsS3lO~=@E-_7eYjb|t9ymvq z_g%0y@guh(%cs}AAs^zMVPDsnCHYJDfkm8EVU)NJtJv-;21GNpE{3INSjtpCPV2Dz z3S3-p`Vbz=TfCMgQtO^3W(3quQ6LKa)3k2uF-7lFb@TDPFnEaN1%vC!p6l9s2Gq#~ zG{OqBb87&8WleEWXSor0dxYL^nYNs~@~Br4w_66B5H4Na|E5{j`0iMKA8o=e2Dtq& zeT?QIUD%M^$}G>1=#W}@%T^GztWH)QPnmOFrL8U$f910a7ZBRIRby?mFL*^1s&{xG z{XJY=ltm2xs{yOP$e+T@?@%|t)!(SC4JWzA`5QOBNoxz+LMrp?ueUjT#YZLNS4=$H znR!dEbM@&doA`WsA*Y7{uem>(i5KfSU$dMW7&yx+FHb0}0`2 z&KM@52r~YINJ`w5%)$V#BJj(aFRBc7xyNZ3CXw?9r=ov2W+l7s?ff#Ohr?28{_8A{ z;=x_87fQvuFH6`{yxXzZvAbq1`N5rUA>OZT1x+-E+0QA|!?F znhR>92B7^$_|W|yDagHV(r$qqXK{>fd|Kh3)MJ-zASE8D0#Q1MsCcAMrZ*{1x{vHZ zEckXEKgQ?6zF14^R+NAbu0#}CY|u|w+rhZg|D*(xxbZ^Bu2!~f%ykX96 zAwZRAjERQ5OnJ#Covc|ZTl42c5BHJXph2#4+84}o_527;`vkM>zo6FG!0>vJto<+w>pUm((8Rut_gIJ335n#5HMNZ*s&vUg_@SqbU< zdwQbc680sQ@1R5HGn3CHE8remPf?-e%DA}2j zQr^2jVO+>`X0!kS!pt!Sxgd*;&!mCXQFhr(>p6!)CUU^`hRazj!lr zp8!byP1b&KZMnvao{vt3Z1t!@|0qABE-#q&OCW7vUf z(P{08dbfu7_}rksk8HGDG{TLjTHZw(>>=`{39|c$H&_V%`qH_oYQ#-`tMRYdfKr{C zE*wRjWLavyl)kYTM4>^*kJos6!`C>eQ7mb{oq$Oz)z7ZlYVZ-pY5VneE z{ZWWZ6=A^I>fvSOAN{_t{yqRmUTTd{Z(i$7sD4~XMRGdUluv$IG=gwDIP(1Y!0@;p z@uF*jUqxMKUY$;zlQTieigFlye+zcbE2*wyl7)re4i-nosieKYPgOI}*;m04q1I>` zI|!L96Y~UTXZ>u-EJ-pB%JT3m&PibFdi2=it+o2|=Ccd7tNv7_o=4g^$79D~egt7$ zaB5|%aLRWUD$ai_sSO2Pw%I&vT%9C8g@C)XMc6_1_+cffd}kv_tEo z90c&SM~irLy>?#d;_$jvf)$i|tvMERO18+?9Z=X=u<2H>BH_6rEQk{5)&dd!t#p$-iHna(?>)l^)U&+YxGQe9To7~8+%5-n z=hXd$YG4leZ@OdNY;Bh!-0LhyS@tldLs;y z;{pEkjJQtmamLP)2Eo3U#!Zav6|-xc^U)pBB;FBl^Ni(@Dad8qr%?gwDmuzludKuV E2dWLBm;e9( literal 2104 zcmaJ@`9BkmA67$V$|A>*a?Y*fm@73S!x*C6DZ*T7TaGb4t|$p}&6VYjVx&)UEHhT$ zazu{!U^?tOA(Jbs_R&A^`Qdq<_xt(b{d#_SUhgcl(}lyLa-sqP0*8@y2-kgG`~wld zJ_93^?e>L;cD!iA=kxc+@$vDFj*jr~a1x0GgTZ(_9+%4<9v)s>TO*UnJ3BjgJbr0u zDK9V2-``(eUf$8sk;P(7PfvS!d9}5*H8nNSXtaig1_FVAKp+MN2HE zD4Rnp5h)-@x^Pm|d*4AJ5$7+)&a7616+bc)%kYkVo+^U~5VT>wS?BXv9wX%)!PvZK zqcyF2#LA;5%ASRm3c^c*g6=w;zdfb2eI0S2^MaO(&GI!s-Nm*$Vlt=dHt_Jz-^Gu? z9SqND*Pjw?6=5HJbFk0#+DO<6GYl?Br&#$*V&JF-pbtXf|5c&gs!tlGI>nliRdGb;UGY` zo%m{>$jHQ=wgcTdMI8YOm9uZ01(w}R*FTl)Qh;Z$_x2KVP+G>7NO6= z`V})M0gh4jpOB}_GvwaZ} zM)~3<*&Wwqt770pf>n976;UOTgR&|NkajPl@6}{e%T7QHidH~>d29&3TN#OUsWKT} ziU2*W%$8n4(H9!ql9;=5Ul{=`d5*XK7W2~T=^O_eIT#*)!@$P++HV=OYDpi>lotGU zU`;NpoE%kc7#j#nSoLB^JJqIf=%wkhvJRtaSFE; znANp%t{Y4CtSZX;4U6`j(~L7_F8jHFr2_FCgWnnTi+K%7GzF1&Xv(<%n@4*@Y@ns7 zM@650Swr=Z_oc$Nt-s852FlmhP@$tsx=_r4k;B7^mf_Frrn(}2lphemR z?V>|;kgBRJ;cAAhh$mgy9qC}ezPHX~>DEsk(CM$?=VK*5Y+FlRMO$W2%^O2g7q*Mu zD6whEX9{p#v+i3=?A;x!qC1ivBS7|WS=miP2hIqlA0?|1)64dTbg>r?Yj_81nEsRY zl^cHhp40WWD41LM=%=BMza53D(H88j;qRm*+g{$6i90bt2xzv%lek6fp+bxYroTmD zDnAh;`;+RsQn*BG=?)Ca{_&=0@)d=_KlJ5Q0p+u(kB7cm;H^yXn6`u9iU!!Ye|v_A zYPR^O2rnvMSGj4&e^7hv-RY(!W&KFIJpJc%nkuF?tV#fb_RLqpxsk$z1-2=cV%S!HPVY<|XJLd2K zu0WavmXrCx*`^@(s~%BB)6!2}DLDP3MAZ|_W%zvlw&bMDD#T>Eu`)Zd{<=t`{TH{|YxoN40A>3mcy zwg*2uK4tFR+tF;C4}8!mMQm%35gCd}Ebb8>j6=_i0sTcQ-hNNHq9_Q}#|nGCxAJ7i zs|~X1d1OI2Zl2yjG(^bhx!b*e!iIhIJK)6-i zk3`a$u=v|ql4q61zc7IQ1?1=#z8@2NE43C|(z%4?G)7Ln)9wxDVK->PE{@$ODWN^* zT)qzRvh;;I?OG&60kB4)^x~cjd3LSmXFYY~Zj{9jLp+_C8#%OpG?=ZYSBKhFc>Rj& z#M6}Q{fw$yxBib7)j~cmQJ^r%?hm%#(wWeeM^0w#RN*-rVcy-XtNnP$H8JXpIJI z-m9Q}3NammG%ebR%=#e{`HsdevXO0L3N;B3w>tF0rD7vRIvE^bYpd!k(5hN3kuA9-;F$@e=;&K#WgHSnNHoe>UX*vlI5 zVglc{b%`?AdXTP%F=hODCAU%a5b6X>#VxO=XX4~1Lse3~)LQp!&u-mQjgM|-q+70g Y0BSD=`c?SPiy$C?v~fZ_fnQ1a7xEV2(*OVf diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 7ebf109d16a..7f2ac8127e3 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -181,6 +181,16 @@ WLibraryBreadCrumb QLabel { color: #B3B3B3; } +WLibraryBreadCrumb QToolButton { + margin-right: 3px; + background: none; + border: none; +} + +WLibraryBreadCrumb QToolButton:hover { + background: none; +} + WBaseLibrary QLabel { margin: 4px 4px 0px 4px; font-size: 12px; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 2fa63c0b7ce..d730299f7e6 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1220,7 +1220,7 @@ #LibrarySidebarButtons QToolButton { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; - border: none; + border: 1px solid #191919; color: #cfb32c; background-color: #191919; } @@ -1280,6 +1280,12 @@ WLibraryBreadCrumb QLabel { margin: 4px 0px 6px 3px; } +WLibraryBreadCrumb QToolButton { + margin-right: 3px; + background: none; + border: none; +} + WBaseLibrary QLabel { padding: 0px 0px 0px 0px; margin: 100px 100px 100px 100px; diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 67dced43d27..c3cf56745e3 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -550,16 +550,15 @@ background-color: #aab2b7; } - QScrollArea WButtonBar, - QScrollArea WButtonBar QWidget { + WButtonBar { border: none; } WButtonBar QToolButton { padding: 2px 2px 2px 2px; color: black; - border: none; background-color: #aab2b7; + border: 2px solid #aab2b7; } WButtonBar QToolButton:hover { @@ -580,6 +579,12 @@ margin: 2px 0px 2px 3px; } + WLibraryBreadCrumb QToolButton { + margin-right: 3px; + background: none; + border: none; + } + WBaseLibrary QLabel { margin-left: 5px; margin-bottom: 5px; diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 755d8440869..584d8ebb5d6 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -3,15 +3,34 @@ #include "widget/wlibrarybreadcrumb.h" #include "library/treeitemmodel.h" +#include "widget/wpixmapstore.h" WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) - : QWidget(parent) { - QHBoxLayout* layout = new QHBoxLayout(this); - m_pIcon = new QLabel(this); - m_pText = new QLabel(this); + : QWidget(parent), + m_pIcon(new QLabel(this)), + m_pText(new QLabel(this)), + m_pPreselectButton(new QToolButton(this)), + m_preselected(false) { + QLayout* layout = new QHBoxLayout(this); + + m_pIcon->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_pIcon); layout->addWidget(m_pText); + + QPixmap preOn(WPixmapStore::getLibraryPixmap( + ":/images/library/ic_library_preselect.png")); + QPixmap preOff(WPixmapStore::getLibraryPixmap( + ":/images/library/ic_library_notpreselect.png")); + + m_preselectIcon.addPixmap(preOn, QIcon::Normal, QIcon::On); + m_preselectIcon.addPixmap(preOff, QIcon::Normal, QIcon::Off); + m_pPreselectButton->setIcon(m_preselectIcon); + m_pPreselectButton->setCheckable(true); + connect(m_pPreselectButton, SIGNAL(clicked()), + this, SLOT(slotPreselectClicked())); + layout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding)); + layout->addWidget(m_pPreselectButton); layout->setSpacing(2); layout->setContentsMargins(0,0,0,0); layout->setAlignment(Qt::AlignVCenter); @@ -28,6 +47,16 @@ QSize WLibraryBreadCrumb::minimumSizeHint() const { return QSize(0, min.height()); } +void WLibraryBreadCrumb::setPreselected(bool value) { + m_preselected = value; + m_pPreselectButton->toggle(); + refreshWidth(); +} + +bool WLibraryBreadCrumb::isPreselected() { + return m_preselected; +} + void WLibraryBreadCrumb::showBreadCrumb(TreeItem* pTree) { LibraryFeature* pFeature = pTree->getFeature(); DEBUG_ASSERT_AND_HANDLE(pFeature != nullptr) { @@ -47,7 +76,6 @@ void WLibraryBreadCrumb::setBreadIcon(const QIcon& icon) { // Get font height int height = m_pText->fontMetrics().height(); QPixmap pix = icon.pixmap(height); - m_pIcon->setContentsMargins(0, 0, 0, 0); m_pIcon->setPixmap(pix); } @@ -56,6 +84,10 @@ void WLibraryBreadCrumb::resizeEvent(QResizeEvent* pEvent) { refreshWidth(); } +void WLibraryBreadCrumb::slotPreselectClicked() { + qDebug() << "Button clicked value:" << m_pPreselectButton->isChecked(); +} + void WLibraryBreadCrumb::setText(const QString &text) { m_longText = text; setToolTip(m_longText); @@ -66,12 +98,15 @@ void WLibraryBreadCrumb::refreshWidth() { QFontMetrics metrics(fontMetrics()); // Measure the text for the label width - int mLText, mRText, mLIcon, mRIcon; + int mLText, mRText, mLIcon, mRIcon, mLPLabel, mRPLabel; m_pText->getContentsMargins(&mLText, nullptr, &mRText, nullptr); m_pIcon->getContentsMargins(&mLIcon, nullptr, &mRIcon, nullptr); - int margins = mLText + mRText + layout()->spacing() + mLIcon + mRIcon; + m_pPreselectButton->getContentsMargins(&mLPLabel, nullptr, &mRPLabel, nullptr); + int margins = mLIcon + mRIcon + layout()->spacing() + + mLText + mRText + mLPLabel + mRPLabel; - int newSize = width() - m_pIcon->width() - margins; + int newSize = width() - m_pIcon->width() - margins - + m_pPreselectButton->width(); QString elidedText = metrics.elidedText(m_longText, Qt::ElideRight, newSize); m_pText->setText(elidedText); } diff --git a/src/widget/wlibrarybreadcrumb.h b/src/widget/wlibrarybreadcrumb.h index f5a996a156a..32a3914f714 100644 --- a/src/widget/wlibrarybreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -1,7 +1,9 @@ #ifndef SRC_WIDGET_WBREADCRUMB_H_ #define SRC_WIDGET_WBREADCRUMB_H_ +#include #include +#include #include class TreeItem; @@ -14,7 +16,12 @@ class WLibraryBreadCrumb : public QWidget { WLibraryBreadCrumb(QWidget* parent = nullptr); virtual QSize minimumSizeHint() const; + void setPreselected(bool value); + bool isPreselected(); + signals: + void preselected(bool); + public slots: void showBreadCrumb(TreeItem* pTree); @@ -25,6 +32,9 @@ class WLibraryBreadCrumb : public QWidget { virtual void resizeEvent(QResizeEvent* pEvent); + private slots: + void slotPreselectClicked(); + private: void setText(const QString& text); @@ -32,6 +42,9 @@ class WLibraryBreadCrumb : public QWidget { QLabel* m_pIcon; QLabel* m_pText; + QToolButton* m_pPreselectButton; + QIcon m_preselectIcon; + bool m_preselected; QString m_longText; }; diff --git a/src/widget/wpixmapstore.cpp b/src/widget/wpixmapstore.cpp index 2fe67cd3103..ad2727fe4dd 100644 --- a/src/widget/wpixmapstore.cpp +++ b/src/widget/wpixmapstore.cpp @@ -370,12 +370,16 @@ void WPixmapStore::setLibraryIconLoader(QSharedPointer pIconLoader) { m_pIconLoader = pIconLoader; } -QIcon WPixmapStore::getLibraryIcon(const QString& filename) { +QIcon WPixmapStore::getLibraryIcon(const QString& fileName) { + return QIcon(getLibraryPixmap(fileName)); +} + +QPixmap WPixmapStore::getLibraryPixmap(const QString& fileName) { if (m_pIconLoader.isNull()) { - return QIcon(filename); + return QPixmap(fileName); } - QImage* image = m_pIconLoader->getImage(filename); + QImage* image = m_pIconLoader->getImage(fileName); if (!m_pLoader.isNull()) { m_pLoader->correctImageColors(image); @@ -383,7 +387,6 @@ QIcon WPixmapStore::getLibraryIcon(const QString& filename) { } QPixmap pixmap(QPixmap::fromImage(*image)); - QIcon icon(pixmap); delete image; - return icon; + return pixmap; } diff --git a/src/widget/wpixmapstore.h b/src/widget/wpixmapstore.h index 1fefeb5b13f..9d13ff3e88c 100644 --- a/src/widget/wpixmapstore.h +++ b/src/widget/wpixmapstore.h @@ -92,7 +92,8 @@ class WPixmapStore { static void setLoader(QSharedPointer ld); static void setLibraryIconLoader(QSharedPointer pIconLoader); - static QIcon getLibraryIcon(const QString& filename); + static QIcon getLibraryIcon(const QString& fileName); + static QPixmap getLibraryPixmap(const QString& fileName); private: static QHash m_paintableCache; From 3cfc7978f0eb10dcb2206e91dade9502960d2a46 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 13:33:47 +0200 Subject: [PATCH 445/552] Prepare library and library pane manager for preselected panes --- src/library/library.cpp | 9 +++------ src/library/library.h | 1 + src/library/librarypanemanager.cpp | 13 +++++++++++++ src/library/librarypanemanager.h | 3 +++ src/widget/wlibrarybreadcrumb.cpp | 4 +++- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 74a59385a57..a526ea1312e 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -626,11 +626,8 @@ void Library::setFocusedPane() { void Library::handleFocus() { // Changes the visual focus effect, removes the existing one and adds the // new focus - m_panes[m_focusedPane]->setFocus(); - for (auto it = m_panes.begin(); it != m_panes.end(); ++it) { - // Remove the focus from not focused panes - if (it.key() != m_focusedPane) { - it.value()->clearFocus(); - } + for (LibraryPaneManager* pPane : m_panes) { + pPane->clearFocus(); } + m_panes[m_focusedPane]->setFocus(); } diff --git a/src/library/library.h b/src/library/library.h index 3cdfc4b079d..474f95b29d8 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -171,6 +171,7 @@ class Library : public QObject { // Can be any integer as it's used with a HashMap int m_focusedPane; + int m_preselectedPane; }; #endif /* LIBRARY_H */ diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 8de55e1d2a6..fa95b28fe83 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -146,6 +146,19 @@ int LibraryPaneManager::getPaneId() { return m_paneId; } +void LibraryPaneManager::setPreselected(bool value) { + if (!m_pBreadCrumb.isNull()) { + m_pBreadCrumb->setPreselected(value); + } +} + +bool LibraryPaneManager::isPreselected() { + if (!m_pBreadCrumb.isNull()) { + return m_pBreadCrumb->isPreselected(); + } + return false; +} + void LibraryPaneManager::slotPaneCollapsed() { m_pLibrary->paneCollapsed(m_paneId); } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 20756b81c5a..318ea6f8584 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -49,6 +49,9 @@ class LibraryPaneManager : public QObject { void showBreadCrumb(const QString& text, const QIcon &icon); int getPaneId(); + + void setPreselected(bool value); + bool isPreselected(); signals: diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 584d8ebb5d6..00fd50be6c2 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -26,6 +26,8 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) m_preselectIcon.addPixmap(preOff, QIcon::Normal, QIcon::Off); m_pPreselectButton->setIcon(m_preselectIcon); m_pPreselectButton->setCheckable(true); + m_pPreselectButton->setChecked(m_preselected); + connect(m_pPreselectButton, SIGNAL(clicked()), this, SLOT(slotPreselectClicked())); @@ -49,7 +51,7 @@ QSize WLibraryBreadCrumb::minimumSizeHint() const { void WLibraryBreadCrumb::setPreselected(bool value) { m_preselected = value; - m_pPreselectButton->toggle(); + m_pPreselectButton->setChecked(value); refreshWidth(); } From d695c76fe627a10fca088cd5dd0b62af4e7d501b Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 13:48:42 +0200 Subject: [PATCH 446/552] Allow only non negative Ids for panes --- src/skin/legacyskinparser.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index f993752adec..f45b37a41ed 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1168,6 +1168,10 @@ QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { SKIN_WARNING(node, *m_pContext) << "SearchBox Id not found"; return nullptr; } + if (id < 0) { + SKIN_WARNING(node, *m_pContext) << "The SearchBox Id cannot be negative"; + return nullptr; + } //qDebug() << "SearchBox ID:" << id; WSearchLineEdit* pSearchLineEdit = new WSearchLineEdit(m_pParent); @@ -1267,14 +1271,18 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); int id = -1; - if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { - //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; - m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, id); + if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { + SKIN_WARNING(node, *m_pContext) << "Pane Id not found"; + return nullptr; } - else { - SKIN_WARNING(node, *m_pContext) << "No Id found"; + if (id < 0) { + SKIN_WARNING(node, *m_pContext) << "The pane Id cannot be negative"; + return nullptr; } + //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; + m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, id); + // This must come after the bindWidget or we will not style any of the // LibraryView's because they have not been added yet. commonWidgetSetup(node, pLibraryWidget, false); @@ -1369,13 +1377,17 @@ QWidget* LegacySkinParser::parseLibraryBreadCrumb(const QDomElement& node) { WLibraryBreadCrumb* pLibraryBreacrumb = new WLibraryBreadCrumb(m_pParent); int id = -1; - if (m_pContext->hasNodeSelectInt(node, "Id", &id)) { - //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; - m_pLibrary->bindBreadCrumb(pLibraryBreacrumb, id); + if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { + SKIN_WARNING(node, *m_pContext) << "BreadCrumb Id not found"; + return nullptr; } - else { - SKIN_WARNING(node, *m_pContext) << "No Id found"; + if (id < 0) { + SKIN_WARNING(node, *m_pContext) << "The BreadCrumb Id cannot be negative"; + return nullptr; } + + //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; + m_pLibrary->bindBreadCrumb(pLibraryBreacrumb, id); setupWidget(node, pLibraryBreacrumb); return pLibraryBreacrumb; From de3065921b998d3c8db57fbeebff11ce98d99aff Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 13:49:29 +0200 Subject: [PATCH 447/552] Remove unnecessary slot in WLibraryBreadcrumb --- src/widget/wlibrarybreadcrumb.cpp | 8 ++------ src/widget/wlibrarybreadcrumb.h | 7 ------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 00fd50be6c2..63f04b6fa1f 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -28,8 +28,8 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) m_pPreselectButton->setCheckable(true); m_pPreselectButton->setChecked(m_preselected); - connect(m_pPreselectButton, SIGNAL(clicked()), - this, SLOT(slotPreselectClicked())); + connect(m_pPreselectButton, SIGNAL(clicked(bool)), + this, SIGNAL(preselected(bool))); layout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding)); layout->addWidget(m_pPreselectButton); @@ -86,10 +86,6 @@ void WLibraryBreadCrumb::resizeEvent(QResizeEvent* pEvent) { refreshWidth(); } -void WLibraryBreadCrumb::slotPreselectClicked() { - qDebug() << "Button clicked value:" << m_pPreselectButton->isChecked(); -} - void WLibraryBreadCrumb::setText(const QString &text) { m_longText = text; setToolTip(m_longText); diff --git a/src/widget/wlibrarybreadcrumb.h b/src/widget/wlibrarybreadcrumb.h index 32a3914f714..8a25e05a9d2 100644 --- a/src/widget/wlibrarybreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -12,7 +12,6 @@ class WLibraryBreadCrumb : public QWidget { Q_OBJECT public: - WLibraryBreadCrumb(QWidget* parent = nullptr); virtual QSize minimumSizeHint() const; @@ -23,20 +22,14 @@ class WLibraryBreadCrumb : public QWidget { void preselected(bool); public slots: - void showBreadCrumb(TreeItem* pTree); void showBreadCrumb(const QString& text, const QIcon& icon); void setBreadIcon(const QIcon& icon); protected: - virtual void resizeEvent(QResizeEvent* pEvent); - private slots: - void slotPreselectClicked(); - private: - void setText(const QString& text); void refreshWidth(); From a24d3bcf1ce71be87eb7fff5aa3af5f54f8a430c Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 14:09:30 +0200 Subject: [PATCH 448/552] Add preselection visuals --- src/library/library.cpp | 52 +++++++++++++++++++----------- src/library/library.h | 3 +- src/library/librarypanemanager.cpp | 11 +++++-- src/library/librarypanemanager.h | 1 + 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index a526ea1312e..12274f75763 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -53,7 +53,8 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, m_pLibraryControl(new LibraryControl(this)), m_pRecordingManager(pRecordingManager), m_scanner(m_pTrackCollection, pConfig), - m_pSidebarExpanded(nullptr) { + m_pSidebarExpanded(nullptr), + m_preselectedPane(-1) { qRegisterMetaType("Library::RemovalType"); connect(&m_scanner, SIGNAL(scanStarted()), @@ -264,6 +265,37 @@ void Library::restoreSaveButton() { pPane->restoreSaveButton(); } +void Library::paneFocused(LibraryPaneManager* pPane) { + DEBUG_ASSERT_AND_HANDLE(pPane) { + return; + } + + if (pPane != m_pSidebarExpanded) { + m_focusedPane = pPane->getPaneId(); + pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); + DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { + return; + } + setFocusedPane(); + handleFocus(); + } + + //qDebug() << "Library::slotPaneFocused" << m_focusedPane; +} + +void Library::panePreselected(LibraryPaneManager* pPane, bool value) { + // Since only one pane can be preselected, set the other panes as not + // preselected + if (value) { + if (m_preselectedPane >= 0) { + m_panes[m_preselectedPane]->setPreselected(false); + } + pPane->setPreselected(true); + m_preselectedPane = pPane->getPaneId(); + } else if (m_preselectedPane == pPane->getPaneId()) { + m_preselectedPane = -1; + } +} void Library::slotRefreshLibraryModels() { m_pMixxxLibraryFeature->refreshLibraryModels(); @@ -497,24 +529,6 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::slotPaneFocused(LibraryPaneManager* pPane) { - DEBUG_ASSERT_AND_HANDLE(pPane) { - return; - } - - if (pPane != m_pSidebarExpanded) { - m_focusedPane = pPane->getPaneId(); - pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); - DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { - return; - } - setFocusedPane(); - handleFocus(); - } - - //qDebug() << "Library::slotPaneFocused" << m_focusedPane; -} - void Library::slotUpdateFocus(LibraryFeature* pFeature) { if (pFeature->getFeatureFocus() >= 0) { m_focusedPane = pFeature->getFeatureFocus(); diff --git a/src/library/library.h b/src/library/library.h index 474f95b29d8..10433916a88 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -96,6 +96,8 @@ class Library : public QObject { void showBreadCrumb(const QString& text, const QIcon& icon); void restoreSearch(const QString& text); void restoreSaveButton(); + void paneFocused(LibraryPaneManager *pPane); + void panePreselected(LibraryPaneManager* pPane, bool value); public slots: @@ -115,7 +117,6 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - void slotPaneFocused(LibraryPaneManager *pPane); // Updates with the focus feature void slotUpdateFocus(LibraryFeature* pFeature); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index fa95b28fe83..8bfee7b8c32 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -66,6 +66,8 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb* pBreadCrumb) { m_pBreadCrumb = pBreadCrumb; pBreadCrumb->installEventFilter(this); + connect(m_pBreadCrumb, SIGNAL(preselected(bool)), + this, SLOT(slotPanePreselected(bool))); } void LibraryPaneManager::addFeature(LibraryFeature* feature) { @@ -159,6 +161,11 @@ bool LibraryPaneManager::isPreselected() { return false; } +void LibraryPaneManager::slotPanePreselected(bool value) { + setPreselected(value); + m_pLibrary->panePreselected(this, value); +} + void LibraryPaneManager::slotPaneCollapsed() { m_pLibrary->paneCollapsed(m_paneId); } @@ -168,7 +175,7 @@ void LibraryPaneManager::slotPaneUncollapsed() { } void LibraryPaneManager::slotPaneFocused() { - m_pLibrary->slotPaneFocused(this); + m_pLibrary->paneFocused(this); } void LibraryPaneManager::slotSearch(const QString& text) { @@ -201,7 +208,7 @@ bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { (m_pPaneWidget->underMouse() || m_pSearchBar->underMouse() || m_pBreadCrumb->underMouse())) { - m_pLibrary->slotPaneFocused(this); + m_pLibrary->paneFocused(this); } // Since this event filter is for the entire application (to handle the diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 318ea6f8584..33b811c0154 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -60,6 +60,7 @@ class LibraryPaneManager : public QObject { public slots: + void slotPanePreselected(bool value); void slotPaneCollapsed(); void slotPaneUncollapsed(); void slotPaneFocused(); From f06ec6cd9c13714d8cb928239e6625b0f6235156 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 24 Aug 2016 15:16:04 +0200 Subject: [PATCH 449/552] Rename featureFocus to featurePane and solve small issues --- src/library/baseplaylistfeature.cpp | 10 ++--- src/library/baseplaylistfeature.h | 2 +- src/library/browse/browsefeature.cpp | 37 ++++++++-------- src/library/browse/browsefeature.h | 2 + src/library/cratefeature.cpp | 63 ++++++++++------------------ src/library/cratefeature.h | 2 + src/library/library.cpp | 16 +++---- src/library/libraryfeature.cpp | 19 +++++---- src/library/libraryfeature.h | 6 +-- src/library/maintenancefeature.cpp | 6 +-- 10 files changed, 76 insertions(+), 87 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 136fdb2825f..2fb3dacb611 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -133,7 +133,7 @@ void BasePlaylistFeature::activate() { return; } - showBrowse(m_featureFocus); + showBrowse(m_featurePane); switchToFeature(); showBreadCrumb(); @@ -142,7 +142,7 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { - if (index == m_lastChildClicked && m_lastClickedFocus == m_featureFocus) { + if (index == m_lastChildClicked && m_lastClickedFocus == m_featurePane) { restoreSearch(""); showTable(m_lastClickedFocus); @@ -152,7 +152,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { } m_lastChildClicked = index; - m_lastClickedFocus = m_featureFocus; + m_lastClickedFocus = m_featurePane; //qDebug() << "BasePlaylistFeature::activateChild()" << index; QSet playlistIds = playlistIdsFromIndex(index); m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); @@ -312,9 +312,9 @@ void BasePlaylistFeature::slotCreatePlaylist() { } } -void BasePlaylistFeature::setFeatureFocus(int focus) { +void BasePlaylistFeature::setFeaturePane(int focus) { m_pPlaylistTableModel = getPlaylistTableModel(focus); - LibraryFeature::setFeatureFocus(focus); + LibraryFeature::setFeaturePane(focus); } void BasePlaylistFeature::slotDeletePlaylist() { diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index d8de941b37f..1927c12cb7b 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -50,7 +50,7 @@ class BasePlaylistFeature : public LibraryFeature { virtual void slotPlaylistContentChanged(int playlistId) = 0; virtual void slotPlaylistTableRenamed(int playlistId, QString a_strName) = 0; void slotCreatePlaylist(); - void setFeatureFocus(int focus); + void setFeaturePane(int focus); protected slots: void slotDeletePlaylist(); diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 591523a55c3..5dce11d6e07 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -234,13 +234,7 @@ void BrowseFeature::activate() { return; } - auto it = m_panes.find(m_featureFocus); - auto itId = m_idBrowse.find(m_featureFocus); - if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { - return; - } - - (*it)->setCurrentIndex(*itId); + showBrowse(m_featurePane); switchToFeature(); m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); m_pLibrary->restoreSearch(QString()); @@ -274,18 +268,9 @@ void BrowseFeature::activateChild(const QModelIndex& index) { m_browseModel.setPath(dir); } - auto itId = m_idTable.find(m_featureFocus); - auto it = m_panes.find(m_featureFocus); - - if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { - qDebug() << "BrowseFeature::activateChild item not found"; - return; - } - - QString bread = index.data(TreeItemModel::RoleBreadCrumb).toString(); - - (*it)->setCurrentIndex(*itId); + showTable(m_featurePane); showTrackModel(&m_proxyModel); + QString bread = index.data(TreeItemModel::RoleBreadCrumb).toString(); showBreadCrumb(bread, getIcon()); emit(enableCoverArtDisplay(true)); @@ -506,3 +491,19 @@ QStringList BrowseFeature::getDefaultQuickLinks() const { qDebug() << "Default quick links:" << result; return result; } + +void BrowseFeature::showBrowse(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idBrowse.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idBrowse.end()) { + (*it)->setCurrentIndex(*itId); + } +} + +void BrowseFeature::showTable(int paneId) { + auto itId = m_idTable.find(paneId); + auto it = m_panes.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idTable.end()) { + (*it)->setCurrentIndex(*itId); + } +} diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index 1eb46ca97b9..d2d26e0b6e2 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -66,6 +66,8 @@ class BrowseFeature : public LibraryFeature { QStringList getDefaultQuickLinks() const; void saveQuickLinks(); void loadQuickLinks(); + void showBrowse(int paneId); + void showTable(int paneId); BrowseTableModel m_browseModel; ProxyTrackModel m_proxyModel; diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 5754a0614ad..1148c23a4e6 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -135,18 +135,9 @@ bool CrateFeature::isSinglePane() const { } int CrateFeature::crateIdFromIndex(QModelIndex index) { - TreeItem* item = static_cast(index.internalPointer()); - if (item == nullptr) { - return -1; - } - - QString dataPath = item->dataPath().toString(); bool ok = false; - int playlistId = dataPath.toInt(&ok); - if (!ok) { - return -1; - } - return playlistId; + int crateId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); + return ok ? crateId : -1; } bool CrateFeature::dragMoveAccept(QUrl url) { @@ -233,50 +224,26 @@ void CrateFeature::activate() { return; } - auto it = m_panes.find(m_featureFocus); - auto itId = m_idBrowse.find(m_featureFocus); - if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { - return; - } - - (*it)->setCurrentIndex(*itId); - + showBrowse(m_featurePane); switchToFeature(); showBreadCrumb(); restoreSearch(QString()); //disable search on crate home - m_featureFocus = -1; emit(enableCoverArtDisplay(true)); } void CrateFeature::activateChild(const QModelIndex& index) { m_lastClickedIndex = index; - if (!index.isValid()) { - return; - } int crateId = crateIdFromIndex(index); if (crateId == -1) { return; } - m_pCrateTableModel = getTableModel(m_focusedPane); - auto it = m_panes.find(m_focusedPane); - auto itId = m_idTable.find(m_focusedPane); - if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { - return; - } - - (*it)->setCurrentIndex(*itId); + m_pCrateTableModel = getTableModel(m_featurePane); m_pCrateTableModel->setTableModel(crateId); - - // Set the feature Focus for a moment to allow the LibraryFeature class - // to find the focused WTrackTable - m_featureFocus = m_focusedPane; - showTrackModel(m_pCrateTableModel); - m_featureFocus = -1; - + showTable(m_featurePane); restoreSearch(""); - showBreadCrumb(index.data(TreeItemModel::RoleBreadCrumb).toString(), - getIcon()); + showBreadCrumb(index); + showTrackModel(m_pCrateTableModel); emit(enableCoverArtDisplay(true)); } @@ -956,3 +923,19 @@ QPointer CrateFeature::getTableModel(int paneId) { } return *it; } + +void CrateFeature::showBrowse(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idBrowse.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idBrowse.end()) { + (*it)->setCurrentIndex(*itId); + } +} + +void CrateFeature::showTable(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idTable.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idTable.end()) { + (*it)->setCurrentIndex(*itId); + } +} diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 6b3651087f5..4dd309384f4 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -92,6 +92,8 @@ class CrateFeature : public LibraryFeature { QModelIndex indexFromCrateId(int crateId); QPointer getTableModel(int paneId); + void showBrowse(int paneId); + void showTable(int paneId); TrackCollection* m_pTrackCollection; CrateDAO& m_crateDao; diff --git a/src/library/library.cpp b/src/library/library.cpp index 12274f75763..85c4d41cfac 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -163,7 +163,7 @@ void Library::destroyInterface() { } for (LibraryFeature* f : m_features) { - f->setFeatureFocus(-1); + f->setFeaturePane(-1); } m_panes.clear(); } @@ -272,7 +272,7 @@ void Library::paneFocused(LibraryPaneManager* pPane) { if (pPane != m_pSidebarExpanded) { m_focusedPane = pPane->getPaneId(); - pPane->getCurrentFeature()->setFeatureFocus(m_focusedPane); + pPane->getCurrentFeature()->setFeaturePane(m_focusedPane); DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } @@ -331,7 +331,7 @@ void Library::onSkinLoadFinished() { } } - (*itF)->setFeatureFocus(m_focusedPane); + (*itF)->setFeaturePane(m_focusedPane); (*itF)->setSavedPane(m_focusedPane); (*itF)->activate(); m_savedFeatures[m_focusedPane] = *itF; @@ -342,7 +342,7 @@ void Library::onSkinLoadFinished() { // The first pane always shows the Mixxx Library feature on start m_focusedPane = m_panes.begin().key(); - (*m_features.begin())->setFeatureFocus(m_focusedPane); + (*m_features.begin())->setFeaturePane(m_focusedPane); slotActivateFeature(*m_features.begin()); } else { @@ -452,14 +452,14 @@ void Library::paneUncollapsed(int paneId) { // pane feature, switch the feature from one pane to the other and set // instead the saved feature LibraryFeature* pPaneFeature = m_panes[paneId]->getCurrentFeature(); - pPaneFeature->setFeatureFocus(m_panes[paneId]->getPaneId()); + pPaneFeature->setFeaturePane(m_panes[paneId]->getPaneId()); for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); if (auxId != paneId && pPaneFeature == pPane->getCurrentFeature()) { LibraryFeature* pSaved = m_savedFeatures[auxId]; pPane->switchToFeature(pSaved); - pSaved->setFeatureFocus(auxId); + pSaved->setFeaturePane(auxId); pSaved->activate(); } } @@ -530,8 +530,8 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { } void Library::slotUpdateFocus(LibraryFeature* pFeature) { - if (pFeature->getFeatureFocus() >= 0) { - m_focusedPane = pFeature->getFeatureFocus(); + if (pFeature->getFeaturePane() >= 0) { + m_focusedPane = pFeature->getFeaturePane(); setFocusedPane(); } } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 3d1e18a7cec..a61ce66faf5 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -36,7 +36,7 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), - m_featureFocus(-1), + m_featurePane(-1), m_focusedPane(-1), m_savedPane(-1) { } @@ -104,12 +104,12 @@ QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { return pContainer; } -void LibraryFeature::setFeatureFocus(int focus) { - m_featureFocus = focus; +void LibraryFeature::setFeaturePane(int paneId) { + m_featurePane = paneId; } -int LibraryFeature::getFeatureFocus() { - return m_featureFocus; +int LibraryFeature::getFeaturePane() { + return m_featurePane; } void LibraryFeature::setFocusedPane(int paneId) { @@ -122,7 +122,7 @@ int LibraryFeature::getFocusedPane() { void LibraryFeature::setSavedPane(int paneId) { m_savedPane = paneId; - setFeatureFocus(m_savedPane); + setFeaturePane(m_savedPane); } int LibraryFeature::getSavedPane() { @@ -237,7 +237,7 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* } void LibraryFeature::showTrackModel(QAbstractItemModel *model) { - auto it = m_trackTables.find(m_featureFocus); + auto it = m_trackTables.find(m_featurePane); if (it == m_trackTables.end() || it->isNull()) { return; } @@ -262,7 +262,8 @@ void LibraryFeature::showBreadCrumb(TreeItem *pTree) { } void LibraryFeature::showBreadCrumb(const QModelIndex& index) { - showBreadCrumb(static_cast(index.internalPointer())); + showBreadCrumb(index.data(TreeItemModel::RoleBreadCrumb).toString(), + getIcon()); } void LibraryFeature::showBreadCrumb(const QString &text, const QIcon& icon) { @@ -274,7 +275,7 @@ void LibraryFeature::showBreadCrumb() { } WTrackTableView *LibraryFeature::getFocusedTable() { - auto it = m_trackTables.find(m_featureFocus); + auto it = m_trackTables.find(m_featurePane); if (it == m_trackTables.end() || it->isNull()) { return nullptr; } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 8299e9392d9..27959c25be7 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -69,8 +69,8 @@ class LibraryFeature : public QObject { virtual TreeItemModel* getChildModel() = 0; - virtual void setFeatureFocus(int focus); - int getFeatureFocus(); + virtual void setFeaturePane(int paneId); + int getFeaturePane(); void setFocusedPane(int paneId); int getFocusedPane(); @@ -155,7 +155,7 @@ class LibraryFeature : public QObject { TrackCollection* m_pTrackCollection; SavedQueriesDAO& m_savedDAO; - int m_featureFocus; + int m_featurePane; int m_focusedPane; int m_savedPane; diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index 031e1ce3023..e05b85cde35 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -57,7 +57,7 @@ void MaintenanceFeature::selectionChanged(const QItemSelection&, return; } - auto it = m_idPaneCurrent.find(m_featureFocus); + auto it = m_idPaneCurrent.find(m_featurePane); if (it == m_idPaneCurrent.end()) { return; } @@ -124,7 +124,7 @@ void MaintenanceFeature::slotTabIndexChanged(int index) { DEBUG_ASSERT_AND_HANDLE(!m_pHiddenView.isNull()) { return; } - m_idPaneCurrent[m_featureFocus] = Pane::Hidden; + m_idPaneCurrent[m_featurePane] = Pane::Hidden; pTable->loadTrackModel(getHiddenTableModel()); title = &kHiddenTitle; @@ -134,7 +134,7 @@ void MaintenanceFeature::slotTabIndexChanged(int index) { return; } - m_idPaneCurrent[m_featureFocus] = Pane::Missing; + m_idPaneCurrent[m_featurePane] = Pane::Missing; pTable->loadTrackModel(getMissingTableModel()); title = &kMissingTitle; From 09af0eeda54ba2897a5d50a6d30b58bc940baf20 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 11:03:20 +0200 Subject: [PATCH 450/552] Remove unnecessary function in MixxxLibraryFeature --- src/library/mixxxlibraryfeature.cpp | 7 ------- src/library/mixxxlibraryfeature.h | 1 - 2 files changed, 8 deletions(-) diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 2f3dd021868..b2df948a540 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -162,13 +162,6 @@ void MixxxLibraryFeature::refreshLibraryModels() { } } -void MixxxLibraryFeature::selectAll() { - QPointer pTable = getFocusedTable(); - if (!pTable.isNull()) { - pTable->selectAll(); - } -} - void MixxxLibraryFeature::onSearch(const QString&) { showBreadCrumb(); if (!m_pSidebar.isNull()) { diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index db81afce09a..b9512f1c139 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -56,7 +56,6 @@ class MixxxLibraryFeature : public LibraryFeature { void onRightClickChild(const QPoint& pos, const QModelIndex&) override; void refreshLibraryModels(); - void selectAll(); void onSearch(const QString&) override; signals: From 3eb4a036b9feac579755c3574047e78c51eb3d15 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 11:03:30 +0200 Subject: [PATCH 451/552] Add new preselect icons --- .../library/ic_library_notpreselect.png | Bin 3520 -> 10169 bytes res/images/library/ic_library_preselect.png | Bin 7579 -> 10947 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/res/images/library/ic_library_notpreselect.png b/res/images/library/ic_library_notpreselect.png index f5cac3aa6615b460876a33043f4b0bab7237177d..4180e63a3263c1e71b0e17ef179a7c4840267cf6 100644 GIT binary patch literal 10169 zcmd5?hcg`R^VT^noQU3g_Yu7ly~gRiL@#m5A&7cN)F6o7i7rZXPOs5h)H}U95pnv@ z_rLhfJNxd;zB9WsJM%uXJJ0j^t&S=YJ~ciX8XA$hniA;QBmQT2IM26i<80uw!?Dv; zRYH6E-zn%SPkoL6z-p#GXlMjv|1)&7tQ^YcAg-^vwlXdpkCFnwcE4rqjE2UDrmm!5 z5U_HZ>sD=VoVFQyY_RTh?XkN4)9db`Pt?ZUJ)6;)bb>TM; z!#~*;ztfd{gY}@}jc$nBL+RWCr0PieI<)S|Ea2i>WH;U;4|TH^(r;_`V(=#&V4htwj&3-Xkb1d0pBMVHZPLf| z1}h#L5@mbH51-PX@Z?Y12m;Tnc>-SMV}opZX(Ml-9f?(8`xm|R1Uo149PQ-lmBU9; zeJ(T@nK;0_zVc2g^y_p1mnl1q;6AqC*%s1i8&+vulU{EfB9*?&*jYShL15l~Yq*SE zWb$)v;UbR~Sbcek=F{|`fmW^%@Jzs+17Q0V#MtqH&d_eKo1<`4j|HB0QK--JNub77 zw$Rr5>zZiGj$Duop}(m3Ag<@%;uG-Bnr_EKfvm~1bqnT!muv8Pz+R`zzwrTuO;XiFB}kH zL1H1_F6Y4nYB9U_CU;TzzN&rQB45r87*7dcaj03w+yjfMg=A~Ifkmym89jXQQX}w6 zoNOlBnrUCNB1^4kghe&)I0TjeQ-;yOv|(&8p0L54o2CeCH=-ZQnzkJ;TdBlJKeds3 z@`s2IDcU73^WK*4d>y8;05!4>1eN=bd>b1YH~~mb9@$~xpAQ8o&Jry z76oG>f7+Z9WAtEIkm3EHr2de7O3qp9$mn~(C$N-oKNNKkJhy3R2E zVJ8m>QY`G4MGkB>x;Sr3hxHzt9}n~(cko{b_i%Z!dz5M4MT#eY;rBfWG8^?@r!vd> z2L$O?#3Pbc9(;mbGnHliU*Jam4aJO*TK)S>a}PR-E?8-v7k<+i-GgI6LprC{I;B_ot&1Gx538z&kKcsQ*Y)BK5^GiY zNNa!VO+xR+W%$%aK2E(t(2CZID;M@;*$BO(xI~>~gc98AU!q^>zTI+mE9G-08kq8&;((n- z?S)`S->IHEV@TcjEKS%Z#s*MQmjxl)+WiJK5pTSG{9)3>d~;45t&h-87`aWi1FhF;R3fLv9Js)VMdWV`Qq=X1IW|E#PX2icZBw;1z26Yx}UXq_31aq^t-zjoL?axC3Qkv zuFq&J$8}2(oF?2Dfy09M(5Jjdki{wj%(JFMzZN4MRBLT1{a)iy|Ma6^_@8mg=Ns*4 z^?p-$#DkI&OQ9{$>ves}@ITeN_2xK1E>}vH5UPAK=^ln)rABD9`oKAQ3%tCF3P2Qn z30;D7xU|GW*_Da*ahEVC&T!w@rB4f1paetyV`zlp^nVyoM%_f)u?lm!ItR+Hw73K~ zN=7?fU@%70BP0hzBDucD;DT8}d|lKt7ygd zQV+oH9{Wk8d-4%u62X!Ic{HO^Yi-vC_Ca<2&~@BwU~@@E=1+ehGBWjG-ucdbNi!6vF5!7sr+z+zB-Bn4`IuRN;(Lpo)mqlJJNcL&j9>RGvpnTNktv&Hip6__nEQ7UHJ zn1-{w#J>fg+s!J@e^;;Ah7aq~|3)*ekpLyjNK%y)OC|b5Yu}X+wPl_EjMo*ar5@|8 z=Ob)OqUME@-r`nOMK1w_#NRiKqkbRse0mH4$R6A0ydL3^pe;{mE_QQGIHb%4=QJRs z(uBVJC#%YWARfuWJXu33iIh6ZGQqjKDQD(Tipoy?A3LyGv#hxO`SpJ=?snHW+sCW` zVLZ}W-ycxHwU(cDQSOCRF(i7bO`jH)*9cIRP8@v~8A#<10{A7K35d4lXp-ubnYec# zNu8vNR@!|P76eK?z!w+u^)VIIBGJGdDN+W`Q8+V+Ewo0wMn!#EuabUeE_GzU9p?qi zzw!!Y-125b5cNtEbW!pK9T$LOZ3^`gor^m1CRrNbnR1NRV%`WBoPyd+K> zy)~j+^EK(S#2+J}ho_yK$UnFb3CYsop&;;>aJ(9uOl}^?r&~noywKp|lAU6oL$La_ zDh43*74Nws)2E5f~x% z3%!h9_iPvaOj5R|^2^?e=1}kV3tyg!ewSNFk-*2obL0GFU{#&|AlfH{*TR~EWtX17 z`)ZAH?bFS)I^W`#HtmpLzm61N4K>Od84B|udu>Tw&Qs51{ttC4Pa1MutLoGCVqktH zPF*3Bz`~RyUEIStrC9F!4dF=>W$uj8B{*+?+dXUW8FiuvKEOIwt&Hjk6$M_edgnZS z%D775##<=(xFSf_s4-`P`I=^DCPY<EXL}`Y-29RXV1K&CwVLn;<#FLmUFsBOO$3*KsPM8Lo<4SXr9^PsM}s#)+uyd0 zp-#q5r$;GFKi^?5l}AHs*^e02dB&94Dh*;$X%pxDPg0P5p0@1+#$s0Hmbu>HJd%bi z=i3z5C(MMA8vNtRud`b9wcMp6(Jxb}L)#13%Y}WZsqK%l@G5V7rcz|gsvD2ga$MzX zi>HJwd{kNgR;`56*7SHnSgXr~$wiXt$5GxcX{Uyld7ZF$wfysFHRltdgS#skrNgeF zV6|OmgxvY}*-_KhfXyt4y7q0uS7Ik}d_o4%xNZ2p&D~xvVb!8)K^F@{v1$$fh@1@i zm~!%}jt!VATF>S~>-K_gYlXV4lRMyOhx$A#98Xdh4&plJLG7h*3lW{xFSpP_neW{E zzJ!OHr8@oP9!y6{+&ps1;ZzCtZJ(4R}KI+EnJ~qZB%O!eMWbGTUK^45z}O~+oO3>e+2W-&W7U;)f-+#fkj)GnEJ3S5xt$Z@;XE3u7_6U zI&p5)RMb=Y&C6NOk9IraxhhAg1VFy1xjfepNE612qNT0%>KSyb4dekF2vQU?6-gsw2Ty16({XOeg zOlZmReRe~j5kic48u;{76e#-mu6)c#$b)qP+YU6!NfcV;)=9M`o%kodPrEWRx*#)A zA$v+@R6mtHt5Yw0LPkgD3D_$HsPUoCDL-v`_w8Qavg_f8#)P)%hD-2&*hn8C4qx0FQ z6iseCUB|=T9mOP;y%ua_N>;-VP4RhNxZJYt%+Jrqb#4Y*OZf3Y_AJ3^(ktJr=B5u; zfOm$U7wU=BPD8%OMZEqP8C!dFgTW=TbBixG#KEGKPpi$~EWMbKnoIck zCy|MXgEr!rlYug3-s8&5ckOkD{kOgfM;c=0Pux+9gu2dCeG=5b&eRYk%o`=Dc*&TD zv>z8^YCA)?dqpUNH{jZ=zUE!q$N)}Uu=CS}FPKu5yorX_Mz!lDgsO1`$T=uiP_$dz zbu@KN^>ujR#jX}Ez{iNAS*J4cam8`B_TS3X<@T3$H09(pZwFurmz}Ygi~Yh%(Co7M z?s`Q|v%e1M@X$A#%_}J4W!eVsU%jD&+oC>)(1G?5Uqvob)iHajblUKw#7T^r=?{Y$ zONOEAW`P)E?QbMM1HW)~TBvA@U+r9K!lvfSw`z2V06yKITu7Yxf@ACVhsY6uq&G)K zX1uTEdkO>lBszpQdF`Av-&~1}n!rA>@=-fh87ttGH(3gV>0ev&rCli=>QDrANup;S2jfR8JZov#fc%C z4oJWrC0zZhrTwm;|JTxTbAbUlEkg06->(uJmG2YsVq1RP zl;DgF>^~1grv$vAi>sV)6@DJWo4)%;8NHPxHXyK95si>HqlikgxgkIY$YzLY{&JO^ zHe308AgIob>Ef;YrAU)GKYz?wOEvZ^%5L-{g8mLBl!hPR$dK+tw87dyt`#DV?=zpTnj1&VbFumG7s>M|5YVHYi2_P%U*Gr_M&?N1v+IF+H!r+5dMI6!Lg zJK2hGHS;H%Kbn%!lQ!!&dWfG4$b~*JNeZt(9R&EWRSO}1xj*su2ftVQRK?tO2@s3rW-Z= z6(AbRj-FNN0VOW4(J+5N1@gGOxzuTE+BP{csBjh8>#VD8eX^<;tK`<@k>>7mDc3jg z(2ha*_RDIPYL_Vth~r9!3n(`6RUG$;8??yBS`Dd`lQ^1Tzb@V0O58Rpx1hyPWP7Nv zzC;~3cQh!vR9dJiCfEWX!MZmF_G0vpLB^LLSRimnj?kVE$wgBC?wo%^?gDoTDIa*Ie_ zbtDpWur;oG>tEgF!l{zrRRpAEfyL%A`h`A{cA1X*$V z!oh0GUeXez+qPC}Z;=+)SaWX@l4;G?R#LSF6%Z6jHNbScwk$PxhVgjuiOZoOki6=WEM zI5&{vQ}ECliXRjl1db1x9kzgGK!@pL-o_s)j!mrn>p_8Xt%M4USC3~ra-t1IXQ5;4R_q_zN_f*4Dy{Kv?NYB9tt`TL8nFkDzPm_q^d3y#zv3>3D z(p*MnJu}T<4j7)kW09~q45uRbRcw5Jyfq+(c!XoE@?~07D*UTP9p|D81-rQBd1pES z0{1k60YXP1wK=mZX-$r(M*T_6$9>d*$GpZKhi3At%1V@`BOBx*oa8{BSF?Wrhpkrb ze6s^5wVK|2f!0q}c=^_{zU?403S}Irur<#nj&**lGc+q2ukwWXsTW#(55Ipi3BFBy zgHhp$@hIB$=MIbDgBUm?Kz$`$Yq%&|pEnM_4n4#&7`)v}5}*0PzGt;}0jQz9$DCe~ z#FT`ihRo)BWT9XBA z!3f7w)jEHq3SNi#kSVDCFp%IW{Q#1~k}e$EHBWEPlCwUT`ckonimFap86EE5*%LIS zUoh^X4q$i;u*Ubetzo_|;}&z_q|WK6gFuW&)YYte&wy|bCUkfKo*cRrcJSM@rO)8- zA^kicd1`WAo0H`NSf*4KQ+0cj0VTek@rbUAX-!hfhn)QBtzAJ&__@3aL-#XM+pycD z4|DS3gy>pFCwz0A$@UN2vX+VU6<1mj)%bJ8iWBq>vmQGwCDR79I=gA?18@dI++>=ia?^XE*yix0BO3 zwUCk~?-u+~UMVJ?Y0nj=rW-qtFvjlwda0iEPhzZXrvVJTbpdG)Z|ZEmGGt7(opB%a z^~P*#z6xnqQ7*#2Uv~N#>5;>ktE!q-_Zg`N=c(jfdZ^`_py&h2N)&Ma3zqb4ALlSW z*a$wiAD^OYgf`3ArYwHt(Og~{SJ_PJzgCvTJ*oT218HP}92pyqp8CwoPZ&v#GE%uo z@d_!VphJp?6e>3SE1TM?+edFswH-)O@AONLu7a>LHzBsoZzX;Bbei#>E@ulh8^tBM zdq!GVSSKbwEd>XXjbcua@2ABFkEyNq810^#r?qSN!0caIx7HT55L3xkq_Rs+411s~ zf5N?hf=tDPM=1>zzcYvrM^X}tC?=@AKUX4S~yLFr6c=N)3@O4ISEtTa9{uB2zQCwZzKl{rYL zxgFxeZXX zrQph*@+bw(6tgDOUBv=rz4%{qL3owU2j*ssL$7V;-7w{q66}>p(TSC^KT=))n(l4S z==Xw6GE7N%oMsv{?C!ETX?@3R%XvKvcsSf#2GzuIEbfLQ6I5s-#I*l3t+bo*K&H6w z2mMO;MgA;_XjUgL+Ett9|2PYB0X!KL{Yz#|8zxMD(v>PSh!~aCeGIo5@q4u0X6YgZX@uQh3o*)Scch!>Ujt(bft2BJsw&e zl%E$=vok-#8-pIPF7&Jpko=z(U{1lVG%C%fn^(jhdU5+R`|#TV14}i#ZZXWRL%^=< zmE-6$=N3gHCu0VGH%}7kVY1otRI4xh)38FyRo=mXCzEd}W7JeTQt-L#;u{`X}6xvSBm@5@J)6N};%&|CIK zM?32JSz%B`q?>f*-mtU}oyq!Bix48P>Q0?`ip_RmTYkX1xF}#q!}@wyrSHdf*_7}L z;TM;w4GQ_4^B*k`*Dc%-|A_bsffMgH1esy6Re-FLCr|u8@gN=h`APeOhq>Ep)Xr%} zcq)uQzJ=ucUdD&t6OjOw3d=sP@xS*0v9i6TK0Rr#p10KBeX%u5k)75q*l_>r-=mJI z36r?Tcgaq7=v-%h)};)tB>g(Zp(sLkiByjIFHa=)Jz!=cBkc@+Ui;LP3|93T@5&}X z><128d||)2^U=Anj7nYQ!x5=JFN5Q~!Rb04x^I&GmImBdAVhUA0U=+BM??q#yBqt_ zc{quy4DmP2$P9A14t%%w;3r3bKYCre|E1B0!w^N)d3t1mTDWe-9|41pbseS^*);eg ziE^TZ9L|o`5L2GRX?&s?vkWSMC{mm!Dw!VzXDzktJ{&~64z4q@X!k)y4s9Y7qj@0a zycUHSRoQ7NbPw@D3!_l}a-rAz^=Qu&t!8+OL9>mD*?!!8TWM%U^yT<38CuaPut}}+ zy6o|u#QRDn;TA z``XO=AW~#q*b4+l?4+p3Up=*Nk3ZjIAUSu&NcH?K5XbCNWqOk3mALLVQT`hXz(>V{ zw2J-8IE`d~*%+H+)Rt=?5ey?XQl?@+7kW&UXiQLD<8kVJ2 z{QD7X{2UIWNd$|f^QS{3n$!>o;Z)9H$Nrm${}58TzF+;rIc#<@{hC__hqH_@&H$Q} z+lcEW&8{-j6UeTh5a_xFwu!p|uxK=`5}5!kYC{*Ot42SCu5yiL^38v}(Vlb4Y?m#+ zFkF3-{U-oRqt_2rv8FJCu(t@m1qD8$1n`9Tub%kidN` zuL@-j4q@sJJA-{3TQK=0GNLDVa+kfn>9@1*w~0fmC)XMeyE@XuoD`;$GJdP!w|u=iQL@~w z!*V(;M3;|YNor(pShCr5CCe|$efkbq768u+9G$mUz<2rD&MeyzYV;BNL<(tG&H$(a zbm_xoU{x0jEvt}4n{NYYe6pgDRpHZC#DerZ&_EHfodIL~=@H~lqxgs6XaKRqEz zq9g5}815uW5{Gb}5H zfBy0h)R&F6=FA$Pk&&%b*sv0cuv=>+4%Lixl_>XL3MIfFZ8OmNA%QZTDOJU)>WQ0{ zG=L7-g4C?AOi239FK7l*!tFWO%|}p#e-NcTvtMr5PnI}mgM%){%Pp(G+Kl_ZP`hiD zrEB!q-Gsp!!SDCY@cO{zq*H3G=B-a%#peC(^AgG3z7oB4`Cx1?%Z5|uenPt+QPpDhDi*7LU8&AC40ezTmIK|7cB^pFLGzfb$*t4sY z$|1giJ-m~Aq=n>B;G#VS;aP)x5+St;3rS)WH`=^! zn@O=b3-z2jD#H??1U!o&+JVpe_|5l-HruNmqH7We^k+_WgP0UQFD zt_0GeB7rOl`B)GD%nE?A>tX;*41xe8^#KSV;J*y(vSl4Z|Ca^u!Nvbty&aO(GIV{>Dv`4-x+e7+dNFF0cW>Hx4nA# z3qNHz_C?~4uZ-hV`F9NIPDbHlV)dt*)lL@CJC8l*-jx&oI2VPd%)r}Rh;bdUO z(L3_@L#js)ubP{J&R&62ru}Q{7JXLGD%-dV!NrQVEbdO+hFqqF!-xJr+?H9mF7wUK zIel3+k;Qs}DAYD3yj++5cXuLnqpYhsVB@(9?PJ!H^Wxwn^b3`Q;k_7N17q0!s&)%i z-+W8WjH>*yJLpbDRqzZy#vdtU*P(jj{$h(y(1h4f)6$2V=&&GO^FI(cusS%YU-rw5 z=+82*9PaM&+W^Xzb5*ck`yKQ1O=;|Y*iun)vs^RUP|!!_Q;N%^W8WU{Gf%bYHSa2e z!NE!j=b2qhlY|$Z1j(~y*$v1dj>0#%$Foj@rj*_(dC4V@#(vHGT<*K;k(J=(+*1lf zj+XxjKCtRluzZmT(=P#yoPNy@r#`-}<@%K4LVF2&`m2L+v6K$lD~skb>z`@n;cC&S zK#WLrR%~IW{(U}sc_(Bfm$1kEfk3-TY4ezh#Zxc?HuG-`xV+yGrs^zrgmMboJ?Dh# zSZ}=E&YMKiQ=(Ch8L0k^@+l569@~d-IE0ps&O37pWRb^Ca zJ0aSUl`Y@3VZ^ZDPn#d}ORrF9uNaaYq*sC6a>+h*fGri_CFDTTzxn2w>f)2HnbtNR zWZovt*^Wcp*TrjBZ{9m458KMm(eHmUBYU=LEcK{NuWD!7`m{H-$F|)qY}QUkL2^N#n#kSxP3wpRWCUn8^AlR`TMXE+C5eX=MKD$kILPhECcevTPLR&?=; zvQ{kml_4!l7>?r{f+KT9TRxW*XKa$QR72B9Uuv`cJ-jG=>xSa8FL`Z4F40wv5-w+% zRa{(Oo(;KIDnSCXy)tjN%56}ilp`iJv!nWlS34fO z1=@9p)H$w{nmThAht}L#MkXYR74N)3mn!24mTQkMuRb{ADikPNk(KzAY^?1iHrRKx z4?E1pe7IIYkFb`_S&&U0QBpu%Q=!w7Q261V$>3aNdIK*i7hFJpQvqqk3ws2sKgG>t z`k4ub#PEyXP?ABqbim%>bEOh7X?Ch6my1_|vSpE<5ZTja(QeA1g@h(RV6;82(FbVS zo+-Xws-t>`$~y9W0%305(nSvG6U+8$lKKF#5e&e&iIxs3@@f_OJ@lY^G|wp#6l9*) zM)!H+tD785{hIU+)J<+Eh`eU4Gm zuj|}Rl4?cu=jpjCd``s)RHvD5Uav`w7?26=RWR&?EhvVZDh%nY4T}ijvOk>pxU`OL zU1hRi(c*ikeye9)A?`;-n$)6jb89uSx7rlcw9*34DG;!>8&IC`lF9?iWc1J5ns)dN zY8#&S`^m`)H^=meR5_$iR#y9{d6_Acv~#2;Jn?_Ddpcl};CUu+dJZ1g=0@9hkxrt} zn!~=vUg2K2vGaR~V~oSdO@Dti8R*WIe2zun<8yL?ko0CKoillCC^7&;9}fsRm#eGQ(i@DMvt~4DQRCn|Y_|?781BBr+bYHB_=e}) z*(Y)Y-HT*9#iqf`q_j3J-DPB{W81hDf*b>=5J^J1d|vVC^N7iy&~nN^1@)?a0#{+B z-#4#4AV_tcD{JzvCdpVuyNNGY>HP9#M~7Klh3@RjXM11!5V~>=bNi**Tl=exyPh)v zZRW7^-$~=w2~~nA`=RGp$lMlQcWnJwicr5!my^eSl8OApe3KM({L|5&{KQgXbU(Lx{H9xC< zZD)>nG=}3L?~AjeuNX4rjEf{{Q{(ruSA^7&t-}fSIG$_d&{<0g`i<+liUSv=@KLrs zElh{Cc?v2BX7ox$a2=Jtt!l=qqVvaBY*~pCL#16}d=(*GiR4>K_Y-RpVvL=nzw@Tz zy172$e{3cK4H3VNidv}t4+q^FFd5FEq*A3X-+~Hyx;*13nfVDK9wB`TmPLtxt-O=c zU9Zr9{D+8F@qtDG1aeH{3Y@SzwOmh4cC;@K-44NSq43NjP0nrT8ZnO7%BtDDoGTVrv6qp*ArPa!Jm|?`%v|&J~(BT=>PG^ zM3Z9g(erfq6Y>qO$5MEKR)%Hw%+y4W=65L_T_>!Q`T*#s04=#n2XqJa@<$alXq@|4mfGND;KaWV79%JGj&0XKN z13OLkx+~E-j%<61?Qy{5Mf)>}Q@ecVirZPFwK)!no<~Y~b$i(tjv?~~m`6^f88YRF zj%VNKdm0XFT{<+Gljw_aiSqFqsOuRu%{dRy&3lo#2sCzEo7T&X`qNLx8&$MpElSMh0URKY@Cm`0(591AK}eo4pFbMwF-@0C4BgH@(W* z;)I|=2Qu@rT1aW@V${PABtK@F`6cb_9(sm5ipaN{~g6lQr8@-a?uMmAkP@V85s@xQMd0K2 zKi`>i=gz#(%zNK==FYwM%=5%(X{zGm(BJ?70DQIQO0OR4&HoA%{J58GnhAKUz*a9* zl>iU_ZG}B$DUTLx#Pipl001uOe+3B0&ZT-ZLcG-A$`CY^iV}*oo}u~Zh6$jiq@e4! ze3a)H?=s@O5whcRUG4tlPkZdaQ_f_g=h|e-ui}*18|YSItzz{_92AId247&XL?;au zgfT&hSfC#;72b7I#ny;7!e3BqFCr{z(rtJ@DZOf@NM=@k_4DbUa@F55lg4(XxAUV> zl`E!goo>EU<40L$`vBj7fDY%mzR3q3Z}m*(Z%<7ixmcn|Q47GO=$pE?UEq`9+dd#H z6w3nJ5Uk(h3jBifMw6ql&}4|oBlk=*&V0pR`Gd>|fH;e)e=1AYGISQut3v>FWx7UE zzJqg_L1aLE!gdS-v~FKlCB)VM(`Shl!ruvp@Fn9=vK9q&+h>?565x*vo35y@sO*D( z{?mKjLxJC2rEz2a)sdqMTJE**p7FNve$h5lM`Q^T?Gvx#b^qKgdnuE0sM*KS`i?%D z&Q?YyTLSnIf@%SN7al#H(e;*x?KO;xLocE3ScyP;=@o7uLg=qLaOgXOh`OjHpnIaY za1d7bGAsG;**RHV0Ew z(#TUimoZ}uw9Qg-1@EsRw$=CWznTDzWchYgkHl2ZY?e^OOV*eFGmHd>eIHUIfu^vi z329~T5wm1*?7t!~9UuN)fjO|0oX7Gc{uPdm*h%s8>P&wkHpy&&xS*(4IaWi7NHRRr zCLnW_psj~dIWaxfp1RssDpWu%S%ywm@*Gh-%BCUoI(OM|&_8=UT|Uz$xnG>}&AO86 zV@pgL$t3t$&De3Y9nZ?^5Jr9oSQS;VI{UJiU-)h&Z#NRoKsl=`kS_{fjC4Y45fn% z2k+(q?w-bBW&_^9`SG_tG{&RypR4v@); z_Us6fAM{c}pf}$1$FaABB%|;X5~%Nk{~v;+frf_N!`8^M7z$(onX*WR^BVvdJqBbn$KDXIYU0P*8-912!j|Mrb_Fo1kx z8*syoYRRV;ud|?qSsa1Zap=5s@A`I$^V5sZwOg4T2Lk%r7!Q{Iahxi+;JLGgy4j32 z5ac}I{Ubzs;pniy#rFX%yQphfbOur?6qod-l?NaF3jK6ZBY*0Ec#@Tg4KBW$)m#re zU#VZ8xV8-2zkU9vRVoQyy>QV7G{;C}rxgqp_>8xXoG|MkZ3pFedth%X?XyS~mrel+ zz_QrVvL~We7?yutn*jeQqIZyDR*HCW*g=!?HrHFs@}Onvd?jbTr`1(;{*;sM#z0ju`(_;W!E}I2F3}h1TguO zXoom_f9>`NRc9?zqy{?96a9yUrXkG44j1NAj$P^s4Z-b>`5ClyaOHk$$KzMhM|ShbB|*@4%H4 zzzyF*J>`erwq^Z6?L>ZZrw0MyIi%1s0|G#s75i2%qj4-VtIf-oecjL-TNf1_j7@PH zO6g)T(6#t&QMqSwGy3BBY!)G7b`))%UdM`Kzw>iXj50l=#l|}|Qq79hLzNjNg)(D` zOK1*u_$)i)$Yip)`ddFcm=(rm>QY$S2RoI=QE*kK1Gfui=rJ@Ny_>XDqaa+BcL9%y zWqU-Vxc&;eq&0uSN?{>7PRcEC=~q%Cg`F=8-^=tHS-^OPmdt==`_NyOlApW zaqrihabqE3 zEL`*Ph_9cIBZZZSO-%@Z1Ta%YBx+BVH-f8yIg7UYt=ta`2f11MsJBLVtfPy{n4nx@ z@g(l4nA6I|USHN$jDddoi{Y=xvd{#~0VU;>p<%!dvP}8rtA-zu-{NJDuk}Jf``nW6 z%HI10!25mT`JcO9S5b}&;W?ku(%AB1TSG}vVW=G?zr`Micw%1ATZUHV_25>9pobHb z7&0SNvk}|ZT(hKBc1av_K6D2OL7rgee&LZ3Aqd~V3`Q?|bTM_Na+>YhyD+U{as7RR zPWwK^o*$bJ%*V>d(0t`H)Ev6A=F7f%d-P=+HP#%-Rr;E=7p=0ylHyL-8_O#-ljty} zgKD668h9x%d}&)o9sXi`k7h^5p{+0R(#&c2x=xa))fbU}r{Q=tZYbZ5tLp{qviQ>b zeT3a8Jpa5-{j2xm0s{A^%f{AQB&Rn_vx?1RxU*&I#a$2=auI{362y7%8uI1n-6?<8 zjQZLv&cN3Oy;dDRtKY!(=t~p*CFc&%=3fE@sE*`lo6ltru5NQg-n73+MdPyWw6*`Noab5j?rOFi+j!BNP5%{R0RmHffz5>MBUbctvT#>bRbQNeBfB*g zA~);iE*9-?oc$j^#MEO}N9$g-;RlSaN_|Wr6pYZxY2>7X@eT65&4X=TG%pFwr_??X5VtCYN7eb$1{*FQsfOVS^ z+q7T<8Y#%3pV_tJ<`e){BTYODFc^6*7HeZg3beDwK?yk;)qh9_{a}JSIAK~gVvmRq z@C&T}LnYESG=1qfrvZ@A-nIO)Pu1ZogmD(S;O)70tn5=|n&q$&X&U?Vk7XY9D_28A z-z@rOYc1`IAI5M0F}uvG-V~#3j#rGj+s_<_aiT%mLMQ)!Ql}3J`@j zz#AQxvtml*?D35|$`0351T$K)NQKABv(BO_pWb(8<2~WC%Wywm;-+m{FbQbg>#5$=HH-h1yA3i*=uL{Bn7(h+b6u2E%SJ;UeD6%;v}32 zi5_eLAwwdNfrDHhli#_jjS)ZWa7|1%xl^)t0!1Wg_0=PpTE6If zK!u*ZF7wZz7pKev%gX&gp7qx#${VIK|06yvLmA|?ZVaX4`LEBSv36}COw#iFqtBSH zc1V2SF>^Go-xhWt;ZhbG%x8CTQ+EadOF~VNq2NCNog9Z2(YD2VL5SC2T1$Fa(2x=%>{u2)?l*YW76w)`lbK&K>YPIVR} z;<7e^wO81s>+u3Lf=5yct!W{LlxrQDv*(|G<);UYYyZe&A@o`mk=s13qyOmfQoJ*u z6)bEuivNn6+`^6I{nT-4@+3C2r)4K-f~s209$2!?;P~#ka@%06&;_iSvi6~AQt^+_ zT?r-5U%zqf0);}3)swIv@eySn34ZvKtEOLHu3p=rI#ht0oP;(s4e!n0T=$qMM!88Y z_rCgw9r4$BP-B7%-Xdw&iT>93q$pG~x+epg@mQjB_9Mkgj&huqQ;-8QDC=Pl1?6uvgCvfx_FcLnYpKzJ0 z#nQ_b#NS~we!8IN-TQ3IZifCPOJT^-0B6x$-ct~T7odgG*p=s;!{@Cq-Lp2DlrKv3;{jo1>>H5cO^5EA zn|gk~u;(AQcQC_&cNd(cPOnLc@Aad^tiG{T@^J9HkJ+b4V0d>*S6}>XQ9gvnG~Yb~DoJ;(djF#H?NM>980ZCR zs?NL{Hf=t&TX^xO=u>;0;lityr@C!2!wE2jhne++X7AYai7IxbC)=OTS_-jgxV+kj zV8(mb${;1p= zbMD_TO7PN{=3x0iQB#W;_6pW_4p+_~ha@1p&2E@Hv85DhMRvKoFW-H!{i(kw!n=^)s zi<5#S5Oy60{unSJTustS!7WqY;@vo!Iq?ZD{^|woVIV@S<`@2o^4x?P3xpy?K)#El=Uh(juS6^4kqMPL$Jdo+b<^At@@$gNOezz|Z z5mQypKG@%hr2VfL60SI z)WtRZH=?a!piN6W{{w>`3ueKUb86)alB9d=o_kLL{hpXNvEfekUrRw6$A(|7{wkj= z=J9Mf?zqlF4^Vkuz2v1NT)4dOoTPU&ILjSklcqvnnby{wl8I7V-tRgr7WRTzRHUeX zxSqqRIdb27)N59*d`PyI4=aB`Tq;nxjX*ARD5q&~50Ea;A|ip<>;2+I1VKd?fq83Z z9_Iea9KTUu;htX=-?J}D5v~$0)9_A#HG3vzF9B)ZnYb4L6V@hFs^raEFbiW|auMQ| zWuh;`qFVFy>t-zrw-{q7PKpxez=6zp?3NU#zMfX)PHr57$_bh3hIKh_embOc@9Sj{WW|``m(=x^ z;oQ$4ic?Qux*aCr+nwcZ{lm<_zkCO8c7!Z@v!bRWJNMo7&H%puz#zLSN=;}n3_caA zb7?%0HleXQ^utH*dmA9KAzQ2D+FxG~@dx(iXRy2+ATErT0~W-e>K?*fy`w&_pG~hg zFKF84#YjFuA91oA6FZuAso|&R8hrHPRfu=@sPB0AV1=$$la_VDA_^ZZecfqYnR7|U zw&{+WQ#l=puSesg^>+}vyzlcnr2$bHJ>hBX8Nm<6V=JaAJk1Gfg+(37v?aXHq(H9F z89jTFvQH5P4cb>6IZOeHED+}GMt$2VH_>UB%Zj-0pPvpia&^Z_iz-3|Tx*i@;m&Iq=HkDW7&ab8i*;RG+3 zgl#F?H`+4jm5+^aI&XReKiJO2Zd}j_{CGys%_sPg_T2}M8+J?gc?lA+CG zxW<_6!oWA883d)-!(N362%>MqB34XssEEawv64)W5ep=~wZl*KU#-32A!m7}S#MkE zR~+cW6UN!v`w4v@ALZ9Mrrt60q)R7nE7T(7U7`!KbpM8N71X={@i>_23*L}7DVae;S)Qjx zH!ujdGxAvNn8{8L8*EaOe5bmqXq?f0p)7TbG1pc9Y9(-fAHyNNp#t$Ne5-O+I1Iz* zjqGN5&bKf2^W%oNvs~RLF%mA7ttNqI>vMb6g$@_-9U(02P{1&yF&2-DPK39gp);pjhjorCa#J^ z?PaySpsiQ)ueklV6YP$G7v9>Y^~5)c&t}0vB2B`Oc(G}IE|U+me0qlXM|i#~FZR`S zb^Yy3A-q9(IZmX-20=>M3|cvcv0c0Gv4Pwi%-o+Ho3+oy-m)7FI*6^+auW0Y>Ta?R zrPMYvFrF)X=^WXl4Q^J%ZO6@7t!DsiP}z348ah%|IFT2tRaCck0*zi9Y-bKwGv~r2 zqvqzlqTynPT_2Wpy`mF3QAbngDSR&>mIGUtX5o)>UmUh0aaSUp<2|1E5Pjh+3+A=# zDV`Xhz}4Aa#<8l#PLXQkZCl22E(T#sv0)Pec&i7u%d{Wc6M9fQBjThY~HDhTgTPkuvN+LnC zx8(1g3c7hf7>AI`PbjPj5)wEm@3+amX&(~eobC95ZMNMya-gto#fSIZ*zs!^IRzGx zqE1>InH!O@#r~OEd7R+xppRby!tsEl5!1_M9E4 z%e#*&ii|?c^Tnu8hHA(3E`zGfuY3vluPVp2BQxvg%?66U%HEP`2K?#V4^%4&djHYY z^i!IebXjeQvWGwM)@bMYCcD(wXNuC(DyV&Z8o0Oi6hC51r7SM?INQ3^DLv4!oq#>A z^DRx!+ddhJ$^$9cZckc8wgI3XK^1TH1$+muf03-yIl&_bnnC_CCDyC!UQhE~W@Xu) zkzuT#w(^S2b z`-`S%-?Jg{@>C|DP!4wBwdqFeB_3{}N5mJG}BfM^Nge87F(K!);-W%`>}WgPNy z6mY6}w{JkB=gjAXia9m6A$1bVnzZY$+2<0(W!0Ow@TzgTaoZOcy*QBP}6kh}}y^{s|0 z&*{6>9$6LPV+W&8&HXwr4Dla*gt`~ zq%YZPb7uRQg&?`9TZL*mBXy3S}Kp##S!EmaUjRnotVhC z%>OX`NKc8a+x5c3hKDxlS!_2i&qT7zmaL{qlqij}@X2d}F*NT$qM`gT9v@NsB575g zwgt202N+Xvr>=VU(os zMnL(EIYj*;!m7`}olu-9&%}}p(^%7MLs|*DhJGEVc7Es6cEN7=rd64)IejSo;P%ewmm&@&WeL}N+wqdRh-rOtN`9(uSWro^5MOjO{eqj615Q2Z{+`!QQ zKuKwRD)w!|C{Vd!CuQ-Xqa|bNTgO@NUTJ~#Z20E$>QH?iN5;P*Q8VToWABS4nDQT2 z$)AJkbn7Zfq<)nrW**@s-;XD8?H?BCS|2Jw#7hGDIDe_6SCtFH2t@<%$-f6;-{_%r zP)1sxD$!L3Su;4WTj9 z$0^FTe$a-@xV;jykN~?Np2R9o(qMh zm*jWWJ}D_(PqGT{y*+NZIcFQ4O%uVPlxpj2w&dy>l|L$u=12UI-!q^LEcDKRd#eor z35nMH$e5swG8yopdE?jSIvdNZd&kRchPONCR|)I5cOrfR&O$T~!BzXJkoPwD%tv*` zfWVpXr_nKFAvhw$LfxqW4y%;It_PnwEng>Uv(veEH9263%x}_YGt*=u6?An0REMK; zu>sO62mvp#3{J8=3tG$)b}xn`F+MmHaalI@l=H$l8KKPfaQ$(9cUJtA+B{6bA6tZU zX(9D%*R}H}UZ=u5m%(P&-5xw3NxEFT%pjEvEQ!3~U+c8%^b{9Mte?o;E#XC_=QLWK z)~#da8OA2mW8&n}mxdnQO|A4Yu4cB1!De^sv!7n1s+D1F!G z`FoH$4Q)7Bds>^$^y$jz9N9UGLZhF!xXkr8B~@qd8C{^eF|Ui`Pe)=+?!&5-{Yc%; z#6-i(;OQ^?ieN$v_OFF=^|0T@HSPHdoNpTwXbB5qD!#Dpqzf!uBxkUTP^QAFT}iqH^QtL^F6_$#n+F3udOKms^i>K4-Zf)=@+m7pd|LjJKgrTW zip-TS#Qb?$RINJAfG^p)_D%v`c7b6UlZ?a0VtfLkbmYU({*1forAE|FP5GZ0(~Xx- z7?#(WGsXkex4pjk?4j2{eu}t|e8<7a1~!e~iHX{7o$k%wmhnzgv6?TgIxF119~a5# zi+#x=0gn#CIux>Hn-5^sCl!O{im^1-G(EpvFEJ3)KdnxtDJA(GL%LZaI6m{cce)=O z2a>+&BuV-8oBJQd+rM{& z5FhObQ(N$or6H3YiTjj7g`p6-OIvRC$;KXq)bDzU*g@H;dQztzWvwpU{+;CFplzfcNs>F<>*I~SQx&>I=(P>_KG*wsb{OC#bt7~!3Q(@m{4id z&G;3w;JeImuZ+8pmk&t1s{ZnQ%%TB^dmLDy1`+L`AXJ3KMSwzi_vJW+bwJQXSk9jdn zN7jU)%89@tDQHcw8Uq%-LAGh6=Y~4Ldx)Co^iq}nHinRf05e3_A;uTCq}jZbZ5dz zS=)k3|J`o}LaI0Dz6o^vmOc$)`$u*2ZaH>2OISw}#6DMhoFY}(MR-A9iBX*48lyk1Z(Q&{nPQc3@MJ2mf@vGQ0X~lZ_?E56v8AHwou%1`CX2`{-tMkj=<5G2GO!=mwpuW8 z5MSB$Pt{rU=8ym8wh@f)rr})%Xt-fjO2Tx03md2N^L)3Zx zFeybuoL{M>>CX^LRe%0RyIiM**=FN4@BBsWd$f0y!lO<^Ykjl%hp#N`#<#;Xt#wtf z1rJILYg+y-Jn2JrSj5HnnQzgfqtf&^fL30>i5o5#WtvnG-EA`&*$Hje2!FdjHrp23 z?Rqp25$QUuwtsrh!v^=uF(;z%xV1kz2xF{leGS(1Dk1ZeT_G|S!4oe%H4QZm?Ta*3 zKjMO9+eWe|x1YB(G~wQpbwS7D6#85N1|UWy{{myhUfWbwP>p8d&)8#kc;<*PhVkoC z6l;OJc(8vNXbW_$t21mEV3H}h@a@kcw$d@CFYe+9g1!=X{iqAvm33~Ps})o7 z!!q21l!NPrOMLWndtB2|Y_Ey(I<~?~F)zO+5sJ!dzkgJ-& zF(aXL6?6H1m92=1P z1%j9@aRI|l_mHe`lTlB2=_4r)=s38i*IrXm;8gw8N#kTcMd3nKVk((x_yK(PmU+SD zT8A(pbalOth88?V3QdWR+yBKd*Yn*m+r(mml)w$p4UQ|`rZ;|4g8?L_9SqI$V&Z$foacS z8ioK9P}g#CpTt?(`lB}K5NB@g2})#gv?;AOc-}GNGqi8bn@L48mmQudFYYYVkj<+9 z`%N7<9CLuhlatf9)Tr?S`ilb6xWfKYUgQ6TPWiEiX%vt0t4y0%jbVRo*ChE&7PUwI z{eSfSWU%T2=I6)T|5JFesTm18Dx=n8SeX7h@v%<+55Q%6JZ7qv?0d9j*)JVr9Zg^k zJOXZdEi#h6PeTPl5$h!_BTQc&S$gP>=@kvY-|5{W9>_f^l_Q@i8PM7KpBobB?9=B) z?(gfw^o(EJ`IG_{2_#!IfPfTV*yUOlF(}ujQ#vuOg0K`K@S+hYJsi%5Lz)Ce5YbjW zCL$#4burS;+E<1dUWFb0_z6F)RbLt-TQY=Oc*eqfAG1la>35xF>X=<-d(41G%{o>d zT7TSZ`G{mCHR;$5ivAa!J>1MP;2GHu*dybr)0f970qGW3W(tZ<6-<#A5BojG**RbL z>6bcFu81J203PGx4;9bLew=VAwxv)Fob8j4%>1GMQZr80L1mPoCC%A~|MRLVi3-y} z2{>jpj#Yu$?Z?hsr&% z9edQ(g$7~WR3BWVFiV{Jmkz#3eSA|Rzwr=^r;C`Tv!19Ezy^HcF}{=^zsUanhMvl0 z#kX%tRI6U(RFsfFchod73NY?T=V?0(o`g1Og6<*c2wps9&nFej%Rzv%w)(Td5THo| zWak0%lo0|%kE%h{VO%FFaLYo1z&CXBf?gg`VXFT*><9hG(}m7QxhX(RSyQR@nZ>*R14?tV6#xJL literal 7579 zcmcgxWmFVSv|kXUl$Hir8Yv~DOJHeOnk5!QmJpB@mQD$&C6;ETMM6T-r9*n9Q&4G; zZkBlb-`Ds3ojG@A?wz^k&dl%LGiT<;fOS+K6EhG40D#BpYRdZe?VtaM@Zo(eS2yl= z-#oO@R8FDrv?c=pnn&s$RDX+{qv&x1J^T0sb$ton6xpe` zS(=u^24Dl0;d!e=KBIE}Ux&U=f1kmkcPyPa=dFK}QBqZdi*&(Z)YE!PU>Sw(+sXwi z>5UZvD4BXiHKkne@tKJalboAy77;spDtX~k0L(&wGXnP&MScWW0TA1ir9p@v!B)lA zz^|#8cXRN>=aVELE`kmpC+3m;b zoB60erGAJcaa^?LozJq48jc1b0Q?F7_!I#E+^Ycozu5al{%1FY68C@Y{$Ex!OkV8~ zuL2PcKx38wvy8qm62$>2-S1=8{i0*QA#CIU+VFJ(F8c!^qkH8#YK_@2?mGueB)L2_ z1*?VwkM--^9jcX6p|}V@2(3UWc?jDpqR0Qfuc5htemrc?*|?PpL)dYjtKy&o@*@D$ z6m$bjD(nDdWo+ZS;N6_Wr@pcrp$Kw1B5Bg667)j0_co5bPKWgfnZVM2iT!n6P~y_v zBLZ->dT)rN6VbrFlwfoNo5(krW)vzGca-;b)loGe2|6)GT@^DN1 zy7P^ARh(oC#jc07=StXJ&_9#(DJ{!>wP-zZ)Ausoop~PxZ%6#|{?nNyuEs-%-$OzN zp{JrI2lN?%w5A_)^oJ9I?qzU8CNGYPLfeeQ>$K&eop~RF0mz;6&D6QmrN-LPcH!F7 zz|pJaAHGz&5=to?bw)D#@u093JKQj>p%h1-sXS!i6! zcy5a|T3!2-1>1J>0OK<752(2`9B)vTNGX02or_f)P;ck(*nn+quLx0La2|Ya!v|v+ zlkpAVWj07Z!d@J-w)Lg}!WB^T2zj}wmm~+vK0imkl)Ap{eIy*t`v*Vq_Hf_h1-kCV zYI=K}+nrW7;kn%&ly4uiIFb$#>^^DfRc+Q#1UjCF z388vk*CyvrQ7b7k2%GTRG%OhAlr}&PtJ&T-P0P1+|6BTD43!V+qMD-zmbyN5q^<~l zWAByL1RYW0fWA&>V0sFypwRmgo-RKX5c6G_AEq3Nu<#!(r;@giNltjFU)O~yJhFrJ z=)=pp@0!PI%do#}g(ck`Qx9Uyg|MrW6yQ7cQT%~SJ$71X*>KyOxfEMMpxrMt2PVI} zFTzLr-`xA3rX?$J1EY1hvV5dj(Y$@hjbnvWi_w6o7@hKH1B(*B?%_Eutv1&nlD~yV5|g=t)8_ zCoV${{?+UYwiyxnx$NFHKeC_2gF&*oYz6xX?-E`v9Fh_o%Ea2v9?sPq4je-Dm6#=d z#+1Oe`3T;lgPZR|iGWY|qo1)XEY`1}(%-YZv?(dd%ax|hX*VU_s{|gn0lFF$cI$fj ztQm*otc|WxLD+9wz7rZy3VeN3f!>jVan5ryGR?)2>-%oX&@B91 zcSw%*XOr);@{lO%IL`W6(xnTPyh`{EIdYdtss8Lz71=(>H=VbWS&`BjOoj7$ezQ}S*COBH0XXUCCn)%F`` zJJUSg&58D!Hg0-K#cAMlk8@@aifCO}$gvCZtj-uzU`j6oQQ7+nTff;G_?F0T9?r?; zU56`M;K9H1X{wylmxHt5>Fr5?pXj+-|LDRm5h9J-{9dB}%E07y#wVt15bN}eMD4h-{({DhHE7Ry zC^Di=Kl{tTr$;o*HVj-x_CI-Jqs#s_W1Z?m`7qCWwb_RlH}LnSnF|BBOfdGnGPZx@ z%8u=TE~JYq%~u0zA}O-_AZk=Yje`PB3H2U$=Ps>EkzMb~ggde05m;tF7klYzg}936u0!*)=i4D$mU$au(LvBGiF&TJ zLKg4{<96oK9p(<5aQ78k2!Ii&|?M{}zRsujY8dPlbWWzb>c^_tb8ggBZcd74c|APFU&4Tt4@> z7ihKEOrAD#`sbeaw#2P|iC?jY1}@oWGoVdldXDyrXa$8`xRqN774mN9TEs_EJ;F7u z_JyQTuaXLx}#K793v{ zA?8yXRyVLf3~lBfbQHzaB^Kv63s0)NuJ?!<6eEyNy{M@tQJ~!B8(^Dn3&h2k!wXKG zpWc3U2c?(mFN#0UqHLHQQ_{)vzvTR3tKDZVbjqWNQrMTn)URqLG_MWtbj_GwRGXBl zS=DO&kqccq{r6E3%(pz(R@KE%!jU6e;K>Qj(=cg_p!w;e)W^%z`v6Vm)%qZZomDuEuLZ>`J>(9 zTxx^rmlP0424C}5ZwKIPL|H%~caD@beY|YuK;4ONs)cugB3CSwgFq)b@5K6`g<|&Z zh+ISBeDLaqJ13}rp4jaQvQVOMQ~-zSx_*q|U$vJVilu$t!dqQ`idsVqY0M)=f?Hi^ zi*|vvp1NNCs+G5^sgkwzHovSqP9?MQW(d^E+NYpq!SrF{BOfQoZYi0y6w?E&pp9zZ z-X%{)tvniNP1k-Wu*TT3DBzhCxWiuT-e>9c@UbGHW5=$5)b%i-v*7MKV_%)gzVpQ? z1i)ed-^JZD=G*}-*rkW|8%fn8tl93*yb=gYz?+@fyH0onS&uNwM#4pU-y6AUTe6U0o(koN%tO5W_a*QE@cy`TBUm6I&`9llJeboC|z>Glyaz_Ss2<= z>4cA6nwSSo?+0=(n^V`i-VEOHQtU2!%mWKtAB|Qg;S?5JKB~#3XMpIR~u1#v%2m=YH4OimGynsOAdzPYe^NfwSm@M1ZHA zRM`ZpJr46f$)u&tkKlfk_H)X$`6N|@tUZ7er-Q2}0mHwSRH;Z6bo=XvmBX=)pub(I zPnM1s!p^pKW+-?`9cxV5Ez6k2XuBax`(n#H;DNwRAz6Ce_~F^;uS0sNsOU2x4WdTU zOjE~kHO2NXGkVYEi%$LOC5yG&lAm8PLPS(Kn37%%D!Wq-o4eF59QR44oL2N3ip_D7 zl~Jj^2ux5%!YnZ@fohptgQ3hAQ3JG+cae8l>~N7xEzpNca+g*|VwZeOoTelsJTXGq zYj5WKXB&_G0jYo7o)VQi0K!s(6vYw>=#zPh?F45E@dqgpp5^GdYF~7V z`RSKqx&6Fe)M<5c^JJ*t0=t zCtpwxUKxceXv4w5Cgr-!;-~Y)G$Ng2Lz{L@M(=hey&SX;QHD(ODM)wKWBV)jEgVqI z_QY4z+utzl_BT4x%e5h*=jsH3$oKLj1dhT!WbHYU4*C*a->#ucDQTad?Ecn^SwK3z zC3r{48x=~kWoxhMXgp{+BT_f&G8t|fc{ksx@0WWLDFugBEJ4fbX|AVg6gV1uMpjABzTS$!2^Naxh#-Vw$8+DqHGGu%=B~~^RY^e!*2V*7UQO)5Z!_>qilf-zChzYT$+(Y z1}!b(3=3m=e(~UMGL<+4W6YH6zg}0OZ&&jMRA`s$&b*Y@_3RVZ@D>}rv2Cb!Y{%u0 zjkiDmVcUvq`t{{hRQpx_<|0CzmNv7LElY@@=ePipyFlgeQCPLfdUNu1lsrW7lp>E# z&$e8K_Lq3}s(RBJc8hn}uHTgr|Aq{`bAT2lo%Gi6KznbT4Vp_QQobCd+8a z$uNwHX9k>h=Zhl7S#?l($T-V3aFDvv;3PBmy!qx}b~;S=7FQOwdz4E#Hi~tyKm0e& z`-?|I!l(z{1hINId+s(Q$JCIfdfKXLb}36u`_CY~zcZUgunk37`MjaR1hlsB&Q2~m zPT;i3KhSPL@~n}-w&D0i<3FmuYCDp{Eokq#A`iW^hX^1UtV+z&M@~B#XmmN^%-7%W z4+7Uoaj#m}ue=hubYjVmAnE8mH+UvpHu)P?Xpi){IBPO4>o~RbV}1@^LN%8M@bkoZ zIcOPkt=9u^Xtw9!hi>P^N`oW?NTaG-wBJlEO7HAhwIWF>_(?S>4XZ2|pwUEn5rgGz zt%fZ$YT#!&vU2(rwUtuAx-BD9*fhU6B(`+hvNI^f7Q6;(*N_?(>-yP#H0|5=G!EK9 zKR4|+Pl`-UC;~&^yl-9fR687|JD%BSnO`S=wa~SKBoZIt=9zym9i2YnSCT9~x?Z*K zB>K^1QrhJM&+Qh7{&zgQr))Pw>GMl&l2s| zOnRQsPb1gXWarP|^^i%*#YKi3IosdO4JhI|*-Y1gE)vqjfQD7BdU}d67!}VSP&Z6j zIoR)J)apBz{HYw@=E8yrmyMswUv6{b&_?GEi?xLoUg8Hd$9as>U@uwQ8|hTHr+sm*xU zmO&$pU@XE-?BL=F8Q9N#sKGVe^EHIz@C&H5S~&(h1fs`T&cw?7#h*VuxNhHnPBu_aNaQsS3lO~=@E-_7eYjb|t9ymvq z_g%0y@guh(%cs}AAs^zMVPDsnCHYJDfkm8EVU)NJtJv-;21GNpE{3INSjtpCPV2Dz z3S3-p`Vbz=TfCMgQtO^3W(3quQ6LKa)3k2uF-7lFb@TDPFnEaN1%vC!p6l9s2Gq#~ zG{OqBb87&8WleEWXSor0dxYL^nYNs~@~Br4w_66B5H4Na|E5{j`0iMKA8o=e2Dtq& zeT?QIUD%M^$}G>1=#W}@%T^GztWH)QPnmOFrL8U$f910a7ZBRIRby?mFL*^1s&{xG z{XJY=ltm2xs{yOP$e+T@?@%|t)!(SC4JWzA`5QOBNoxz+LMrp?ueUjT#YZLNS4=$H znR!dEbM@&doA`WsA*Y7{uem>(i5KfSU$dMW7&yx+FHb0}0`2 z&KM@52r~YINJ`w5%)$V#BJj(aFRBc7xyNZ3CXw?9r=ov2W+l7s?ff#Ohr?28{_8A{ z;=x_87fQvuFH6`{yxXzZvAbq1`N5rUA>OZT1x+-E+0QA|!?F znhR>92B7^$_|W|yDagHV(r$qqXK{>fd|Kh3)MJ-zASE8D0#Q1MsCcAMrZ*{1x{vHZ zEckXEKgQ?6zF14^R+NAbu0#}CY|u|w+rhZg|D*(xxbZ^Bu2!~f%ykX96 zAwZRAjERQ5OnJ#Covc|ZTl42c5BHJXph2#4+84}o_527;`vkM>zo6FG!0>vJto<+w>pUm((8Rut_gIJ335n#5HMNZ*s&vUg_@SqbU< zdwQbc680sQ@1R5HGn3CHE8remPf?-e%DA}2j zQr^2jVO+>`X0!kS!pt!Sxgd*;&!mCXQFhr(>p6!)CUU^`hRazj!lr zp8!byP1b&KZMnvao{vt3Z1t!@|0qABE-#q&OCW7vUf z(P{08dbfu7_}rksk8HGDG{TLjTHZw(>>=`{39|c$H&_V%`qH_oYQ#-`tMRYdfKr{C zE*wRjWLavyl)kYTM4>^*kJos6!`C>eQ7mb{oq$Oz)z7ZlYVZ-pY5VneE z{ZWWZ6=A^I>fvSOAN{_t{yqRmUTTd{Z(i$7sD4~XMRGdUluv$IG=gwDIP(1Y!0@;p z@uF*jUqxMKUY$;zlQTieigFlye+zcbE2*wyl7)re4i-nosieKYPgOI}*;m04q1I>` zI|!L96Y~UTXZ>u-EJ-pB%JT3m&PibFdi2=it+o2|=Ccd7tNv7_o=4g^$79D~egt7$ zaB5|%aLRWUD$ai_sSO2Pw%I&vT%9C8g@C)XMc6_1_+cffd}kv_tEo z90c&SM~irLy>?#d;_$jvf)$i|tvMERO18+?9Z=X=u<2H>BH_6rEQk{5)&dd!t#p$-iHna(?>)l^)U&+YxGQe9To7~8+%5-n z=hXd$YG4leZ@OdNY;Bh!-0LhyS@tldLs;y z;{pEkjJQtmamLP)2Eo3U#!Zav6|-xc^U)pBB;FBl^Ni(@Dad8qr%?gwDmuzludKuV E2dWLBm;e9( From 18a86cf1df061edf612f36cd6df43f7fe0accc1a Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 11:19:51 +0200 Subject: [PATCH 452/552] Rename getPane for better description --- src/library/library.cpp | 8 ++++---- src/library/library.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 85c4d41cfac..3b00b87755e 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -108,7 +108,7 @@ Library::~Library() { void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { // Get the value once to avoid searching again in the hash - LibraryPaneManager* pPane = getPane(id); + LibraryPaneManager* pPane = getOrCreatePane(id); pPane->bindSearchBar(searchLine); } @@ -129,7 +129,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, KeyboardEventFilter* pKeyboard, int paneId) { // Get the value once to avoid searching again in the hash - LibraryPaneManager* pPane = getPane(paneId); + LibraryPaneManager* pPane = getOrCreatePane(paneId); if (pPane == nullptr) { return; } @@ -151,7 +151,7 @@ void Library::bindSidebarExpanded(WBaseLibrary* expandedPane, void Library::bindBreadCrumb(WLibraryBreadCrumb* pBreadCrumb, int paneId) { // Get the value once to avoid searching again in the hash - LibraryPaneManager* pPane = getPane(paneId); + LibraryPaneManager* pPane = getOrCreatePane(paneId); pPane->setBreadCrumb(pBreadCrumb); } @@ -537,7 +537,7 @@ void Library::slotUpdateFocus(LibraryFeature* pFeature) { } -LibraryPaneManager* Library::getPane(int paneId) { +LibraryPaneManager* Library::getOrCreatePane(int paneId) { //qDebug() << "Library::createPane" << id; // Get the value once to avoid searching again in the hash auto it = m_panes.find(paneId); diff --git a/src/library/library.h b/src/library/library.h index 10433916a88..797b4ca2006 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -143,7 +143,7 @@ class Library : public QObject { private: // If the pane exists returns it, otherwise it creates the pane - LibraryPaneManager* getPane(int paneId); + LibraryPaneManager* getOrCreatePane(int paneId); LibraryPaneManager* getFocusedPane(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); From d41b74f666d41002aa783933d78e01eca8c4df75 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 12:28:34 +0200 Subject: [PATCH 453/552] Add paneId to some methods to avoid some potential bugs --- src/library/banshee/bansheefeature.cpp | 4 ++-- src/library/browse/browsefeature.cpp | 4 ++-- src/library/itunes/itunesfeature.cpp | 6 +++--- src/library/library.cpp | 16 ++++++++-------- src/library/library.h | 8 ++++---- src/library/libraryfeature.cpp | 10 +++++----- src/library/rhythmbox/rhythmboxfeature.cpp | 4 ++-- src/library/traktor/traktorfeature.cpp | 6 +++--- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index fbb243f3485..da242db4761 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -126,7 +126,7 @@ void BansheeFeature::activate() { m_pBansheePlaylistModel->setTableModel(0); // Gets the master playlist showTrackModel(m_pBansheePlaylistModel); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(); enableCoverArtDisplay(true); } @@ -140,7 +140,7 @@ void BansheeFeature::activateChild(const QModelIndex& index) { m_pBansheePlaylistModel->setTableModel(playlistID); showTrackModel(m_pBansheePlaylistModel); - m_pLibrary->showBreadCrumb(item); + showBreadCrumb(item); enableCoverArtDisplay(true); } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 5dce11d6e07..0cd5c14d6b4 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -236,8 +236,8 @@ void BrowseFeature::activate() { showBrowse(m_featurePane); switchToFeature(); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); - m_pLibrary->restoreSearch(QString()); + showBreadCrumb(); + restoreSearch(QString()); enableCoverArtDisplay(true); } diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index f727c5ba548..6d781475250 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -151,7 +151,7 @@ void ITunesFeature::activate(bool forceReload) { NULL, tr("Select your iTunes library"), QDir::homePath(), "*.xml"); QFileInfo dbFile(m_dbfile); if (m_dbfile.isEmpty() || !dbFile.exists()) { - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(); showTrackModel(m_pITunesTrackModel); return; } @@ -183,7 +183,7 @@ void ITunesFeature::activate(bool forceReload) { } showTrackModel(m_pITunesTrackModel); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(); enableCoverArtDisplay(true); } @@ -194,7 +194,7 @@ void ITunesFeature::activateChild(const QModelIndex& index) { m_pITunesPlaylistModel->setPlaylist(playlist); showTrackModel(m_pITunesPlaylistModel); - m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); + showBreadCrumb(index); enableCoverArtDisplay(true); } diff --git a/src/library/library.cpp b/src/library/library.cpp index 3b00b87755e..a3ff818e73f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -214,8 +214,8 @@ void Library::switchToFeature(LibraryFeature* pFeature) { handleFocus(); } -void Library::showBreadCrumb(TreeItem *pTree) { - LibraryPaneManager* pPane = getFocusedPane(); +void Library::showBreadCrumb(int paneId, TreeItem *pTree) { + LibraryPaneManager* pPane = getOrCreatePane(paneId); DEBUG_ASSERT_AND_HANDLE(pPane) { return; } @@ -223,8 +223,8 @@ void Library::showBreadCrumb(TreeItem *pTree) { pPane->showBreadCrumb(pTree); } -void Library::showBreadCrumb(const QString &text, const QIcon &icon) { - LibraryPaneManager* pPane = getFocusedPane(); +void Library::showBreadCrumb(int paneId, const QString &text, const QIcon &icon) { + LibraryPaneManager* pPane = getOrCreatePane(paneId); DEBUG_ASSERT_AND_HANDLE(pPane) { return; } @@ -248,8 +248,8 @@ void Library::slotLoadTrackToPlayer(TrackPointer pTrack, QString group, bool pla emit(loadTrackToPlayer(pTrack, group, play)); } -void Library::restoreSearch(const QString& text) { - LibraryPaneManager* pPane = getFocusedPane(); +void Library::restoreSearch(int paneId, const QString& text) { + LibraryPaneManager* pPane = getOrCreatePane(paneId); DEBUG_ASSERT_AND_HANDLE(pPane) { return; } @@ -257,8 +257,8 @@ void Library::restoreSearch(const QString& text) { } -void Library::restoreSaveButton() { - LibraryPaneManager* pPane = getFocusedPane(); +void Library::restoreSaveButton(int paneId) { + LibraryPaneManager* pPane = getOrCreatePane(paneId); DEBUG_ASSERT_AND_HANDLE(pPane) { return; } diff --git a/src/library/library.h b/src/library/library.h index 797b4ca2006..1396b200348 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -92,10 +92,10 @@ class Library : public QObject { } void switchToFeature(LibraryFeature* pFeature); - void showBreadCrumb(TreeItem* pTree); - void showBreadCrumb(const QString& text, const QIcon& icon); - void restoreSearch(const QString& text); - void restoreSaveButton(); + void showBreadCrumb(int paneId, TreeItem* pTree); + void showBreadCrumb(int paneId, const QString& text, const QIcon& icon); + void restoreSearch(int paneId, const QString& text); + void restoreSaveButton(int paneId); void paneFocused(LibraryPaneManager *pPane); void panePreselected(LibraryPaneManager* pPane, bool value); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index a61ce66faf5..30f8e0c06c7 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -250,15 +250,15 @@ void LibraryFeature::switchToFeature() { } void LibraryFeature::restoreSearch(const QString& search) { - m_pLibrary->restoreSearch(search); + m_pLibrary->restoreSearch(m_featurePane, search); } void LibraryFeature::restoreSaveButton() { - m_pLibrary->restoreSaveButton(); + m_pLibrary->restoreSaveButton(m_featurePane); } void LibraryFeature::showBreadCrumb(TreeItem *pTree) { - m_pLibrary->showBreadCrumb(pTree); + m_pLibrary->showBreadCrumb(m_featurePane, pTree); } void LibraryFeature::showBreadCrumb(const QModelIndex& index) { @@ -267,11 +267,11 @@ void LibraryFeature::showBreadCrumb(const QModelIndex& index) { } void LibraryFeature::showBreadCrumb(const QString &text, const QIcon& icon) { - m_pLibrary->showBreadCrumb(text, icon); + m_pLibrary->showBreadCrumb(m_featurePane, text, icon); } void LibraryFeature::showBreadCrumb() { - m_pLibrary->showBreadCrumb(title().toString(), getIcon()); + showBreadCrumb(title().toString(), getIcon()); } WTrackTableView *LibraryFeature::getFocusedTable() { diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 64fb5086356..0e1d4590183 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -136,7 +136,7 @@ void RhythmboxFeature::activate() { } showTrackModel(m_pRhythmboxTrackModel); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(); enableCoverArtDisplay(true); } @@ -147,7 +147,7 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { m_pRhythmboxPlaylistModel->setPlaylist(playlist); showTrackModel(m_pRhythmboxPlaylistModel); - m_pLibrary->showBreadCrumb(static_cast(index.internalPointer())); + showBreadCrumb(index); enableCoverArtDisplay(true); } diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 64325e8bfad..3926186ee39 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -164,7 +164,7 @@ void TraktorFeature::activate() { } showTrackModel(m_pTraktorTableModel); - m_pLibrary->showBreadCrumb(m_childModel.getItem(QModelIndex())); + showBreadCrumb(); enableCoverArtDisplay(true); } @@ -180,7 +180,7 @@ void TraktorFeature::activateChild(const QModelIndex& index) { m_pTraktorPlaylistModel->setPlaylist(item->dataPath().toString()); showTrackModel(m_pTraktorPlaylistModel); - m_pLibrary->showBreadCrumb(item); + showBreadCrumb(item); enableCoverArtDisplay(true); } } @@ -619,7 +619,7 @@ void TraktorFeature::onTrackCollectionLoaded() { //m_pTraktorTableModel->select(); showTrackModel(m_pTraktorTableModel); - m_pLibrary->showBreadCrumb(root); + showBreadCrumb(root); qDebug() << "Traktor library loaded successfully"; } else { QMessageBox::warning( From a83505e075f6de6b0874cabc43294e374dcf105e Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 12:29:13 +0200 Subject: [PATCH 454/552] Add new preselection behavior --- src/library/library.cpp | 90 ++++++++++++++++++++++++++----------- src/library/library.h | 2 + src/widget/wbaselibrary.cpp | 1 + 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index a3ff818e73f..2bd6793b9bb 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -198,20 +198,17 @@ void Library::addFeature(LibraryFeature* feature) { void Library::switchToFeature(LibraryFeature* pFeature) { m_pSidebarExpanded->switchToFeature(pFeature); - slotUpdateFocus(pFeature); - LibraryPaneManager* pPane = getFocusedPane(); - DEBUG_ASSERT_AND_HANDLE(pPane) { + LibraryPaneManager* pPane = getPreselectedPane(); + if (pPane == nullptr) { + // No pane is preselected so we are handling an activateChild() method + // or similar. We only change the input focus to the feature one. + m_focusedPane = pFeature->getFeaturePane(); + handleFocus(); return; } - WBaseLibrary* pWLibrary = pPane->getPaneWidget(); - // Only change the current pane if it's not shown already - if (pWLibrary->getCurrentFeature() != pFeature) { - pPane->switchToFeature(pFeature); - } - - handleFocus(); + pPane->switchToFeature(pFeature); } void Library::showBreadCrumb(int paneId, TreeItem *pTree) { @@ -287,14 +284,11 @@ void Library::panePreselected(LibraryPaneManager* pPane, bool value) { // Since only one pane can be preselected, set the other panes as not // preselected if (value) { - if (m_preselectedPane >= 0) { - m_panes[m_preselectedPane]->setPreselected(false); - } - pPane->setPreselected(true); m_preselectedPane = pPane->getPaneId(); } else if (m_preselectedPane == pPane->getPaneId()) { m_preselectedPane = -1; } + handlePreselection(); } void Library::slotRefreshLibraryModels() { @@ -322,27 +316,29 @@ void Library::onSkinLoadFinished() { // Assign a feature to show on each pane unless there are more panes // than features while (itP != m_panes.end() && itF != m_features.end()) { - m_focusedPane = itP.key(); + m_preselectedPane = itP.key(); if (first) { first = false; // Set the first pane as saved pane to all features for (LibraryFeature* pFeature : m_features) { - pFeature->setSavedPane(m_focusedPane); + pFeature->setSavedPane(m_preselectedPane); } } - (*itF)->setFeaturePane(m_focusedPane); - (*itF)->setSavedPane(m_focusedPane); + m_savedFeatures[m_preselectedPane] = *itF; + (*itP)->setCurrentFeature(*itF); + + (*itF)->setFeaturePane(m_preselectedPane); + (*itF)->setSavedPane(m_preselectedPane); (*itF)->activate(); - m_savedFeatures[m_focusedPane] = *itF; ++itP; ++itF; } // The first pane always shows the Mixxx Library feature on start - m_focusedPane = m_panes.begin().key(); - (*m_features.begin())->setFeaturePane(m_focusedPane); + m_preselectedPane = m_panes.begin().key(); + (*m_features.begin())->setFeaturePane(m_preselectedPane); slotActivateFeature(*m_features.begin()); } else { @@ -451,12 +447,15 @@ void Library::paneUncollapsed(int paneId) { // If the current shown feature in some pane is the same as the uncollapsed // pane feature, switch the feature from one pane to the other and set // instead the saved feature - LibraryFeature* pPaneFeature = m_panes[paneId]->getCurrentFeature(); - pPaneFeature->setFeaturePane(m_panes[paneId]->getPaneId()); + LibraryFeature* pFeature = m_panes[paneId]->getCurrentFeature(); + if (pFeature == nullptr) { + return; + } + pFeature->setFeaturePane(m_panes[paneId]->getPaneId()); for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); - if (auxId != paneId && pPaneFeature == pPane->getCurrentFeature()) { + if (auxId != paneId && pFeature == pPane->getCurrentFeature()) { LibraryFeature* pSaved = m_savedFeatures[auxId]; pPane->switchToFeature(pSaved); pSaved->setFeaturePane(auxId); @@ -466,6 +465,25 @@ void Library::paneUncollapsed(int paneId) { } void Library::slotActivateFeature(LibraryFeature* pFeature) { + if (m_preselectedPane < 0) { + // No pane is preselcted, use the saved pane instead + m_preselectedPane = pFeature->getSavedPane(); + } + + m_pSidebarExpanded->switchToFeature(pFeature); + pFeature->setSavedPane(m_preselectedPane); + + if (m_panes[m_preselectedPane]->getCurrentFeature() != pFeature) { + m_panes[m_preselectedPane]->setCurrentFeature(pFeature); + pFeature->activate(); + } + m_preselectedPane = -1; + handlePreselection(); + + + + + /* // The feature is being shown currently in the focused pane if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { pFeature->setSavedPane(m_focusedPane); @@ -511,6 +529,7 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { pFeature->setSavedPane(m_focusedPane); pFeature->activate(); handleFocus(); + */ } void Library::slotHoverFeature(LibraryFeature *pFeature) { @@ -545,6 +564,11 @@ LibraryPaneManager* Library::getOrCreatePane(int paneId) { return *it; } + // The paneId must be non negative + DEBUG_ASSERT_AND_HANDLE(paneId >= 0) { + return nullptr; + } + // Create a new pane only if there are more features than panes if (m_panes.size() >= m_features.size()) { qWarning() << "Library: there are more panes declared than features"; @@ -566,7 +590,14 @@ LibraryPaneManager* Library::getFocusedPane() { if (it == m_panes.end()) { return nullptr; } - + return *it; +} + +LibraryPaneManager* Library::getPreselectedPane() { + auto it = m_panes.find(m_preselectedPane); + if (it == m_panes.end()) { + return nullptr; + } return *it; } @@ -645,3 +676,12 @@ void Library::handleFocus() { } m_panes[m_focusedPane]->setFocus(); } + +void Library::handlePreselection() { + for (LibraryPaneManager* pPane : m_panes) { + pPane->setPreselected(false); + } + if (m_preselectedPane >= 0) { + m_panes[m_preselectedPane]->setPreselected(true); + } +} diff --git a/src/library/library.h b/src/library/library.h index 1396b200348..0717c9a80bf 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -145,11 +145,13 @@ class Library : public QObject { // If the pane exists returns it, otherwise it creates the pane LibraryPaneManager* getOrCreatePane(int paneId); LibraryPaneManager* getFocusedPane(); + LibraryPaneManager* getPreselectedPane(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); void setFocusedPane(); void handleFocus(); + void handlePreselection(); UserSettingsPointer m_pConfig; SidebarModel* m_pSidebarModel; diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index fd6527e876f..f68e05b6f7e 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -48,6 +48,7 @@ void WBaseLibrary::setShowFocus(int sFocus) { void WBaseLibrary::switchToFeature(LibraryFeature *pFeature) { auto it = m_featureMap.find(pFeature); + // Only change the current feature if it's not shown already if (it != m_featureMap.end() && currentWidget() != (*it)) { m_pCurrentFeature = pFeature; setCurrentWidget(*it); From 54af6b2848e0315007dd4de73b62ab55c201f9a4 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 13:42:22 +0200 Subject: [PATCH 455/552] Access to FocusedPane and Preselected pane only from the library This also improves a bit of speed --- src/library/baseplaylistfeature.cpp | 6 +- src/library/cratefeature.cpp | 2 +- src/library/historyfeature.cpp | 2 +- src/library/library.cpp | 85 +++++------------------------ src/library/library.h | 7 +-- src/library/libraryfeature.cpp | 18 +++--- src/library/libraryfeature.h | 7 +-- 7 files changed, 34 insertions(+), 93 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 2fb3dacb611..9c847258a27 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -118,7 +118,7 @@ BasePlaylistFeature::~BasePlaylistFeature() { QPointer BasePlaylistFeature::getPlaylistTableModel(int paneId) { if (paneId < 0) { - paneId = m_focusedPane; + paneId = m_featurePane; } auto it = m_playlistTableModel.find(paneId); if (it == m_playlistTableModel.end() || it->isNull()) { @@ -155,11 +155,11 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { m_lastClickedFocus = m_featurePane; //qDebug() << "BasePlaylistFeature::activateChild()" << index; QSet playlistIds = playlistIdsFromIndex(index); - m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); + m_pPlaylistTableModel = getPlaylistTableModel(m_featurePane); if (!playlistIds.isEmpty() && m_pPlaylistTableModel) { m_pPlaylistTableModel->setTableModel(playlistIds); - showTable(m_focusedPane); + showTable(m_featurePane); // Set the feature Focus for a moment to allow the LibraryFeature class // to find the focused WTrackTable diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 1148c23a4e6..b806b5ecccb 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -249,7 +249,7 @@ void CrateFeature::activateChild(const QModelIndex& index) { void CrateFeature::activateCrate(int crateId) { //qDebug() << "CrateFeature::activateCrate()" << crateId; - m_pCrateTableModel = getTableModel(m_focusedPane); + m_pCrateTableModel = getTableModel(m_featurePane); QModelIndex index = indexFromCrateId(crateId); if (crateId != -1 && index.isValid()) { diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index aa6a1861656..8f65430aa63 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -207,7 +207,7 @@ QWidget* HistoryFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard void HistoryFeature::slotJoinWithNext() { //qDebug() << "slotJoinWithPrevious() row:" << m_lastRightClickedIndex.data(); - m_pPlaylistTableModel = getPlaylistTableModel(m_focusedPane); + m_pPlaylistTableModel = getPlaylistTableModel(m_featurePane); if (m_lastRightClickedIndex.isValid()) { bool ok; int currentPlaylistId = diff --git a/src/library/library.cpp b/src/library/library.cpp index 2bd6793b9bb..25b2b1890af 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -209,6 +209,8 @@ void Library::switchToFeature(LibraryFeature* pFeature) { } pPane->switchToFeature(pFeature); + m_preselectedPane = -1; + handlePreselection(); } void Library::showBreadCrumb(int paneId, TreeItem *pTree) { @@ -273,7 +275,6 @@ void Library::paneFocused(LibraryPaneManager* pPane) { DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { return; } - setFocusedPane(); handleFocus(); } @@ -291,6 +292,14 @@ void Library::panePreselected(LibraryPaneManager* pPane, bool value) { handlePreselection(); } +int Library::getFocusedPaneId() { + return m_focusedPane; +} + +int Library::getPreselectedPaneId() { + return m_preselectedPane; +} + void Library::slotRefreshLibraryModels() { m_pMixxxLibraryFeature->refreshLibraryModels(); m_pAnalysisFeature->refreshLibraryModels(); @@ -337,7 +346,8 @@ void Library::onSkinLoadFinished() { } // The first pane always shows the Mixxx Library feature on start - m_preselectedPane = m_panes.begin().key(); + m_preselectedPane = m_focusedPane = m_panes.begin().key(); + handleFocus(); (*m_features.begin())->setFeaturePane(m_preselectedPane); slotActivateFeature(*m_features.begin()); } @@ -431,7 +441,6 @@ void Library::paneCollapsed(int paneId) { int auxId = pPane->getPaneId(); if (!m_collapsedPanes.contains(auxId) && !focused) { m_focusedPane = pPane->getPaneId(); - setFocusedPane(); pPane->setFocus(); focused = true; } @@ -470,66 +479,17 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { m_preselectedPane = pFeature->getSavedPane(); } - m_pSidebarExpanded->switchToFeature(pFeature); pFeature->setSavedPane(m_preselectedPane); + pFeature->setFeaturePane(m_preselectedPane); if (m_panes[m_preselectedPane]->getCurrentFeature() != pFeature) { m_panes[m_preselectedPane]->setCurrentFeature(pFeature); pFeature->activate(); + } else { + m_pSidebarExpanded->switchToFeature(pFeature); } m_preselectedPane = -1; handlePreselection(); - - - - - /* - // The feature is being shown currently in the focused pane - if (m_panes[m_focusedPane]->getCurrentFeature() == pFeature) { - pFeature->setSavedPane(m_focusedPane); - m_pSidebarExpanded->switchToFeature(pFeature); - handleFocus(); - return; - } - - if (m_pSidebarExpanded->getCurrentFeature() != pFeature) { - // If the feature is not already shown, follow restore in old pane - int savedPane = pFeature->getSavedPane(); - if (savedPane >= 0 && !m_collapsedPanes.contains(savedPane)) { - // The feature is shown in some not collapsed pane - m_focusedPane = savedPane; - setFocusedPane(); - } - } else if (pFeature->isSinglePane()) { - // Swap panes in case of a single Pane feature - LibraryFeature* pOldFeature = m_panes[m_focusedPane]->getCurrentFeature(); - int newFocusPane = m_focusedPane; - m_focusedPane = pFeature->getSavedPane(); - m_panes[m_focusedPane]->setCurrentFeature(pOldFeature); - pOldFeature->setSavedPane(m_focusedPane); - pOldFeature->activate(); - m_focusedPane = newFocusPane; - } - - LibraryFeature* pCurrentFeature = m_panes[m_focusedPane]->getCurrentFeature(); - if (pCurrentFeature != pFeature && - pCurrentFeature->getSavedPane() == m_focusedPane) { - // If this feature it's still shown in another pane change the feature - // focus to the other pane - for (LibraryPaneManager* p : m_panes) { - if (!m_collapsedPanes.contains(p->getPaneId()) && - p->getCurrentFeature() == pCurrentFeature) { - pCurrentFeature->setSavedPane(p->getPaneId()); - break; - } - } - } - - m_panes[m_focusedPane]->setCurrentFeature(pFeature); - pFeature->setSavedPane(m_focusedPane); - pFeature->activate(); - handleFocus(); - */ } void Library::slotHoverFeature(LibraryFeature *pFeature) { @@ -548,14 +508,6 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::slotUpdateFocus(LibraryFeature* pFeature) { - if (pFeature->getFeaturePane() >= 0) { - m_focusedPane = pFeature->getFeaturePane(); - setFocusedPane(); - } -} - - LibraryPaneManager* Library::getOrCreatePane(int paneId) { //qDebug() << "Library::createPane" << id; // Get the value once to avoid searching again in the hash @@ -580,7 +532,6 @@ LibraryPaneManager* Library::getOrCreatePane(int paneId) { m_panes.insert(paneId, pPane); m_focusedPane = paneId; - setFocusedPane(); return pPane; } @@ -662,12 +613,6 @@ void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface addFeature(new MaintenanceFeature(pConfig, this, this, m_pTrackCollection)); } -void Library::setFocusedPane() { - for (LibraryFeature* pFeature : m_features) { - pFeature->setFocusedPane(m_focusedPane); - } -} - void Library::handleFocus() { // Changes the visual focus effect, removes the existing one and adds the // new focus diff --git a/src/library/library.h b/src/library/library.h index 0717c9a80bf..624c201db06 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -98,6 +98,9 @@ class Library : public QObject { void restoreSaveButton(int paneId); void paneFocused(LibraryPaneManager *pPane); void panePreselected(LibraryPaneManager* pPane, bool value); + + int getFocusedPaneId(); + int getPreselectedPaneId(); public slots: @@ -117,9 +120,6 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - - // Updates with the focus feature - void slotUpdateFocus(LibraryFeature* pFeature); void scan() { m_scanner.scan(); @@ -148,7 +148,6 @@ class Library : public QObject { LibraryPaneManager* getPreselectedPane(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); - void setFocusedPane(); void handleFocus(); void handlePreselection(); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 30f8e0c06c7..9a138f455c7 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -37,7 +37,6 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pTrackCollection(pTrackCollection), m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), m_featurePane(-1), - m_focusedPane(-1), m_savedPane(-1) { } @@ -112,23 +111,22 @@ int LibraryFeature::getFeaturePane() { return m_featurePane; } -void LibraryFeature::setFocusedPane(int paneId) { - m_focusedPane = paneId; -} - -int LibraryFeature::getFocusedPane() { - return m_focusedPane; -} - void LibraryFeature::setSavedPane(int paneId) { m_savedPane = paneId; - setFeaturePane(m_savedPane); } int LibraryFeature::getSavedPane() { return m_savedPane; } +int LibraryFeature::getFocusedPane() { + return m_pLibrary->getFocusedPaneId(); +} + +int LibraryFeature::getPreselectedPane() { + return m_pLibrary->getPreselectedPaneId(); +} + SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery sQuery) { WTrackTableView* pTable = getFocusedTable(); if (pTable == nullptr) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 27959c25be7..babdc8493ec 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -72,12 +72,12 @@ class LibraryFeature : public QObject { virtual void setFeaturePane(int paneId); int getFeaturePane(); - void setFocusedPane(int paneId); - int getFocusedPane(); - void setSavedPane(int paneId); int getSavedPane(); + int getFocusedPane(); + int getPreselectedPane(); + virtual SavedSearchQuery saveQuery(SavedSearchQuery sQuery); virtual void restoreQuery(int id); virtual QList getSavedQueries() const; @@ -156,7 +156,6 @@ class LibraryFeature : public QObject { SavedQueriesDAO& m_savedDAO; int m_featurePane; - int m_focusedPane; int m_savedPane; private: From 60033ccb2eb03d3f1c73d419e59858ed6c3f3937 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 13:42:49 +0200 Subject: [PATCH 456/552] Remove unnecessary app event filter improving performance --- src/library/librarypanemanager.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 8bfee7b8c32..054915d155f 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -14,7 +14,6 @@ LibraryPaneManager::LibraryPaneManager(int paneId, Library *pLibrary, QObject* p m_pBreadCrumb(nullptr), m_paneId(paneId), m_pLibrary(pLibrary) { - qApp->installEventFilter(this); } LibraryPaneManager::~LibraryPaneManager() { @@ -65,7 +64,6 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { void LibraryPaneManager::setBreadCrumb(WLibraryBreadCrumb* pBreadCrumb) { m_pBreadCrumb = pBreadCrumb; - pBreadCrumb->installEventFilter(this); connect(m_pBreadCrumb, SIGNAL(preselected(bool)), this, SLOT(slotPanePreselected(bool))); } @@ -199,20 +197,15 @@ void LibraryPaneManager::slotSearchCleared() { } bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { - if (m_pPaneWidget.isNull() || m_pSearchBar.isNull() || - m_pBreadCrumb.isNull()) { + if (m_pPaneWidget.isNull() || m_pSearchBar.isNull()) { return false; } if (event->type() == QEvent::MouseButtonPress && - (m_pPaneWidget->underMouse() || - m_pSearchBar->underMouse() || - m_pBreadCrumb->underMouse())) { + (m_pPaneWidget->underMouse() || m_pSearchBar->underMouse())) { + m_pLibrary->paneFocused(this); + } else if (event->type() == QEvent::FocusIn) { m_pLibrary->paneFocused(this); } - - // Since this event filter is for the entire application (to handle the - // mouse event), NEVER return true. If true is returned I will block all - // application events and will block the entire application. return false; } From d3ba7b0b4051c8f8d672c9e1bb2f10c5b75905a3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 14:43:44 +0200 Subject: [PATCH 457/552] Fix some issues with playlists --- src/library/baseplaylistfeature.cpp | 51 +++++++++++++++++------------ src/library/baseplaylistfeature.h | 4 +-- src/library/historyfeature.cpp | 8 +++-- src/library/libraryfeature.cpp | 3 ++ src/library/libraryfeature.h | 2 ++ src/library/playlistfeature.cpp | 8 +++-- 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 9c847258a27..1a1324290a1 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -128,8 +128,8 @@ QPointer BasePlaylistFeature::getPlaylistTableModel(int pane } void BasePlaylistFeature::activate() { - if (m_lastChildClicked.isValid()) { - activateChild(m_lastChildClicked); + if (m_lastChildClicked[m_featurePane].isValid()) { + activateChild(m_lastChildClicked[m_featurePane]); return; } @@ -142,17 +142,19 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { - if (index == m_lastChildClicked && m_lastClickedFocus == m_featurePane) { + if (getPreselectedPane() >= 0) { + m_featurePane = getPreselectedPane(); + } + + if (index == m_lastChildClicked[m_featurePane]) { restoreSearch(""); - - showTable(m_lastClickedFocus); - showBreadCrumb(index); + showTable(m_featurePane); switchToFeature(); return; } - m_lastChildClicked = index; - m_lastClickedFocus = m_featurePane; + m_lastChildClicked[m_featurePane] = index; + //qDebug() << "BasePlaylistFeature::activateChild()" << index; QSet playlistIds = playlistIdsFromIndex(index); m_pPlaylistTableModel = getPlaylistTableModel(m_featurePane); @@ -178,9 +180,6 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { m_pPlaylistTableModel->setTableModel(playlistId); showTrackModel(m_pPlaylistTableModel); //m_pPlaylistTableModel->select(); - emit(enableCoverArtDisplay(true)); - // Update selection - emit(featureSelect(this, m_lastRightClickedIndex)); activateChild(m_lastRightClickedIndex); } } @@ -303,9 +302,11 @@ void BasePlaylistFeature::slotCreatePlaylist() { int playlistId = m_playlistDao.createPlaylist(name); if (playlistId != -1) { + m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex; activatePlaylist(playlistId); } else { - QMessageBox::warning(NULL, + QMessageBox::warning(nullptr, tr("Playlist Creation Failed"), tr("An unknown error occurred while creating playlist: ") + name); @@ -335,13 +336,21 @@ void BasePlaylistFeature::slotDeletePlaylist() { return; } + m_playlistDao.deletePlaylist(playlistId); + // This avoids a bug where the m_lastChildClicked index is still a valid // index but it's not true since we just deleted it - if (m_lastChildClicked == m_lastRightClickedIndex) { - m_lastChildClicked = QModelIndex(); - } - - m_playlistDao.deletePlaylist(playlistId); + for (auto it = m_playlistTableModel.begin(); + it != m_playlistTableModel.end(); ++it) { + + if ((*it)->getPlaylist() == playlistId) { + // Show the browse widget, this avoids a problem when the same + // playlist is shown twice and gets deleted. One of the panes + // gets still showing the unexisting playlist. + m_lastChildClicked[it.key()] = QModelIndex(); + showBrowse(it.key()); + } + } activate(); } } @@ -450,7 +459,7 @@ void BasePlaylistFeature::slotCreateImportPlaylist() { slotImportPlaylistFile(playlistFile); } - activatePlaylist(lastPlaylistId); + m_lastChildClicked[m_featurePane] = constructChildModel(lastPlaylistId); } void BasePlaylistFeature::slotExportPlaylist() { @@ -720,7 +729,7 @@ QModelIndex BasePlaylistFeature::constructChildModel(int selectedId) { buildPlaylistList(); m_childModel->setRootItem(new TreeItem("$root", "$root", this, nullptr)); - QList data_list; + QList dataList; int selectedRow = -1; // Access the invisible root item TreeItem* root = m_childModel->getItem(QModelIndex()); @@ -737,12 +746,12 @@ QModelIndex BasePlaylistFeature::constructChildModel(int selectedId) { item->setBold(m_playlistsSelectedTrackIsIn.contains(p.id)); decorateChild(item, p.id); - data_list.append(item); + dataList.append(item); ++row; } // Append all the newly created TreeItems in a dynamic way to the childmodel - m_childModel->insertRows(data_list, 0, m_playlistList.size()); + m_childModel->insertRows(dataList, 0, m_playlistList.size()); return m_childModel->index(selectedRow, 0); } diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 1927c12cb7b..ddc0dc99ec4 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -121,8 +121,8 @@ class BasePlaylistFeature : public LibraryFeature { QModelIndex m_lastRightClickedIndex; TreeItemModel* m_childModel; TrackPointer m_pSelectedTrack; - QModelIndex m_lastChildClicked; - int m_lastClickedFocus; + + QHash m_lastChildClicked; private slots: void slotTrackSelected(TrackPointer pTrack); diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 8f65430aa63..017b15c8856 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -72,7 +72,7 @@ void HistoryFeature::onRightClick(const QPoint&) { void HistoryFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex &index) { //Save the model index so we can get it in the action slots... - m_lastChildClicked = m_lastRightClickedIndex = index; + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex = index; bool ok; int playlistId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); if (!ok || playlistId < 0) { @@ -322,7 +322,8 @@ void HistoryFeature::slotPlaylistTableChanged(int playlistId) { PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_SET_LOG || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex; } } @@ -349,7 +350,8 @@ void HistoryFeature::slotPlaylistTableRenamed(int playlistId, enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_SET_LOG || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex; if (type != PlaylistDAO::PLHT_UNKNOWN) { activatePlaylist(playlistId); } diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 9a138f455c7..1c52f38c714 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -231,6 +231,9 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* this, SLOT(onRightClickChild(const QPoint&, const QModelIndex&))); connect(pSidebar, SIGNAL(expanded(const QModelIndex&)), this, SLOT(onLazyChildExpandation(const QModelIndex&))); + connect(this, SIGNAL(selectIndex(const QModelIndex&)), + pSidebar, SLOT(selectIndex(const QModelIndex&))); + return pSidebar; } diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index babdc8493ec..ea34b5b4ea2 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -109,6 +109,8 @@ class LibraryFeature : public QObject { void featureLoadingFinished(LibraryFeature*); // emit this signal to select pFeature void featureSelect(LibraryFeature* pFeature, const QModelIndex& index); + // emit this signal to select an index + void selectIndex(const QModelIndex& index); // emit this signal to enable/disable the cover art widget void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 3184493a5b1..fc08d40c751 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -61,7 +61,7 @@ void PlaylistFeature::onRightClick(const QPoint& globalPos) { void PlaylistFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { //Save the model index so we can get it in the action slots... - m_lastChildClicked = m_lastRightClickedIndex = index; + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex = index; int playlistId = playlistIdFromIndex(index); bool locked = m_playlistDao.isPlaylistLocked(playlistId); @@ -214,7 +214,8 @@ void PlaylistFeature::slotPlaylistTableChanged(int playlistId) { enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_NOT_HIDDEN || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex; } } @@ -243,7 +244,8 @@ void PlaylistFeature::slotPlaylistTableRenamed(int playlistId, enum PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId); if (type == PlaylistDAO::PLHT_NOT_HIDDEN || type == PlaylistDAO::PLHT_UNKNOWN) { // In case of a deleted Playlist - m_lastChildClicked = m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastRightClickedIndex = constructChildModel(playlistId); + m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex; if (type != PlaylistDAO::PLHT_UNKNOWN) { activatePlaylist(playlistId); } From 9f4aadef43fb4dc890c9424633bc7493c813d508 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 14:50:00 +0200 Subject: [PATCH 458/552] Fix the same playlist issue with crates --- src/library/cratefeature.cpp | 23 ++++++++++++++++++++--- src/library/cratefeature.h | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index b806b5ecccb..8a054547eed 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -219,8 +219,8 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { - if (m_lastClickedIndex.isValid()) { - activateChild(m_lastClickedIndex); + if (m_lastClickedIndex[m_featurePane].isValid()) { + activateChild(m_lastClickedIndex[m_featurePane]); return; } @@ -232,7 +232,11 @@ void CrateFeature::activate() { } void CrateFeature::activateChild(const QModelIndex& index) { - m_lastClickedIndex = index; + if (getPreselectedPane() >= 0) { + m_featurePane = getPreselectedPane(); + } + + m_lastClickedIndex[m_featurePane] = index; int crateId = crateIdFromIndex(index); if (crateId == -1) { return; @@ -343,6 +347,19 @@ void CrateFeature::slotDeleteCrate() { bool deleted = m_crateDao.deleteCrate(crateId); if (deleted) { + // This avoids a bug where the m_lastChildClicked index is still a valid + // index but it's not true since we just deleted it + for (auto it = m_crateTableModel.begin(); + it != m_crateTableModel.end(); ++it) { + if ((*it)->getCrate() == crateId) { + // Show the browse widget, this avoids a problem when the same + // playlist is shown twice and gets deleted. One of the panes + // gets still showing the unexisting crate. + m_lastClickedIndex[it.key()] = QModelIndex(); + showBrowse(it.key()); + } + } + activate(); } else { qDebug() << "Failed to delete crateId" << crateId; diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index 4dd309384f4..23817f0d7fb 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -118,7 +118,7 @@ class CrateFeature : public LibraryFeature { QHash > m_panes; QHash m_idBrowse; QHash m_idTable; - QModelIndex m_lastClickedIndex; + QHash m_lastClickedIndex; }; #endif /* CRATEFEATURE_H */ From b43651c43e0bb0e51794b8f2e2004c7332b2d71c Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 25 Aug 2016 21:26:07 +0200 Subject: [PATCH 459/552] Add preview of preselection --- build/depends.py | 1 + src/library/library.cpp | 36 +++++++++++++++++---- src/library/library.h | 8 ++++- src/library/librarypanemanager.cpp | 20 ++++++------ src/library/librarypanemanager.h | 9 +++--- src/skin/legacyskinparser.cpp | 4 +-- src/widget/wfeatureclickbutton.cpp | 8 +++++ src/widget/wfeatureclickbutton.h | 6 ++++ src/widget/wlibrarybreadcrumb.cpp | 11 +++++-- src/widget/wlibrarybreadcrumb.h | 8 +++-- src/widget/wtristatebutton.cpp | 52 ++++++++++++++++++++++++++++++ src/widget/wtristatebutton.h | 34 +++++++++++++++++++ 12 files changed, 169 insertions(+), 28 deletions(-) create mode 100644 src/widget/wtristatebutton.cpp create mode 100644 src/widget/wtristatebutton.h diff --git a/build/depends.py b/build/depends.py index c78c7ab0186..897db14a35e 100644 --- a/build/depends.py +++ b/build/depends.py @@ -834,6 +834,7 @@ def sources(self, build): "widget/wlibrarybreadcrumb.cpp", "widget/wminiviewscrollbar.cpp", "widget/wverticalscrollarea.cpp", + "widget/wtristatebutton.cpp", "musicbrainz/network.cpp", "musicbrainz/tagfetcher.cpp", diff --git a/src/library/library.cpp b/src/library/library.cpp index 25b2b1890af..967e8d2ecdc 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -54,7 +54,10 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, m_pRecordingManager(pRecordingManager), m_scanner(m_pTrackCollection, pConfig), m_pSidebarExpanded(nullptr), - m_preselectedPane(-1) { + m_hoveredFeature(nullptr), + m_focusedPane(-1), + m_preselectedPane(-1), + m_previewPreselectedPane(-1) { qRegisterMetaType("Library::RemovalType"); connect(&m_scanner, SIGNAL(scanStarted()), @@ -112,7 +115,7 @@ void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { pPane->bindSearchBar(searchLine); } -void Library::bindSidebarWidget(WButtonBar* sidebar) { +void Library::bindSidebarButtons(WButtonBar* sidebar) { for (LibraryFeature* f : m_features) { WFeatureClickButton* button = sidebar->addButton(f); @@ -122,6 +125,10 @@ void Library::bindSidebarWidget(WButtonBar* sidebar) { this, SLOT(slotHoverFeature(LibraryFeature*))); connect(button, SIGNAL(rightClicked(const QPoint&)), f, SLOT(onRightClick(const QPoint&))); + connect(button, SIGNAL(hovered(LibraryFeature*)), + this, SLOT(slotPreviewPreselection(LibraryFeature*))); + connect(button, SIGNAL(leaved(LibraryFeature*)), + this, SLOT(slotDisablePreviewPreselection(LibraryFeature*))); } } @@ -434,14 +441,14 @@ void Library::paneCollapsed(int paneId) { m_collapsedPanes.insert(paneId); // Automatically switch the focus to a non collapsed pane - m_panes[paneId]->clearFocus(); + m_panes[paneId]->setFocused(false); bool focused = false; for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); if (!m_collapsedPanes.contains(auxId) && !focused) { m_focusedPane = pPane->getPaneId(); - pPane->setFocus(); + pPane->setFocused(true); focused = true; } @@ -508,6 +515,20 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } +void Library::slotPreviewPreselection(LibraryFeature* pFeature) { + m_hoveredFeature = pFeature; + m_previewPreselectedPane = pFeature->getSavedPane(); + handlePreselection(); +} + +void Library::slotDisablePreviewPreselection(LibraryFeature* pFeature) { + if (pFeature == m_hoveredFeature) { + m_previewPreselectedPane = -1; + m_hoveredFeature = nullptr; + } + handlePreselection(); +} + LibraryPaneManager* Library::getOrCreatePane(int paneId) { //qDebug() << "Library::createPane" << id; // Get the value once to avoid searching again in the hash @@ -617,16 +638,19 @@ void Library::handleFocus() { // Changes the visual focus effect, removes the existing one and adds the // new focus for (LibraryPaneManager* pPane : m_panes) { - pPane->clearFocus(); + pPane->setFocused(false); } - m_panes[m_focusedPane]->setFocus(); + m_panes[m_focusedPane]->setFocused(true); } void Library::handlePreselection() { for (LibraryPaneManager* pPane : m_panes) { pPane->setPreselected(false); + pPane->setPreviewed(false); } if (m_preselectedPane >= 0) { m_panes[m_preselectedPane]->setPreselected(true); + } else if (m_previewPreselectedPane >= 0) { + m_panes[m_previewPreselectedPane]->setPreviewed(true); } } diff --git a/src/library/library.h b/src/library/library.h index 624c201db06..b5f8ca144ab 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -59,7 +59,7 @@ class Library : public QObject { virtual ~Library(); void bindSearchBar(WSearchLineEdit* searchLine, int id); - void bindSidebarWidget(WButtonBar* sidebar); + void bindSidebarButtons(WButtonBar* sidebar); void bindPaneWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarExpanded(WBaseLibrary* expandedPane, @@ -120,6 +120,9 @@ class Library : public QObject { void onSkinLoadFinished(); void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); + + void slotPreviewPreselection(LibraryFeature* pFeature); + void slotDisablePreviewPreselection(LibraryFeature* pFeature); void scan() { m_scanner.scan(); @@ -170,10 +173,13 @@ class Library : public QObject { QList m_features; QSet m_collapsedPanes; QHash m_savedFeatures; + // Used to show the preselected pane when the mouse is over the button + LibraryFeature* m_hoveredFeature; // Can be any integer as it's used with a HashMap int m_focusedPane; int m_preselectedPane; + int m_previewPreselectedPane; }; #endif /* LIBRARY_H */ diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 054915d155f..8953419c9d2 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -92,18 +92,12 @@ LibraryFeature *LibraryPaneManager::getCurrentFeature() const { return m_pCurrentFeature; } -void LibraryPaneManager::setFocus() { - //qDebug() << "LibraryPaneManager::setFocus"; +void LibraryPaneManager::setFocused(bool value) { DEBUG_ASSERT_AND_HANDLE(m_pPaneWidget) { return; } - m_pPaneWidget->setProperty("showFocus", 1); -} - -void LibraryPaneManager::clearFocus() { - //qDebug() << "LibraryPaneManager::clearFocus"; - m_pPaneWidget->setProperty("showFocus", 0); + m_pPaneWidget->setProperty("showFocus", (int) value); } void LibraryPaneManager::switchToFeature(LibraryFeature* pFeature) { @@ -142,7 +136,7 @@ void LibraryPaneManager::showBreadCrumb(const QString &text, const QIcon& icon) m_pBreadCrumb->showBreadCrumb(text, icon); } -int LibraryPaneManager::getPaneId() { +int LibraryPaneManager::getPaneId() const { return m_paneId; } @@ -152,13 +146,19 @@ void LibraryPaneManager::setPreselected(bool value) { } } -bool LibraryPaneManager::isPreselected() { +bool LibraryPaneManager::isPreselected() const { if (!m_pBreadCrumb.isNull()) { return m_pBreadCrumb->isPreselected(); } return false; } +void LibraryPaneManager::setPreviewed(bool value) { + if (!m_pBreadCrumb.isNull()) { + m_pBreadCrumb->setPreviewed(value); + } +} + void LibraryPaneManager::slotPanePreselected(bool value) { setPreselected(value); m_pLibrary->panePreselected(this, value); diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 33b811c0154..6c963d277a0 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -39,8 +39,7 @@ class LibraryPaneManager : public QObject { void setCurrentFeature(LibraryFeature* pFeature); LibraryFeature* getCurrentFeature() const; - void setFocus(); - void clearFocus(); + void setFocused(bool value); void restoreSearch(const QString& text); void restoreSaveButton(); @@ -48,10 +47,12 @@ class LibraryPaneManager : public QObject { void showBreadCrumb(TreeItem* pTree); void showBreadCrumb(const QString& text, const QIcon &icon); - int getPaneId(); + int getPaneId() const; void setPreselected(bool value); - bool isPreselected(); + bool isPreselected() const; + + void setPreviewed(bool value); signals: diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index f45b37a41ed..79a28e842a6 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1337,7 +1337,7 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { WButtonBar* pLibrarySidebar = new WButtonBar(scroll); pLibrarySidebar->installEventFilter(m_pKeyboard); - m_pLibrary->bindSidebarWidget(pLibrarySidebar); + m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); WBaseLibrary* pLibrarySidebarExpanded = new WBaseLibrary(pContainer); @@ -1357,7 +1357,7 @@ QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { WButtonBar* pLibrarySidebar = new WButtonBar(scroll); pLibrarySidebar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); pLibrarySidebar->installEventFilter(m_pKeyboard); - m_pLibrary->bindSidebarWidget(pLibrarySidebar); + m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); setupWidget(node, scroll); diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index 2d5df12b1a5..dc87fbe9362 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -26,6 +26,14 @@ WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* pare } } +void WFeatureClickButton::enterEvent(QEvent*) { + emit(hovered(m_pFeature)); +} + +void WFeatureClickButton::leaveEvent(QEvent*) { + emit(leaved(m_pFeature)); +} + void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::RightButton) { emit(rightClicked(event->globalPos())); diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index a3136eef0a6..f25a49930ef 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -21,9 +21,14 @@ class WFeatureClickButton : public QToolButton void clicked(LibraryFeature*); void rightClicked(const QPoint&); void hoverShow(LibraryFeature*); + + void hovered(LibraryFeature*); + void leaved(LibraryFeature*); protected: + void enterEvent(QEvent*); + void leaveEvent(QEvent*); void mousePressEvent(QMouseEvent* event); void dragEnterEvent(QDragEnterEvent* event); @@ -44,6 +49,7 @@ class WFeatureClickButton : public QToolButton ControlProxy m_textControl; LibraryFeature* m_pFeature; QBasicTimer m_hoverTimer; + bool m_mousEntered; }; #endif // WRIGHTCLICKBUTTON_H diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index 63f04b6fa1f..a193d198305 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -4,12 +4,13 @@ #include "library/treeitemmodel.h" #include "widget/wpixmapstore.h" +#include "widget/wtristatebutton.h" WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) : QWidget(parent), m_pIcon(new QLabel(this)), m_pText(new QLabel(this)), - m_pPreselectButton(new QToolButton(this)), + m_pPreselectButton(new WTriStateButton(this)), m_preselected(false) { QLayout* layout = new QHBoxLayout(this); @@ -24,8 +25,8 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) m_preselectIcon.addPixmap(preOn, QIcon::Normal, QIcon::On); m_preselectIcon.addPixmap(preOff, QIcon::Normal, QIcon::Off); + m_preselectIcon.addPixmap(preOn, QIcon::Active, QIcon::Off); m_pPreselectButton->setIcon(m_preselectIcon); - m_pPreselectButton->setCheckable(true); m_pPreselectButton->setChecked(m_preselected); connect(m_pPreselectButton, SIGNAL(clicked(bool)), @@ -55,10 +56,14 @@ void WLibraryBreadCrumb::setPreselected(bool value) { refreshWidth(); } -bool WLibraryBreadCrumb::isPreselected() { +bool WLibraryBreadCrumb::isPreselected() const { return m_preselected; } +void WLibraryBreadCrumb::setPreviewed(bool value) { + m_pPreselectButton->setHovered(value); +} + void WLibraryBreadCrumb::showBreadCrumb(TreeItem* pTree) { LibraryFeature* pFeature = pTree->getFeature(); DEBUG_ASSERT_AND_HANDLE(pFeature != nullptr) { diff --git a/src/widget/wlibrarybreadcrumb.h b/src/widget/wlibrarybreadcrumb.h index 8a25e05a9d2..91d5fa5dd4f 100644 --- a/src/widget/wlibrarybreadcrumb.h +++ b/src/widget/wlibrarybreadcrumb.h @@ -7,6 +7,7 @@ #include class TreeItem; +class WTriStateButton; class WLibraryBreadCrumb : public QWidget { Q_OBJECT @@ -16,7 +17,9 @@ class WLibraryBreadCrumb : public QWidget { virtual QSize minimumSizeHint() const; void setPreselected(bool value); - bool isPreselected(); + bool isPreselected() const; + + void setPreviewed(bool value); signals: void preselected(bool); @@ -35,8 +38,9 @@ class WLibraryBreadCrumb : public QWidget { QLabel* m_pIcon; QLabel* m_pText; - QToolButton* m_pPreselectButton; + WTriStateButton* m_pPreselectButton; QIcon m_preselectIcon; + QIcon m_previewIcon; bool m_preselected; QString m_longText; diff --git a/src/widget/wtristatebutton.cpp b/src/widget/wtristatebutton.cpp new file mode 100644 index 00000000000..cce9237918f --- /dev/null +++ b/src/widget/wtristatebutton.cpp @@ -0,0 +1,52 @@ +#include "wtristatebutton.h" + + +WTriStateButton::WTriStateButton(QWidget* parent) + : QToolButton(parent), + m_state(State::Unactive) { + setCheckable(true); +} + +void WTriStateButton::setChecked(bool value) { + m_state = value ? State::Active : State::Unactive; + updateButton(); +} + +bool WTriStateButton::isChecked() const { + return m_state == State::Active; +} + +void WTriStateButton::setState(State state) { + m_state = state; + updateButton(); +} + +WTriStateButton::State WTriStateButton::getState() const { + return m_state; +} + +void WTriStateButton::setHovered(bool value) { + m_state = value ? State::Hovered : State::Unactive; + updateButton(); +} + +void WTriStateButton::setIcon(const QIcon& icon) { + m_icon = icon; + updateButton(); +} + +void WTriStateButton::updateButton() { + QPixmap pix; + switch (m_state) { + case State::Unactive: + pix = m_icon.pixmap(height(), QIcon::Normal, QIcon::Off); + break; + case State::Active: + pix = m_icon.pixmap(height(), QIcon::Normal, QIcon::On); + break; + case State::Hovered: + pix = m_icon.pixmap(height(), QIcon::Active, QIcon::Off); + break; + } + QToolButton::setIcon(QIcon(pix)); +} diff --git a/src/widget/wtristatebutton.h b/src/widget/wtristatebutton.h new file mode 100644 index 00000000000..ba0f9ec2b1d --- /dev/null +++ b/src/widget/wtristatebutton.h @@ -0,0 +1,34 @@ +#ifndef WTRISTATEBUTTON_H +#define WTRISTATEBUTTON_H + +#include + +class WTriStateButton : public QToolButton +{ + public: + enum State { + Unactive, + Active, + Hovered + }; + + WTriStateButton(QWidget* parent = nullptr); + + void setChecked(bool value); + bool isChecked() const; + + void setState(State state); + State getState() const; + + void setHovered(bool value); + + void setIcon(const QIcon& icon); + + private: + void updateButton(); + + QIcon m_icon; + State m_state; +}; + +#endif // WTRISTATEBUTTON_H From 9aa271fe5bed5a2518511752b04c3f5fdffa7936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 26 Aug 2016 00:41:58 +0200 Subject: [PATCH 460/552] ButtonBar is now controllable by keyboard --- res/skins/Deere/style.qss | 5 ++ res/skins/Shade/skin.xml | 10 +++- src/skin/legacyskinparser.cpp | 4 ++ src/widget/wbuttonbar.cpp | 91 +++++++++++++++++++++++++++++- src/widget/wbuttonbar.h | 9 ++- src/widget/wfeatureclickbutton.cpp | 13 +++++ src/widget/wfeatureclickbutton.h | 16 +++--- src/widget/wverticalscrollarea.cpp | 5 ++ src/widget/wverticalscrollarea.h | 4 ++ 9 files changed, 145 insertions(+), 12 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 7f2ac8127e3..b80109a09a4 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -174,6 +174,11 @@ WBaseLibrary[showFocus="1"] { background-color: #4B4B4B; } +QToolButton:focus, +QToolButton:focus::hover { + background-color: #006596; +} + WLibraryBreadCrumb QLabel { margin: 4px 4px; font-size: 12px; diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index c3cf56745e3..9865c8f883a 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -437,7 +437,7 @@ } WSearchLineEdit:focus { padding: 2px; - border: 2px solid #FF6600; + border: 2px solid #e74421; font: 12px/14px sans-serif; font-family: "Open Sans"; background: rgba(255, 102, 0,50); @@ -561,10 +561,16 @@ border: 2px solid #aab2b7; } + + WButtonBar QToolButton:hover { border: 2px solid #626f87; } + WButtonBar QToolButton:focus { + border: 2px solid #e74421; + } + WBaseLibrary[showFocus="0"] { padding: 2px 0 0 0; border: none; @@ -572,7 +578,7 @@ WBaseLibrary[showFocus="1"] { padding: 2px 1px 1px 1px; - border-top: 2px solid aqua; + border-top: 2px solid #e74421; } WLibraryBreadCrumb QLabel { diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 79a28e842a6..b782f76a984 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1339,6 +1339,8 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); + connect(pLibrarySidebar, SIGNAL(ensureVisible(QWidget*)), + scroll, SLOT(slotEnsureVisible(QWidget*))); WBaseLibrary* pLibrarySidebarExpanded = new WBaseLibrary(pContainer); pLibrarySidebarExpanded->installEventFilter(m_pKeyboard); @@ -1359,6 +1361,8 @@ QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); + connect(pLibrarySidebar, SIGNAL(ensureVisible(QWidget*)), + scroll, SLOT(slotEnsureVisible(QWidget*))); setupWidget(node, scroll); return scroll; diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 8920f65caa5..984f14fd3c6 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -6,7 +6,8 @@ #include "library/libraryfeature.h" WButtonBar::WButtonBar(QWidget* parent) - : QFrame(parent) { + : QFrame(parent), + m_focusItem(0) { QHBoxLayout* pHb = new QHBoxLayout(this); pHb->setContentsMargins(0,0,0,0); @@ -29,7 +30,7 @@ WButtonBar::WButtonBar(QWidget* parent) w1->setLayout(m_pLayout); setLayout(pHb); - setFocusPolicy(Qt::NoFocus); + setFocusPolicy(Qt::StrongFocus); setAutoFillBackground(true); } @@ -39,3 +40,89 @@ WFeatureClickButton* WButtonBar::addButton(LibraryFeature* pFeature) { updateGeometry(); return button; } + +void WButtonBar::keyPressEvent(QKeyEvent* event) { + bool focusFound = false; + switch(event->key()) { + case Qt::Key_Up: + for (int i = m_pLayout->count() - 1; i >= 0; --i) { + QLayoutItem* item = m_pLayout->itemAt(i); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + if (widget->hasFocus()) { + m_focusItem = i; + focusFound = true; + } else if (focusFound == true) { + widget->setFocus(); + emit ensureVisible(widget); + m_focusItem = i; + qDebug() << "Focus to" << i; + return; + } + } + } + } + if (focusFound == false) { + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + widget->setFocus(); + emit ensureVisible(widget); + return; + } + } + } + QWidget::keyPressEvent(event); + break; + case Qt::Key_Down: + for (int i = 0; i < m_pLayout->count(); ++i) { + QLayoutItem* item = m_pLayout->itemAt(i); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + if (widget->hasFocus()) { + m_focusItem = i; + focusFound = true; + } else if (focusFound == true) { + widget->setFocus(); + emit ensureVisible(widget); + m_focusItem = i; + qDebug() << "Focus to" << i; + return; + } + } + } + } + if (focusFound == false) { + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + widget->setFocus(); + emit ensureVisible(widget); + return; + } + } + } + QWidget::keyPressEvent(event); + break; + default: + QWidget::keyPressEvent(event); + break; + } +} + +void WButtonBar::focusInEvent(QFocusEvent* event) { + QWidget::focusInEvent(event); + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + widget->setFocus(); + emit ensureVisible(widget); + } + } +} + diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 35c5908357d..3c295825d47 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -17,9 +17,16 @@ class WButtonBar : public QFrame WFeatureClickButton* addButton(LibraryFeature *pFeature); - private: + signals: + void ensureVisible(QWidget* widget); + + protected: + void keyPressEvent(QKeyEvent* event) override; + void focusInEvent(QFocusEvent* event) override; + private: QLayout* m_pLayout; + int m_focusItem; }; #endif // WBUTTONBAR_H diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index dc87fbe9362..d58c1f80efb 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -24,6 +24,8 @@ WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* pare } else { slotTextDisplayChanged(1.0); } + + setFocusPolicy(Qt::ClickFocus); } void WFeatureClickButton::enterEvent(QEvent*) { @@ -92,3 +94,14 @@ void WFeatureClickButton::slotTextDisplayChanged(double value) { } } +void WFeatureClickButton::keyPressEvent(QKeyEvent* event) { + qDebug() << event; + switch(event->key()) { + case Qt::Key_Return: + emit(clicked(m_pFeature)); + break; + default: + QWidget::keyPressEvent(event); + break; + } +} diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index f25a49930ef..11976056b4a 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -27,15 +27,17 @@ class WFeatureClickButton : public QToolButton protected: - void enterEvent(QEvent*); - void leaveEvent(QEvent*); - void mousePressEvent(QMouseEvent* event); + void enterEvent(QEvent*) override; + void leaveEvent(QEvent*) override; + void mousePressEvent(QMouseEvent* event) override; + void keyPressEvent(QKeyEvent * event) override; - void dragEnterEvent(QDragEnterEvent* event); - void dragLeaveEvent(QDragLeaveEvent*); - void dropEvent(QDropEvent* event); + void dragEnterEvent(QDragEnterEvent* event) override; + void dragLeaveEvent(QDragLeaveEvent*) override; + void dropEvent(QDropEvent* event) override; + + void timerEvent(QTimerEvent* event) override; - void timerEvent(QTimerEvent* event); private slots: diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index 174eca43406..c0594c23516 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -38,3 +38,8 @@ void WVerticalScrollArea::calcSize() { } setFixedWidth(width + vScrollWidth); } + +void WVerticalScrollArea::slotEnsureVisible(QWidget* widget) { + qDebug() << "WVerticalScrollArea::slotEnsureVisible"; + ensureWidgetVisible(widget, 0, 0); +} diff --git a/src/widget/wverticalscrollarea.h b/src/widget/wverticalscrollarea.h index 74ab5ca49d2..9b16c05f254 100644 --- a/src/widget/wverticalscrollarea.h +++ b/src/widget/wverticalscrollarea.h @@ -5,11 +5,15 @@ class WVerticalScrollArea : public QScrollArea { + Q_OBJECT public: WVerticalScrollArea(QWidget* parent = nullptr); void setWidget(QWidget* widget); + public slots: + void slotEnsureVisible(QWidget* widget); + protected: bool eventFilter(QObject* o, QEvent* e) override; void resizeEvent(QResizeEvent* e) override; From 449590a9a8e70c39fb1f129901cf9afcee917058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 27 Aug 2016 01:24:53 +0200 Subject: [PATCH 461/552] respect frame width when calculating the button bar width --- res/skins/Deere/library.xml | 3 +++ res/skins/Deere/style.qss | 4 ---- res/skins/LateNight/style.qss | 2 +- src/widget/wverticalscrollarea.cpp | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index 0079c568fc9..eabdac48553 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -25,6 +25,9 @@ LibraryToggle [Library],show_library + + 6,6 + min,me LibrarySidebarButtons diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index b80109a09a4..025bcd29cf6 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -166,10 +166,6 @@ WBaseLibrary[showFocus="1"] { image: url(:/images/library/ic_library_unchecked.png); } -#LibrarySidebarButtons { - margin-top: 5px; -} - #LibrarySidebarButtons, WButtonBar { background-color: #4B4B4B; } diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index d730299f7e6..b284e422c0d 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1262,7 +1262,7 @@ #LibrarySidebarButtons WButtonBar { background-color: #191919; - margin: 0px 2px 0px 0px; + margin: 0px 1px 0px 0px; } #LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index c0594c23516..a0e54910df8 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -36,7 +36,7 @@ void WVerticalScrollArea::calcSize() { if (height() <= widget()->minimumSizeHint().height()) { vScrollWidth = verticalScrollBar()->width(); } - setFixedWidth(width + vScrollWidth); + setFixedWidth(width + frameWidth() * 2 + vScrollWidth); } void WVerticalScrollArea::slotEnsureVisible(QWidget* widget) { From 01031f037103c3fb3dc4a9da9605d6c228af92a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 28 Aug 2016 23:33:43 +0200 Subject: [PATCH 462/552] Enable preselection preview for keyboard navigation --- src/library/library.cpp | 37 ++++++++++++++++++++++++++---- src/library/library.h | 7 ++++-- src/library/libraryfeature.cpp | 2 +- src/widget/wfeatureclickbutton.cpp | 18 ++++++++++++--- src/widget/wfeatureclickbutton.h | 7 ++++-- 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 967e8d2ecdc..c61e10b22ac 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -55,6 +55,7 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, m_scanner(m_pTrackCollection, pConfig), m_pSidebarExpanded(nullptr), m_hoveredFeature(nullptr), + m_focusedFeature(nullptr), m_focusedPane(-1), m_preselectedPane(-1), m_previewPreselectedPane(-1) { @@ -126,9 +127,13 @@ void Library::bindSidebarButtons(WButtonBar* sidebar) { connect(button, SIGNAL(rightClicked(const QPoint&)), f, SLOT(onRightClick(const QPoint&))); connect(button, SIGNAL(hovered(LibraryFeature*)), - this, SLOT(slotPreviewPreselection(LibraryFeature*))); + this, SLOT(slotSetHoveredFeature(LibraryFeature*))); connect(button, SIGNAL(leaved(LibraryFeature*)), - this, SLOT(slotDisablePreviewPreselection(LibraryFeature*))); + this, SLOT(slotResetHoveredFeature(LibraryFeature*))); + connect(button, SIGNAL(focusIn(LibraryFeature*)), + this, SLOT(slotSetFocusedFeature(LibraryFeature*))); + connect(button, SIGNAL(focusOut(LibraryFeature*)), + this, SLOT(slotResetFocusedFeature(LibraryFeature*))); } } @@ -515,15 +520,37 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { emit(setTrackTableRowHeight(rowHeight)); } -void Library::slotPreviewPreselection(LibraryFeature* pFeature) { +void Library::slotSetHoveredFeature(LibraryFeature* pFeature) { m_hoveredFeature = pFeature; m_previewPreselectedPane = pFeature->getSavedPane(); handlePreselection(); } -void Library::slotDisablePreviewPreselection(LibraryFeature* pFeature) { +void Library::slotResetHoveredFeature(LibraryFeature* pFeature) { if (pFeature == m_hoveredFeature) { - m_previewPreselectedPane = -1; + if (m_focusedFeature) { + m_previewPreselectedPane = m_focusedFeature->getSavedPane(); + } else { + m_previewPreselectedPane = -1; + } + m_hoveredFeature = nullptr; + } + handlePreselection(); +} + +void Library::slotSetFocusedFeature(LibraryFeature* pFeature) { + m_focusedFeature = pFeature; + m_previewPreselectedPane = pFeature->getSavedPane(); + handlePreselection(); +} + +void Library::slotResetFocusedFeature(LibraryFeature* pFeature) { + if (pFeature == m_focusedFeature) { + if (m_hoveredFeature) { + m_previewPreselectedPane = m_hoveredFeature->getSavedPane(); + } else { + m_previewPreselectedPane = -1; + } m_hoveredFeature = nullptr; } handlePreselection(); diff --git a/src/library/library.h b/src/library/library.h index b5f8ca144ab..d9e4a1931c5 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -121,8 +121,10 @@ class Library : public QObject { void slotSetTrackTableFont(const QFont& font); void slotSetTrackTableRowHeight(int rowHeight); - void slotPreviewPreselection(LibraryFeature* pFeature); - void slotDisablePreviewPreselection(LibraryFeature* pFeature); + void slotSetHoveredFeature(LibraryFeature* pFeature); + void slotResetHoveredFeature(LibraryFeature* pFeature); + void slotSetFocusedFeature(LibraryFeature* pFeature); + void slotResetFocusedFeature(LibraryFeature* pFeature); void scan() { m_scanner.scan(); @@ -175,6 +177,7 @@ class Library : public QObject { QHash m_savedFeatures; // Used to show the preselected pane when the mouse is over the button LibraryFeature* m_hoveredFeature; + LibraryFeature* m_focusedFeature; // Can be any integer as it's used with a HashMap int m_focusedPane; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 1c52f38c714..cc529217b7b 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -275,7 +275,7 @@ void LibraryFeature::showBreadCrumb() { showBreadCrumb(title().toString(), getIcon()); } -WTrackTableView *LibraryFeature::getFocusedTable() { +WTrackTableView* LibraryFeature::getFocusedTable() { auto it = m_trackTables.find(m_featurePane); if (it == m_trackTables.end() || it->isNull()) { return nullptr; diff --git a/src/widget/wfeatureclickbutton.cpp b/src/widget/wfeatureclickbutton.cpp index d58c1f80efb..f496ae41ab3 100644 --- a/src/widget/wfeatureclickbutton.cpp +++ b/src/widget/wfeatureclickbutton.cpp @@ -28,14 +28,27 @@ WFeatureClickButton::WFeatureClickButton(LibraryFeature* pFeature, QWidget* pare setFocusPolicy(Qt::ClickFocus); } -void WFeatureClickButton::enterEvent(QEvent*) { +void WFeatureClickButton::enterEvent(QEvent* pEvent) { + QToolButton::enterEvent(pEvent); emit(hovered(m_pFeature)); } -void WFeatureClickButton::leaveEvent(QEvent*) { +void WFeatureClickButton::leaveEvent(QEvent* pEvent) { + QToolButton::leaveEvent(pEvent); emit(leaved(m_pFeature)); } +void WFeatureClickButton::focusInEvent(QFocusEvent* pEvent) { + QToolButton::focusInEvent(pEvent); + emit(focusIn(m_pFeature)); +} + +void WFeatureClickButton::focusOutEvent(QFocusEvent* pEvent) { + QToolButton::focusOutEvent(pEvent); + emit(focusOut(m_pFeature)); +} + + void WFeatureClickButton::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::RightButton) { emit(rightClicked(event->globalPos())); @@ -95,7 +108,6 @@ void WFeatureClickButton::slotTextDisplayChanged(double value) { } void WFeatureClickButton::keyPressEvent(QKeyEvent* event) { - qDebug() << event; switch(event->key()) { case Qt::Key_Return: emit(clicked(m_pFeature)); diff --git a/src/widget/wfeatureclickbutton.h b/src/widget/wfeatureclickbutton.h index 11976056b4a..31d8a43f845 100644 --- a/src/widget/wfeatureclickbutton.h +++ b/src/widget/wfeatureclickbutton.h @@ -13,8 +13,7 @@ class WFeatureClickButton : public QToolButton Q_OBJECT public: - WFeatureClickButton(LibraryFeature* pFeature = nullptr, - QWidget* parent = nullptr); + WFeatureClickButton(LibraryFeature* pFeature, QWidget* parent); signals: @@ -24,11 +23,15 @@ class WFeatureClickButton : public QToolButton void hovered(LibraryFeature*); void leaved(LibraryFeature*); + void focusIn(LibraryFeature*); + void focusOut(LibraryFeature*); protected: void enterEvent(QEvent*) override; void leaveEvent(QEvent*) override; + void focusInEvent(QFocusEvent*) override; + void focusOutEvent(QFocusEvent*) override; void mousePressEvent(QMouseEvent* event) override; void keyPressEvent(QKeyEvent * event) override; From 3a4ddc1c96b2523510be7697c5932a72339252e0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 29 Aug 2016 12:00:15 +0200 Subject: [PATCH 463/552] Fix bug with exporting empty playlists --- src/library/baseplaylistfeature.cpp | 4 ++-- src/library/cratefeature.cpp | 4 ++-- src/library/export/trackexportworker.cpp | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 1a1324290a1..a27abc7e611 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -578,8 +578,8 @@ void BasePlaylistFeature::slotExportTrackFiles() { tracks.push_back(pPlaylistTableModel->getTrack(index)); } - TrackExportWizard track_export(nullptr, m_pConfig, tracks); - track_export.exportTracks(); + TrackExportWizard trackExport(nullptr, m_pConfig, tracks); + trackExport.exportTracks(); } void BasePlaylistFeature::slotAddToAutoDJ() { diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 8a054547eed..c158006112e 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -804,8 +804,8 @@ void CrateFeature::slotExportTrackFiles() { trackpointers.push_back(m_pCrateTableModel->getTrack(index)); } - TrackExportWizard track_export(nullptr, m_pConfig, trackpointers); - track_export.exportTracks(); + TrackExportWizard trackExport(nullptr, m_pConfig, trackpointers); + trackExport.exportTracks(); } void CrateFeature::slotCrateTableChanged(int crateId) { diff --git a/src/library/export/trackexportworker.cpp b/src/library/export/trackexportworker.cpp index f4ec52fc255..013e8615d0b 100644 --- a/src/library/export/trackexportworker.cpp +++ b/src/library/export/trackexportworker.cpp @@ -70,21 +70,29 @@ QMap createCopylist(const QList& tracks) { void TrackExportWorker::run() { int i = 0; - QMap copy_list = createCopylist(m_tracks); - for (auto it = copy_list.constBegin(); it != copy_list.constEnd(); ++it) { + QMap copyList = createCopylist(m_tracks); + for (auto it = copyList.constBegin(); it != copyList.constEnd(); ++it) { // We emit progress twice per loop, which may seem excessive, but it // guarantees that we emit a sane progress before we start and after // we end. In between, each filename will get its own visible tick // on the bar, which looks really nice. - emit(progress(it->fileName(), i, copy_list.size())); + emit(progress(it->fileName(), i, copyList.size())); copyFile(*it, it.key()); if (load_atomic(m_bStop)) { emit(canceled()); return; } ++i; - emit(progress(it->fileName(), i, copy_list.size())); + emit(progress(it->fileName(), i, copyList.size())); } + + // If no file is being copied sleep a bit of time to allow the dialog to be + // shown, otherwise no dialog is shown and it seems that anything is done + if (copyList.size() <= 0) { + QThread::msleep(500); + } + + emit progress("", copyList.size(), copyList.size()); } void TrackExportWorker::copyFile(const QFileInfo& source_fileinfo, From b3a6ac4587468cae5c093bbd5ae4ad33b6b6109c Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 29 Aug 2016 13:33:30 +0200 Subject: [PATCH 464/552] Remove enable coverart since it's always enabled --- src/library/analysisfeature.cpp | 1 - src/library/autodj/autodjfeature.cpp | 1 - src/library/banshee/bansheefeature.cpp | 2 -- src/library/baseplaylistfeature.cpp | 2 -- src/library/browse/browsefeature.cpp | 2 -- src/library/cratefeature.cpp | 3 --- src/library/itunes/itunesfeature.cpp | 3 --- src/library/maintenancefeature.cpp | 2 -- src/library/mixxxlibraryfeature.cpp | 1 - src/library/recording/recordingfeature.cpp | 1 - src/library/rhythmbox/rhythmboxfeature.cpp | 2 -- src/library/traktor/traktorfeature.cpp | 2 -- 12 files changed, 22 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 1d11c99b7aa..c05d4419638 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -117,7 +117,6 @@ void AnalysisFeature::activate() { if (!m_pAnalysisView.isNull()) { restoreSearch(m_pAnalysisView->currentSearch()); } - emit(enableCoverArtDisplay(true)); } void AnalysisFeature::analyzeTracks(QList trackIds) { diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index 71e244d967a..b5a7bc8b44e 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -156,7 +156,6 @@ void AutoDJFeature::activate() { showBreadCrumb(); restoreSearch(QString()); //Null String disables search box - emit(enableCoverArtDisplay(true)); } bool AutoDJFeature::dropAccept(QList urls, QObject* pSource) { diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index da242db4761..a789bda9326 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -127,7 +127,6 @@ void BansheeFeature::activate() { showTrackModel(m_pBansheePlaylistModel); showBreadCrumb(); - enableCoverArtDisplay(true); } void BansheeFeature::activateChild(const QModelIndex& index) { @@ -141,7 +140,6 @@ void BansheeFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pBansheePlaylistModel); showBreadCrumb(item); - enableCoverArtDisplay(true); } } diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index a27abc7e611..09e2636d2c3 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -138,7 +138,6 @@ void BasePlaylistFeature::activate() { showBreadCrumb(); restoreSearch(QString()); // Null String disables search box - emit(enableCoverArtDisplay(true)); } void BasePlaylistFeature::activateChild(const QModelIndex& index) { @@ -170,7 +169,6 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { restoreSearch(""); showBreadCrumb(index); - emit(enableCoverArtDisplay(true)); } } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 0cd5c14d6b4..75f312798a5 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -239,7 +239,6 @@ void BrowseFeature::activate() { showBreadCrumb(); restoreSearch(QString()); - enableCoverArtDisplay(true); } // Note: This is executed whenever you single click on an child item @@ -273,7 +272,6 @@ void BrowseFeature::activateChild(const QModelIndex& index) { QString bread = index.data(TreeItemModel::RoleBreadCrumb).toString(); showBreadCrumb(bread, getIcon()); - emit(enableCoverArtDisplay(true)); } void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index c158006112e..820a4fdfe2d 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -228,7 +228,6 @@ void CrateFeature::activate() { switchToFeature(); showBreadCrumb(); restoreSearch(QString()); //disable search on crate home - emit(enableCoverArtDisplay(true)); } void CrateFeature::activateChild(const QModelIndex& index) { @@ -248,7 +247,6 @@ void CrateFeature::activateChild(const QModelIndex& index) { restoreSearch(""); showBreadCrumb(index); showTrackModel(m_pCrateTableModel); - emit(enableCoverArtDisplay(true)); } void CrateFeature::activateCrate(int crateId) { @@ -259,7 +257,6 @@ void CrateFeature::activateCrate(int crateId) { if (crateId != -1 && index.isValid()) { m_pCrateTableModel->setTableModel(crateId); showTrackModel(m_pCrateTableModel); - emit(enableCoverArtDisplay(true)); // Update selection emit(featureSelect(this, m_lastRightClickedIndex)); activateChild(m_lastRightClickedIndex); diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 6d781475250..c63f6bc08e5 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -122,7 +122,6 @@ QString ITunesFeature::getSettingsName() const { void ITunesFeature::activate() { activate(false); - enableCoverArtDisplay(true); } void ITunesFeature::activate(bool forceReload) { @@ -184,7 +183,6 @@ void ITunesFeature::activate(bool forceReload) { showTrackModel(m_pITunesTrackModel); showBreadCrumb(); - enableCoverArtDisplay(true); } void ITunesFeature::activateChild(const QModelIndex& index) { @@ -195,7 +193,6 @@ void ITunesFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pITunesPlaylistModel); showBreadCrumb(index); - enableCoverArtDisplay(true); } TreeItemModel* ITunesFeature::getChildModel() { diff --git a/src/library/maintenancefeature.cpp b/src/library/maintenancefeature.cpp index e05b85cde35..cc956a2235b 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/maintenancefeature.cpp @@ -47,7 +47,6 @@ void MaintenanceFeature::activate() { slotTabIndexChanged(m_pTab->currentIndex()); switchToFeature(); - emit(enableCoverArtDisplay(true)); } void MaintenanceFeature::selectionChanged(const QItemSelection&, @@ -154,7 +153,6 @@ void MaintenanceFeature::slotTabIndexChanged(int index) { switchToFeature(); restoreSearch(""); showBreadCrumb(kMaintenanceTitle % " > " % (*title), getIcon()); - emit(enableCoverArtDisplay(true)); } void MaintenanceFeature::slotUnhideHidden() { diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index b2df948a540..a3411fe7bbc 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -194,7 +194,6 @@ void MixxxLibraryFeature::activate() { restoreSearch(""); showBreadCrumb(); - emit(enableCoverArtDisplay(true)); } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 36046aae222..d328dc1267a 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -75,7 +75,6 @@ void RecordingFeature::activate() { showBreadCrumb(); restoreSearch(""); - enableCoverArtDisplay(true); } BrowseTableModel* RecordingFeature::getBrowseTableModel() { diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 0e1d4590183..659e6acef94 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -137,7 +137,6 @@ void RhythmboxFeature::activate() { showTrackModel(m_pRhythmboxTrackModel); showBreadCrumb(); - enableCoverArtDisplay(true); } void RhythmboxFeature::activateChild(const QModelIndex& index) { @@ -148,7 +147,6 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pRhythmboxPlaylistModel); showBreadCrumb(index); - enableCoverArtDisplay(true); } TreeItem* RhythmboxFeature::importMusicCollection() { diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 3926186ee39..5facf950922 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -165,7 +165,6 @@ void TraktorFeature::activate() { showTrackModel(m_pTraktorTableModel); showBreadCrumb(); - enableCoverArtDisplay(true); } void TraktorFeature::activateChild(const QModelIndex& index) { @@ -181,7 +180,6 @@ void TraktorFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pTraktorPlaylistModel); showBreadCrumb(item); - enableCoverArtDisplay(true); } } From cb56196246183cbfbbdb0ad2304224a03cd0907d Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 29 Aug 2016 14:38:53 +0200 Subject: [PATCH 465/552] Fix analysis selection get hidden on feature change --- src/library/analysisfeature.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index c05d4419638..9b0cfe4b86b 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -110,8 +110,8 @@ void AnalysisFeature::selectAll() { } void AnalysisFeature::activate() { - //qDebug() << "AnalysisFeature::activate()"; - showTrackModel(getAnalysisTableModel()); + //qDebug() << "AnalysisFeature::activate()"; + switchToFeature(); showBreadCrumb(); if (!m_pAnalysisView.isNull()) { @@ -189,7 +189,7 @@ void AnalysisFeature::tableSelectionChanged(const QItemSelection&, return; } - const QModelIndexList &indexes = pTable->selectionModel()->selectedIndexes(); + QModelIndexList indexes = pTable->selectionModel()->selectedIndexes(); m_pAnalysisView->setSelectedIndexes(indexes); } From 66779f1d625bbe4d06701d8fc9de0560af6e7474 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 14:10:15 +0200 Subject: [PATCH 466/552] Added new role behavior to allow to all models use the same roles --- src/library/abstractmodelroles.h | 16 ++++++++++++++++ src/library/baseplaylistfeature.cpp | 2 +- src/library/browse/browsefeature.cpp | 4 ++-- src/library/cratefeature.cpp | 2 +- src/library/historyfeature.cpp | 6 +++--- src/library/historytreemodel.cpp | 2 +- src/library/libraryfoldermodel.cpp | 8 ++++---- src/library/libraryfoldersfeature.cpp | 4 ++-- src/library/librarytreemodel.cpp | 8 ++++---- src/library/mixxxlibraryfeature.cpp | 8 ++++---- src/library/sidebarmodel.cpp | 2 +- src/library/treeitemmodel.cpp | 16 ++++++++-------- src/widget/wlibrarysidebar.cpp | 2 +- 13 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 src/library/abstractmodelroles.h diff --git a/src/library/abstractmodelroles.h b/src/library/abstractmodelroles.h new file mode 100644 index 00000000000..072d43121e1 --- /dev/null +++ b/src/library/abstractmodelroles.h @@ -0,0 +1,16 @@ +#ifndef ABSTRACTMODELROLES_H +#define ABSTRACTMODELROLES_H + +#include + +enum AbstractRole { + RoleDataPath = Qt::UserRole, + RoleBold, + RoleDivider, + RoleQuery, + RoleBreadCrumb, + RoleSettings, + RoleFirstLetter +}; + +#endif // ABSTRACTMODELROLES_H diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 09e2636d2c3..3e5a16bb670 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -637,7 +637,7 @@ QString BasePlaylistFeature::getValidPlaylistName() const { QSet BasePlaylistFeature::playlistIdsFromIndex(const QModelIndex &index) const { bool ok = false; - int playlistId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); + int playlistId = index.data(AbstractRole::RoleDataPath).toInt(&ok); if (!ok) { return QSet(); } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 75f312798a5..74d324683b9 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -246,7 +246,7 @@ void BrowseFeature::activate() { void BrowseFeature::activateChild(const QModelIndex& index) { m_lastClickedChild = index; QString data = index.data().toString(); - QString dataPath = index.data(TreeItemModel::RoleDataPath).toString(); + QString dataPath = index.data(AbstractRole::RoleDataPath).toString(); qDebug() << "BrowseFeature::activateChild " << data << dataPath; if (dataPath == QUICK_LINK_NODE || dataPath == DEVICE_NODE) { @@ -269,7 +269,7 @@ void BrowseFeature::activateChild(const QModelIndex& index) { showTable(m_featurePane); showTrackModel(&m_proxyModel); - QString bread = index.data(TreeItemModel::RoleBreadCrumb).toString(); + QString bread = index.data(AbstractRole::RoleBreadCrumb).toString(); showBreadCrumb(bread, getIcon()); } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 820a4fdfe2d..54a6337588f 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -136,7 +136,7 @@ bool CrateFeature::isSinglePane() const { int CrateFeature::crateIdFromIndex(QModelIndex index) { bool ok = false; - int crateId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); + int crateId = index.data(AbstractRole::RoleDataPath).toInt(&ok); return ok ? crateId : -1; } diff --git a/src/library/historyfeature.cpp b/src/library/historyfeature.cpp index 017b15c8856..88251474311 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/historyfeature.cpp @@ -74,7 +74,7 @@ void HistoryFeature::onRightClickChild(const QPoint& globalPos, const QModelInde //Save the model index so we can get it in the action slots... m_lastChildClicked[m_featurePane] = m_lastRightClickedIndex = index; bool ok; - int playlistId = index.data(TreeItemModel::RoleDataPath).toInt(&ok); + int playlistId = index.data(AbstractRole::RoleDataPath).toInt(&ok); if (!ok || playlistId < 0) { return; } @@ -154,7 +154,7 @@ PlaylistTableModel* HistoryFeature::constructTableModel() { } QSet HistoryFeature::playlistIdsFromIndex(const QModelIndex& index) const { - QList auxList = index.data(TreeItemModel::RoleQuery).toList(); + QList auxList = index.data(AbstractRole::RoleQuery).toList(); QSet playlistIds; for (QVariant& var : auxList) { bool ok; @@ -211,7 +211,7 @@ void HistoryFeature::slotJoinWithNext() { if (m_lastRightClickedIndex.isValid()) { bool ok; int currentPlaylistId = - m_lastRightClickedIndex.data(TreeItemModel::RoleDataPath).toInt(&ok); + m_lastRightClickedIndex.data(AbstractRole::RoleDataPath).toInt(&ok); if (!ok) { return; diff --git a/src/library/historytreemodel.cpp b/src/library/historytreemodel.cpp index 368aea9af98..58f6ccac7f4 100644 --- a/src/library/historytreemodel.cpp +++ b/src/library/historytreemodel.cpp @@ -112,7 +112,7 @@ QModelIndex HistoryTreeModel::indexFromPlaylistId(int playlistId) { } QVariant HistoryTreeModel::data(const QModelIndex& index, int role) const { - if (role != TreeItemModel::RoleQuery) { + if (role != AbstractRole::RoleQuery) { return TreeItemModel::data(index, role); } diff --git a/src/library/libraryfoldermodel.cpp b/src/library/libraryfoldermodel.cpp index ad083133aa1..cbcc7a6dc03 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/libraryfoldermodel.cpp @@ -33,7 +33,7 @@ LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, } bool LibraryFolderModel::setData(const QModelIndex& index, const QVariant& value, int role) { - if (role == TreeItemModel::RoleSettings) { + if (role == AbstractRole::RoleSettings) { m_folderRecursive = value.toBool(); m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), ConfigValue((int)m_folderRecursive)); @@ -44,7 +44,7 @@ bool LibraryFolderModel::setData(const QModelIndex& index, const QVariant& value } QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { - if (role == TreeItemModel::RoleSettings) { + if (role == AbstractRole::RoleSettings) { return m_folderRecursive; } @@ -53,7 +53,7 @@ QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { return TreeItemModel::data(index, role); } - if (role == TreeItemModel::RoleBreadCrumb) { + if (role == AbstractRole::RoleBreadCrumb) { if (pTree == m_pShowAllItem) { return m_pFeature->title(); } else { @@ -61,7 +61,7 @@ QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { } } - if (role == TreeItemModel::RoleQuery) { + if (role == AbstractRole::RoleQuery) { // User has clicked the show all item if (pTree == m_pShowAllItem) { return ""; diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/libraryfoldersfeature.cpp index 824d245936a..6c4f1b5d71b 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/libraryfoldersfeature.cpp @@ -37,7 +37,7 @@ void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, const QModelIndex&) { bool recursive = m_pChildModel->data(QModelIndex(), - TreeItemModel::RoleSettings).toBool(); + AbstractRole::RoleSettings).toBool(); QMenu menu; QAction* showRecursive = menu.addAction(tr("Show recursive view in folders")); @@ -48,7 +48,7 @@ void LibraryFoldersFeature::onRightClickChild(const QPoint&pos, if (selected == showRecursive) { m_pChildModel->setData(QModelIndex(), selected->isChecked(), - TreeItemModel::RoleSettings); + AbstractRole::RoleSettings); } else { // Menu rejected return; diff --git a/src/library/librarytreemodel.cpp b/src/library/librarytreemodel.cpp index afa0506dbd7..f24874e60a5 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/librarytreemodel.cpp @@ -53,7 +53,7 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { - if (role == TreeItemModel::RoleSettings) { + if (role == AbstractRole::RoleSettings) { return m_sortOrder; } @@ -62,7 +62,7 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { return TreeItemModel::data(index, role); } - if (role == TreeItemModel::RoleBreadCrumb) { + if (role == AbstractRole::RoleBreadCrumb) { if (pTree == m_pLibraryItem) { return m_pFeature->title(); } else { @@ -70,7 +70,7 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { } } - if (role == TreeItemModel::RoleQuery) { + if (role == AbstractRole::RoleQuery) { return getQuery(pTree); } @@ -107,7 +107,7 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { } bool LibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { - if (role == TreeItemModel::RoleSettings) { + if (role == AbstractRole::RoleSettings) { m_sortOrder = value.toStringList(); m_pConfig->set(ConfigKey("[Library]", LIBRARYTREEMODEL_SORT), ConfigValue(m_sortOrder.join(","))); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index a3411fe7bbc..88246039250 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -198,7 +198,7 @@ void MixxxLibraryFeature::activate() { void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_lastClickedIndex = index; - QString query = index.data(TreeItemModel::RoleQuery).toString(); + QString query = index.data(AbstractRole::RoleQuery).toString(); //qDebug() << "MixxxLibraryFeature::activateChild" << query; if (query == "$groupingSettings$") { @@ -209,7 +209,7 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_pLibraryTableModel->search(query); switchToFeature(); - showBreadCrumb(index.data(TreeItemModel::RoleBreadCrumb).toString(), getIcon()); + showBreadCrumb(index.data(AbstractRole::RoleBreadCrumb).toString(), getIcon()); restoreSearch(query); } @@ -219,7 +219,7 @@ void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, // Create the sort menu QMenu menu; QVariant varSort = m_pChildModel->data(QModelIndex(), - TreeItemModel::RoleSettings); + AbstractRole::RoleSettings); QStringList currentSort = varSort.toStringList(); QActionGroup* orderGroup = new QActionGroup(&menu); @@ -265,6 +265,6 @@ void MixxxLibraryFeature::setTreeSettings(const QVariant& settings) { if (m_pChildModel.isNull()) { return; } - m_pChildModel->setData(QModelIndex(), settings, TreeItemModel::RoleSettings); + m_pChildModel->setData(QModelIndex(), settings, AbstractRole::RoleSettings); m_pChildModel->reloadTree(); } diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp index a5fe522e72f..90dca35267c 100644 --- a/src/library/sidebarmodel.cpp +++ b/src/library/sidebarmodel.cpp @@ -197,7 +197,7 @@ QVariant SidebarModel::data(const QModelIndex& index, int role) const { } else { return tree_item->dataPath(); } - } else if (role == TreeItemModel::RoleDataPath) { + } else if (role == AbstractRole::RoleDataPath) { // We use Qt::UserRole to ask for the datapath. return tree_item->dataPath(); } else if (role == Qt::FontRole) { diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 38f3a72f62d..3f8b01568dd 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -67,13 +67,13 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const { } case Qt::DecorationRole: return item->getIcon(); - case Role::RoleDataPath: + case AbstractRole::RoleDataPath: return item->dataPath(); - case Role::RoleBold: + case AbstractRole::RoleBold: return item->isBold(); - case Role::RoleDivider: + case AbstractRole::RoleDivider: return item->isDivider(); - case Role::RoleBreadCrumb: + case AbstractRole::RoleBreadCrumb: return getBreadCrumbString(item); } @@ -93,13 +93,13 @@ bool TreeItemModel::setData(const QModelIndex &a_rIndex, case Qt::DisplayRole: pItem->setData(a_rValue, pItem->dataPath()); break; - case Role::RoleDataPath: + case AbstractRole::RoleDataPath: pItem->setData(pItem->data(), a_rValue); break; - case Role::RoleBold: + case AbstractRole::RoleBold: pItem->setBold(a_rValue.toBool()); break; - case Role::RoleDivider: + case AbstractRole::RoleDivider: pItem->setDivider(a_rValue.toBool()); break; default: @@ -115,7 +115,7 @@ Qt::ItemFlags TreeItemModel::flags(const QModelIndex &index) const { return 0; Qt::ItemFlags flags = Qt::ItemIsEnabled; - bool divider = index.data(Role::RoleDivider).toBool(); + bool divider = index.data(AbstractRole::RoleDivider).toBool(); if (!divider) { flags |= Qt::ItemIsSelectable; } diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index b6eff73812a..175fd5c1448 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -22,7 +22,7 @@ WSidebarItemDelegate::WSidebarItemDelegate(QObject* parent) void WSidebarItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - bool divider = index.data(TreeItemModel::RoleDivider).toBool(); + bool divider = index.data(AbstractRole::RoleDivider).toBool(); if (!divider) { QStyledItemDelegate::paint(painter, option, index); return; From d01389af578c6d6a34475f1d89b616e926655d49 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 14:14:49 +0200 Subject: [PATCH 467/552] Begin using RoleFirstLetter --- src/library/basesqltablemodel.cpp | 37 ++++++++++++++++- src/library/basesqltablemodel.h | 2 + src/library/libraryfeature.cpp | 4 +- src/library/treeitemmodel.cpp | 4 ++ src/library/treeitemmodel.h | 13 +----- src/widget/wminiviewscrollbar.cpp | 66 +++---------------------------- src/widget/wminiviewscrollbar.h | 10 ----- src/widget/wtracktableview.cpp | 6 +-- 8 files changed, 51 insertions(+), 91 deletions(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 0ca55fe8738..7bb63ebc653 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -20,6 +20,7 @@ #include "util/dnd.h" #include "util/assert.h" #include "util/performancetimer.h" +#include "util/stringhelper.h" static const bool sDebug = false; @@ -583,12 +584,16 @@ QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole && - role != Qt::ToolTipRole)) { + role != Qt::ToolTipRole && + role != AbstractRole::RoleFirstLetter)) { return QVariant(); } int row = index.row(); int column = index.column(); + if (role == AbstractRole::RoleFirstLetter && !m_sortColumns.isEmpty()) { + column = m_sortColumns.first().m_column; + } // This value is the value in its most raw form. It was looked up either // from the SQL table or from the cached track layer. @@ -682,6 +687,17 @@ QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { value = locked ? Qt::Checked : Qt::Unchecked; } break; + case AbstractRole::RoleFirstLetter: + if (isValidColumn(column)) { + if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) && + value.toString().size() == 4) { + // Show the decade + value = value.toString().at(2); + } else { + value = StringHelper::getFirstCharForGrouping(value.toString()); + } + } + break; default: break; } @@ -922,12 +938,16 @@ QVariant BaseSqlTableModel::getBaseValue( const QModelIndex& index, int role) const { if (role != Qt::DisplayRole && role != Qt::ToolTipRole && - role != Qt::EditRole) { + role != Qt::EditRole && + role != AbstractRole::RoleFirstLetter) { return QVariant(); } int row = index.row(); int column = index.column(); + if (role == AbstractRole::RoleFirstLetter && !m_sortColumns.isEmpty()) { + column = m_sortColumns.first().m_column; + } if (row < 0 || row >= m_rowInfo.size()) { return QVariant(); @@ -1117,3 +1137,16 @@ void BaseSqlTableModel::deserialzeSortColumns(QString serialized) { m_sortColumns << SortColumn(col, ord); } } + +bool BaseSqlTableModel::isValidColumn(int column) const { + return + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ARTIST) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GENRE) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TITLE) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) || + column == fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_ARTIST) || + column == fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_TITLE); +} diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 977e954f0ce..1ebda44baec 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -5,6 +5,7 @@ #include #include +#include "library/abstractmodelroles.h" #include "library/basetrackcache.h" #include "library/dao/trackdao.h" #include "library/trackcollection.h" @@ -127,6 +128,7 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { QSqlDatabase database() const; QString serializedSortColumns() const; void deserialzeSortColumns(QString serialized); + bool isValidColumn(int column) const; struct RowInfo { TrackId trackId; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 1c52f38c714..4b06565e0d6 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -218,8 +218,6 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* // Set sidebar mini view WMiniViewScrollBar* pMiniView = new WMiniViewScrollBar(pSidebar); pMiniView->setTreeView(pSidebar); - pMiniView->setSortColumn(0); - pMiniView->setRole(Qt::DisplayRole); pMiniView->setModel(pModel); pSidebar->setVerticalScrollBar(pMiniView); @@ -263,7 +261,7 @@ void LibraryFeature::showBreadCrumb(TreeItem *pTree) { } void LibraryFeature::showBreadCrumb(const QModelIndex& index) { - showBreadCrumb(index.data(TreeItemModel::RoleBreadCrumb).toString(), + showBreadCrumb(index.data(AbstractRole::RoleBreadCrumb).toString(), getIcon()); } diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 3f8b01568dd..9953551e958 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -3,6 +3,8 @@ #include "library/treeitemmodel.h" +#include "util/stringhelper.h" + /* * Just a word about how the TreeItem objects and TreeItemModels are used in general: * TreeItems are used by the TreeItemModel class to display tree @@ -75,6 +77,8 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const { return item->isDivider(); case AbstractRole::RoleBreadCrumb: return getBreadCrumbString(item); + case AbstractRole::RoleFirstLetter: + return StringHelper::getFirstCharForGrouping(item->data().toString()); } return QVariant(); diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index bc4286b3e5a..2907186f924 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -1,29 +1,20 @@ #ifndef TREE_ITEM_MODEL_H #define TREE_ITEM_MODEL_H -#include #include #include #include #include +#include "library/abstractmodelroles.h" #include "library/treeitem.h" class LibraryFeature; class TreeItemModel : public QAbstractItemModel { Q_OBJECT - public: - enum Role { - RoleDataPath = Qt::UserRole, - RoleBold, - RoleDivider, - RoleQuery, - RoleBreadCrumb, - RoleSettings - }; - + public: TreeItemModel(QObject* parent = nullptr); virtual ~TreeItemModel(); diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index f6565e99c52..8491a93b492 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -3,9 +3,7 @@ #include #include -#include "library/basesqltablemodel.h" -#include "library/columncache.h" -#include "util/stringhelper.h" +#include "library/abstractmodelroles.h" #include "wminiviewscrollbar.h" @@ -18,8 +16,6 @@ float interpolSize(float current, float max1, float max2) { WMiniViewScrollBar::WMiniViewScrollBar(QWidget* parent) : QScrollBar(parent), - m_sortColumn(-1), - m_dataRole(Qt::DisplayRole), m_showLetters(true) { setMouseTracking(true); @@ -35,15 +31,6 @@ bool WMiniViewScrollBar::showLetters() const { return m_showLetters; } -void WMiniViewScrollBar::setSortColumn(int column) { - m_sortColumn = column; - triggerUpdate(); -} - -int WMiniViewScrollBar::sortColumn() const { - return m_sortColumn; -} - void WMiniViewScrollBar::setTreeView(QPointer pTreeView) { m_pTreeView = pTreeView; } @@ -52,15 +39,6 @@ QPointer WMiniViewScrollBar::getTreeView() { return m_pTreeView; } -void WMiniViewScrollBar::setRole(int role) { - m_dataRole = role; - triggerUpdate(); -} - -int WMiniViewScrollBar::role() const { - return m_dataRole; -} - void WMiniViewScrollBar::setModel(QAbstractItemModel* model) { m_pModel = model; if (!m_pModel.isNull()) { @@ -181,23 +159,13 @@ void WMiniViewScrollBar::refreshCharMap() { int size = m_pModel->rowCount(); const QModelIndex& rootIndex = m_pModel->index(0, 0); - m_letters.clear(); - if (!isValidColumn()) { - return; - } - + m_letters.clear(); for (int i = 0; i < size; ++i) { - const QModelIndex& index = rootIndex.sibling(i, m_sortColumn); - QString text = index.data(m_dataRole).toString(); + const QModelIndex& index = rootIndex.sibling(i, 0); + + QChar c = index.data(AbstractRole::RoleFirstLetter).toChar(); int count = getVisibleChildCount(index); - QChar c; - if (m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) && - text.size() >= 3) { - c = text.at(2); - } else { - c = StringHelper::getFirstCharForGrouping(text); - } addToLastCharCount(c, count); } } @@ -272,28 +240,6 @@ QStyleOptionSlider WMiniViewScrollBar::getStyleOptions() { return opt; } -int WMiniViewScrollBar::getFieldIndex(ColumnCache::Column col) { - QPointer pModel = qobject_cast(m_pModel); - if (pModel.isNull()) { - return -1; - } - - return pModel->fieldIndex(col); -} - -bool WMiniViewScrollBar::isValidColumn() { - return m_sortColumn == 0 || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ARTIST) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GENRE) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TITLE) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_ARTIST) || - m_sortColumn == getFieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_TITLE); -} - void WMiniViewScrollBar::addToLastCharCount(const QChar& c, int sum) { if (m_letters.size() <= 0) { m_letters.append({c, sum}); @@ -323,7 +269,7 @@ int WMiniViewScrollBar::getVisibleChildCount(const QModelIndex& index) { int total = 1; int rowCount = m_pModel->rowCount(index); for (int i = 0; i < rowCount; ++i) { - total += getVisibleChildCount(index.child(i, m_sortColumn)); + total += getVisibleChildCount(index.child(i, 0)); } return total; } diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index fd5f248573f..fd50dde5ed0 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -16,15 +16,9 @@ class WMiniViewScrollBar : public QScrollBar void setShowLetters(bool show); bool showLetters() const; - - void setSortColumn(int column); - int sortColumn() const; void setTreeView(QPointer pTreeView); QPointer getTreeView(); - - void setRole(int role); - int role() const; void setModel(QAbstractItemModel* model); @@ -56,13 +50,9 @@ class WMiniViewScrollBar : public QScrollBar void refreshCharMap(); void computeLettersSize(); QStyleOptionSlider getStyleOptions(); - int getFieldIndex(ColumnCache::Column col); - bool isValidColumn(); void addToLastCharCount(const QChar& c, int sum = 1); int getVisibleChildCount(const QModelIndex &index); - int m_sortColumn; - int m_dataRole; bool m_showLetters; // Contains the times each character appears in the model diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index c35a201ae7a..ca8c705567e 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1576,11 +1576,7 @@ void WTrackTableView::doSortByColumn(int headerSection) { if (first.isValid()) { scrollTo(first, QAbstractItemView::EnsureVisible); } - - if (!m_pScrollBar.isNull()) { - m_pScrollBar->setSortColumn(headerSection); - } - + emit(tableChanged()); } From 981218e06ba06a0f849c06f62ca9578df59cf639 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 14:51:19 +0200 Subject: [PATCH 468/552] Fix printing strange characters --- src/library/basesqltablemodel.cpp | 2 ++ src/widget/wminiviewscrollbar.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 7bb63ebc653..d78730c76be 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -696,6 +696,8 @@ QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { } else { value = StringHelper::getFirstCharForGrouping(value.toString()); } + } else { + value = QVariant(); } break; default: diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index 8491a93b492..e78307ec02b 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -71,7 +71,7 @@ void WMiniViewScrollBar::paintEvent(QPaintEvent* event) { // Draw each letter in its position for (const CharPosition& p : m_computedPosition) { - if (p.position < 0 || p.character.isNull()) { + if (p.position < 0 || p.character.isNull() || !p.character.isPrint()) { continue; } QFont f(font()); From d9d9f8d59ec3f7910fc6d8929b0ca147f82a35e3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 14:51:46 +0200 Subject: [PATCH 469/552] Fix WMiniViewScrollBar not updating sometimes --- src/widget/wminiviewscrollbar.cpp | 2 ++ src/widget/wminiviewscrollbar.h | 6 +++--- src/widget/wtracktableview.cpp | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index e78307ec02b..ecb9c97b2c9 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -44,6 +44,8 @@ void WMiniViewScrollBar::setModel(QAbstractItemModel* model) { if (!m_pModel.isNull()) { connect(m_pModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(triggerUpdate())); + connect(m_pModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + this, SLOT(triggerUpdate())); triggerUpdate(); } diff --git a/src/widget/wminiviewscrollbar.h b/src/widget/wminiviewscrollbar.h index fd50dde5ed0..90aa7e2eacc 100644 --- a/src/widget/wminiviewscrollbar.h +++ b/src/widget/wminiviewscrollbar.h @@ -21,6 +21,9 @@ class WMiniViewScrollBar : public QScrollBar QPointer getTreeView(); void setModel(QAbstractItemModel* model); + + public slots: + void triggerUpdate(); protected: virtual void paintEvent(QPaintEvent* event); @@ -41,9 +44,6 @@ class WMiniViewScrollBar : public QScrollBar bool bold; }; - private slots: - void triggerUpdate(); - private: // The purpose of this function is to avoid computing all the sizes in the // paintEvent function which can block the GUI thread diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index ca8c705567e..9b41c86be9c 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1577,6 +1577,10 @@ void WTrackTableView::doSortByColumn(int headerSection) { scrollTo(first, QAbstractItemView::EnsureVisible); } + if (!m_pScrollBar.isNull()) { + m_pScrollBar->triggerUpdate(); + } + emit(tableChanged()); } From 1415f21d048fd16af24ec0e81e05d2fa3949f54a Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 20:25:00 +0200 Subject: [PATCH 470/552] Rename LibraryTreeModel to MixxxLibraryTreeModel --- build/depends.py | 2 +- src/library/mixxxlibraryfeature.cpp | 2 +- src/library/mixxxlibraryfeature.h | 2 +- ...reemodel.cpp => mixxxlibrarytreemodel.cpp} | 25 ++++++++++--------- ...arytreemodel.h => mixxxlibrarytreemodel.h} | 10 ++++---- 5 files changed, 21 insertions(+), 20 deletions(-) rename src/library/{librarytreemodel.cpp => mixxxlibrarytreemodel.cpp} (92%) rename src/library/{librarytreemodel.h => mixxxlibrarytreemodel.h} (83%) diff --git a/build/depends.py b/build/depends.py index f6f441cc124..0206a1072d5 100644 --- a/build/depends.py +++ b/build/depends.py @@ -874,6 +874,7 @@ def sources(self, build): "library/autodj/autodjprocessor.cpp", "library/dao/directorydao.cpp", "library/mixxxlibraryfeature.cpp", + "library/mixxxlibrarytreemodel.cpp", "library/libraryfoldersfeature.cpp", "library/baseplaylistfeature.cpp", "library/playlistfeature.cpp", @@ -952,7 +953,6 @@ def sources(self, build): "library/treeitemmodel.cpp", "library/treeitem.cpp", - "library/librarytreemodel.cpp", "library/parser.cpp", "library/parserpls.cpp", diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 88246039250..525eefe0532 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -117,7 +117,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); - setChildModel(new LibraryTreeModel(this, m_pTrackCollection, m_pConfig)); + setChildModel(new MixxxLibraryTreeModel(this, m_pTrackCollection, m_pConfig)); m_pBaseTrackCache = QSharedPointer(pBaseTrackCache); diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h index b9512f1c139..c097e1530e9 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/mixxxlibraryfeature.h @@ -17,7 +17,7 @@ #include #include "library/libraryfeature.h" -#include "library/librarytreemodel.h" +#include "library/mixxxlibrarytreemodel.h" #include "library/dao/trackdao.h" #include "preferences/usersettings.h" diff --git a/src/library/librarytreemodel.cpp b/src/library/mixxxlibrarytreemodel.cpp similarity index 92% rename from src/library/librarytreemodel.cpp rename to src/library/mixxxlibrarytreemodel.cpp index f24874e60a5..cc80fec2709 100644 --- a/src/library/librarytreemodel.cpp +++ b/src/library/mixxxlibrarytreemodel.cpp @@ -7,16 +7,16 @@ #include "util/stringhelper.h" #include "widget/wpixmapstore.h" -#include "library/librarytreemodel.h" +#include "library/mixxxlibrarytreemodel.h" namespace { QHash m_hashToIndex; } -LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig, - QObject* parent) +MixxxLibraryTreeModel::MixxxLibraryTreeModel(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, + UserSettingsPointer pConfig, + QObject* parent) : TreeItemModel(parent), m_pFeature(pFeature), m_pTrackCollection(pTrackCollection), @@ -52,7 +52,7 @@ LibraryTreeModel::LibraryTreeModel(LibraryFeature* pFeature, } -QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { +QVariant MixxxLibraryTreeModel::data(const QModelIndex& index, int role) const { if (role == AbstractRole::RoleSettings) { return m_sortOrder; } @@ -106,7 +106,8 @@ QVariant LibraryTreeModel::data(const QModelIndex& index, int role) const { return TreeItemModel::data(index, role); } -bool LibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { +bool MixxxLibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, + int role) { if (role == AbstractRole::RoleSettings) { m_sortOrder = value.toStringList(); m_pConfig->set(ConfigKey("[Library]", LIBRARYTREEMODEL_SORT), @@ -117,7 +118,7 @@ bool LibraryTreeModel::setData(const QModelIndex& index, const QVariant& value, } } -void LibraryTreeModel::reloadTree() { +void MixxxLibraryTreeModel::reloadTree() { //qDebug() << "LibraryTreeModel::reloadTracksTree"; // Create root item @@ -137,12 +138,12 @@ void LibraryTreeModel::reloadTree() { triggerRepaint(); } -void LibraryTreeModel::coverFound(const QObject* requestor, int requestReference, - const CoverInfo&, QPixmap pixmap, bool fromCache) { +void MixxxLibraryTreeModel::coverFound(const QObject* requestor, int requestReference, + const CoverInfo&, QPixmap pixmap, bool fromCache) { if (requestor == this && !pixmap.isNull() && !fromCache) { - auto it = m_hashToIndex.find(requestReference); - if (it == m_hashToIndex.end()) { + auto it = m_hashToIndex[this].find(requestReference); + if (it == m_hashToIndex[this].end()) { return; } diff --git a/src/library/librarytreemodel.h b/src/library/mixxxlibrarytreemodel.h similarity index 83% rename from src/library/librarytreemodel.h rename to src/library/mixxxlibrarytreemodel.h index 41e751ee59c..9fce412ade0 100644 --- a/src/library/librarytreemodel.h +++ b/src/library/mixxxlibrarytreemodel.h @@ -15,13 +15,13 @@ class TrackCollection; const QString LIBRARYTREEMODEL_SORT = "LibraryTree_Sort"; // ConfigValue key for Library Tree Model sort -class LibraryTreeModel : public TreeItemModel { +class MixxxLibraryTreeModel : public TreeItemModel { Q_OBJECT public: - LibraryTreeModel(LibraryFeature* pFeature, - TrackCollection* pTrackCollection, - UserSettingsPointer pConfig, - QObject* parent = nullptr); + MixxxLibraryTreeModel(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, + UserSettingsPointer pConfig, + QObject* parent = nullptr); virtual QVariant data(const QModelIndex& index, int role) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role); From 353bc96c3097548e31b8d78fad0c9787ab0826d3 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 20:25:38 +0200 Subject: [PATCH 471/552] Rename RoleFirstLetter to RoleGroupingLetter --- src/library/abstractmodelroles.h | 2 +- src/library/basesqltablemodel.cpp | 10 +++++----- src/library/treeitemmodel.cpp | 2 +- src/widget/wminiviewscrollbar.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/library/abstractmodelroles.h b/src/library/abstractmodelroles.h index 072d43121e1..00ff7e7d9a1 100644 --- a/src/library/abstractmodelroles.h +++ b/src/library/abstractmodelroles.h @@ -10,7 +10,7 @@ enum AbstractRole { RoleQuery, RoleBreadCrumb, RoleSettings, - RoleFirstLetter + RoleGroupingLetter }; #endif // ABSTRACTMODELROLES_H diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index d78730c76be..d1326b45ce5 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -585,13 +585,13 @@ QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { role != Qt::EditRole && role != Qt::CheckStateRole && role != Qt::ToolTipRole && - role != AbstractRole::RoleFirstLetter)) { + role != AbstractRole::RoleGroupingLetter)) { return QVariant(); } int row = index.row(); int column = index.column(); - if (role == AbstractRole::RoleFirstLetter && !m_sortColumns.isEmpty()) { + if (role == AbstractRole::RoleGroupingLetter && !m_sortColumns.isEmpty()) { column = m_sortColumns.first().m_column; } @@ -687,7 +687,7 @@ QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { value = locked ? Qt::Checked : Qt::Unchecked; } break; - case AbstractRole::RoleFirstLetter: + case AbstractRole::RoleGroupingLetter: if (isValidColumn(column)) { if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) && value.toString().size() == 4) { @@ -941,13 +941,13 @@ QVariant BaseSqlTableModel::getBaseValue( if (role != Qt::DisplayRole && role != Qt::ToolTipRole && role != Qt::EditRole && - role != AbstractRole::RoleFirstLetter) { + role != AbstractRole::RoleGroupingLetter) { return QVariant(); } int row = index.row(); int column = index.column(); - if (role == AbstractRole::RoleFirstLetter && !m_sortColumns.isEmpty()) { + if (role == AbstractRole::RoleGroupingLetter && !m_sortColumns.isEmpty()) { column = m_sortColumns.first().m_column; } diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 9953551e958..58938208fa8 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -77,7 +77,7 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const { return item->isDivider(); case AbstractRole::RoleBreadCrumb: return getBreadCrumbString(item); - case AbstractRole::RoleFirstLetter: + case AbstractRole::RoleGroupingLetter: return StringHelper::getFirstCharForGrouping(item->data().toString()); } diff --git a/src/widget/wminiviewscrollbar.cpp b/src/widget/wminiviewscrollbar.cpp index ecb9c97b2c9..b4f3dd413e3 100644 --- a/src/widget/wminiviewscrollbar.cpp +++ b/src/widget/wminiviewscrollbar.cpp @@ -165,7 +165,7 @@ void WMiniViewScrollBar::refreshCharMap() { for (int i = 0; i < size; ++i) { const QModelIndex& index = rootIndex.sibling(i, 0); - QChar c = index.data(AbstractRole::RoleFirstLetter).toChar(); + QChar c = index.data(AbstractRole::RoleGroupingLetter).toChar(); int count = getVisibleChildCount(index); addToLastCharCount(c, count); From 94b4600c72a46e7f4db16666b71e6aea45856645 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 20:25:57 +0200 Subject: [PATCH 472/552] Add pointer in m_hashToIndex to avoid some inheritance problems --- src/library/mixxxlibrarytreemodel.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/library/mixxxlibrarytreemodel.cpp b/src/library/mixxxlibrarytreemodel.cpp index cc80fec2709..9deb002ac77 100644 --- a/src/library/mixxxlibrarytreemodel.cpp +++ b/src/library/mixxxlibrarytreemodel.cpp @@ -10,7 +10,12 @@ #include "library/mixxxlibrarytreemodel.h" namespace { -QHash m_hashToIndex; +// This is used since MixxxLibraryTreeModel inherits QAbstractItemModel +// and since the data() method is a const method a class atribute can't be +// changed so this is a hack to allow using coverarts in the model +// since there's another pointer to the class there's no problem in two classes +// coexisting. +QHash > m_hashToIndex; } MixxxLibraryTreeModel::MixxxLibraryTreeModel(LibraryFeature* pFeature, @@ -57,11 +62,19 @@ QVariant MixxxLibraryTreeModel::data(const QModelIndex& index, int role) const { return m_sortOrder; } + TreeItem* pTree = static_cast(index.internalPointer()); DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { return TreeItemModel::data(index, role); } + if (role == AbstractRole::RoleGroupingLetter) { + if (pTree == m_pLibraryItem || pTree == m_pSettings) { + return QChar(); + } + return TreeItemModel::data(index, role); + } + if (role == AbstractRole::RoleBreadCrumb) { if (pTree == m_pLibraryItem) { return m_pFeature->title(); @@ -93,7 +106,7 @@ QVariant MixxxLibraryTreeModel::data(const QModelIndex& index, int role) const { // coverFound slot is called. Since the data function is const // and we cannot change that we use m_hashToIndex in an anonymous // namespace to store the future value that we will get - m_hashToIndex.insert(info.type, index); + m_hashToIndex[this].insert(info.type, index); // Return a temporary icon return QIcon(":/images/library/cover_default.png"); @@ -152,7 +165,7 @@ void MixxxLibraryTreeModel::coverFound(const QObject* requestor, int requestRefe } } -QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { +QVariant MixxxLibraryTreeModel::getQuery(TreeItem* pTree) const { DEBUG_ASSERT_AND_HANDLE(pTree != nullptr) { return ""; } @@ -191,7 +204,7 @@ QVariant LibraryTreeModel::getQuery(TreeItem* pTree) const { return result.join(" "); } -void LibraryTreeModel::createTracksTree() { +void MixxxLibraryTreeModel::createTracksTree() { QStringList columns; for (const QString& col : m_sortOrder) { @@ -314,7 +327,7 @@ void LibraryTreeModel::createTracksTree() { } } -void LibraryTreeModel::addCoverArt(const LibraryTreeModel::CoverIndex& index, +void MixxxLibraryTreeModel::addCoverArt(const MixxxLibraryTreeModel::CoverIndex& index, const QSqlQuery& query, TreeItem* pTree) { CoverInfo c; c.hash = query.value(index.iCoverHash).toInt(); From c9a0eabe52e5c7f39d069dae27a4a3d9fd6d6a48 Mon Sep 17 00:00:00 2001 From: jmigual Date: Tue, 30 Aug 2016 20:45:43 +0200 Subject: [PATCH 473/552] Fix small CSS issue with showFocus border --- res/skins/Deere/style.qss | 4 +--- res/skins/LateNight/style.qss | 6 ++---- res/skins/Shade/skin.xml | 4 +--- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 7f2ac8127e3..0927a160024 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -148,12 +148,10 @@ QTableView::indicator:unchecked { } WBaseLibrary[showFocus="0"] { - padding: 2px 0 0 0; - border: none; + border-top: 2px solid transparent; } WBaseLibrary[showFocus="1"] { - padding: 2px 0 0 0; border-top: 2px solid #0080BE; } diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index d730299f7e6..a9ed7e357df 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1463,11 +1463,9 @@ QTreeView::item:selected { } WLibrary[showFocus="0"] { - padding: 2px 0 0 0; - border: none; + border-top: 2px solid #0f0f0f; } WLibrary[showFocus="1"] { - padding: 2px 0 0 0; - border-top: 2px solid #FF7100 !important; + border-top: 2px solid #FF7100; } diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index c3cf56745e3..5d368865ac9 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -566,12 +566,10 @@ } WBaseLibrary[showFocus="0"] { - padding: 2px 0 0 0; - border: none; + border-top: 2px solid transparent; } WBaseLibrary[showFocus="1"] { - padding: 2px 1px 1px 1px; border-top: 2px solid aqua; } From 45ee8acf1e25e71eff631b70dd48f0a00abff763 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 12:45:23 +0200 Subject: [PATCH 474/552] Move crates --- build/depends.py | 5 +- src/library/features/crates/cratefeature.cpp | 955 ++++++++++++++++++ src/library/features/crates/cratefeature.h | 124 +++ .../features/crates/cratetablemodel.cpp | 195 ++++ src/library/features/crates/cratetablemodel.h | 34 + src/library/library.cpp | 2 +- 6 files changed, 1312 insertions(+), 3 deletions(-) create mode 100644 src/library/features/crates/cratefeature.cpp create mode 100644 src/library/features/crates/cratefeature.h create mode 100644 src/library/features/crates/cratetablemodel.cpp create mode 100644 src/library/features/crates/cratetablemodel.h diff --git a/build/depends.py b/build/depends.py index 0206a1072d5..72a3c891114 100644 --- a/build/depends.py +++ b/build/depends.py @@ -918,7 +918,9 @@ def sources(self, build): "library/itunes/itunesfeature.cpp", "library/traktor/traktorfeature.cpp", - "library/cratefeature.cpp", + "library/features/crates/cratefeature.cpp", + "library/features/crates/cratetablemodel.cpp", + "library/sidebarmodel.cpp", "library/library.cpp", "library/librarypanemanager.cpp", @@ -931,7 +933,6 @@ def sources(self, build): "library/scanner/recursivescandirectorytask.cpp", "library/dao/cratedao.cpp", - "library/cratetablemodel.cpp", "library/dao/cuedao.cpp", "library/dao/cue.cpp", "library/dao/trackdao.cpp", diff --git a/src/library/features/crates/cratefeature.cpp b/src/library/features/crates/cratefeature.cpp new file mode 100644 index 00000000000..bb2f8916420 --- /dev/null +++ b/src/library/features/crates/cratefeature.cpp @@ -0,0 +1,955 @@ +// cratefeature.cpp +// Created 10/22/2009 by RJ Ryan (rryan@mit.edu) + +#include +#include +#include +#include +#include + +#include "library/features/crates/cratefeature.h" + +#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/features/crates/cratetablemodel.h" +#include "library/export/trackexportwizard.h" +#include "library/library.h" +#include "library/parsercsv.h" +#include "library/parser.h" +#include "library/parserm3u.h" +#include "library/parserpls.h" +#include "library/queryutil.h" +#include "library/trackcollection.h" +#include "sources/soundsourceproxy.h" +#include "util/dnd.h" +#include "util/duration.h" +#include "util/time.h" +#include "widget/wlibrarystack.h" +#include "widget/wlibrarytextbrowser.h" + +CrateFeature::CrateFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection) + : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), + m_pTrackCollection(pTrackCollection), + m_crateDao(pTrackCollection->getCrateDAO()), + m_pCrateTableModel(nullptr) { + + m_pCreateCrateAction = new QAction(tr("Create New Crate"),this); + connect(m_pCreateCrateAction, SIGNAL(triggered()), + this, SLOT(slotCreateCrate())); + + m_pDeleteCrateAction = new QAction(tr("Remove"),this); + connect(m_pDeleteCrateAction, SIGNAL(triggered()), + this, SLOT(slotDeleteCrate())); + + m_pRenameCrateAction = new QAction(tr("Rename"),this); + connect(m_pRenameCrateAction, SIGNAL(triggered()), + this, SLOT(slotRenameCrate())); + + m_pLockCrateAction = new QAction(tr("Lock"),this); + connect(m_pLockCrateAction, SIGNAL(triggered()), + this, SLOT(slotToggleCrateLock())); + + m_pImportPlaylistAction = new QAction(tr("Import Crate"),this); + connect(m_pImportPlaylistAction, SIGNAL(triggered()), + this, SLOT(slotImportPlaylist())); + + m_pCreateImportPlaylistAction = new QAction(tr("Import Crate"), this); + connect(m_pCreateImportPlaylistAction, SIGNAL(triggered()), + this, SLOT(slotCreateImportCrate())); + + m_pExportPlaylistAction = new QAction(tr("Export Crate"), this); + connect(m_pExportPlaylistAction, SIGNAL(triggered()), + this, SLOT(slotExportPlaylist())); + + m_pExportTrackFilesAction = new QAction(tr("Export Track Files"), this); + connect(m_pExportTrackFilesAction, SIGNAL(triggered()), + this, SLOT(slotExportTrackFiles())); + + m_pDuplicateCrateAction = new QAction(tr("Duplicate"),this); + connect(m_pDuplicateCrateAction, SIGNAL(triggered()), + this, SLOT(slotDuplicateCrate())); + + m_pAnalyzeCrateAction = new QAction(tr("Analyze entire Crate"),this); + connect(m_pAnalyzeCrateAction, SIGNAL(triggered()), + this, SLOT(slotAnalyzeCrate())); + + m_pAutoDjTrackSource = new QAction(tr("Auto DJ Track Source"),this); + m_pAutoDjTrackSource->setCheckable(true); + connect(m_pAutoDjTrackSource, SIGNAL(changed()), + this, SLOT(slotAutoDjTrackSourceChanged())); + + connect(&m_crateDao, SIGNAL(added(int)), + this, SLOT(slotCrateTableChanged(int))); + + connect(&m_crateDao, SIGNAL(deleted(int)), + this, SLOT(slotCrateTableChanged(int))); + + connect(&m_crateDao, SIGNAL(changed(int)), + this, SLOT(slotCrateContentChanged(int))); + + connect(&m_crateDao, SIGNAL(renamed(int,QString)), + this, SLOT(slotCrateTableRenamed(int,QString))); + + connect(&m_crateDao, SIGNAL(lockChanged(int)), + this, SLOT(slotCrateTableChanged(int))); + + // construct child model + TreeItem *pRootItem = new TreeItem(); + pRootItem->setLibraryFeature(this); + m_childModel.setRootItem(pRootItem); + constructChildModel(-1); + + connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), + this, SLOT(slotTrackSelected(TrackPointer))); +} + +CrateFeature::~CrateFeature() { + //delete QActions + delete m_pExportTrackFilesAction; + delete m_pCreateCrateAction; + delete m_pDeleteCrateAction; + delete m_pRenameCrateAction; + delete m_pDuplicateCrateAction; + delete m_pLockCrateAction; + delete m_pImportPlaylistAction; + delete m_pAnalyzeCrateAction; + delete m_pAutoDjTrackSource; +} + +QVariant CrateFeature::title() { + return tr("Crates"); +} + +QString CrateFeature::getIconPath() { + return ":/images/library/ic_library_crates.png"; +} + +QString CrateFeature::getSettingsName() const { + return "CrateFeature"; +} + +bool CrateFeature::isSinglePane() const { + return false; +} + +int CrateFeature::crateIdFromIndex(QModelIndex index) { + bool ok = false; + int crateId = index.data(AbstractRole::RoleDataPath).toInt(&ok); + return ok ? crateId : -1; +} + +bool CrateFeature::dragMoveAccept(QUrl url) { + return SoundSourceProxy::isUrlSupported(url) || + Parser::isPlaylistFilenameSupported(url.toLocalFile()); +} + + +bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList urls, + QObject* pSource) { + int crateId = crateIdFromIndex(index); + + QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); + QList trackIds; + if (pSource) { + trackIds = m_pTrackCollection->getTrackDAO().getTrackIds(files); + m_pTrackCollection->getTrackDAO().unhideTracks(trackIds); + } else { + // Adds track, does not insert duplicates, handles unremoving logic. + trackIds = m_pTrackCollection->getTrackDAO().addMultipleTracks(files, true); + } + //qDebug() << "CrateFeature::dropAcceptChild adding tracks" + // << trackIds.size() << " to crate "<< crateId; + // remove tracks that could not be added + for (int trackIdIndex = 0; trackIdIndex < trackIds.size(); ++trackIdIndex) { + if (!trackIds.at(trackIdIndex).isValid()) { + trackIds.removeAt(trackIdIndex--); + } + } + + // Request a name for the crate if it's a new crate + if (crateId < 0) { + QString name = getValidCrateName(); + if (name.isNull()) { + return false; + } + + crateId = m_crateDao.createCrate(name); + // An error happened + if (crateId < 0) { + return false; + } + } + + m_crateDao.addTracksToCrate(crateId, &trackIds); + return true; +} + +bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { + int crateId = crateIdFromIndex(index); + bool locked = m_crateDao.isCrateLocked(crateId); + bool formatSupported = SoundSourceProxy::isUrlSupported(url) || + Parser::isPlaylistFilenameSupported(url.toLocalFile()); + return !locked && formatSupported; +} + +QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, + int paneId) { + WLibraryStack* pContainer = new WLibraryStack(nullptr); + m_panes[paneId] = pContainer; + + WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(pContainer); + pEdit->setHtml(getRootViewHtml()); + pEdit->setOpenLinks(false); + pEdit->installEventFilter(pKeyboard); + connect(pEdit, SIGNAL(anchorClicked(const QUrl)), + this, SLOT(htmlLinkClicked(const QUrl))); + + m_idBrowse[paneId] = pContainer->addWidget(pEdit); + + QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); + m_idTable[paneId] = pContainer->addWidget(pTable); + + return pContainer; +} + +TreeItemModel* CrateFeature::getChildModel() { + return &m_childModel; +} + +void CrateFeature::activate() { + if (m_lastClickedIndex[m_featurePane].isValid()) { + activateChild(m_lastClickedIndex[m_featurePane]); + return; + } + + showBrowse(m_featurePane); + switchToFeature(); + showBreadCrumb(); + restoreSearch(QString()); //disable search on crate home +} + +void CrateFeature::activateChild(const QModelIndex& index) { + if (getPreselectedPane() >= 0) { + m_featurePane = getPreselectedPane(); + } + + m_lastClickedIndex[m_featurePane] = index; + int crateId = crateIdFromIndex(index); + if (crateId == -1) { + return; + } + + m_pCrateTableModel = getTableModel(m_featurePane); + m_pCrateTableModel->setTableModel(crateId); + showTable(m_featurePane); + restoreSearch(""); + showBreadCrumb(index); + showTrackModel(m_pCrateTableModel); +} + +void CrateFeature::activateCrate(int crateId) { + //qDebug() << "CrateFeature::activateCrate()" << crateId; + m_pCrateTableModel = getTableModel(m_featurePane); + + QModelIndex index = indexFromCrateId(crateId); + if (crateId != -1 && index.isValid()) { + m_pCrateTableModel->setTableModel(crateId); + showTrackModel(m_pCrateTableModel); + // Update selection + emit(featureSelect(this, m_lastRightClickedIndex)); + activateChild(m_lastRightClickedIndex); + } +} + + +void CrateFeature::onRightClick(const QPoint& globalPos) { + m_lastRightClickedIndex = QModelIndex(); + QMenu menu(nullptr); + menu.addAction(m_pCreateCrateAction); + menu.addSeparator(); + menu.addAction(m_pCreateImportPlaylistAction); + menu.exec(globalPos); +} + +void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { + //Save the model index so we can get it in the action slots... + m_lastRightClickedIndex = index; + int crateId = crateIdFromIndex(index); + + bool locked = m_crateDao.isCrateLocked(crateId); + + m_pDeleteCrateAction->setEnabled(!locked); + m_pRenameCrateAction->setEnabled(!locked); + + bool bAutoDj = m_crateDao.isCrateInAutoDj(crateId); + m_pAutoDjTrackSource->setChecked(bAutoDj); + + m_pLockCrateAction->setText(locked ? tr("Unlock") : tr("Lock")); + + QMenu menu(nullptr); + menu.addAction(m_pCreateCrateAction); + menu.addSeparator(); + if (crateId >= 0) { + menu.addAction(m_pRenameCrateAction); + menu.addAction(m_pDuplicateCrateAction); + menu.addAction(m_pDeleteCrateAction); + menu.addAction(m_pLockCrateAction); + menu.addSeparator(); + menu.addAction(m_pAutoDjTrackSource); + menu.addSeparator(); + menu.addAction(m_pAnalyzeCrateAction); + menu.addSeparator(); + } + menu.addAction(m_pImportPlaylistAction); + if (crateId >= 0) { + menu.addAction(m_pExportPlaylistAction); + menu.addAction(m_pExportTrackFilesAction); + } + menu.exec(globalPos); +} + +void CrateFeature::slotCreateCrate() { + QString name = getValidCrateName(); + if (name.isNull()) { + // The user canceled + return; + } + + int crateId = m_crateDao.createCrate(name); + if (crateId != -1) { + activateCrate(crateId); + } else { + qDebug() << "Error creating crate with name " << name; + QMessageBox::warning(nullptr, + tr("Creating Crate Failed"), + tr("An unknown error occurred while creating crate: ") + + name); + } +} + +void CrateFeature::slotDeleteCrate() { + int crateId = crateIdFromIndex(m_lastRightClickedIndex); + if (crateId == -1) { + return; + } + + bool locked = m_crateDao.isCrateLocked(crateId); + if (locked) { + qDebug() << "Skipping crate deletion because crate" << crateId << "is locked."; + return; + } + + bool deleted = m_crateDao.deleteCrate(crateId); + + if (deleted) { + // This avoids a bug where the m_lastChildClicked index is still a valid + // index but it's not true since we just deleted it + for (auto it = m_crateTableModel.begin(); + it != m_crateTableModel.end(); ++it) { + if ((*it)->getCrate() == crateId) { + // Show the browse widget, this avoids a problem when the same + // playlist is shown twice and gets deleted. One of the panes + // gets still showing the unexisting crate. + m_lastClickedIndex[it.key()] = QModelIndex(); + showBrowse(it.key()); + } + } + + activate(); + } else { + qDebug() << "Failed to delete crateId" << crateId; + } +} + +void CrateFeature::slotRenameCrate() { + int crateId = crateIdFromIndex(m_lastRightClickedIndex); + if (crateId == -1) { + return; + } + QString oldName = m_crateDao.crateName(crateId); + + bool locked = m_crateDao.isCrateLocked(crateId); + if (locked) { + qDebug() << "Skipping crate rename because crate" << crateId << "is locked."; + return; + } + + QString newName; + bool validNameGiven = false; + + while (!validNameGiven) { + bool ok = false; + newName = QInputDialog::getText(NULL, + tr("Rename Crate"), + tr("Enter new name for crate:"), + QLineEdit::Normal, + oldName, + &ok).trimmed(); + + if (!ok || newName == oldName) { + return; + } + + int existingId = m_crateDao.getCrateIdByName(newName); + + if (existingId != -1) { + QMessageBox::warning(NULL, + tr("Renaming Crate Failed"), + tr("A crate by that name already exists.")); + } else if (newName.isEmpty()) { + QMessageBox::warning(NULL, + tr("Renaming Crate Failed"), + tr("A crate cannot have a blank name.")); + } else { + validNameGiven = true; + } + } + + if (!m_crateDao.renameCrate(crateId, newName)) { + qDebug() << "Failed to rename crateId" << crateId; + } +} + +void CrateFeature::slotDuplicateCrate() { + int oldCrateId = crateIdFromIndex(m_lastRightClickedIndex); + if (oldCrateId == -1) { + return; + } + QString oldName = m_crateDao.crateName(oldCrateId); + + QString name; + bool validNameGiven = false; + while (!validNameGiven) { + bool ok = false; + name = QInputDialog::getText(NULL, + tr("Duplicate Crate"), + tr("Enter name for new crate:"), + QLineEdit::Normal, + //: Appendix to default name when duplicating a crate + oldName + tr("_copy" , "[noun]"), + &ok).trimmed(); + + if (!ok || name == oldName) { + return; + } + + int existingId = m_crateDao.getCrateIdByName(name); + if (existingId != -1) { + QMessageBox::warning(NULL, + tr("Renaming Crate Failed"), + tr("A crate by that name already exists.")); + } else if (name.isEmpty()) { + QMessageBox::warning(NULL, + tr("Renaming Crate Failed"), + tr("A crate cannot have a blank name.")); + } else { + validNameGiven = true; + } + } + + int newCrateId = m_crateDao.createCrate(name); + m_crateDao.copyCrateTracks(oldCrateId, newCrateId); + + if (newCrateId != -1) { + activateCrate(newCrateId); + } else { + qDebug() << "Error creating crate with name " << name; + QMessageBox::warning(NULL, + tr("Creating Crate Failed"), + tr("An unknown error occurred while creating crate: ") + + name); + } +} + +void CrateFeature::slotToggleCrateLock() { + int crateId = crateIdFromIndex(m_lastRightClickedIndex); + if (crateId == -1) { + return; + } + QString crateName = m_crateDao.crateName(crateId); + bool locked = !m_crateDao.isCrateLocked(crateId); + + if (!m_crateDao.setCrateLocked(crateId, locked)) { + qDebug() << "Failed to toggle lock of crateId " << crateId; + } +} + +void CrateFeature::slotAutoDjTrackSourceChanged() { + int crateId = crateIdFromIndex(m_lastRightClickedIndex); + if (crateId != -1) { + m_crateDao.setCrateInAutoDj(crateId, m_pAutoDjTrackSource->isChecked()); + } +} + +void CrateFeature::buildCrateList() { + m_crateList.clear(); + + QString queryString = QString( + "CREATE TEMPORARY VIEW IF NOT EXISTS CratesCountsDurations " + "AS SELECT " + " crates.id as id, " + " crates.name as name, " + " COUNT(library.id) as count, " + " SUM(library.duration) as durationSeconds " + "FROM crates " + "LEFT JOIN crate_tracks ON crate_tracks.crate_id = crates.id " + "LEFT JOIN library ON crate_tracks.track_id = library.id " + "WHERE show = 1 " + "GROUP BY crates.id;"); + QSqlQuery query(m_pTrackCollection->getDatabase()); + if (!query.exec(queryString)) { + LOG_FAILED_QUERY(query); + } + + QSqlTableModel crateListTableModel(this, m_pTrackCollection->getDatabase()); + crateListTableModel.setTable("CratesCountsDurations"); + crateListTableModel.setSort(crateListTableModel.fieldIndex("name"), + Qt::AscendingOrder); + crateListTableModel.select(); + while (crateListTableModel.canFetchMore()) { + crateListTableModel.fetchMore(); + } + QSqlRecord record = crateListTableModel.record(); + int nameColumn = record.indexOf("name"); + int idColumn = record.indexOf("id"); + int countColumn = record.indexOf("count"); + int durationColumn = record.indexOf("durationSeconds"); + + for (int row = 0; row < crateListTableModel.rowCount(); ++row) { + int id = crateListTableModel.data( + crateListTableModel.index(row, idColumn)).toInt(); + QString name = crateListTableModel.data( + crateListTableModel.index(row, nameColumn)).toString(); + int count = crateListTableModel.data( + crateListTableModel.index(row, countColumn)).toInt(); + int duration = crateListTableModel.data( + crateListTableModel.index(row, durationColumn)).toInt(); + m_crateList.append(qMakePair(id, QString("%1 (%2) %3") + .arg(name, QString::number(count), + mixxx::Duration::formatSeconds(duration)))); + } +} + +/** + * Purpose: When inserting or removing playlists, + * we require the sidebar model not to reset. + * This method queries the database and does dynamic insertion +*/ +QModelIndex CrateFeature::constructChildModel(int selected_id) { + buildCrateList(); + QList data_list; + int selected_row = -1; + // Access the invisible root item + TreeItem* root = m_childModel.getItem(QModelIndex()); + + int row = 0; + for (QList >::const_iterator it = m_crateList.begin(); + it != m_crateList.end(); ++it, ++row) { + int crate_id = it->first; + QString crate_name = it->second; + + if (selected_id == crate_id) { + // save index for selection + selected_row = row; + m_childModel.index(selected_row, 0); + } + + // Create the TreeItem whose parent is the invisible root item + TreeItem* item = new TreeItem(crate_name, QString::number(crate_id), this, root); + bool locked = m_crateDao.isCrateLocked(crate_id); + item->setIcon(locked ? QIcon(":/images/library/ic_library_locked.png") : QIcon()); + item->setBold(m_cratesSelectedTrackIsIn.contains(crate_id)); + data_list.append(item); + } + + // Append all the newly created TreeItems in a dynamic way to the childmodel + m_childModel.insertRows(data_list, 0, m_crateList.size()); + if (selected_row == -1) { + return QModelIndex(); + } + return m_childModel.index(selected_row, 0); +} + +void CrateFeature::updateChildModel(int selected_id) { + buildCrateList(); + + int row = 0; + for (QList >::const_iterator it = m_crateList.begin(); + it != m_crateList.end(); ++it, ++row) { + int crate_id = it->first; + QString crate_name = it->second; + + if (selected_id == crate_id) { + TreeItem* item = m_childModel.getItem(indexFromCrateId(crate_id)); + item->setData(crate_name, QString::number(crate_id)); + bool locked = m_crateDao.isCrateLocked(crate_id); + item->setIcon(locked ? QIcon(":/images/library/ic_library_locked.png") : QIcon()); + + } + + } +} + +/** + * Clears the child model dynamically + */ +void CrateFeature::clearChildModel() { + m_childModel.removeRows(0, m_crateList.size()); + m_crateList.clear(); +} + +void CrateFeature::slotImportPlaylist() { + //qDebug() << "slotImportPlaylist() row:" ; //<< m_lastRightClickedIndex.data(); + + QString playlistFile = getPlaylistFile(); + if (playlistFile.isEmpty()) { + return; + } + + // Update the import/export crate directory + QFileInfo fileName(playlistFile); + m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), + ConfigValue(fileName.dir().absolutePath())); + + slotImportPlaylistFile(playlistFile); + activateChild(m_lastRightClickedIndex); +} + +void CrateFeature::slotImportPlaylistFile(const QString &playlist_file) { + // The user has picked a new directory via a file dialog. This means the + // system sandboxer (if we are sandboxed) has granted us permission to this + // folder. We don't need access to this file on a regular basis so we do not + // register a security bookmark. + + Parser* playlist_parser = NULL; + + if (playlist_file.endsWith(".m3u", Qt::CaseInsensitive) || + playlist_file.endsWith(".m3u8", Qt::CaseInsensitive)) { + // .m3u8 is Utf8 representation of an m3u playlist + playlist_parser = new ParserM3u(); + } else if (playlist_file.endsWith(".pls", Qt::CaseInsensitive)) { + playlist_parser = new ParserPls(); + } else if (playlist_file.endsWith(".csv", Qt::CaseInsensitive)) { + playlist_parser = new ParserCsv(); + } else { + return; + } + + if (playlist_parser) { + QList entries = playlist_parser->parse(playlist_file); + //qDebug() << "Size of Imported Playlist: " << entries.size(); + + //Iterate over the List that holds URLs of playlist entires + m_pCrateTableModel->addTracks(QModelIndex(), entries); + + //delete the parser object + delete playlist_parser; + } +} + +void CrateFeature::slotCreateImportCrate() { + + // Get file to read + QStringList playlist_files = LibraryFeature::getPlaylistFiles(); + if (playlist_files.isEmpty()) { + return; + } + + + // Set last import directory + QFileInfo fileName(playlist_files.first()); + m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), + ConfigValue(fileName.dir().absolutePath())); + + int lastCrateId = -1; + + // For each selected file + for (const QString& playlistFile : playlist_files) { + fileName = QFileInfo(playlistFile); + + // Get a valid name + QString baseName = fileName.baseName(); + QString name; + bool validNameGiven = false; + int i = 0; + while (!validNameGiven) { + name = baseName; + if (i != 0) { + name += QString::number(i); + } + + // Check name + int existingId = m_crateDao.getCrateIdByName(name); + + validNameGiven = (existingId == -1); + ++i; + } + + lastCrateId = m_crateDao.createCrate(name); + + if (lastCrateId != -1) { + m_pCrateTableModel->setTableModel(lastCrateId); + } + else { + QMessageBox::warning(NULL, + tr("Crate Creation Failed"), + tr("An unknown error occurred while creating crate: ") + + name); + return; + } + + slotImportPlaylistFile(playlistFile); + } + activateCrate(lastCrateId); +} + +void CrateFeature::slotAnalyzeCrate() { + if (m_lastRightClickedIndex.isValid()) { + int crateId = crateIdFromIndex(m_lastRightClickedIndex); + if (crateId >= 0) { + QList ids = m_crateDao.getTrackIds(crateId); + emit(analyzeTracks(ids)); + } + } +} + +void CrateFeature::slotExportPlaylist() { + int crateId = m_pCrateTableModel->getCrate(); + QString crateName = m_crateDao.crateName(crateId); + qDebug() << "Export crate" << crateId << crateName; + + QString lastCrateDirectory = m_pConfig->getValueString( + ConfigKey("[Library]", "LastImportExportCrateDirectory"), + QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); + + QString file_location = QFileDialog::getSaveFileName( + NULL, + tr("Export Crate"), + lastCrateDirectory.append("/").append(crateName), + tr("M3U Playlist (*.m3u);;M3U8 Playlist (*.m3u8);;PLS Playlist (*.pls);;Text CSV (*.csv);;Readable Text (*.txt)")); + // Exit method if user cancelled the open dialog. + if (file_location.isNull() || file_location.isEmpty()) { + return; + } + + // Update the import/export crate directory + QFileInfo fileName(file_location); + m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), + ConfigValue(fileName.dir().absolutePath())); + + // The user has picked a new directory via a file dialog. This means the + // system sandboxer (if we are sandboxed) has granted us permission to this + // folder. We don't need access to this file on a regular basis so we do not + // register a security bookmark. + + // check config if relative paths are desired + bool useRelativePath = static_cast( + m_pConfig->getValueString( + ConfigKey("[Library]", "UseRelativePathOnExport")).toInt()); + + // Create list of files of the crate + QList playlist_items; + // Create a new table model since the main one might have an active search. + QScopedPointer pCrateTableModel( + new CrateTableModel(this, m_pTrackCollection)); + pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); + pCrateTableModel->select(); + + if (file_location.endsWith(".csv", Qt::CaseInsensitive)) { + ParserCsv::writeCSVFile(file_location, pCrateTableModel.data(), useRelativePath); + } else if (file_location.endsWith(".txt", Qt::CaseInsensitive)) { + ParserCsv::writeReadableTextFile(file_location, pCrateTableModel.data(), false); + } else{ + // populate a list of files of the crate + QList playlist_items; + int rows = pCrateTableModel->rowCount(); + for (int i = 0; i < rows; ++i) { + QModelIndex index = m_pCrateTableModel->index(i, 0); + playlist_items << m_pCrateTableModel->getTrackLocation(index); + } + + if (file_location.endsWith(".pls", Qt::CaseInsensitive)) { + ParserPls::writePLSFile(file_location, playlist_items, useRelativePath); + } else if (file_location.endsWith(".m3u8", Qt::CaseInsensitive)) { + ParserM3u::writeM3U8File(file_location, playlist_items, useRelativePath); + } else { + //default export to M3U if file extension is missing + if(!file_location.endsWith(".m3u", Qt::CaseInsensitive)) + { + qDebug() << "Crate export: No valid file extension specified. Appending .m3u " + << "and exporting to M3U."; + file_location.append(".m3u"); + } + ParserM3u::writeM3UFile(file_location, playlist_items, useRelativePath); + } + } +} + +void CrateFeature::slotExportTrackFiles() { + // Create a new table model since the main one might have an active search. + QScopedPointer pCrateTableModel( + new CrateTableModel(this, m_pTrackCollection)); + pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); + pCrateTableModel->select(); + + int rows = pCrateTableModel->rowCount(); + QList trackpointers; + for (int i = 0; i < rows; ++i) { + QModelIndex index = m_pCrateTableModel->index(i, 0); + trackpointers.push_back(m_pCrateTableModel->getTrack(index)); + } + + TrackExportWizard trackExport(nullptr, m_pConfig, trackpointers); + trackExport.exportTracks(); +} + +void CrateFeature::slotCrateTableChanged(int crateId) { + //qDebug() << "slotCrateTableChanged() crateId:" << crateId; + clearChildModel(); + m_lastRightClickedIndex = constructChildModel(crateId); +} + +void CrateFeature::slotCrateContentChanged(int crateId) { + //qDebug() << "slotCrateContentChanged()crateId:" << crateId; + updateChildModel(crateId); +} + +void CrateFeature::slotCrateTableRenamed(int a_iCrateId, + QString /* a_strName */) { + activateCrate(a_iCrateId); +} + +void CrateFeature::htmlLinkClicked(const QUrl& link) { + if (QString(link.path())=="create") { + slotCreateCrate(); + } else { + qDebug() << "Unknown crate link clicked" << link; + } +} + +QString CrateFeature::getRootViewHtml() const { + QString cratesTitle = tr("Crates"); + QString cratesSummary = tr("Crates are a great way to help organize the music you want to DJ with."); + QString cratesSummary2 = tr("Make a crate for your next gig, for your favorite electrohouse tracks, or for your most requested songs."); + QString cratesSummary3 = tr("Crates let you organize your music however you'd like!"); + + QString html; + QString createCrateLink = tr("Create New Crate"); + html.append(QString("

%1

").arg(cratesTitle)); + html.append(""); + html.append(QString("
"); + html.append(QString("

%1

").arg(cratesSummary)); + html.append(QString("

%1

").arg(cratesSummary2)); + html.append(QString("

%1

").arg(cratesSummary3)); + html.append("
"); + html.append(""); + html.append("
%1") + .arg(createCrateLink)); + html.append("
"); + return html; +} + +void CrateFeature::slotTrackSelected(TrackPointer pTrack) { + m_pSelectedTrack = pTrack; + TrackId trackId(pTrack.isNull() ? TrackId() : pTrack->getId()); + m_crateDao.getCratesTrackIsIn(trackId, &m_cratesSelectedTrackIsIn); + + TreeItem* rootItem = m_childModel.getItem(QModelIndex()); + if (rootItem == nullptr) { + return; + } + + // Set all crates the track is in bold (or if there is no track selected, + // clear all the bolding). + int row = 0; + for (QList >::const_iterator it = m_crateList.begin(); + it != m_crateList.end(); ++it, ++row) { + TreeItem* crate = rootItem->child(row); + if (crate == nullptr) { + continue; + } + int crateId = it->first; + bool shouldBold = m_cratesSelectedTrackIsIn.contains(crateId); + crate->setBold(shouldBold); + } + + m_childModel.triggerRepaint(); +} + +void CrateFeature::slotResetSelectedTrack() { + slotTrackSelected(TrackPointer()); +} + +QString CrateFeature::getValidCrateName() { + QString name; + bool validNameGiven = false; + + while (!validNameGiven) { + bool ok = false; + name = QInputDialog::getText(nullptr, + tr("Create New Crate"), + tr("Enter name for new crate:"), + QLineEdit::Normal, tr("New Crate"), + &ok).trimmed(); + + if (!ok) { + return QString(); + } + + int existingId = m_crateDao.getCrateIdByName(name); + + if (existingId != -1) { + QMessageBox::warning(nullptr, + tr("Creating Crate Failed"), + tr("A crate by that name already exists.")); + } else if (name.isEmpty()) { + QMessageBox::warning(nullptr, + tr("Creating Crate Failed"), + tr("A crate cannot have a blank name.")); + } else { + validNameGiven = true; + } + } + return name; +} + +QModelIndex CrateFeature::indexFromCrateId(int crateId) { + int row = 0; + for (QList >::const_iterator it = m_crateList.begin(); + it != m_crateList.end(); ++it, ++row) { + int current_id = it->first; + QString crate_name = it->second; + + if (crateId == current_id) { + return m_childModel.index(row, 0); + } + } + return QModelIndex(); +} + +QPointer CrateFeature::getTableModel(int paneId) { + auto it = m_crateTableModel.find(paneId); + if (it == m_crateTableModel.end() || it->isNull()) { + it = m_crateTableModel.insert(paneId, + new CrateTableModel(this, m_pTrackCollection)); + } + return *it; +} + +void CrateFeature::showBrowse(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idBrowse.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idBrowse.end()) { + (*it)->setCurrentIndex(*itId); + } +} + +void CrateFeature::showTable(int paneId) { + auto it = m_panes.find(paneId); + auto itId = m_idTable.find(paneId); + if (it != m_panes.end() && !it->isNull() && itId != m_idTable.end()) { + (*it)->setCurrentIndex(*itId); + } +} diff --git a/src/library/features/crates/cratefeature.h b/src/library/features/crates/cratefeature.h new file mode 100644 index 00000000000..23817f0d7fb --- /dev/null +++ b/src/library/features/crates/cratefeature.h @@ -0,0 +1,124 @@ +#ifndef CRATEFEATURE_H +#define CRATEFEATURE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "library/libraryfeature.h" +#include "library/treeitemmodel.h" +#include "preferences/usersettings.h" +#include "track/track.h" + +class TrackCollection; +class TreeItemModel; +class CrateTableModel; +class CrateDAO; + +class CrateFeature : public LibraryFeature { + Q_OBJECT + public: + CrateFeature(UserSettingsPointer pConfig, + Library* pLibrary, + QObject* parent, + TrackCollection* pTrackCollection); + virtual ~CrateFeature(); + + QVariant title() override; + QString getIconPath() override; + QString getSettingsName() const override; + bool isSinglePane() const override; + + void onSearch(QString&) {} + + bool dragMoveAccept(QUrl url); + bool dropAcceptChild(const QModelIndex& index, QList urls, + QObject* pSource); + bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); + + QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) override; + + TreeItemModel* getChildModel(); + + signals: + void analyzeTracks(QList); + + public slots: + void activate(); + void activateChild(const QModelIndex& index); + void activateCrate(int crateId); + void onRightClick(const QPoint& globalPos); + void onRightClickChild(const QPoint& globalPos, QModelIndex index); + + void slotCreateCrate(); + void slotDeleteCrate(); + void slotRenameCrate(); + void slotDuplicateCrate(); + void slotAutoDjTrackSourceChanged(); + void slotToggleCrateLock(); + void slotImportPlaylist(); + void slotImportPlaylistFile(const QString &playlist_file); + void slotCreateImportCrate(); + void slotExportPlaylist(); + // Copy all of the tracks in a crate to a new directory (like a thumbdrive). + void slotExportTrackFiles(); + void slotAnalyzeCrate(); + void slotCrateTableChanged(int crateId); + void slotCrateContentChanged(int crateId); + void slotCrateTableRenamed(int crateId, QString a_strName); + void htmlLinkClicked(const QUrl& link); + + private slots: + void slotTrackSelected(TrackPointer pTrack); + void slotResetSelectedTrack(); + + private: + QString getValidCrateName(); + QString getRootViewHtml() const; + QModelIndex constructChildModel(int selected_id); + void updateChildModel(int selected_id); + void clearChildModel(); + void buildCrateList(); + int crateIdFromIndex(QModelIndex index); + // Get the QModelIndex of a crate based on its id. Returns QModelIndex() + // on failure. + QModelIndex indexFromCrateId(int crateId); + + QPointer getTableModel(int paneId); + void showBrowse(int paneId); + void showTable(int paneId); + + TrackCollection* m_pTrackCollection; + CrateDAO& m_crateDao; + QAction* m_pCreateCrateAction; + QAction* m_pDeleteCrateAction; + QAction* m_pRenameCrateAction; + QAction* m_pLockCrateAction; + QAction* m_pDuplicateCrateAction; + QAction* m_pAutoDjTrackSource; + QAction* m_pImportPlaylistAction; + QAction* m_pCreateImportPlaylistAction; + QAction* m_pExportPlaylistAction; + QAction* m_pExportTrackFilesAction; + QAction* m_pAnalyzeCrateAction; + QList > m_crateList; + QHash > m_crateTableModel; + CrateTableModel* m_pCrateTableModel; + QModelIndex m_lastRightClickedIndex; + TreeItemModel m_childModel; + TrackPointer m_pSelectedTrack; + QSet m_cratesSelectedTrackIsIn; + QHash > m_panes; + QHash m_idBrowse; + QHash m_idTable; + QHash m_lastClickedIndex; +}; + +#endif /* CRATEFEATURE_H */ diff --git a/src/library/features/crates/cratetablemodel.cpp b/src/library/features/crates/cratetablemodel.cpp new file mode 100644 index 00000000000..a91b726b698 --- /dev/null +++ b/src/library/features/crates/cratetablemodel.cpp @@ -0,0 +1,195 @@ + +// cratetablemodel.cpp +// Created 10/25/2009 by RJ Ryan (rryan@mit.edu) + +#include + +#include "library/features/crates/cratetablemodel.h" +#include "library/queryutil.h" +#include "library/trackcollection.h" +#include "mixer/playermanager.h" + +CrateTableModel::CrateTableModel(QObject* pParent, + TrackCollection* pTrackCollection) + : BaseSqlTableModel(pParent, pTrackCollection, + "mixxx.db.model.crate"), + m_iCrateId(-1), + m_crateDAO(pTrackCollection->getCrateDAO()) { +} + +CrateTableModel::~CrateTableModel() { +} + +void CrateTableModel::setTableModel(int crateId) { + //qDebug() << "CrateTableModel::setCrate()" << crateId; + if (crateId == m_iCrateId) { + qDebug() << "Already focused on crate " << crateId; + return; + } + m_iCrateId = crateId; + + QString tableName = QString("crate_%1").arg(m_iCrateId); + QSqlQuery query(m_database); + FieldEscaper escaper(m_database); + QString filter = "library.mixxx_deleted = 0"; + QStringList columns; + columns << "crate_tracks." + CRATETRACKSTABLE_TRACKID + " AS " + LIBRARYTABLE_ID + << "'' AS " + LIBRARYTABLE_PREVIEW + // For sorting the cover art column we give LIBRARYTABLE_COVERART + // the same value as the cover hash. + << LIBRARYTABLE_COVERART_HASH + " AS " + LIBRARYTABLE_COVERART; + + // We drop files that have been explicitly deleted from mixxx + // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where + // removed files were not removed from crates, so some users will have + // libraries where this is the case. + QString queryString = QString("CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " + "SELECT %2 FROM %3 " + "INNER JOIN library ON library.id = %3.%4 " + "WHERE %3.%5 = %6 AND %7") + .arg(escaper.escapeString(tableName), + columns.join(","), + CRATE_TRACKS_TABLE, + CRATETRACKSTABLE_TRACKID, + CRATETRACKSTABLE_CRATEID, + QString::number(crateId), + filter); + query.prepare(queryString); + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + + columns[0] = LIBRARYTABLE_ID; + columns[1] = LIBRARYTABLE_PREVIEW; + columns[2] = LIBRARYTABLE_COVERART; + setTable(tableName, LIBRARYTABLE_ID, columns, + m_pTrackCollection->getTrackSource()); + setSearch(""); + setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); +} + +bool CrateTableModel::addTrack(const QModelIndex& index, QString location) { + Q_UNUSED(index); + + // This will only succeed if the file actually exist. + QFileInfo fileInfo(location); + if (!fileInfo.exists()) { + qDebug() << "CrateTableModel::addTrack:" + << "File" + << location + << "not found"; + return false; + } + + TrackDAO& trackDao = m_pTrackCollection->getTrackDAO(); + // If a track is dropped but it isn't in the library, then add it because + // the user probably dropped a file from outside Mixxx into this crate. + // If the track is already contained in the library it will not insert + // a duplicate. It also handles unremoving logic if the track has been + // removed from the library recently and re-adds it. + const TrackPointer pTrack(trackDao.addSingleTrack(fileInfo, true)); + if (pTrack.isNull()) { + qDebug() << "CrateTableModel::addTrack:" + << "Failed to add track" + << location + << "to library"; + return false; + } + + const TrackId trackId(pTrack->getId()); + if (m_pTrackCollection->getCrateDAO().addTrackToCrate(trackId, m_iCrateId)) { + // TODO(rryan) just add the track dont select + select(); + return true; + } else { + qDebug() << "CrateTableModel::addTrack:" + << "Failed to add track" + << location + << "to crate" + << m_iCrateId; + return false; + } +} + +int CrateTableModel::addTracks(const QModelIndex& index, + const QList& locations) { + Q_UNUSED(index); + // If a track is dropped but it isn't in the library, then add it because + // the user probably dropped a file from outside Mixxx into this crate. + QList fileInfoList; + foreach(QString fileLocation, locations) { + QFileInfo fileInfo(fileLocation); + if (fileInfo.exists()) { + fileInfoList.append(fileInfo); + } + } + + QList trackIds(m_trackDAO.addMultipleTracks(fileInfoList, true)); + + int tracksAdded = m_crateDAO.addTracksToCrate(m_iCrateId, &trackIds); + if (tracksAdded > 0) { + select(); + } + + if (locations.size() - tracksAdded > 0) { + qDebug() << "CrateTableModel::addTracks could not add" + << locations.size() - tracksAdded + << "to crate" << m_iCrateId; + } + return tracksAdded; +} + +void CrateTableModel::removeTracks(const QModelIndexList& indices) { + bool locked = m_crateDAO.isCrateLocked(m_iCrateId); + + if (!locked) { + QList trackIds; + foreach (QModelIndex index, indices) { + trackIds.append(getTrackId(index)); + } + m_crateDAO.removeTracksFromCrate(trackIds, m_iCrateId); + select(); + } +} + +bool CrateTableModel::isColumnInternal(int column) { + if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ID) || + column == fieldIndex(ColumnCache::COLUMN_CRATETRACKSTABLE_TRACKID) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PLAYED) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_MIXXXDELETED) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID)|| + column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_FSDELETED) || + (PlayerManager::numPreviewDecks() == 0 && + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_LOCATION) || + column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_HASH)) { + return true; + } + return false; +} + +TrackModel::CapabilitiesFlags CrateTableModel::getCapabilities() const { + CapabilitiesFlags caps = TRACKMODELCAPS_NONE + | TRACKMODELCAPS_RECEIVEDROPS + | TRACKMODELCAPS_ADDTOPLAYLIST + | TRACKMODELCAPS_ADDTOCRATE + | TRACKMODELCAPS_ADDTOAUTODJ + | TRACKMODELCAPS_RELOADMETADATA + | TRACKMODELCAPS_LOADTODECK + | TRACKMODELCAPS_LOADTOSAMPLER + | TRACKMODELCAPS_LOADTOPREVIEWDECK + | TRACKMODELCAPS_REMOVE + | TRACKMODELCAPS_MANIPULATEBEATS + | TRACKMODELCAPS_CLEAR_BEATS + | TRACKMODELCAPS_RESETPLAYED; + + bool locked = m_crateDAO.isCrateLocked(m_iCrateId); + if (locked) { + caps |= TRACKMODELCAPS_LOCKED; + } + + return caps; +} diff --git a/src/library/features/crates/cratetablemodel.h b/src/library/features/crates/cratetablemodel.h new file mode 100644 index 00000000000..10a080e9ebc --- /dev/null +++ b/src/library/features/crates/cratetablemodel.h @@ -0,0 +1,34 @@ +// cratetablemodel.h +// Created 10/25/2009 by RJ Ryan (rryan@mit.edu) + +#ifndef CRATETABLEMODEL_H +#define CRATETABLEMODEL_H + +#include "library/basesqltablemodel.h" +#include "library/dao/cratedao.h" + +class CrateTableModel : public BaseSqlTableModel { + Q_OBJECT + public: + CrateTableModel(QObject* parent, TrackCollection* pTrackCollection); + virtual ~CrateTableModel(); + + void setTableModel(int crateId=-1); + int getCrate() const { + return m_iCrateId; + } + + // From TrackModel + bool isColumnInternal(int column); + void removeTracks(const QModelIndexList& indices); + bool addTrack(const QModelIndex &index, QString location); + // Returns the number of unsuccessful track additions + int addTracks(const QModelIndex& index, const QList& locations); + TrackModel::CapabilitiesFlags getCapabilities() const; + + private: + int m_iCrateId; + CrateDAO& m_crateDAO; +}; + +#endif /* CRATETABLEMODEL_H */ diff --git a/src/library/library.cpp b/src/library/library.cpp index c61e10b22ac..b5f7e4b9fb8 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -11,7 +11,7 @@ #include "library/autodj/autodjfeature.h" #include "library/banshee/bansheefeature.h" #include "library/browse/browsefeature.h" -#include "library/cratefeature.h" +#include "library/features/crates/cratefeature.h" #include "library/libraryfoldersfeature.h" #include "library/historyfeature.h" #include "library/itunes/itunesfeature.h" From bf864f99af8ebecd52f2c9d5fff27d83ecc0587e Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 13:00:37 +0200 Subject: [PATCH 475/552] Move iTunes and Recordings feature --- build/depends.py | 8 ++++---- src/library/{ => features}/itunes/itunesfeature.cpp | 4 ++-- src/library/{ => features}/itunes/itunesfeature.h | 0 src/library/{ => features}/recording/dlgrecording.cpp | 4 ++-- src/library/{ => features}/recording/dlgrecording.h | 6 +++--- src/library/{ => features}/recording/dlgrecording.ui | 0 src/library/{ => features}/recording/recordingfeature.cpp | 6 +++--- src/library/{ => features}/recording/recordingfeature.h | 0 src/library/library.cpp | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) rename src/library/{ => features}/itunes/itunesfeature.cpp (99%) rename src/library/{ => features}/itunes/itunesfeature.h (100%) rename src/library/{ => features}/recording/dlgrecording.cpp (98%) rename src/library/{ => features}/recording/dlgrecording.h (95%) rename src/library/{ => features}/recording/dlgrecording.ui (100%) rename src/library/{ => features}/recording/recordingfeature.cpp (96%) rename src/library/{ => features}/recording/recordingfeature.h (100%) diff --git a/build/depends.py b/build/depends.py index 72a3c891114..f461efb3225 100644 --- a/build/depends.py +++ b/build/depends.py @@ -900,8 +900,6 @@ def sources(self, build): "library/export/trackexportwizard.cpp", "library/export/trackexportworker.cpp", - "library/recording/recordingfeature.cpp", - "library/recording/dlgrecording.cpp", "recording/recordingmanager.cpp", "engine/sidechain/enginerecord.cpp", @@ -915,11 +913,13 @@ def sources(self, build): "library/banshee/bansheeplaylistmodel.cpp", "library/banshee/bansheedbconnection.cpp", - "library/itunes/itunesfeature.cpp", "library/traktor/traktorfeature.cpp", "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", + "library/features/itunes/itunesfeature.cpp", + "library/features/recording/recordingfeature.cpp", + "library/features/recording/dlgrecording.cpp", "library/sidebarmodel.cpp", "library/library.cpp", @@ -1125,7 +1125,7 @@ def sources(self, build): 'library/dlgtagfetcher.ui', 'library/dlgtrackinfo.ui', 'library/export/dlgtrackexport.ui', - 'library/recording/dlgrecording.ui', + 'library/features/recording/dlgrecording.ui', 'preferences/dialog/dlgprefautodjdlg.ui', 'preferences/dialog/dlgprefbeatsdlg.ui', 'preferences/dialog/dlgprefcontrolsdlg.ui', diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/features/itunes/itunesfeature.cpp similarity index 99% rename from src/library/itunes/itunesfeature.cpp rename to src/library/features/itunes/itunesfeature.cpp index c63f6bc08e5..48d6ab0c5ae 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/features/itunes/itunesfeature.cpp @@ -8,7 +8,7 @@ #include #include -#include "library/itunes/itunesfeature.h" +#include "library/features/itunes/itunesfeature.h" #include "library/basetrackcache.h" #include "library/dao/settingsdao.h" @@ -190,7 +190,7 @@ void ITunesFeature::activateChild(const QModelIndex& index) { QString playlist = index.data().toString(); qDebug() << "Activating " << playlist; m_pITunesPlaylistModel->setPlaylist(playlist); - + showTrackModel(m_pITunesPlaylistModel); showBreadCrumb(index); } diff --git a/src/library/itunes/itunesfeature.h b/src/library/features/itunes/itunesfeature.h similarity index 100% rename from src/library/itunes/itunesfeature.h rename to src/library/features/itunes/itunesfeature.h diff --git a/src/library/recording/dlgrecording.cpp b/src/library/features/recording/dlgrecording.cpp similarity index 98% rename from src/library/recording/dlgrecording.cpp rename to src/library/features/recording/dlgrecording.cpp index 77c22d42d94..f6212efe904 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/features/recording/dlgrecording.cpp @@ -1,7 +1,7 @@ #include #include "control/controlobject.h" -#include "library/recording/dlgrecording.h" +#include "library/features/recording/dlgrecording.h" #include "library/trackcollection.h" #include "widget/wwidget.h" #include "widget/wskincolor.h" @@ -44,7 +44,7 @@ void DlgRecording::onShow() { void DlgRecording::setProxyTrackModel(ProxyTrackModel* pProxyModel) { m_pProxyModel = pProxyModel; - + m_pProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); } diff --git a/src/library/recording/dlgrecording.h b/src/library/features/recording/dlgrecording.h similarity index 95% rename from src/library/recording/dlgrecording.h rename to src/library/features/recording/dlgrecording.h index cd9c1c05d78..8ef90f9ad1f 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/features/recording/dlgrecording.h @@ -10,7 +10,7 @@ #include "controllers/keyboard/keyboardeventfilter.h" #include "recording/recordingmanager.h" #include "track/track.h" -#include "library/recording/ui_dlgrecording.h" +#include "library/features/recording/ui_dlgrecording.h" class PlaylistTableModel; class QSqlTableModel; @@ -33,10 +33,10 @@ class DlgRecording : public QFrame, public Ui::DlgRecording { void slotBytesRecorded(long); void refreshBrowseModel(); void slotDurationRecorded(QString durationRecorded); - + private: void refreshLabel(); - + TrackCollection* m_pTrackCollection; BrowseTableModel* m_pBrowseModel; ProxyTrackModel* m_pProxyModel; diff --git a/src/library/recording/dlgrecording.ui b/src/library/features/recording/dlgrecording.ui similarity index 100% rename from src/library/recording/dlgrecording.ui rename to src/library/features/recording/dlgrecording.ui diff --git a/src/library/recording/recordingfeature.cpp b/src/library/features/recording/recordingfeature.cpp similarity index 96% rename from src/library/recording/recordingfeature.cpp rename to src/library/features/recording/recordingfeature.cpp index d328dc1267a..bbba89e9aac 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/features/recording/recordingfeature.cpp @@ -2,11 +2,11 @@ // Created 03/26/2010 by Tobias Rafreider #include "controllers/keyboard/keyboardeventfilter.h" -#include "library/recording/dlgrecording.h" -#include "track/track.h" -#include "library/recording/recordingfeature.h" +#include "library/features/recording/dlgrecording.h" +#include "library/features/recording/recordingfeature.h" #include "library/library.h" #include "library/trackcollection.h" +#include "track/track.h" #include "widget/wlibrary.h" #include "widget/wtracktableview.h" diff --git a/src/library/recording/recordingfeature.h b/src/library/features/recording/recordingfeature.h similarity index 100% rename from src/library/recording/recordingfeature.h rename to src/library/features/recording/recordingfeature.h diff --git a/src/library/library.cpp b/src/library/library.cpp index b5f7e4b9fb8..8c4ea70ffc8 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -12,9 +12,10 @@ #include "library/banshee/bansheefeature.h" #include "library/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" +#include "library/features/itunes/itunesfeature.h" +#include "library/features/recording/recordingfeature.h" #include "library/libraryfoldersfeature.h" #include "library/historyfeature.h" -#include "library/itunes/itunesfeature.h" #include "library/librarycontrol.h" #include "library/libraryfeature.h" #include "library/library.h" @@ -25,7 +26,6 @@ #include "library/maintenancefeature.h" #include "library/mixxxlibraryfeature.h" #include "library/playlistfeature.h" -#include "library/recording/recordingfeature.h" #include "library/rhythmbox/rhythmboxfeature.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" From 7f56f70e1defcb78ca9bc8164078c0510e4d6379 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 13:09:35 +0200 Subject: [PATCH 476/552] Move Traktor and RhythmBox Features --- build/depends.py | 5 ++--- src/library/{ => features}/rhythmbox/rhythmboxfeature.cpp | 3 +-- src/library/{ => features}/rhythmbox/rhythmboxfeature.h | 0 src/library/{ => features}/traktor/traktorfeature.cpp | 4 +--- src/library/{ => features}/traktor/traktorfeature.h | 0 src/library/library.cpp | 4 ++-- 6 files changed, 6 insertions(+), 10 deletions(-) rename src/library/{ => features}/rhythmbox/rhythmboxfeature.cpp (99%) rename src/library/{ => features}/rhythmbox/rhythmboxfeature.h (100%) rename src/library/{ => features}/traktor/traktorfeature.cpp (99%) rename src/library/{ => features}/traktor/traktorfeature.h (100%) diff --git a/build/depends.py b/build/depends.py index f461efb3225..28209cff743 100644 --- a/build/depends.py +++ b/build/depends.py @@ -907,19 +907,18 @@ def sources(self, build): "library/baseexternallibraryfeature.cpp", "library/baseexternaltrackmodel.cpp", "library/baseexternalplaylistmodel.cpp", - "library/rhythmbox/rhythmboxfeature.cpp", "library/banshee/bansheefeature.cpp", "library/banshee/bansheeplaylistmodel.cpp", "library/banshee/bansheedbconnection.cpp", - "library/traktor/traktorfeature.cpp", - "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", "library/features/itunes/itunesfeature.cpp", "library/features/recording/recordingfeature.cpp", "library/features/recording/dlgrecording.cpp", + "library/features/rhythmbox/rhythmboxfeature.cpp", + "library/features/traktor/traktorfeature.cpp", "library/sidebarmodel.cpp", "library/library.cpp", diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/features/rhythmbox/rhythmboxfeature.cpp similarity index 99% rename from src/library/rhythmbox/rhythmboxfeature.cpp rename to src/library/features/rhythmbox/rhythmboxfeature.cpp index 659e6acef94..2b70ca5dd24 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/features/rhythmbox/rhythmboxfeature.cpp @@ -3,11 +3,10 @@ #include #include -#include "library/rhythmbox/rhythmboxfeature.h" +#include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/baseexternaltrackmodel.h" #include "library/baseexternalplaylistmodel.h" -#include "library/library.h" #include "library/queryutil.h" RhythmboxFeature::RhythmboxFeature(UserSettingsPointer pConfig, diff --git a/src/library/rhythmbox/rhythmboxfeature.h b/src/library/features/rhythmbox/rhythmboxfeature.h similarity index 100% rename from src/library/rhythmbox/rhythmboxfeature.h rename to src/library/features/rhythmbox/rhythmboxfeature.h diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/features/traktor/traktorfeature.cpp similarity index 99% rename from src/library/traktor/traktorfeature.cpp rename to src/library/features/traktor/traktorfeature.cpp index 5facf950922..79fd444feec 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/features/traktor/traktorfeature.cpp @@ -8,11 +8,9 @@ #include #include -#include "library/traktor/traktorfeature.h" +#include "library/features/traktor/traktorfeature.h" -#include "library/library.h" #include "library/librarytablemodel.h" -#include "library/missingtablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" #include "util/sandbox.h" diff --git a/src/library/traktor/traktorfeature.h b/src/library/features/traktor/traktorfeature.h similarity index 100% rename from src/library/traktor/traktorfeature.h rename to src/library/features/traktor/traktorfeature.h diff --git a/src/library/library.cpp b/src/library/library.cpp index 8c4ea70ffc8..d4fe9b8272b 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -14,6 +14,8 @@ #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" #include "library/features/recording/recordingfeature.h" +#include "library/features/rhythmbox/rhythmboxfeature.h" +#include "library/features/traktor/traktorfeature.h" #include "library/libraryfoldersfeature.h" #include "library/historyfeature.h" #include "library/librarycontrol.h" @@ -26,11 +28,9 @@ #include "library/maintenancefeature.h" #include "library/mixxxlibraryfeature.h" #include "library/playlistfeature.h" -#include "library/rhythmbox/rhythmboxfeature.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" -#include "library/traktor/traktorfeature.h" #include "mixer/playermanager.h" #include "util/assert.h" #include "util/sandbox.h" From 163032c5fd4d6b1c66d52e665d637ce4bc93a4f5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 13:31:56 +0200 Subject: [PATCH 477/552] Move BaseExternalFeature --- build/depends.py | 17 +++++++++-------- src/library/banshee/bansheefeature.cpp | 2 +- src/library/banshee/bansheefeature.h | 2 +- .../{ => features/analysis}/analysisfeature.cpp | 5 ++--- .../{ => features/analysis}/analysisfeature.h | 2 +- .../analysis}/analysislibrarytablemodel.cpp | 2 +- .../analysis}/analysislibrarytablemodel.h | 2 +- .../{ => features/analysis}/dlganalysis.cpp | 4 ++-- .../{ => features/analysis}/dlganalysis.h | 6 +++--- .../{ => features/analysis}/dlganalysis.ui | 0 .../baseexternallibraryfeature.cpp | 4 ++-- .../baseexternallibraryfeature.h | 0 .../baseexternalplaylistmodel.cpp | 2 +- .../baseexternalplaylistmodel.h | 0 .../baseexternaltrackmodel.cpp | 2 +- .../baseexternaltrackmodel.h | 0 src/library/features/itunes/itunesfeature.cpp | 4 ++-- src/library/features/itunes/itunesfeature.h | 2 +- .../features/rhythmbox/rhythmboxfeature.cpp | 4 ++-- .../features/rhythmbox/rhythmboxfeature.h | 2 +- src/library/features/traktor/traktorfeature.h | 6 +++--- src/library/library.cpp | 2 +- 22 files changed, 35 insertions(+), 35 deletions(-) rename src/library/{ => features/analysis}/analysisfeature.cpp (98%) rename src/library/{ => features/analysis}/analysisfeature.h (97%) rename src/library/{ => features/analysis}/analysislibrarytablemodel.cpp (92%) rename src/library/{ => features/analysis}/analysislibrarytablemodel.h (91%) rename src/library/{ => features/analysis}/dlganalysis.cpp (97%) rename src/library/{ => features/analysis}/dlganalysis.h (92%) rename src/library/{ => features/analysis}/dlganalysis.ui (100%) rename src/library/{ => features/baseexternalfeature}/baseexternallibraryfeature.cpp (98%) rename src/library/{ => features/baseexternalfeature}/baseexternallibraryfeature.h (100%) rename src/library/{ => features/baseexternalfeature}/baseexternalplaylistmodel.cpp (98%) rename src/library/{ => features/baseexternalfeature}/baseexternalplaylistmodel.h (100%) rename src/library/{ => features/baseexternalfeature}/baseexternaltrackmodel.cpp (98%) rename src/library/{ => features/baseexternalfeature}/baseexternaltrackmodel.h (100%) diff --git a/build/depends.py b/build/depends.py index 28209cff743..9f7d15ae2d6 100644 --- a/build/depends.py +++ b/build/depends.py @@ -859,7 +859,6 @@ def sources(self, build): "library/librarytablemodel.cpp", "library/searchquery.cpp", "library/searchqueryparser.cpp", - "library/analysislibrarytablemodel.cpp", "library/missingtablemodel.cpp", "library/hiddentablemodel.cpp", "library/proxytrackmodel.cpp", @@ -869,7 +868,6 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", - "library/analysisfeature.cpp", "library/autodj/autodjfeature.cpp", "library/autodj/autodjprocessor.cpp", "library/dao/directorydao.cpp", @@ -880,7 +878,6 @@ def sources(self, build): "library/playlistfeature.cpp", "library/historyfeature.cpp", "library/autodj/dlgautodj.cpp", - "library/dlganalysis.cpp", "library/dlgcoverartfullsize.cpp", "library/dlghidden.cpp", "library/dlgmissing.cpp", @@ -903,17 +900,21 @@ def sources(self, build): "recording/recordingmanager.cpp", "engine/sidechain/enginerecord.cpp", - # External Library Features - "library/baseexternallibraryfeature.cpp", - "library/baseexternaltrackmodel.cpp", - "library/baseexternalplaylistmodel.cpp", "library/banshee/bansheefeature.cpp", "library/banshee/bansheeplaylistmodel.cpp", "library/banshee/bansheedbconnection.cpp", + "library/features/analysis/analysisfeature.cpp", + "library/features/analysis/analysislibrarytablemodel.cpp", + "library/features/analysis/dlganalysis.cpp", "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", + + # External Library Features + "library/features/baseexternalfeature/baseexternallibraryfeature.cpp", + "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", + "library/features/baseexternalfeature/baseexternalplaylistmodel.cpp", "library/features/itunes/itunesfeature.cpp", "library/features/recording/recordingfeature.cpp", "library/features/recording/dlgrecording.cpp", @@ -1117,13 +1118,13 @@ def sources(self, build): 'dialog/dlgaboutdlg.ui', 'dialog/dlgdevelopertoolsdlg.ui', 'library/autodj/dlgautodj.ui', - 'library/dlganalysis.ui', 'library/dlgcoverartfullsize.ui', 'library/dlghidden.ui', 'library/dlgmissing.ui', 'library/dlgtagfetcher.ui', 'library/dlgtrackinfo.ui', 'library/export/dlgtrackexport.ui', + 'library/features/analysis/dlganalysis.ui', 'library/features/recording/dlgrecording.ui', 'preferences/dialog/dlgprefautodjdlg.ui', 'preferences/dialog/dlgprefbeatsdlg.ui', diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index a789bda9326..4131bdefa2b 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -6,7 +6,7 @@ #include "library/banshee/bansheedbconnection.h" #include "library/dao/settingsdao.h" -#include "library/baseexternalplaylistmodel.h" +#include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" #include "library/banshee/bansheeplaylistmodel.h" #include "library/library.h" diff --git a/src/library/banshee/bansheefeature.h b/src/library/banshee/bansheefeature.h index a9bd24e9fe3..d74e6966acf 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/banshee/bansheefeature.h @@ -8,7 +8,7 @@ #include #include -#include "library/baseexternallibraryfeature.h" +#include "library/features/baseexternalfeature/baseexternallibraryfeature.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" #include "library/banshee/bansheedbconnection.h" diff --git a/src/library/analysisfeature.cpp b/src/library/features/analysis/analysisfeature.cpp similarity index 98% rename from src/library/analysisfeature.cpp rename to src/library/features/analysis/analysisfeature.cpp index 9b0cfe4b86b..4234c7efcd2 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/features/analysis/analysisfeature.cpp @@ -6,9 +6,8 @@ #include "analyzer/analyzerqueue.h" #include "controllers/keyboard/keyboardeventfilter.h" -#include "library/analysisfeature.h" -#include "library/dlganalysis.h" -#include "library/library.h" +#include "library/features/analysis/analysisfeature.h" +#include "library/features/analysis/dlganalysis.h" #include "library/librarytablemodel.h" #include "library/trackcollection.h" #include "sources/soundsourceproxy.h" diff --git a/src/library/analysisfeature.h b/src/library/features/analysis/analysisfeature.h similarity index 97% rename from src/library/analysisfeature.h rename to src/library/features/analysis/analysisfeature.h index 6ec1dd25d38..c97bf30f9ef 100644 --- a/src/library/analysisfeature.h +++ b/src/library/features/analysis/analysisfeature.h @@ -13,7 +13,7 @@ #include #include "library/libraryfeature.h" -#include "library/dlganalysis.h" +#include "library/features/analysis/dlganalysis.h" #include "library/treeitemmodel.h" #include "preferences/usersettings.h" diff --git a/src/library/analysislibrarytablemodel.cpp b/src/library/features/analysis/analysislibrarytablemodel.cpp similarity index 92% rename from src/library/analysislibrarytablemodel.cpp rename to src/library/features/analysis/analysislibrarytablemodel.cpp index 1c0bb7bcd46..fb5fb598712 100644 --- a/src/library/analysislibrarytablemodel.cpp +++ b/src/library/features/analysis/analysislibrarytablemodel.cpp @@ -1,6 +1,6 @@ #include -#include "analysislibrarytablemodel.h" +#include "library/features/analysis/analysislibrarytablemodel.h" #include "library/trackcollection.h" const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')"; diff --git a/src/library/analysislibrarytablemodel.h b/src/library/features/analysis/analysislibrarytablemodel.h similarity index 91% rename from src/library/analysislibrarytablemodel.h rename to src/library/features/analysis/analysislibrarytablemodel.h index a3bfe38a6ea..fe5a72bb777 100644 --- a/src/library/analysislibrarytablemodel.h +++ b/src/library/features/analysis/analysislibrarytablemodel.h @@ -2,7 +2,7 @@ #define ANALYSISLIBRARYTABLEMODEL_H_ #include -#include "librarytablemodel.h" +#include "library/librarytablemodel.h" class AnalysisLibraryTableModel : public LibraryTableModel { diff --git a/src/library/dlganalysis.cpp b/src/library/features/analysis/dlganalysis.cpp similarity index 97% rename from src/library/dlganalysis.cpp rename to src/library/features/analysis/dlganalysis.cpp index cc2fe5ff18a..de0caca9c78 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/features/analysis/dlganalysis.cpp @@ -1,7 +1,7 @@ #include -#include "library/analysisfeature.h" -#include "library/dlganalysis.h" +#include "library/features/analysis/analysisfeature.h" +#include "library/features/analysis/dlganalysis.h" #include "library/trackcollection.h" #include "util/assert.h" #include "widget/wanalysislibrarytableview.h" diff --git a/src/library/dlganalysis.h b/src/library/features/analysis/dlganalysis.h similarity index 92% rename from src/library/dlganalysis.h rename to src/library/features/analysis/dlganalysis.h index 9a83b0491ef..4a338b3ddb3 100644 --- a/src/library/dlganalysis.h +++ b/src/library/features/analysis/dlganalysis.h @@ -4,11 +4,11 @@ #include #include -#include "preferences/usersettings.h" -#include "library/analysislibrarytablemodel.h" +#include "library/features/analysis/analysislibrarytablemodel.h" +#include "library/features/analysis/ui_dlganalysis.h" #include "library/libraryview.h" #include "library/trackcollection.h" -#include "library/ui_dlganalysis.h" +#include "preferences/usersettings.h" class AnalysisLibraryTableModel; class WAnalysisLibraryTableView; diff --git a/src/library/dlganalysis.ui b/src/library/features/analysis/dlganalysis.ui similarity index 100% rename from src/library/dlganalysis.ui rename to src/library/features/analysis/dlganalysis.ui diff --git a/src/library/baseexternallibraryfeature.cpp b/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp similarity index 98% rename from src/library/baseexternallibraryfeature.cpp rename to src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp index 450a9277689..1f59e0a059e 100644 --- a/src/library/baseexternallibraryfeature.cpp +++ b/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp @@ -1,7 +1,7 @@ -#include "library/baseexternallibraryfeature.h" - #include +#include "library/features/baseexternalfeature/baseexternallibraryfeature.h" + #include "library/basesqltablemodel.h" BaseExternalLibraryFeature::BaseExternalLibraryFeature(UserSettingsPointer pConfig, diff --git a/src/library/baseexternallibraryfeature.h b/src/library/features/baseexternalfeature/baseexternallibraryfeature.h similarity index 100% rename from src/library/baseexternallibraryfeature.h rename to src/library/features/baseexternalfeature/baseexternallibraryfeature.h diff --git a/src/library/baseexternalplaylistmodel.cpp b/src/library/features/baseexternalfeature/baseexternalplaylistmodel.cpp similarity index 98% rename from src/library/baseexternalplaylistmodel.cpp rename to src/library/features/baseexternalfeature/baseexternalplaylistmodel.cpp index c1ae1253488..66d1f441e56 100644 --- a/src/library/baseexternalplaylistmodel.cpp +++ b/src/library/features/baseexternalfeature/baseexternalplaylistmodel.cpp @@ -1,4 +1,4 @@ -#include "library/baseexternalplaylistmodel.h" +#include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" #include "library/queryutil.h" #include "mixer/playermanager.h" diff --git a/src/library/baseexternalplaylistmodel.h b/src/library/features/baseexternalfeature/baseexternalplaylistmodel.h similarity index 100% rename from src/library/baseexternalplaylistmodel.h rename to src/library/features/baseexternalfeature/baseexternalplaylistmodel.h diff --git a/src/library/baseexternaltrackmodel.cpp b/src/library/features/baseexternalfeature/baseexternaltrackmodel.cpp similarity index 98% rename from src/library/baseexternaltrackmodel.cpp rename to src/library/features/baseexternalfeature/baseexternaltrackmodel.cpp index 22aa56528cd..9589656dd1e 100644 --- a/src/library/baseexternaltrackmodel.cpp +++ b/src/library/features/baseexternalfeature/baseexternaltrackmodel.cpp @@ -1,4 +1,4 @@ -#include "library/baseexternaltrackmodel.h" +#include "library/features/baseexternalfeature/baseexternaltrackmodel.h" #include "library/trackcollection.h" #include "library/queryutil.h" #include "mixer/playermanager.h" diff --git a/src/library/baseexternaltrackmodel.h b/src/library/features/baseexternalfeature/baseexternaltrackmodel.h similarity index 100% rename from src/library/baseexternaltrackmodel.h rename to src/library/features/baseexternalfeature/baseexternaltrackmodel.h diff --git a/src/library/features/itunes/itunesfeature.cpp b/src/library/features/itunes/itunesfeature.cpp index 48d6ab0c5ae..a8060588e6f 100644 --- a/src/library/features/itunes/itunesfeature.cpp +++ b/src/library/features/itunes/itunesfeature.cpp @@ -12,8 +12,8 @@ #include "library/basetrackcache.h" #include "library/dao/settingsdao.h" -#include "library/baseexternaltrackmodel.h" -#include "library/baseexternalplaylistmodel.h" +#include "library/features/baseexternalfeature/baseexternaltrackmodel.h" +#include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" #include "library/library.h" #include "library/queryutil.h" #include "util/lcs.h" diff --git a/src/library/features/itunes/itunesfeature.h b/src/library/features/itunes/itunesfeature.h index 320e476e372..83ff9ff1666 100644 --- a/src/library/features/itunes/itunesfeature.h +++ b/src/library/features/itunes/itunesfeature.h @@ -10,7 +10,7 @@ #include #include -#include "library/baseexternallibraryfeature.h" +#include "library/features/baseexternalfeature/baseexternallibraryfeature.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" diff --git a/src/library/features/rhythmbox/rhythmboxfeature.cpp b/src/library/features/rhythmbox/rhythmboxfeature.cpp index 2b70ca5dd24..396607d1a32 100644 --- a/src/library/features/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/features/rhythmbox/rhythmboxfeature.cpp @@ -5,8 +5,8 @@ #include "library/features/rhythmbox/rhythmboxfeature.h" -#include "library/baseexternaltrackmodel.h" -#include "library/baseexternalplaylistmodel.h" +#include "library/features/baseexternalfeature/baseexternaltrackmodel.h" +#include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" #include "library/queryutil.h" RhythmboxFeature::RhythmboxFeature(UserSettingsPointer pConfig, diff --git a/src/library/features/rhythmbox/rhythmboxfeature.h b/src/library/features/rhythmbox/rhythmboxfeature.h index c7a638c9e5b..a5ed60b4873 100644 --- a/src/library/features/rhythmbox/rhythmboxfeature.h +++ b/src/library/features/rhythmbox/rhythmboxfeature.h @@ -11,7 +11,7 @@ #include #include -#include "library/baseexternallibraryfeature.h" +#include "library/features/baseexternalfeature/baseexternallibraryfeature.h" #include "library/treeitemmodel.h" #include "library/trackcollection.h" diff --git a/src/library/features/traktor/traktorfeature.h b/src/library/features/traktor/traktorfeature.h index 9f5475c87a3..0def70d0b23 100644 --- a/src/library/features/traktor/traktorfeature.h +++ b/src/library/features/traktor/traktorfeature.h @@ -11,9 +11,9 @@ #include #include -#include "library/baseexternallibraryfeature.h" -#include "library/baseexternaltrackmodel.h" -#include "library/baseexternalplaylistmodel.h" +#include "library/features/baseexternalfeature/baseexternallibraryfeature.h" +#include "library/features/baseexternalfeature/baseexternaltrackmodel.h" +#include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" #include "library/treeitemmodel.h" class TrackCollection; diff --git a/src/library/library.cpp b/src/library/library.cpp index d4fe9b8272b..1b353b6a63d 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -7,10 +7,10 @@ #include #include -#include "library/analysisfeature.h" #include "library/autodj/autodjfeature.h" #include "library/banshee/bansheefeature.h" #include "library/browse/browsefeature.h" +#include "library/features/analysis/analysisfeature.h" #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" #include "library/features/recording/recordingfeature.h" From a271def52fe3b3f61935a6b8d063d85fe8a8e9b0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 13:44:34 +0200 Subject: [PATCH 478/552] Move Browse Feature --- build/depends.py | 12 +++++++----- src/library/{ => features}/browse/browsefeature.cpp | 3 +-- src/library/{ => features}/browse/browsefeature.h | 4 ++-- .../{ => features}/browse/browsetablemodel.cpp | 4 ++-- src/library/{ => features}/browse/browsetablemodel.h | 2 +- src/library/{ => features}/browse/browsethread.cpp | 2 +- src/library/{ => features}/browse/browsethread.h | 0 .../{ => features}/browse/foldertreemodel.cpp | 4 ++-- src/library/{ => features}/browse/foldertreemodel.h | 0 src/library/features/recording/dlgrecording.h | 2 +- src/library/features/recording/recordingfeature.h | 4 ++-- src/library/library.cpp | 2 +- src/library/sidebarmodel.cpp | 2 +- 13 files changed, 21 insertions(+), 20 deletions(-) rename src/library/{ => features}/browse/browsefeature.cpp (99%) rename src/library/{ => features}/browse/browsefeature.h (95%) rename src/library/{ => features}/browse/browsetablemodel.cpp (99%) rename src/library/{ => features}/browse/browsetablemodel.h (98%) rename src/library/{ => features}/browse/browsethread.cpp (99%) rename src/library/{ => features}/browse/browsethread.h (100%) rename src/library/{ => features}/browse/foldertreemodel.cpp (97%) rename src/library/{ => features}/browse/foldertreemodel.h (100%) diff --git a/build/depends.py b/build/depends.py index 9f7d15ae2d6..72d5c985ed0 100644 --- a/build/depends.py +++ b/build/depends.py @@ -888,11 +888,6 @@ def sources(self, build): "library/libraryfoldermodel.cpp", "library/dao/savedqueriesdao.cpp", - "library/browse/browsetablemodel.cpp", - "library/browse/browsethread.cpp", - "library/browse/browsefeature.cpp", - "library/browse/foldertreemodel.cpp", - "library/export/trackexportdlg.cpp", "library/export/trackexportwizard.cpp", "library/export/trackexportworker.cpp", @@ -905,9 +900,16 @@ def sources(self, build): "library/banshee/bansheeplaylistmodel.cpp", "library/banshee/bansheedbconnection.cpp", + # Library Features "library/features/analysis/analysisfeature.cpp", "library/features/analysis/analysislibrarytablemodel.cpp", "library/features/analysis/dlganalysis.cpp", + + "library/features/browse/browsetablemodel.cpp", + "library/features/browse/browsethread.cpp", + "library/features/browse/browsefeature.cpp", + "library/features/browse/foldertreemodel.cpp", + "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", diff --git a/src/library/browse/browsefeature.cpp b/src/library/features/browse/browsefeature.cpp similarity index 99% rename from src/library/browse/browsefeature.cpp rename to src/library/features/browse/browsefeature.cpp index 74d324683b9..d8029ba4f3a 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/features/browse/browsefeature.cpp @@ -10,8 +10,7 @@ #include #include "controllers/keyboard/keyboardeventfilter.h" -#include "library/browse/browsefeature.h" -#include "library/library.h" +#include "library/features/browse/browsefeature.h" #include "library/trackcollection.h" #include "util/sandbox.h" #include "widget/wlibrary.h" diff --git a/src/library/browse/browsefeature.h b/src/library/features/browse/browsefeature.h similarity index 95% rename from src/library/browse/browsefeature.h rename to src/library/features/browse/browsefeature.h index d2d26e0b6e2..d839b43174b 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/features/browse/browsefeature.h @@ -15,8 +15,8 @@ #include #include "preferences/usersettings.h" -#include "library/browse/browsetablemodel.h" -#include "library/browse/foldertreemodel.h" +#include "library/features/browse/browsetablemodel.h" +#include "library/features/browse/foldertreemodel.h" #include "library/libraryfeature.h" #include "library/proxytrackmodel.h" diff --git a/src/library/browse/browsetablemodel.cpp b/src/library/features/browse/browsetablemodel.cpp similarity index 99% rename from src/library/browse/browsetablemodel.cpp rename to src/library/features/browse/browsetablemodel.cpp index 93f3ae3ff6f..11b250dcee7 100644 --- a/src/library/browse/browsetablemodel.cpp +++ b/src/library/features/browse/browsetablemodel.cpp @@ -5,8 +5,8 @@ #include #include -#include "library/browse/browsetablemodel.h" -#include "library/browse/browsethread.h" +#include "library/features/browse/browsetablemodel.h" +#include "library/features/browse/browsethread.h" #include "library/previewbuttondelegate.h" #include "mixer/playerinfo.h" #include "control/controlobject.h" diff --git a/src/library/browse/browsetablemodel.h b/src/library/features/browse/browsetablemodel.h similarity index 98% rename from src/library/browse/browsetablemodel.h rename to src/library/features/browse/browsetablemodel.h index e31135c0ded..fd1ce20d52b 100644 --- a/src/library/browse/browsetablemodel.h +++ b/src/library/features/browse/browsetablemodel.h @@ -8,7 +8,7 @@ #include "library/trackcollection.h" #include "recording/recordingmanager.h" #include "util/file.h" -#include "library/browse/browsethread.h" +#include "library/features/browse/browsethread.h" //constants const int COLUMN_PREVIEW = 0; diff --git a/src/library/browse/browsethread.cpp b/src/library/features/browse/browsethread.cpp similarity index 99% rename from src/library/browse/browsethread.cpp rename to src/library/features/browse/browsethread.cpp index 56afcc24a0f..605742bf516 100644 --- a/src/library/browse/browsethread.cpp +++ b/src/library/features/browse/browsethread.cpp @@ -7,7 +7,7 @@ #include #include -#include "library/browse/browsetablemodel.h" +#include "library/features/browse/browsetablemodel.h" #include "sources/soundsourceproxy.h" #include "track/trackmetadata.h" #include "util/trace.h" diff --git a/src/library/browse/browsethread.h b/src/library/features/browse/browsethread.h similarity index 100% rename from src/library/browse/browsethread.h rename to src/library/features/browse/browsethread.h diff --git a/src/library/browse/foldertreemodel.cpp b/src/library/features/browse/foldertreemodel.cpp similarity index 97% rename from src/library/browse/foldertreemodel.cpp rename to src/library/features/browse/foldertreemodel.cpp index 0dfdc3b74e1..49b6a9c23e7 100644 --- a/src/library/browse/foldertreemodel.cpp +++ b/src/library/features/browse/foldertreemodel.cpp @@ -12,8 +12,8 @@ #include -#include "library/browse/foldertreemodel.h" -#include "library/browse/browsefeature.h" +#include "library/features/browse/foldertreemodel.h" +#include "library/features/browse/browsefeature.h" #include "util/file.h" FolderTreeModel::FolderTreeModel(QObject *parent) diff --git a/src/library/browse/foldertreemodel.h b/src/library/features/browse/foldertreemodel.h similarity index 100% rename from src/library/browse/foldertreemodel.h rename to src/library/features/browse/foldertreemodel.h diff --git a/src/library/features/recording/dlgrecording.h b/src/library/features/recording/dlgrecording.h index 8ef90f9ad1f..d7dc69e0ca2 100644 --- a/src/library/features/recording/dlgrecording.h +++ b/src/library/features/recording/dlgrecording.h @@ -2,7 +2,7 @@ #define DLGRECORDING_H #include "preferences/usersettings.h" -#include "library/browse/browsetablemodel.h" +#include "library/features/browse/browsetablemodel.h" #include "library/libraryview.h" #include "library/proxytrackmodel.h" #include "library/library.h" diff --git a/src/library/features/recording/recordingfeature.h b/src/library/features/recording/recordingfeature.h index de1a32c96bf..d83b80cae3c 100644 --- a/src/library/features/recording/recordingfeature.h +++ b/src/library/features/recording/recordingfeature.h @@ -8,8 +8,8 @@ #include #include "preferences/usersettings.h" -#include "library/browse/browsetablemodel.h" -#include "library/browse/foldertreemodel.h" +#include "library/features/browse/browsetablemodel.h" +#include "library/features/browse/foldertreemodel.h" #include "library/libraryfeature.h" #include "library/proxytrackmodel.h" #include "recording/recordingmanager.h" diff --git a/src/library/library.cpp b/src/library/library.cpp index 1b353b6a63d..debf01bfff1 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -9,8 +9,8 @@ #include "library/autodj/autodjfeature.h" #include "library/banshee/bansheefeature.h" -#include "library/browse/browsefeature.h" #include "library/features/analysis/analysisfeature.h" +#include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" #include "library/features/recording/recordingfeature.h" diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp index 90dca35267c..5204cf1a854 100644 --- a/src/library/sidebarmodel.cpp +++ b/src/library/sidebarmodel.cpp @@ -5,7 +5,7 @@ #include "library/libraryfeature.h" #include "library/sidebarmodel.h" #include "library/treeitem.h" -#include "library/browse/browsefeature.h" +#include "library/features/browse/browsefeature.h" #include "util/assert.h" SidebarModel::SidebarModel(QObject* parent) From 37546398cd6e5053a4ee333c890bc5523def07e9 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 13:55:14 +0200 Subject: [PATCH 479/552] Move Banshee Feature --- build/depends.py | 9 ++++----- .../{ => features}/banshee/bansheedbconnection.cpp | 2 +- src/library/{ => features}/banshee/bansheedbconnection.h | 0 src/library/{ => features}/banshee/bansheefeature.cpp | 7 +++---- src/library/{ => features}/banshee/bansheefeature.h | 3 +-- .../{ => features}/banshee/bansheeplaylistmodel.cpp | 7 ++++--- .../{ => features}/banshee/bansheeplaylistmodel.h | 8 ++++---- src/library/library.cpp | 2 +- 8 files changed, 18 insertions(+), 20 deletions(-) rename src/library/{ => features}/banshee/bansheedbconnection.cpp (99%) rename src/library/{ => features}/banshee/bansheedbconnection.h (100%) rename src/library/{ => features}/banshee/bansheefeature.cpp (97%) rename src/library/{ => features}/banshee/bansheefeature.h (96%) rename src/library/{ => features}/banshee/bansheeplaylistmodel.cpp (99%) rename src/library/{ => features}/banshee/bansheeplaylistmodel.h (96%) diff --git a/build/depends.py b/build/depends.py index 72d5c985ed0..81af2f6767d 100644 --- a/build/depends.py +++ b/build/depends.py @@ -895,16 +895,15 @@ def sources(self, build): "recording/recordingmanager.cpp", "engine/sidechain/enginerecord.cpp", - - "library/banshee/bansheefeature.cpp", - "library/banshee/bansheeplaylistmodel.cpp", - "library/banshee/bansheedbconnection.cpp", - # Library Features "library/features/analysis/analysisfeature.cpp", "library/features/analysis/analysislibrarytablemodel.cpp", "library/features/analysis/dlganalysis.cpp", + "library/features/banshee/bansheefeature.cpp", + "library/features/banshee/bansheeplaylistmodel.cpp", + "library/features/banshee/bansheedbconnection.cpp", + "library/features/browse/browsetablemodel.cpp", "library/features/browse/browsethread.cpp", "library/features/browse/browsefeature.cpp", diff --git a/src/library/banshee/bansheedbconnection.cpp b/src/library/features/banshee/bansheedbconnection.cpp similarity index 99% rename from src/library/banshee/bansheedbconnection.cpp rename to src/library/features/banshee/bansheedbconnection.cpp index ed8acb58636..663d2b10cd8 100644 --- a/src/library/banshee/bansheedbconnection.cpp +++ b/src/library/features/banshee/bansheedbconnection.cpp @@ -6,7 +6,7 @@ #include #include "library/queryutil.h" -#include "library/banshee/bansheedbconnection.h" +#include "library/features/banshee/bansheedbconnection.h" #include "util/performancetimer.h" BansheeDbConnection::BansheeDbConnection() { diff --git a/src/library/banshee/bansheedbconnection.h b/src/library/features/banshee/bansheedbconnection.h similarity index 100% rename from src/library/banshee/bansheedbconnection.h rename to src/library/features/banshee/bansheedbconnection.h diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/features/banshee/bansheefeature.cpp similarity index 97% rename from src/library/banshee/bansheefeature.cpp rename to src/library/features/banshee/bansheefeature.cpp index 4131bdefa2b..ad6e4ac8d7d 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/features/banshee/bansheefeature.cpp @@ -2,13 +2,12 @@ #include #include -#include "library/banshee/bansheefeature.h" +#include "library/features/banshee/bansheefeature.h" -#include "library/banshee/bansheedbconnection.h" #include "library/dao/settingsdao.h" +#include "library/features/banshee/bansheedbconnection.h" +#include "library/features/banshee/bansheeplaylistmodel.h" #include "library/features/baseexternalfeature/baseexternalplaylistmodel.h" -#include "library/banshee/bansheeplaylistmodel.h" -#include "library/library.h" const QString BansheeFeature::BANSHEE_MOUNT_KEY = "mixxx.BansheeFeature.mount"; diff --git a/src/library/banshee/bansheefeature.h b/src/library/features/banshee/bansheefeature.h similarity index 96% rename from src/library/banshee/bansheefeature.h rename to src/library/features/banshee/bansheefeature.h index d74e6966acf..3ab83c37908 100644 --- a/src/library/banshee/bansheefeature.h +++ b/src/library/features/banshee/bansheefeature.h @@ -8,11 +8,10 @@ #include #include +#include "library/features/banshee/bansheedbconnection.h" #include "library/features/baseexternalfeature/baseexternallibraryfeature.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" -#include "library/banshee/bansheedbconnection.h" - class BansheePlaylistModel; diff --git a/src/library/banshee/bansheeplaylistmodel.cpp b/src/library/features/banshee/bansheeplaylistmodel.cpp similarity index 99% rename from src/library/banshee/bansheeplaylistmodel.cpp rename to src/library/features/banshee/bansheeplaylistmodel.cpp index ec162d478ca..829eb36cc8b 100644 --- a/src/library/banshee/bansheeplaylistmodel.cpp +++ b/src/library/features/banshee/bansheeplaylistmodel.cpp @@ -1,11 +1,12 @@ #include #include -#include "library/banshee/bansheeplaylistmodel.h" -#include "library/banshee/bansheedbconnection.h" +#include "library/features/banshee/bansheeplaylistmodel.h" + +#include "library/features/banshee/bansheedbconnection.h" +#include "library/previewbuttondelegate.h" #include "library/queryutil.h" #include "library/starrating.h" -#include "library/previewbuttondelegate.h" #include "track/beatfactory.h" #include "track/beats.h" #include "mixer/playermanager.h" diff --git a/src/library/banshee/bansheeplaylistmodel.h b/src/library/features/banshee/bansheeplaylistmodel.h similarity index 96% rename from src/library/banshee/bansheeplaylistmodel.h rename to src/library/features/banshee/bansheeplaylistmodel.h index 95ba244342b..2c87d0e4f20 100644 --- a/src/library/banshee/bansheeplaylistmodel.h +++ b/src/library/features/banshee/bansheeplaylistmodel.h @@ -4,12 +4,12 @@ #include #include -#include "library/trackmodel.h" -#include "library/trackcollection.h" +#include "library/basesqltablemodel.h" #include "library/dao/trackdao.h" -#include "library/banshee/bansheedbconnection.h" +#include "library/features/banshee/bansheedbconnection.h" #include "library/stardelegate.h" -#include "library/basesqltablemodel.h" +#include "library/trackmodel.h" +#include "library/trackcollection.h" class BansheePlaylistModel : public BaseSqlTableModel { Q_OBJECT diff --git a/src/library/library.cpp b/src/library/library.cpp index debf01bfff1..32368c66646 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -8,8 +8,8 @@ #include #include "library/autodj/autodjfeature.h" -#include "library/banshee/bansheefeature.h" #include "library/features/analysis/analysisfeature.h" +#include "library/features/banshee/bansheefeature.h" #include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" From 3720fe6fddeedb67b726ff7000f11a436fe63fd0 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 14:06:09 +0200 Subject: [PATCH 480/552] Move AutoDJ Feature --- build/depends.py | 9 +++++---- src/library/dao/playlistdao.cpp | 4 ++-- .../{ => features}/autodj/autodjfeature.cpp | 14 ++++++-------- src/library/{ => features}/autodj/autodjfeature.h | 5 ++--- .../{ => features}/autodj/autodjprocessor.cpp | 10 +++++----- .../{ => features}/autodj/autodjprocessor.h | 2 +- src/library/{ => features}/autodj/dlgautodj.cpp | 8 +++----- src/library/{ => features}/autodj/dlgautodj.h | 13 ++++--------- src/library/{ => features}/autodj/dlgautodj.ui | 0 src/library/library.cpp | 2 +- 10 files changed, 29 insertions(+), 38 deletions(-) rename src/library/{ => features}/autodj/autodjfeature.cpp (98%) rename src/library/{ => features}/autodj/autodjfeature.h (99%) rename src/library/{ => features}/autodj/autodjprocessor.cpp (99%) rename src/library/{ => features}/autodj/autodjprocessor.h (100%) rename src/library/{ => features}/autodj/dlgautodj.cpp (97%) rename src/library/{ => features}/autodj/dlgautodj.h (75%) rename src/library/{ => features}/autodj/dlgautodj.ui (100%) diff --git a/build/depends.py b/build/depends.py index 81af2f6767d..07343c12674 100644 --- a/build/depends.py +++ b/build/depends.py @@ -868,8 +868,6 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", - "library/autodj/autodjfeature.cpp", - "library/autodj/autodjprocessor.cpp", "library/dao/directorydao.cpp", "library/mixxxlibraryfeature.cpp", "library/mixxxlibrarytreemodel.cpp", @@ -877,7 +875,6 @@ def sources(self, build): "library/baseplaylistfeature.cpp", "library/playlistfeature.cpp", "library/historyfeature.cpp", - "library/autodj/dlgautodj.cpp", "library/dlgcoverartfullsize.cpp", "library/dlghidden.cpp", "library/dlgmissing.cpp", @@ -899,6 +896,10 @@ def sources(self, build): "library/features/analysis/analysisfeature.cpp", "library/features/analysis/analysislibrarytablemodel.cpp", "library/features/analysis/dlganalysis.cpp", + + "library/features/autodj/autodjfeature.cpp", + "library/features/autodj/autodjprocessor.cpp", + "library/features/autodj/dlgautodj.cpp", "library/features/banshee/bansheefeature.cpp", "library/features/banshee/bansheeplaylistmodel.cpp", @@ -1118,7 +1119,6 @@ def sources(self, build): 'controllers/dlgprefcontrollersdlg.ui', 'dialog/dlgaboutdlg.ui', 'dialog/dlgdevelopertoolsdlg.ui', - 'library/autodj/dlgautodj.ui', 'library/dlgcoverartfullsize.ui', 'library/dlghidden.ui', 'library/dlgmissing.ui', @@ -1126,6 +1126,7 @@ def sources(self, build): 'library/dlgtrackinfo.ui', 'library/export/dlgtrackexport.ui', 'library/features/analysis/dlganalysis.ui', + 'library/features/autodj/dlgautodj.ui', 'library/features/recording/dlgrecording.ui', 'preferences/dialog/dlgprefautodjdlg.ui', 'preferences/dialog/dlgprefbeatsdlg.ui', diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index 50aa06c9c8f..368febf6a4e 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -1,11 +1,11 @@ #include #include -#include "track/track.h" #include "library/dao/playlistdao.h" +#include "library/features/autodj/autodjprocessor.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/autodj/autodjprocessor.h" +#include "track/track.h" #include "util/math.h" PlaylistDAO::PlaylistDAO(QSqlDatabase& database) diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/features/autodj/autodjfeature.cpp similarity index 98% rename from src/library/autodj/autodjfeature.cpp rename to src/library/features/autodj/autodjfeature.cpp index b5a7bc8b44e..9834d1f2575 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/features/autodj/autodjfeature.cpp @@ -8,19 +8,17 @@ #include #include -#include "library/autodj/autodjfeature.h" +#include "library/features/autodj/autodjfeature.h" -#include "library/library.h" +#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/features/autodj/autodjprocessor.h" +#include "library/features/autodj/dlgautodj.h" #include "library/parser.h" -#include "library/autodj/autodjprocessor.h" #include "library/trackcollection.h" -#include "library/autodj/dlgautodj.h" #include "mixer/playermanager.h" -#include "widget/wlibrary.h" -#include "widget/wlibrarysidebar.h" -#include "controllers/keyboard/keyboardeventfilter.h" #include "sources/soundsourceproxy.h" #include "util/dnd.h" +#include "widget/wlibrarysidebar.h" static const int kMaxRetrieveAttempts = 3; @@ -118,7 +116,7 @@ QWidget* AutoDJFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) QTabWidget* pContainer = new QTabWidget(nullptr); // Add controls - m_pAutoDJView = new DlgAutoDJ(pContainer, m_pLibrary, m_pAutoDJProcessor); + m_pAutoDJView = new DlgAutoDJ(pContainer, m_pAutoDJProcessor); m_pAutoDJView->installEventFilter(pKeyboard); QScrollArea* pScroll = new QScrollArea(pContainer); pScroll->setWidget(m_pAutoDJView); diff --git a/src/library/autodj/autodjfeature.h b/src/library/features/autodj/autodjfeature.h similarity index 99% rename from src/library/autodj/autodjfeature.h rename to src/library/features/autodj/autodjfeature.h index 2b0d70d300c..e6289d53791 100644 --- a/src/library/autodj/autodjfeature.h +++ b/src/library/features/autodj/autodjfeature.h @@ -16,11 +16,10 @@ #include #include +#include "library/dao/autodjcratesdao.h" #include "library/libraryfeature.h" -#include "preferences/usersettings.h" #include "library/treeitemmodel.h" - -#include "library/dao/autodjcratesdao.h" +#include "preferences/usersettings.h" #include "widget/wtracktableview.h" class DlgAutoDJ; diff --git a/src/library/autodj/autodjprocessor.cpp b/src/library/features/autodj/autodjprocessor.cpp similarity index 99% rename from src/library/autodj/autodjprocessor.cpp rename to src/library/features/autodj/autodjprocessor.cpp index 24ad9d5637a..4f09d15c740 100644 --- a/src/library/autodj/autodjprocessor.cpp +++ b/src/library/features/autodj/autodjprocessor.cpp @@ -1,11 +1,11 @@ -#include "library/autodj/autodjprocessor.h" +#include "library/features/autodj/autodjprocessor.h" -#include "library/trackcollection.h" -#include "control/controlpushbutton.h" #include "control/controlproxy.h" -#include "util/math.h" -#include "mixer/playermanager.h" +#include "control/controlpushbutton.h" +#include "library/trackcollection.h" #include "mixer/basetrackplayer.h" +#include "mixer/playermanager.h" +#include "util/math.h" #define kConfigKey "[Auto DJ]" const char* kTransitionPreferenceName = "Transition"; diff --git a/src/library/autodj/autodjprocessor.h b/src/library/features/autodj/autodjprocessor.h similarity index 100% rename from src/library/autodj/autodjprocessor.h rename to src/library/features/autodj/autodjprocessor.h index 8a560a50b9b..d9a8e768bbd 100644 --- a/src/library/autodj/autodjprocessor.h +++ b/src/library/features/autodj/autodjprocessor.h @@ -5,10 +5,10 @@ #include #include -#include "preferences/usersettings.h" #include "control/controlproxy.h" #include "engine/enginechannel.h" #include "library/playlisttablemodel.h" +#include "preferences/usersettings.h" #include "track/track.h" #include "util/class.h" diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/features/autodj/dlgautodj.cpp similarity index 97% rename from src/library/autodj/dlgautodj.cpp rename to src/library/features/autodj/dlgautodj.cpp index 98fa7186129..bec2c3bd8ec 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/features/autodj/dlgautodj.cpp @@ -1,21 +1,19 @@ #include -#include "library/autodj/dlgautodj.h" +#include "library/features/autodj/dlgautodj.h" #include "library/playlisttablemodel.h" -#include "widget/wtracktableview.h" #include "util/assert.h" #include "util/duration.h" +#include "widget/wtracktableview.h" DlgAutoDJ::DlgAutoDJ(QWidget* parent, - Library* pLibrary, AutoDJProcessor* pProcessor) : QFrame(parent), Ui::DlgAutoDJ(), m_pAutoDJProcessor(pProcessor), // no sorting - m_pAutoDJTableModel(nullptr), - m_pLibrary(pLibrary) { + m_pAutoDJTableModel(nullptr) { setupUi(this); // We do _NOT_ take ownership of this from AutoDJProcessor. diff --git a/src/library/autodj/dlgautodj.h b/src/library/features/autodj/dlgautodj.h similarity index 75% rename from src/library/autodj/dlgautodj.h rename to src/library/features/autodj/dlgautodj.h index f7ac02d6196..f5572fe7ff1 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/features/autodj/dlgautodj.h @@ -5,14 +5,10 @@ #include #include -#include "library/autodj/ui_dlgautodj.h" -#include "preferences/usersettings.h" -#include "track/track.h" -#include "library/libraryview.h" -#include "library/library.h" +#include "library/features/autodj/autodjprocessor.h" +#include "library/features/autodj/ui_dlgautodj.h" #include "library/trackcollection.h" -#include "library/autodj/autodjprocessor.h" -#include "controllers/keyboard/keyboardeventfilter.h" +#include "track/track.h" class PlaylistTableModel; class WTrackTableView; @@ -20,7 +16,7 @@ class WTrackTableView; class DlgAutoDJ : public QFrame, public Ui::DlgAutoDJ { Q_OBJECT public: - DlgAutoDJ(QWidget* parent, Library *pLibrary, AutoDJProcessor* pProcessor); + DlgAutoDJ(QWidget* parent, AutoDJProcessor* pProcessor); virtual ~DlgAutoDJ(); void onShow(); @@ -44,7 +40,6 @@ class DlgAutoDJ : public QFrame, public Ui::DlgAutoDJ { private: AutoDJProcessor* m_pAutoDJProcessor; PlaylistTableModel* m_pAutoDJTableModel; - Library* m_pLibrary; QModelIndexList m_selectedRows; }; diff --git a/src/library/autodj/dlgautodj.ui b/src/library/features/autodj/dlgautodj.ui similarity index 100% rename from src/library/autodj/dlgautodj.ui rename to src/library/features/autodj/dlgautodj.ui diff --git a/src/library/library.cpp b/src/library/library.cpp index 32368c66646..f1dc062bc40 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -7,8 +7,8 @@ #include #include -#include "library/autodj/autodjfeature.h" #include "library/features/analysis/analysisfeature.h" +#include "library/features/autodj/autodjfeature.h" #include "library/features/banshee/bansheefeature.h" #include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" From 887d5a7739df98611ec7b6a8d7ac7c256a942989 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 14:18:15 +0200 Subject: [PATCH 481/552] Move BasePlaylist --- build/depends.py | 3 ++- .../baseexternalfeature/baseexternallibraryfeature.cpp | 4 ++-- .../{ => features/baseplaylist}/baseplaylistfeature.cpp | 7 +++---- .../{ => features/baseplaylist}/baseplaylistfeature.h | 0 src/library/historyfeature.h | 2 +- src/library/playlistfeature.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/library/{ => features/baseplaylist}/baseplaylistfeature.cpp (99%) rename src/library/{ => features/baseplaylist}/baseplaylistfeature.h (100%) diff --git a/build/depends.py b/build/depends.py index 07343c12674..c4251a3e9db 100644 --- a/build/depends.py +++ b/build/depends.py @@ -872,7 +872,6 @@ def sources(self, build): "library/mixxxlibraryfeature.cpp", "library/mixxxlibrarytreemodel.cpp", "library/libraryfoldersfeature.cpp", - "library/baseplaylistfeature.cpp", "library/playlistfeature.cpp", "library/historyfeature.cpp", "library/dlgcoverartfullsize.cpp", @@ -904,6 +903,8 @@ def sources(self, build): "library/features/banshee/bansheefeature.cpp", "library/features/banshee/bansheeplaylistmodel.cpp", "library/features/banshee/bansheedbconnection.cpp", + + "library/features/baseplaylist/baseplaylistfeature.cpp", "library/features/browse/browsetablemodel.cpp", "library/features/browse/browsethread.cpp", diff --git a/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp b/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp index 1f59e0a059e..741e29dbb79 100644 --- a/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp +++ b/src/library/features/baseexternalfeature/baseexternallibraryfeature.cpp @@ -88,8 +88,8 @@ void BaseExternalLibraryFeature::slotImportAsMixxxPlaylist() { playlistDao.appendTracksToPlaylist(trackIds, playlistId); } else { // Do not change strings here without also changing strings in - // src/library/baseplaylistfeature.cpp - QMessageBox::warning(NULL, + // src/library/features/baseplaylist/baseplaylistfeature.cpp + QMessageBox::warning(nullptr, tr("Playlist Creation Failed"), tr("An unknown error occurred while creating playlist: ") + playlist); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp similarity index 99% rename from src/library/baseplaylistfeature.cpp rename to src/library/features/baseplaylist/baseplaylistfeature.cpp index 3e5a16bb670..906021499a2 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -1,10 +1,11 @@ -#include "library/baseplaylistfeature.h" - #include #include #include #include +#include "library/features/baseplaylist/baseplaylistfeature.h" + +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/export/trackexportwizard.h" #include "library/library.h" #include "library/parser.h" @@ -14,8 +15,6 @@ #include "library/playlisttablemodel.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" -#include "controllers/keyboard/keyboardeventfilter.h" -#include "widget/wlibrary.h" #include "widget/wlibrarystack.h" #include "widget/wlibrarytextbrowser.h" #include "util/assert.h" diff --git a/src/library/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h similarity index 100% rename from src/library/baseplaylistfeature.h rename to src/library/features/baseplaylist/baseplaylistfeature.h diff --git a/src/library/historyfeature.h b/src/library/historyfeature.h index f0ea5475e84..cc2825901ef 100644 --- a/src/library/historyfeature.h +++ b/src/library/historyfeature.h @@ -7,7 +7,7 @@ #include #include -#include "library/baseplaylistfeature.h" +#include "library/features/baseplaylist/baseplaylistfeature.h" #include "preferences/usersettings.h" class TrackCollection; diff --git a/src/library/playlistfeature.h b/src/library/playlistfeature.h index 23ae5f98623..7aa63d5c53e 100644 --- a/src/library/playlistfeature.h +++ b/src/library/playlistfeature.h @@ -11,7 +11,7 @@ #include #include -#include "library/baseplaylistfeature.h" +#include "library/features/baseplaylist/baseplaylistfeature.h" #include "preferences/usersettings.h" class TrackCollection; From b2f1b954be096c3887a4c870604d6f02b2a8c144 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 14:20:54 +0200 Subject: [PATCH 482/552] Remove duplicated files --- src/library/cratefeature.cpp | 955 -------------------------------- src/library/cratefeature.h | 124 ----- src/library/cratetablemodel.cpp | 195 ------- src/library/cratetablemodel.h | 34 -- 4 files changed, 1308 deletions(-) delete mode 100644 src/library/cratefeature.cpp delete mode 100644 src/library/cratefeature.h delete mode 100644 src/library/cratetablemodel.cpp delete mode 100644 src/library/cratetablemodel.h diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp deleted file mode 100644 index 54a6337588f..00000000000 --- a/src/library/cratefeature.cpp +++ /dev/null @@ -1,955 +0,0 @@ -// cratefeature.cpp -// Created 10/22/2009 by RJ Ryan (rryan@mit.edu) - -#include -#include -#include -#include -#include - -#include "library/cratefeature.h" - -#include "controllers/keyboard/keyboardeventfilter.h" -#include "library/cratetablemodel.h" -#include "library/export/trackexportwizard.h" -#include "library/library.h" -#include "library/parsercsv.h" -#include "library/parser.h" -#include "library/parserm3u.h" -#include "library/parserpls.h" -#include "library/queryutil.h" -#include "library/trackcollection.h" -#include "sources/soundsourceproxy.h" -#include "util/dnd.h" -#include "util/duration.h" -#include "util/time.h" -#include "widget/wlibrarystack.h" -#include "widget/wlibrarytextbrowser.h" - -CrateFeature::CrateFeature(UserSettingsPointer pConfig, - Library* pLibrary, - QObject* parent, - TrackCollection* pTrackCollection) - : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), - m_pTrackCollection(pTrackCollection), - m_crateDao(pTrackCollection->getCrateDAO()), - m_pCrateTableModel(nullptr) { - - m_pCreateCrateAction = new QAction(tr("Create New Crate"),this); - connect(m_pCreateCrateAction, SIGNAL(triggered()), - this, SLOT(slotCreateCrate())); - - m_pDeleteCrateAction = new QAction(tr("Remove"),this); - connect(m_pDeleteCrateAction, SIGNAL(triggered()), - this, SLOT(slotDeleteCrate())); - - m_pRenameCrateAction = new QAction(tr("Rename"),this); - connect(m_pRenameCrateAction, SIGNAL(triggered()), - this, SLOT(slotRenameCrate())); - - m_pLockCrateAction = new QAction(tr("Lock"),this); - connect(m_pLockCrateAction, SIGNAL(triggered()), - this, SLOT(slotToggleCrateLock())); - - m_pImportPlaylistAction = new QAction(tr("Import Crate"),this); - connect(m_pImportPlaylistAction, SIGNAL(triggered()), - this, SLOT(slotImportPlaylist())); - - m_pCreateImportPlaylistAction = new QAction(tr("Import Crate"), this); - connect(m_pCreateImportPlaylistAction, SIGNAL(triggered()), - this, SLOT(slotCreateImportCrate())); - - m_pExportPlaylistAction = new QAction(tr("Export Crate"), this); - connect(m_pExportPlaylistAction, SIGNAL(triggered()), - this, SLOT(slotExportPlaylist())); - - m_pExportTrackFilesAction = new QAction(tr("Export Track Files"), this); - connect(m_pExportTrackFilesAction, SIGNAL(triggered()), - this, SLOT(slotExportTrackFiles())); - - m_pDuplicateCrateAction = new QAction(tr("Duplicate"),this); - connect(m_pDuplicateCrateAction, SIGNAL(triggered()), - this, SLOT(slotDuplicateCrate())); - - m_pAnalyzeCrateAction = new QAction(tr("Analyze entire Crate"),this); - connect(m_pAnalyzeCrateAction, SIGNAL(triggered()), - this, SLOT(slotAnalyzeCrate())); - - m_pAutoDjTrackSource = new QAction(tr("Auto DJ Track Source"),this); - m_pAutoDjTrackSource->setCheckable(true); - connect(m_pAutoDjTrackSource, SIGNAL(changed()), - this, SLOT(slotAutoDjTrackSourceChanged())); - - connect(&m_crateDao, SIGNAL(added(int)), - this, SLOT(slotCrateTableChanged(int))); - - connect(&m_crateDao, SIGNAL(deleted(int)), - this, SLOT(slotCrateTableChanged(int))); - - connect(&m_crateDao, SIGNAL(changed(int)), - this, SLOT(slotCrateContentChanged(int))); - - connect(&m_crateDao, SIGNAL(renamed(int,QString)), - this, SLOT(slotCrateTableRenamed(int,QString))); - - connect(&m_crateDao, SIGNAL(lockChanged(int)), - this, SLOT(slotCrateTableChanged(int))); - - // construct child model - TreeItem *pRootItem = new TreeItem(); - pRootItem->setLibraryFeature(this); - m_childModel.setRootItem(pRootItem); - constructChildModel(-1); - - connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), - this, SLOT(slotTrackSelected(TrackPointer))); -} - -CrateFeature::~CrateFeature() { - //delete QActions - delete m_pExportTrackFilesAction; - delete m_pCreateCrateAction; - delete m_pDeleteCrateAction; - delete m_pRenameCrateAction; - delete m_pDuplicateCrateAction; - delete m_pLockCrateAction; - delete m_pImportPlaylistAction; - delete m_pAnalyzeCrateAction; - delete m_pAutoDjTrackSource; -} - -QVariant CrateFeature::title() { - return tr("Crates"); -} - -QString CrateFeature::getIconPath() { - return ":/images/library/ic_library_crates.png"; -} - -QString CrateFeature::getSettingsName() const { - return "CrateFeature"; -} - -bool CrateFeature::isSinglePane() const { - return false; -} - -int CrateFeature::crateIdFromIndex(QModelIndex index) { - bool ok = false; - int crateId = index.data(AbstractRole::RoleDataPath).toInt(&ok); - return ok ? crateId : -1; -} - -bool CrateFeature::dragMoveAccept(QUrl url) { - return SoundSourceProxy::isUrlSupported(url) || - Parser::isPlaylistFilenameSupported(url.toLocalFile()); -} - - -bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList urls, - QObject* pSource) { - int crateId = crateIdFromIndex(index); - - QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); - QList trackIds; - if (pSource) { - trackIds = m_pTrackCollection->getTrackDAO().getTrackIds(files); - m_pTrackCollection->getTrackDAO().unhideTracks(trackIds); - } else { - // Adds track, does not insert duplicates, handles unremoving logic. - trackIds = m_pTrackCollection->getTrackDAO().addMultipleTracks(files, true); - } - //qDebug() << "CrateFeature::dropAcceptChild adding tracks" - // << trackIds.size() << " to crate "<< crateId; - // remove tracks that could not be added - for (int trackIdIndex = 0; trackIdIndex < trackIds.size(); ++trackIdIndex) { - if (!trackIds.at(trackIdIndex).isValid()) { - trackIds.removeAt(trackIdIndex--); - } - } - - // Request a name for the crate if it's a new crate - if (crateId < 0) { - QString name = getValidCrateName(); - if (name.isNull()) { - return false; - } - - crateId = m_crateDao.createCrate(name); - // An error happened - if (crateId < 0) { - return false; - } - } - - m_crateDao.addTracksToCrate(crateId, &trackIds); - return true; -} - -bool CrateFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { - int crateId = crateIdFromIndex(index); - bool locked = m_crateDao.isCrateLocked(crateId); - bool formatSupported = SoundSourceProxy::isUrlSupported(url) || - Parser::isPlaylistFilenameSupported(url.toLocalFile()); - return !locked && formatSupported; -} - -QWidget* CrateFeature::createPaneWidget(KeyboardEventFilter *pKeyboard, - int paneId) { - WLibraryStack* pContainer = new WLibraryStack(nullptr); - m_panes[paneId] = pContainer; - - WLibraryTextBrowser* pEdit = new WLibraryTextBrowser(pContainer); - pEdit->setHtml(getRootViewHtml()); - pEdit->setOpenLinks(false); - pEdit->installEventFilter(pKeyboard); - connect(pEdit, SIGNAL(anchorClicked(const QUrl)), - this, SLOT(htmlLinkClicked(const QUrl))); - - m_idBrowse[paneId] = pContainer->addWidget(pEdit); - - QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); - m_idTable[paneId] = pContainer->addWidget(pTable); - - return pContainer; -} - -TreeItemModel* CrateFeature::getChildModel() { - return &m_childModel; -} - -void CrateFeature::activate() { - if (m_lastClickedIndex[m_featurePane].isValid()) { - activateChild(m_lastClickedIndex[m_featurePane]); - return; - } - - showBrowse(m_featurePane); - switchToFeature(); - showBreadCrumb(); - restoreSearch(QString()); //disable search on crate home -} - -void CrateFeature::activateChild(const QModelIndex& index) { - if (getPreselectedPane() >= 0) { - m_featurePane = getPreselectedPane(); - } - - m_lastClickedIndex[m_featurePane] = index; - int crateId = crateIdFromIndex(index); - if (crateId == -1) { - return; - } - - m_pCrateTableModel = getTableModel(m_featurePane); - m_pCrateTableModel->setTableModel(crateId); - showTable(m_featurePane); - restoreSearch(""); - showBreadCrumb(index); - showTrackModel(m_pCrateTableModel); -} - -void CrateFeature::activateCrate(int crateId) { - //qDebug() << "CrateFeature::activateCrate()" << crateId; - m_pCrateTableModel = getTableModel(m_featurePane); - - QModelIndex index = indexFromCrateId(crateId); - if (crateId != -1 && index.isValid()) { - m_pCrateTableModel->setTableModel(crateId); - showTrackModel(m_pCrateTableModel); - // Update selection - emit(featureSelect(this, m_lastRightClickedIndex)); - activateChild(m_lastRightClickedIndex); - } -} - - -void CrateFeature::onRightClick(const QPoint& globalPos) { - m_lastRightClickedIndex = QModelIndex(); - QMenu menu(nullptr); - menu.addAction(m_pCreateCrateAction); - menu.addSeparator(); - menu.addAction(m_pCreateImportPlaylistAction); - menu.exec(globalPos); -} - -void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { - //Save the model index so we can get it in the action slots... - m_lastRightClickedIndex = index; - int crateId = crateIdFromIndex(index); - - bool locked = m_crateDao.isCrateLocked(crateId); - - m_pDeleteCrateAction->setEnabled(!locked); - m_pRenameCrateAction->setEnabled(!locked); - - bool bAutoDj = m_crateDao.isCrateInAutoDj(crateId); - m_pAutoDjTrackSource->setChecked(bAutoDj); - - m_pLockCrateAction->setText(locked ? tr("Unlock") : tr("Lock")); - - QMenu menu(nullptr); - menu.addAction(m_pCreateCrateAction); - menu.addSeparator(); - if (crateId >= 0) { - menu.addAction(m_pRenameCrateAction); - menu.addAction(m_pDuplicateCrateAction); - menu.addAction(m_pDeleteCrateAction); - menu.addAction(m_pLockCrateAction); - menu.addSeparator(); - menu.addAction(m_pAutoDjTrackSource); - menu.addSeparator(); - menu.addAction(m_pAnalyzeCrateAction); - menu.addSeparator(); - } - menu.addAction(m_pImportPlaylistAction); - if (crateId >= 0) { - menu.addAction(m_pExportPlaylistAction); - menu.addAction(m_pExportTrackFilesAction); - } - menu.exec(globalPos); -} - -void CrateFeature::slotCreateCrate() { - QString name = getValidCrateName(); - if (name.isNull()) { - // The user canceled - return; - } - - int crateId = m_crateDao.createCrate(name); - if (crateId != -1) { - activateCrate(crateId); - } else { - qDebug() << "Error creating crate with name " << name; - QMessageBox::warning(nullptr, - tr("Creating Crate Failed"), - tr("An unknown error occurred while creating crate: ") - + name); - } -} - -void CrateFeature::slotDeleteCrate() { - int crateId = crateIdFromIndex(m_lastRightClickedIndex); - if (crateId == -1) { - return; - } - - bool locked = m_crateDao.isCrateLocked(crateId); - if (locked) { - qDebug() << "Skipping crate deletion because crate" << crateId << "is locked."; - return; - } - - bool deleted = m_crateDao.deleteCrate(crateId); - - if (deleted) { - // This avoids a bug where the m_lastChildClicked index is still a valid - // index but it's not true since we just deleted it - for (auto it = m_crateTableModel.begin(); - it != m_crateTableModel.end(); ++it) { - if ((*it)->getCrate() == crateId) { - // Show the browse widget, this avoids a problem when the same - // playlist is shown twice and gets deleted. One of the panes - // gets still showing the unexisting crate. - m_lastClickedIndex[it.key()] = QModelIndex(); - showBrowse(it.key()); - } - } - - activate(); - } else { - qDebug() << "Failed to delete crateId" << crateId; - } -} - -void CrateFeature::slotRenameCrate() { - int crateId = crateIdFromIndex(m_lastRightClickedIndex); - if (crateId == -1) { - return; - } - QString oldName = m_crateDao.crateName(crateId); - - bool locked = m_crateDao.isCrateLocked(crateId); - if (locked) { - qDebug() << "Skipping crate rename because crate" << crateId << "is locked."; - return; - } - - QString newName; - bool validNameGiven = false; - - while (!validNameGiven) { - bool ok = false; - newName = QInputDialog::getText(NULL, - tr("Rename Crate"), - tr("Enter new name for crate:"), - QLineEdit::Normal, - oldName, - &ok).trimmed(); - - if (!ok || newName == oldName) { - return; - } - - int existingId = m_crateDao.getCrateIdByName(newName); - - if (existingId != -1) { - QMessageBox::warning(NULL, - tr("Renaming Crate Failed"), - tr("A crate by that name already exists.")); - } else if (newName.isEmpty()) { - QMessageBox::warning(NULL, - tr("Renaming Crate Failed"), - tr("A crate cannot have a blank name.")); - } else { - validNameGiven = true; - } - } - - if (!m_crateDao.renameCrate(crateId, newName)) { - qDebug() << "Failed to rename crateId" << crateId; - } -} - -void CrateFeature::slotDuplicateCrate() { - int oldCrateId = crateIdFromIndex(m_lastRightClickedIndex); - if (oldCrateId == -1) { - return; - } - QString oldName = m_crateDao.crateName(oldCrateId); - - QString name; - bool validNameGiven = false; - while (!validNameGiven) { - bool ok = false; - name = QInputDialog::getText(NULL, - tr("Duplicate Crate"), - tr("Enter name for new crate:"), - QLineEdit::Normal, - //: Appendix to default name when duplicating a crate - oldName + tr("_copy" , "[noun]"), - &ok).trimmed(); - - if (!ok || name == oldName) { - return; - } - - int existingId = m_crateDao.getCrateIdByName(name); - if (existingId != -1) { - QMessageBox::warning(NULL, - tr("Renaming Crate Failed"), - tr("A crate by that name already exists.")); - } else if (name.isEmpty()) { - QMessageBox::warning(NULL, - tr("Renaming Crate Failed"), - tr("A crate cannot have a blank name.")); - } else { - validNameGiven = true; - } - } - - int newCrateId = m_crateDao.createCrate(name); - m_crateDao.copyCrateTracks(oldCrateId, newCrateId); - - if (newCrateId != -1) { - activateCrate(newCrateId); - } else { - qDebug() << "Error creating crate with name " << name; - QMessageBox::warning(NULL, - tr("Creating Crate Failed"), - tr("An unknown error occurred while creating crate: ") - + name); - } -} - -void CrateFeature::slotToggleCrateLock() { - int crateId = crateIdFromIndex(m_lastRightClickedIndex); - if (crateId == -1) { - return; - } - QString crateName = m_crateDao.crateName(crateId); - bool locked = !m_crateDao.isCrateLocked(crateId); - - if (!m_crateDao.setCrateLocked(crateId, locked)) { - qDebug() << "Failed to toggle lock of crateId " << crateId; - } -} - -void CrateFeature::slotAutoDjTrackSourceChanged() { - int crateId = crateIdFromIndex(m_lastRightClickedIndex); - if (crateId != -1) { - m_crateDao.setCrateInAutoDj(crateId, m_pAutoDjTrackSource->isChecked()); - } -} - -void CrateFeature::buildCrateList() { - m_crateList.clear(); - - QString queryString = QString( - "CREATE TEMPORARY VIEW IF NOT EXISTS CratesCountsDurations " - "AS SELECT " - " crates.id as id, " - " crates.name as name, " - " COUNT(library.id) as count, " - " SUM(library.duration) as durationSeconds " - "FROM crates " - "LEFT JOIN crate_tracks ON crate_tracks.crate_id = crates.id " - "LEFT JOIN library ON crate_tracks.track_id = library.id " - "WHERE show = 1 " - "GROUP BY crates.id;"); - QSqlQuery query(m_pTrackCollection->getDatabase()); - if (!query.exec(queryString)) { - LOG_FAILED_QUERY(query); - } - - QSqlTableModel crateListTableModel(this, m_pTrackCollection->getDatabase()); - crateListTableModel.setTable("CratesCountsDurations"); - crateListTableModel.setSort(crateListTableModel.fieldIndex("name"), - Qt::AscendingOrder); - crateListTableModel.select(); - while (crateListTableModel.canFetchMore()) { - crateListTableModel.fetchMore(); - } - QSqlRecord record = crateListTableModel.record(); - int nameColumn = record.indexOf("name"); - int idColumn = record.indexOf("id"); - int countColumn = record.indexOf("count"); - int durationColumn = record.indexOf("durationSeconds"); - - for (int row = 0; row < crateListTableModel.rowCount(); ++row) { - int id = crateListTableModel.data( - crateListTableModel.index(row, idColumn)).toInt(); - QString name = crateListTableModel.data( - crateListTableModel.index(row, nameColumn)).toString(); - int count = crateListTableModel.data( - crateListTableModel.index(row, countColumn)).toInt(); - int duration = crateListTableModel.data( - crateListTableModel.index(row, durationColumn)).toInt(); - m_crateList.append(qMakePair(id, QString("%1 (%2) %3") - .arg(name, QString::number(count), - mixxx::Duration::formatSeconds(duration)))); - } -} - -/** - * Purpose: When inserting or removing playlists, - * we require the sidebar model not to reset. - * This method queries the database and does dynamic insertion -*/ -QModelIndex CrateFeature::constructChildModel(int selected_id) { - buildCrateList(); - QList data_list; - int selected_row = -1; - // Access the invisible root item - TreeItem* root = m_childModel.getItem(QModelIndex()); - - int row = 0; - for (QList >::const_iterator it = m_crateList.begin(); - it != m_crateList.end(); ++it, ++row) { - int crate_id = it->first; - QString crate_name = it->second; - - if (selected_id == crate_id) { - // save index for selection - selected_row = row; - m_childModel.index(selected_row, 0); - } - - // Create the TreeItem whose parent is the invisible root item - TreeItem* item = new TreeItem(crate_name, QString::number(crate_id), this, root); - bool locked = m_crateDao.isCrateLocked(crate_id); - item->setIcon(locked ? QIcon(":/images/library/ic_library_locked.png") : QIcon()); - item->setBold(m_cratesSelectedTrackIsIn.contains(crate_id)); - data_list.append(item); - } - - // Append all the newly created TreeItems in a dynamic way to the childmodel - m_childModel.insertRows(data_list, 0, m_crateList.size()); - if (selected_row == -1) { - return QModelIndex(); - } - return m_childModel.index(selected_row, 0); -} - -void CrateFeature::updateChildModel(int selected_id) { - buildCrateList(); - - int row = 0; - for (QList >::const_iterator it = m_crateList.begin(); - it != m_crateList.end(); ++it, ++row) { - int crate_id = it->first; - QString crate_name = it->second; - - if (selected_id == crate_id) { - TreeItem* item = m_childModel.getItem(indexFromCrateId(crate_id)); - item->setData(crate_name, QString::number(crate_id)); - bool locked = m_crateDao.isCrateLocked(crate_id); - item->setIcon(locked ? QIcon(":/images/library/ic_library_locked.png") : QIcon()); - - } - - } -} - -/** - * Clears the child model dynamically - */ -void CrateFeature::clearChildModel() { - m_childModel.removeRows(0, m_crateList.size()); - m_crateList.clear(); -} - -void CrateFeature::slotImportPlaylist() { - //qDebug() << "slotImportPlaylist() row:" ; //<< m_lastRightClickedIndex.data(); - - QString playlistFile = getPlaylistFile(); - if (playlistFile.isEmpty()) { - return; - } - - // Update the import/export crate directory - QFileInfo fileName(playlistFile); - m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), - ConfigValue(fileName.dir().absolutePath())); - - slotImportPlaylistFile(playlistFile); - activateChild(m_lastRightClickedIndex); -} - -void CrateFeature::slotImportPlaylistFile(const QString &playlist_file) { - // The user has picked a new directory via a file dialog. This means the - // system sandboxer (if we are sandboxed) has granted us permission to this - // folder. We don't need access to this file on a regular basis so we do not - // register a security bookmark. - - Parser* playlist_parser = NULL; - - if (playlist_file.endsWith(".m3u", Qt::CaseInsensitive) || - playlist_file.endsWith(".m3u8", Qt::CaseInsensitive)) { - // .m3u8 is Utf8 representation of an m3u playlist - playlist_parser = new ParserM3u(); - } else if (playlist_file.endsWith(".pls", Qt::CaseInsensitive)) { - playlist_parser = new ParserPls(); - } else if (playlist_file.endsWith(".csv", Qt::CaseInsensitive)) { - playlist_parser = new ParserCsv(); - } else { - return; - } - - if (playlist_parser) { - QList entries = playlist_parser->parse(playlist_file); - //qDebug() << "Size of Imported Playlist: " << entries.size(); - - //Iterate over the List that holds URLs of playlist entires - m_pCrateTableModel->addTracks(QModelIndex(), entries); - - //delete the parser object - delete playlist_parser; - } -} - -void CrateFeature::slotCreateImportCrate() { - - // Get file to read - QStringList playlist_files = LibraryFeature::getPlaylistFiles(); - if (playlist_files.isEmpty()) { - return; - } - - - // Set last import directory - QFileInfo fileName(playlist_files.first()); - m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), - ConfigValue(fileName.dir().absolutePath())); - - int lastCrateId = -1; - - // For each selected file - for (const QString& playlistFile : playlist_files) { - fileName = QFileInfo(playlistFile); - - // Get a valid name - QString baseName = fileName.baseName(); - QString name; - bool validNameGiven = false; - int i = 0; - while (!validNameGiven) { - name = baseName; - if (i != 0) { - name += QString::number(i); - } - - // Check name - int existingId = m_crateDao.getCrateIdByName(name); - - validNameGiven = (existingId == -1); - ++i; - } - - lastCrateId = m_crateDao.createCrate(name); - - if (lastCrateId != -1) { - m_pCrateTableModel->setTableModel(lastCrateId); - } - else { - QMessageBox::warning(NULL, - tr("Crate Creation Failed"), - tr("An unknown error occurred while creating crate: ") - + name); - return; - } - - slotImportPlaylistFile(playlistFile); - } - activateCrate(lastCrateId); -} - -void CrateFeature::slotAnalyzeCrate() { - if (m_lastRightClickedIndex.isValid()) { - int crateId = crateIdFromIndex(m_lastRightClickedIndex); - if (crateId >= 0) { - QList ids = m_crateDao.getTrackIds(crateId); - emit(analyzeTracks(ids)); - } - } -} - -void CrateFeature::slotExportPlaylist() { - int crateId = m_pCrateTableModel->getCrate(); - QString crateName = m_crateDao.crateName(crateId); - qDebug() << "Export crate" << crateId << crateName; - - QString lastCrateDirectory = m_pConfig->getValueString( - ConfigKey("[Library]", "LastImportExportCrateDirectory"), - QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); - - QString file_location = QFileDialog::getSaveFileName( - NULL, - tr("Export Crate"), - lastCrateDirectory.append("/").append(crateName), - tr("M3U Playlist (*.m3u);;M3U8 Playlist (*.m3u8);;PLS Playlist (*.pls);;Text CSV (*.csv);;Readable Text (*.txt)")); - // Exit method if user cancelled the open dialog. - if (file_location.isNull() || file_location.isEmpty()) { - return; - } - - // Update the import/export crate directory - QFileInfo fileName(file_location); - m_pConfig->set(ConfigKey("[Library]","LastImportExportCrateDirectory"), - ConfigValue(fileName.dir().absolutePath())); - - // The user has picked a new directory via a file dialog. This means the - // system sandboxer (if we are sandboxed) has granted us permission to this - // folder. We don't need access to this file on a regular basis so we do not - // register a security bookmark. - - // check config if relative paths are desired - bool useRelativePath = static_cast( - m_pConfig->getValueString( - ConfigKey("[Library]", "UseRelativePathOnExport")).toInt()); - - // Create list of files of the crate - QList playlist_items; - // Create a new table model since the main one might have an active search. - QScopedPointer pCrateTableModel( - new CrateTableModel(this, m_pTrackCollection)); - pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); - pCrateTableModel->select(); - - if (file_location.endsWith(".csv", Qt::CaseInsensitive)) { - ParserCsv::writeCSVFile(file_location, pCrateTableModel.data(), useRelativePath); - } else if (file_location.endsWith(".txt", Qt::CaseInsensitive)) { - ParserCsv::writeReadableTextFile(file_location, pCrateTableModel.data(), false); - } else{ - // populate a list of files of the crate - QList playlist_items; - int rows = pCrateTableModel->rowCount(); - for (int i = 0; i < rows; ++i) { - QModelIndex index = m_pCrateTableModel->index(i, 0); - playlist_items << m_pCrateTableModel->getTrackLocation(index); - } - - if (file_location.endsWith(".pls", Qt::CaseInsensitive)) { - ParserPls::writePLSFile(file_location, playlist_items, useRelativePath); - } else if (file_location.endsWith(".m3u8", Qt::CaseInsensitive)) { - ParserM3u::writeM3U8File(file_location, playlist_items, useRelativePath); - } else { - //default export to M3U if file extension is missing - if(!file_location.endsWith(".m3u", Qt::CaseInsensitive)) - { - qDebug() << "Crate export: No valid file extension specified. Appending .m3u " - << "and exporting to M3U."; - file_location.append(".m3u"); - } - ParserM3u::writeM3UFile(file_location, playlist_items, useRelativePath); - } - } -} - -void CrateFeature::slotExportTrackFiles() { - // Create a new table model since the main one might have an active search. - QScopedPointer pCrateTableModel( - new CrateTableModel(this, m_pTrackCollection)); - pCrateTableModel->setTableModel(m_pCrateTableModel->getCrate()); - pCrateTableModel->select(); - - int rows = pCrateTableModel->rowCount(); - QList trackpointers; - for (int i = 0; i < rows; ++i) { - QModelIndex index = m_pCrateTableModel->index(i, 0); - trackpointers.push_back(m_pCrateTableModel->getTrack(index)); - } - - TrackExportWizard trackExport(nullptr, m_pConfig, trackpointers); - trackExport.exportTracks(); -} - -void CrateFeature::slotCrateTableChanged(int crateId) { - //qDebug() << "slotCrateTableChanged() crateId:" << crateId; - clearChildModel(); - m_lastRightClickedIndex = constructChildModel(crateId); -} - -void CrateFeature::slotCrateContentChanged(int crateId) { - //qDebug() << "slotCrateContentChanged()crateId:" << crateId; - updateChildModel(crateId); -} - -void CrateFeature::slotCrateTableRenamed(int a_iCrateId, - QString /* a_strName */) { - activateCrate(a_iCrateId); -} - -void CrateFeature::htmlLinkClicked(const QUrl& link) { - if (QString(link.path())=="create") { - slotCreateCrate(); - } else { - qDebug() << "Unknown crate link clicked" << link; - } -} - -QString CrateFeature::getRootViewHtml() const { - QString cratesTitle = tr("Crates"); - QString cratesSummary = tr("Crates are a great way to help organize the music you want to DJ with."); - QString cratesSummary2 = tr("Make a crate for your next gig, for your favorite electrohouse tracks, or for your most requested songs."); - QString cratesSummary3 = tr("Crates let you organize your music however you'd like!"); - - QString html; - QString createCrateLink = tr("Create New Crate"); - html.append(QString("

%1

").arg(cratesTitle)); - html.append(""); - html.append(QString("
"); - html.append(QString("

%1

").arg(cratesSummary)); - html.append(QString("

%1

").arg(cratesSummary2)); - html.append(QString("

%1

").arg(cratesSummary3)); - html.append("
"); - html.append(""); - html.append("
%1") - .arg(createCrateLink)); - html.append("
"); - return html; -} - -void CrateFeature::slotTrackSelected(TrackPointer pTrack) { - m_pSelectedTrack = pTrack; - TrackId trackId(pTrack.isNull() ? TrackId() : pTrack->getId()); - m_crateDao.getCratesTrackIsIn(trackId, &m_cratesSelectedTrackIsIn); - - TreeItem* rootItem = m_childModel.getItem(QModelIndex()); - if (rootItem == nullptr) { - return; - } - - // Set all crates the track is in bold (or if there is no track selected, - // clear all the bolding). - int row = 0; - for (QList >::const_iterator it = m_crateList.begin(); - it != m_crateList.end(); ++it, ++row) { - TreeItem* crate = rootItem->child(row); - if (crate == nullptr) { - continue; - } - int crateId = it->first; - bool shouldBold = m_cratesSelectedTrackIsIn.contains(crateId); - crate->setBold(shouldBold); - } - - m_childModel.triggerRepaint(); -} - -void CrateFeature::slotResetSelectedTrack() { - slotTrackSelected(TrackPointer()); -} - -QString CrateFeature::getValidCrateName() { - QString name; - bool validNameGiven = false; - - while (!validNameGiven) { - bool ok = false; - name = QInputDialog::getText(nullptr, - tr("Create New Crate"), - tr("Enter name for new crate:"), - QLineEdit::Normal, tr("New Crate"), - &ok).trimmed(); - - if (!ok) { - return QString(); - } - - int existingId = m_crateDao.getCrateIdByName(name); - - if (existingId != -1) { - QMessageBox::warning(nullptr, - tr("Creating Crate Failed"), - tr("A crate by that name already exists.")); - } else if (name.isEmpty()) { - QMessageBox::warning(nullptr, - tr("Creating Crate Failed"), - tr("A crate cannot have a blank name.")); - } else { - validNameGiven = true; - } - } - return name; -} - -QModelIndex CrateFeature::indexFromCrateId(int crateId) { - int row = 0; - for (QList >::const_iterator it = m_crateList.begin(); - it != m_crateList.end(); ++it, ++row) { - int current_id = it->first; - QString crate_name = it->second; - - if (crateId == current_id) { - return m_childModel.index(row, 0); - } - } - return QModelIndex(); -} - -QPointer CrateFeature::getTableModel(int paneId) { - auto it = m_crateTableModel.find(paneId); - if (it == m_crateTableModel.end() || it->isNull()) { - it = m_crateTableModel.insert(paneId, - new CrateTableModel(this, m_pTrackCollection)); - } - return *it; -} - -void CrateFeature::showBrowse(int paneId) { - auto it = m_panes.find(paneId); - auto itId = m_idBrowse.find(paneId); - if (it != m_panes.end() && !it->isNull() && itId != m_idBrowse.end()) { - (*it)->setCurrentIndex(*itId); - } -} - -void CrateFeature::showTable(int paneId) { - auto it = m_panes.find(paneId); - auto itId = m_idTable.find(paneId); - if (it != m_panes.end() && !it->isNull() && itId != m_idTable.end()) { - (*it)->setCurrentIndex(*itId); - } -} diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h deleted file mode 100644 index 23817f0d7fb..00000000000 --- a/src/library/cratefeature.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef CRATEFEATURE_H -#define CRATEFEATURE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "library/libraryfeature.h" -#include "library/treeitemmodel.h" -#include "preferences/usersettings.h" -#include "track/track.h" - -class TrackCollection; -class TreeItemModel; -class CrateTableModel; -class CrateDAO; - -class CrateFeature : public LibraryFeature { - Q_OBJECT - public: - CrateFeature(UserSettingsPointer pConfig, - Library* pLibrary, - QObject* parent, - TrackCollection* pTrackCollection); - virtual ~CrateFeature(); - - QVariant title() override; - QString getIconPath() override; - QString getSettingsName() const override; - bool isSinglePane() const override; - - void onSearch(QString&) {} - - bool dragMoveAccept(QUrl url); - bool dropAcceptChild(const QModelIndex& index, QList urls, - QObject* pSource); - bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); - - QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) override; - - TreeItemModel* getChildModel(); - - signals: - void analyzeTracks(QList); - - public slots: - void activate(); - void activateChild(const QModelIndex& index); - void activateCrate(int crateId); - void onRightClick(const QPoint& globalPos); - void onRightClickChild(const QPoint& globalPos, QModelIndex index); - - void slotCreateCrate(); - void slotDeleteCrate(); - void slotRenameCrate(); - void slotDuplicateCrate(); - void slotAutoDjTrackSourceChanged(); - void slotToggleCrateLock(); - void slotImportPlaylist(); - void slotImportPlaylistFile(const QString &playlist_file); - void slotCreateImportCrate(); - void slotExportPlaylist(); - // Copy all of the tracks in a crate to a new directory (like a thumbdrive). - void slotExportTrackFiles(); - void slotAnalyzeCrate(); - void slotCrateTableChanged(int crateId); - void slotCrateContentChanged(int crateId); - void slotCrateTableRenamed(int crateId, QString a_strName); - void htmlLinkClicked(const QUrl& link); - - private slots: - void slotTrackSelected(TrackPointer pTrack); - void slotResetSelectedTrack(); - - private: - QString getValidCrateName(); - QString getRootViewHtml() const; - QModelIndex constructChildModel(int selected_id); - void updateChildModel(int selected_id); - void clearChildModel(); - void buildCrateList(); - int crateIdFromIndex(QModelIndex index); - // Get the QModelIndex of a crate based on its id. Returns QModelIndex() - // on failure. - QModelIndex indexFromCrateId(int crateId); - - QPointer getTableModel(int paneId); - void showBrowse(int paneId); - void showTable(int paneId); - - TrackCollection* m_pTrackCollection; - CrateDAO& m_crateDao; - QAction* m_pCreateCrateAction; - QAction* m_pDeleteCrateAction; - QAction* m_pRenameCrateAction; - QAction* m_pLockCrateAction; - QAction* m_pDuplicateCrateAction; - QAction* m_pAutoDjTrackSource; - QAction* m_pImportPlaylistAction; - QAction* m_pCreateImportPlaylistAction; - QAction* m_pExportPlaylistAction; - QAction* m_pExportTrackFilesAction; - QAction* m_pAnalyzeCrateAction; - QList > m_crateList; - QHash > m_crateTableModel; - CrateTableModel* m_pCrateTableModel; - QModelIndex m_lastRightClickedIndex; - TreeItemModel m_childModel; - TrackPointer m_pSelectedTrack; - QSet m_cratesSelectedTrackIsIn; - QHash > m_panes; - QHash m_idBrowse; - QHash m_idTable; - QHash m_lastClickedIndex; -}; - -#endif /* CRATEFEATURE_H */ diff --git a/src/library/cratetablemodel.cpp b/src/library/cratetablemodel.cpp deleted file mode 100644 index 3ffc8cc8e9d..00000000000 --- a/src/library/cratetablemodel.cpp +++ /dev/null @@ -1,195 +0,0 @@ - -// cratetablemodel.cpp -// Created 10/25/2009 by RJ Ryan (rryan@mit.edu) - -#include - -#include "library/cratetablemodel.h" -#include "library/queryutil.h" -#include "library/trackcollection.h" -#include "mixer/playermanager.h" - -CrateTableModel::CrateTableModel(QObject* pParent, - TrackCollection* pTrackCollection) - : BaseSqlTableModel(pParent, pTrackCollection, - "mixxx.db.model.crate"), - m_iCrateId(-1), - m_crateDAO(pTrackCollection->getCrateDAO()) { -} - -CrateTableModel::~CrateTableModel() { -} - -void CrateTableModel::setTableModel(int crateId) { - //qDebug() << "CrateTableModel::setCrate()" << crateId; - if (crateId == m_iCrateId) { - qDebug() << "Already focused on crate " << crateId; - return; - } - m_iCrateId = crateId; - - QString tableName = QString("crate_%1").arg(m_iCrateId); - QSqlQuery query(m_database); - FieldEscaper escaper(m_database); - QString filter = "library.mixxx_deleted = 0"; - QStringList columns; - columns << "crate_tracks." + CRATETRACKSTABLE_TRACKID + " AS " + LIBRARYTABLE_ID - << "'' AS " + LIBRARYTABLE_PREVIEW - // For sorting the cover art column we give LIBRARYTABLE_COVERART - // the same value as the cover hash. - << LIBRARYTABLE_COVERART_HASH + " AS " + LIBRARYTABLE_COVERART; - - // We drop files that have been explicitly deleted from mixxx - // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where - // removed files were not removed from crates, so some users will have - // libraries where this is the case. - QString queryString = QString("CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " - "SELECT %2 FROM %3 " - "INNER JOIN library ON library.id = %3.%4 " - "WHERE %3.%5 = %6 AND %7") - .arg(escaper.escapeString(tableName), - columns.join(","), - CRATE_TRACKS_TABLE, - CRATETRACKSTABLE_TRACKID, - CRATETRACKSTABLE_CRATEID, - QString::number(crateId), - filter); - query.prepare(queryString); - if (!query.exec()) { - LOG_FAILED_QUERY(query); - } - - columns[0] = LIBRARYTABLE_ID; - columns[1] = LIBRARYTABLE_PREVIEW; - columns[2] = LIBRARYTABLE_COVERART; - setTable(tableName, LIBRARYTABLE_ID, columns, - m_pTrackCollection->getTrackSource()); - setSearch(""); - setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); -} - -bool CrateTableModel::addTrack(const QModelIndex& index, QString location) { - Q_UNUSED(index); - - // This will only succeed if the file actually exist. - QFileInfo fileInfo(location); - if (!fileInfo.exists()) { - qDebug() << "CrateTableModel::addTrack:" - << "File" - << location - << "not found"; - return false; - } - - TrackDAO& trackDao = m_pTrackCollection->getTrackDAO(); - // If a track is dropped but it isn't in the library, then add it because - // the user probably dropped a file from outside Mixxx into this crate. - // If the track is already contained in the library it will not insert - // a duplicate. It also handles unremoving logic if the track has been - // removed from the library recently and re-adds it. - const TrackPointer pTrack(trackDao.addSingleTrack(fileInfo, true)); - if (pTrack.isNull()) { - qDebug() << "CrateTableModel::addTrack:" - << "Failed to add track" - << location - << "to library"; - return false; - } - - const TrackId trackId(pTrack->getId()); - if (m_pTrackCollection->getCrateDAO().addTrackToCrate(trackId, m_iCrateId)) { - // TODO(rryan) just add the track dont select - select(); - return true; - } else { - qDebug() << "CrateTableModel::addTrack:" - << "Failed to add track" - << location - << "to crate" - << m_iCrateId; - return false; - } -} - -int CrateTableModel::addTracks(const QModelIndex& index, - const QList& locations) { - Q_UNUSED(index); - // If a track is dropped but it isn't in the library, then add it because - // the user probably dropped a file from outside Mixxx into this crate. - QList fileInfoList; - foreach(QString fileLocation, locations) { - QFileInfo fileInfo(fileLocation); - if (fileInfo.exists()) { - fileInfoList.append(fileInfo); - } - } - - QList trackIds(m_trackDAO.addMultipleTracks(fileInfoList, true)); - - int tracksAdded = m_crateDAO.addTracksToCrate(m_iCrateId, &trackIds); - if (tracksAdded > 0) { - select(); - } - - if (locations.size() - tracksAdded > 0) { - qDebug() << "CrateTableModel::addTracks could not add" - << locations.size() - tracksAdded - << "to crate" << m_iCrateId; - } - return tracksAdded; -} - -void CrateTableModel::removeTracks(const QModelIndexList& indices) { - bool locked = m_crateDAO.isCrateLocked(m_iCrateId); - - if (!locked) { - QList trackIds; - foreach (QModelIndex index, indices) { - trackIds.append(getTrackId(index)); - } - m_crateDAO.removeTracksFromCrate(trackIds, m_iCrateId); - select(); - } -} - -bool CrateTableModel::isColumnInternal(int column) { - if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ID) || - column == fieldIndex(ColumnCache::COLUMN_CRATETRACKSTABLE_TRACKID) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PLAYED) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_MIXXXDELETED) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID)|| - column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_FSDELETED) || - (PlayerManager::numPreviewDecks() == 0 && - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_LOCATION) || - column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_HASH)) { - return true; - } - return false; -} - -TrackModel::CapabilitiesFlags CrateTableModel::getCapabilities() const { - CapabilitiesFlags caps = TRACKMODELCAPS_NONE - | TRACKMODELCAPS_RECEIVEDROPS - | TRACKMODELCAPS_ADDTOPLAYLIST - | TRACKMODELCAPS_ADDTOCRATE - | TRACKMODELCAPS_ADDTOAUTODJ - | TRACKMODELCAPS_RELOADMETADATA - | TRACKMODELCAPS_LOADTODECK - | TRACKMODELCAPS_LOADTOSAMPLER - | TRACKMODELCAPS_LOADTOPREVIEWDECK - | TRACKMODELCAPS_REMOVE - | TRACKMODELCAPS_MANIPULATEBEATS - | TRACKMODELCAPS_CLEAR_BEATS - | TRACKMODELCAPS_RESETPLAYED; - - bool locked = m_crateDAO.isCrateLocked(m_iCrateId); - if (locked) { - caps |= TRACKMODELCAPS_LOCKED; - } - - return caps; -} diff --git a/src/library/cratetablemodel.h b/src/library/cratetablemodel.h deleted file mode 100644 index 10a080e9ebc..00000000000 --- a/src/library/cratetablemodel.h +++ /dev/null @@ -1,34 +0,0 @@ -// cratetablemodel.h -// Created 10/25/2009 by RJ Ryan (rryan@mit.edu) - -#ifndef CRATETABLEMODEL_H -#define CRATETABLEMODEL_H - -#include "library/basesqltablemodel.h" -#include "library/dao/cratedao.h" - -class CrateTableModel : public BaseSqlTableModel { - Q_OBJECT - public: - CrateTableModel(QObject* parent, TrackCollection* pTrackCollection); - virtual ~CrateTableModel(); - - void setTableModel(int crateId=-1); - int getCrate() const { - return m_iCrateId; - } - - // From TrackModel - bool isColumnInternal(int column); - void removeTracks(const QModelIndexList& indices); - bool addTrack(const QModelIndex &index, QString location); - // Returns the number of unsuccessful track additions - int addTracks(const QModelIndex& index, const QList& locations); - TrackModel::CapabilitiesFlags getCapabilities() const; - - private: - int m_iCrateId; - CrateDAO& m_crateDAO; -}; - -#endif /* CRATETABLEMODEL_H */ From 4f1e9fa877a8e974532eabe5cbe24ccf10e70ebd Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 14:33:01 +0200 Subject: [PATCH 483/552] Move Maintenance Feature --- build/depends.py | 15 ++++++++------- .../{ => features/maintenance}/dlghidden.cpp | 4 ++-- .../{ => features/maintenance}/dlghidden.h | 8 +++----- .../{ => features/maintenance}/dlghidden.ui | 0 .../{ => features/maintenance}/dlgmissing.cpp | 4 ++-- .../{ => features/maintenance}/dlgmissing.h | 8 +++----- .../{ => features/maintenance}/dlgmissing.ui | 0 .../maintenance}/hiddentablemodel.cpp | 2 +- .../{ => features/maintenance}/hiddentablemodel.h | 0 .../maintenance}/maintenancefeature.cpp | 10 +++++----- .../maintenance}/maintenancefeature.h | 0 .../maintenance}/missingtablemodel.cpp | 4 ++-- .../maintenance}/missingtablemodel.h | 2 +- src/library/library.cpp | 2 +- src/library/mixxxlibraryfeature.cpp | 4 ---- 15 files changed, 28 insertions(+), 35 deletions(-) rename src/library/{ => features/maintenance}/dlghidden.cpp (90%) rename src/library/{ => features/maintenance}/dlghidden.h (89%) rename src/library/{ => features/maintenance}/dlghidden.ui (100%) rename src/library/{ => features/maintenance}/dlgmissing.cpp (89%) rename src/library/{ => features/maintenance}/dlgmissing.h (89%) rename src/library/{ => features/maintenance}/dlgmissing.ui (100%) rename src/library/{ => features/maintenance}/hiddentablemodel.cpp (98%) rename src/library/{ => features/maintenance}/hiddentablemodel.h (100%) rename src/library/{ => features/maintenance}/maintenancefeature.cpp (95%) rename src/library/{ => features/maintenance}/maintenancefeature.h (100%) rename src/library/{ => features/maintenance}/missingtablemodel.cpp (98%) rename src/library/{ => features/maintenance}/missingtablemodel.h (95%) diff --git a/build/depends.py b/build/depends.py index c4251a3e9db..ef17af66fe4 100644 --- a/build/depends.py +++ b/build/depends.py @@ -859,8 +859,6 @@ def sources(self, build): "library/librarytablemodel.cpp", "library/searchquery.cpp", "library/searchqueryparser.cpp", - "library/missingtablemodel.cpp", - "library/hiddentablemodel.cpp", "library/proxytrackmodel.cpp", "library/coverart.cpp", "library/coverartcache.cpp", @@ -875,11 +873,8 @@ def sources(self, build): "library/playlistfeature.cpp", "library/historyfeature.cpp", "library/dlgcoverartfullsize.cpp", - "library/dlghidden.cpp", - "library/dlgmissing.cpp", "library/dlgtagfetcher.cpp", "library/dlgtrackinfo.cpp", - "library/maintenancefeature.cpp", "library/historytreemodel.cpp", "library/libraryfoldermodel.cpp", "library/dao/savedqueriesdao.cpp", @@ -914,6 +909,12 @@ def sources(self, build): "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", + "library/features/maintenance/dlghidden.cpp", + "library/features/maintenance/dlgmissing.cpp", + "library/features/maintenance/hiddentablemodel.cpp", + "library/features/maintenance/maintenancefeature.cpp", + "library/features/maintenance/missingtablemodel.cpp", + # External Library Features "library/features/baseexternalfeature/baseexternallibraryfeature.cpp", "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", @@ -1121,13 +1122,13 @@ def sources(self, build): 'dialog/dlgaboutdlg.ui', 'dialog/dlgdevelopertoolsdlg.ui', 'library/dlgcoverartfullsize.ui', - 'library/dlghidden.ui', - 'library/dlgmissing.ui', 'library/dlgtagfetcher.ui', 'library/dlgtrackinfo.ui', 'library/export/dlgtrackexport.ui', 'library/features/analysis/dlganalysis.ui', 'library/features/autodj/dlgautodj.ui', + 'library/features/maintenance/dlghidden.ui', + 'library/features/maintenance/dlgmissing.ui', 'library/features/recording/dlgrecording.ui', 'preferences/dialog/dlgprefautodjdlg.ui', 'preferences/dialog/dlgprefbeatsdlg.ui', diff --git a/src/library/dlghidden.cpp b/src/library/features/maintenance/dlghidden.cpp similarity index 90% rename from src/library/dlghidden.cpp rename to src/library/features/maintenance/dlghidden.cpp index 54f8a46030f..203c0088576 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/features/maintenance/dlghidden.cpp @@ -1,7 +1,7 @@ #include "QItemSelection" -#include "library/dlghidden.h" -#include "library/hiddentablemodel.h" +#include "library/features/maintenance/dlghidden.h" +#include "library/features/maintenance/hiddentablemodel.h" #include "widget/wtracktableview.h" #include "util/assert.h" diff --git a/src/library/dlghidden.h b/src/library/features/maintenance/dlghidden.h similarity index 89% rename from src/library/dlghidden.h rename to src/library/features/maintenance/dlghidden.h index a084ea450e3..2fd67d83ed8 100644 --- a/src/library/dlghidden.h +++ b/src/library/features/maintenance/dlghidden.h @@ -1,12 +1,10 @@ #ifndef DLGHIDDEN_H #define DLGHIDDEN_H -#include "library/ui_dlghidden.h" -#include "preferences/usersettings.h" -#include "library/library.h" -#include "library/libraryview.h" -#include "library/trackcollection.h" #include "controllers/keyboard/keyboardeventfilter.h" +#include "library/features/maintenance/ui_dlghidden.h" +#include "library/trackcollection.h" +#include "preferences/usersettings.h" class WTrackTableView; class HiddenTableModel; diff --git a/src/library/dlghidden.ui b/src/library/features/maintenance/dlghidden.ui similarity index 100% rename from src/library/dlghidden.ui rename to src/library/features/maintenance/dlghidden.ui diff --git a/src/library/dlgmissing.cpp b/src/library/features/maintenance/dlgmissing.cpp similarity index 89% rename from src/library/dlgmissing.cpp rename to src/library/features/maintenance/dlgmissing.cpp index 72e17b67aa4..140d8c916c6 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/features/maintenance/dlgmissing.cpp @@ -1,6 +1,6 @@ -#include "library/dlgmissing.h" +#include "library/features/maintenance/dlgmissing.h" -#include "library/missingtablemodel.h" +#include "library/features/maintenance/missingtablemodel.h" #include "widget/wtracktableview.h" #include "util/assert.h" diff --git a/src/library/dlgmissing.h b/src/library/features/maintenance/dlgmissing.h similarity index 89% rename from src/library/dlgmissing.h rename to src/library/features/maintenance/dlgmissing.h index 6438e035b36..22ccbe0a729 100644 --- a/src/library/dlgmissing.h +++ b/src/library/features/maintenance/dlgmissing.h @@ -1,12 +1,10 @@ #ifndef DLGMISSING_H #define DLGMISSING_H -#include "library/ui_dlgmissing.h" -#include "preferences/usersettings.h" -#include "library/library.h" -#include "library/libraryview.h" -#include "library/trackcollection.h" #include "controllers/keyboard/keyboardeventfilter.h" +#include "library/features/maintenance/ui_dlgmissing.h" +#include "library/trackcollection.h" +#include "preferences/usersettings.h" class WTrackTableView; class MissingTableModel; diff --git a/src/library/dlgmissing.ui b/src/library/features/maintenance/dlgmissing.ui similarity index 100% rename from src/library/dlgmissing.ui rename to src/library/features/maintenance/dlgmissing.ui diff --git a/src/library/hiddentablemodel.cpp b/src/library/features/maintenance/hiddentablemodel.cpp similarity index 98% rename from src/library/hiddentablemodel.cpp rename to src/library/features/maintenance/hiddentablemodel.cpp index c103ed88f22..e1a090ea5a2 100644 --- a/src/library/hiddentablemodel.cpp +++ b/src/library/features/maintenance/hiddentablemodel.cpp @@ -1,4 +1,4 @@ -#include "library/hiddentablemodel.h" +#include "library/features/maintenance/hiddentablemodel.h" HiddenTableModel::HiddenTableModel(QObject* parent, TrackCollection* pTrackCollection) diff --git a/src/library/hiddentablemodel.h b/src/library/features/maintenance/hiddentablemodel.h similarity index 100% rename from src/library/hiddentablemodel.h rename to src/library/features/maintenance/hiddentablemodel.h diff --git a/src/library/maintenancefeature.cpp b/src/library/features/maintenance/maintenancefeature.cpp similarity index 95% rename from src/library/maintenancefeature.cpp rename to src/library/features/maintenance/maintenancefeature.cpp index cc956a2235b..9ce4eb2474c 100644 --- a/src/library/maintenancefeature.cpp +++ b/src/library/features/maintenance/maintenancefeature.cpp @@ -1,11 +1,11 @@ #include #include -#include "library/dlghidden.h" -#include "library/dlgmissing.h" -#include "library/hiddentablemodel.h" -#include "library/maintenancefeature.h" -#include "library/missingtablemodel.h" +#include "library/features/maintenance/dlghidden.h" +#include "library/features/maintenance/dlgmissing.h" +#include "library/features/maintenance/hiddentablemodel.h" +#include "library/features/maintenance/maintenancefeature.h" +#include "library/features/maintenance/missingtablemodel.h" #include "widget/wtracktableview.h" diff --git a/src/library/maintenancefeature.h b/src/library/features/maintenance/maintenancefeature.h similarity index 100% rename from src/library/maintenancefeature.h rename to src/library/features/maintenance/maintenancefeature.h diff --git a/src/library/missingtablemodel.cpp b/src/library/features/maintenance/missingtablemodel.cpp similarity index 98% rename from src/library/missingtablemodel.cpp rename to src/library/features/maintenance/missingtablemodel.cpp index e706777cbef..d69130402fd 100644 --- a/src/library/missingtablemodel.cpp +++ b/src/library/features/maintenance/missingtablemodel.cpp @@ -1,8 +1,8 @@ #include -#include "library/trackcollection.h" -#include "library/missingtablemodel.h" +#include "library/features/maintenance/missingtablemodel.h" #include "library/librarytablemodel.h" +#include "library/trackcollection.h" const QString MissingTableModel::MISSINGFILTER = "mixxx_deleted=0 AND fs_deleted=1"; diff --git a/src/library/missingtablemodel.h b/src/library/features/maintenance/missingtablemodel.h similarity index 95% rename from src/library/missingtablemodel.h rename to src/library/features/maintenance/missingtablemodel.h index aca3d5c684f..f6678635fac 100644 --- a/src/library/missingtablemodel.h +++ b/src/library/features/maintenance/missingtablemodel.h @@ -6,8 +6,8 @@ #include #include -#include "trackmodel.h" #include "library/basesqltablemodel.h" +#include "library/trackmodel.h" class TrackCollection; diff --git a/src/library/library.cpp b/src/library/library.cpp index f1dc062bc40..5acb4ad0b84 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -13,6 +13,7 @@ #include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" +#include "library/features/maintenance/maintenancefeature.h" #include "library/features/recording/recordingfeature.h" #include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/features/traktor/traktorfeature.h" @@ -25,7 +26,6 @@ #include "library/library_preferences.h" #include "library/librarysidebarexpandedmanager.h" #include "library/librarytablemodel.h" -#include "library/maintenancefeature.h" #include "library/mixxxlibraryfeature.h" #include "library/playlistfeature.h" #include "library/sidebarmodel.h" diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 525eefe0532..2a148ed4df5 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -9,16 +9,12 @@ #include "library/mixxxlibraryfeature.h" #include "library/basetrackcache.h" -#include "library/dlghidden.h" -#include "library/dlgmissing.h" -#include "library/library.h" #include "library/librarytablemodel.h" #include "library/parser.h" #include "library/queryutil.h" #include "library/trackcollection.h" #include "sources/soundsourceproxy.h" #include "util/dnd.h" -#include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" #include "widget/wlibrarystack.h" #include "widget/wtracktableview.h" From eca6620393aaf9963d0abf527d140ea8e2159d61 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 14:39:43 +0200 Subject: [PATCH 484/552] Move MixxxLibrary --- build/depends.py | 5 +++-- .../{ => features/mixxxlibrary}/mixxxlibraryfeature.cpp | 2 +- .../{ => features/mixxxlibrary}/mixxxlibraryfeature.h | 2 +- .../{ => features/mixxxlibrary}/mixxxlibrarytreemodel.cpp | 2 +- .../{ => features/mixxxlibrary}/mixxxlibrarytreemodel.h | 0 src/library/library.cpp | 2 +- src/library/libraryfoldersfeature.h | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) rename src/library/{ => features/mixxxlibrary}/mixxxlibraryfeature.cpp (99%) rename src/library/{ => features/mixxxlibrary}/mixxxlibraryfeature.h (97%) rename src/library/{ => features/mixxxlibrary}/mixxxlibrarytreemodel.cpp (99%) rename src/library/{ => features/mixxxlibrary}/mixxxlibrarytreemodel.h (100%) diff --git a/build/depends.py b/build/depends.py index ef17af66fe4..fc219b85f4b 100644 --- a/build/depends.py +++ b/build/depends.py @@ -867,8 +867,6 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", "library/dao/directorydao.cpp", - "library/mixxxlibraryfeature.cpp", - "library/mixxxlibrarytreemodel.cpp", "library/libraryfoldersfeature.cpp", "library/playlistfeature.cpp", "library/historyfeature.cpp", @@ -915,6 +913,9 @@ def sources(self, build): "library/features/maintenance/maintenancefeature.cpp", "library/features/maintenance/missingtablemodel.cpp", + "library/features/mixxxlibrary/mixxxlibraryfeature.cpp", + "library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp", + # External Library Features "library/features/baseexternalfeature/baseexternallibraryfeature.cpp", "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp similarity index 99% rename from src/library/mixxxlibraryfeature.cpp rename to src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp index 2a148ed4df5..10327d99c9c 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp @@ -6,7 +6,7 @@ #include #include -#include "library/mixxxlibraryfeature.h" +#include "library/features/mixxxlibrary/mixxxlibraryfeature.h" #include "library/basetrackcache.h" #include "library/librarytablemodel.h" diff --git a/src/library/mixxxlibraryfeature.h b/src/library/features/mixxxlibrary/mixxxlibraryfeature.h similarity index 97% rename from src/library/mixxxlibraryfeature.h rename to src/library/features/mixxxlibrary/mixxxlibraryfeature.h index c097e1530e9..ae6ba93edd5 100644 --- a/src/library/mixxxlibraryfeature.h +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.h @@ -17,7 +17,7 @@ #include #include "library/libraryfeature.h" -#include "library/mixxxlibrarytreemodel.h" +#include "library/features/mixxxlibrary/mixxxlibrarytreemodel.h" #include "library/dao/trackdao.h" #include "preferences/usersettings.h" diff --git a/src/library/mixxxlibrarytreemodel.cpp b/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp similarity index 99% rename from src/library/mixxxlibrarytreemodel.cpp rename to src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp index 9deb002ac77..314715600eb 100644 --- a/src/library/mixxxlibrarytreemodel.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp @@ -7,7 +7,7 @@ #include "util/stringhelper.h" #include "widget/wpixmapstore.h" -#include "library/mixxxlibrarytreemodel.h" +#include "library/features/mixxxlibrary/mixxxlibrarytreemodel.h" namespace { // This is used since MixxxLibraryTreeModel inherits QAbstractItemModel diff --git a/src/library/mixxxlibrarytreemodel.h b/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.h similarity index 100% rename from src/library/mixxxlibrarytreemodel.h rename to src/library/features/mixxxlibrary/mixxxlibrarytreemodel.h diff --git a/src/library/library.cpp b/src/library/library.cpp index 5acb4ad0b84..b6d67974454 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -14,6 +14,7 @@ #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" #include "library/features/maintenance/maintenancefeature.h" +#include "library/features/mixxxlibrary/mixxxlibraryfeature.h" #include "library/features/recording/recordingfeature.h" #include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/features/traktor/traktorfeature.h" @@ -26,7 +27,6 @@ #include "library/library_preferences.h" #include "library/librarysidebarexpandedmanager.h" #include "library/librarytablemodel.h" -#include "library/mixxxlibraryfeature.h" #include "library/playlistfeature.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" diff --git a/src/library/libraryfoldersfeature.h b/src/library/libraryfoldersfeature.h index 7e2d367a958..398a6ee42e7 100644 --- a/src/library/libraryfoldersfeature.h +++ b/src/library/libraryfoldersfeature.h @@ -1,7 +1,7 @@ #ifndef LIBRARYFOLDERSFEATURE_H #define LIBRARYFOLDERSFEATURE_H -#include "library/mixxxlibraryfeature.h" +#include "library/features/mixxxlibrary/mixxxlibraryfeature.h" class LibraryFoldersModel; From 4c98543c47f426831b9737efcdc9559d41f21df1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 17:16:51 +0200 Subject: [PATCH 485/552] Move LibraryFolders feature --- build/depends.py | 5 +++-- .../{ => features/libraryfolder}/libraryfoldermodel.cpp | 2 +- .../{ => features/libraryfolder}/libraryfoldermodel.h | 0 .../{ => features/libraryfolder}/libraryfoldersfeature.cpp | 4 ++-- .../{ => features/libraryfolder}/libraryfoldersfeature.h | 0 src/library/library.cpp | 3 ++- 6 files changed, 8 insertions(+), 6 deletions(-) rename src/library/{ => features/libraryfolder}/libraryfoldermodel.cpp (99%) rename src/library/{ => features/libraryfolder}/libraryfoldermodel.h (100%) rename src/library/{ => features/libraryfolder}/libraryfoldersfeature.cpp (93%) rename src/library/{ => features/libraryfolder}/libraryfoldersfeature.h (100%) diff --git a/build/depends.py b/build/depends.py index fc219b85f4b..1373a254cd8 100644 --- a/build/depends.py +++ b/build/depends.py @@ -867,14 +867,12 @@ def sources(self, build): "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", "library/dao/directorydao.cpp", - "library/libraryfoldersfeature.cpp", "library/playlistfeature.cpp", "library/historyfeature.cpp", "library/dlgcoverartfullsize.cpp", "library/dlgtagfetcher.cpp", "library/dlgtrackinfo.cpp", "library/historytreemodel.cpp", - "library/libraryfoldermodel.cpp", "library/dao/savedqueriesdao.cpp", "library/export/trackexportdlg.cpp", @@ -907,6 +905,9 @@ def sources(self, build): "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", + "library/features/libraryfolder/libraryfoldermodel.cpp", + "library/features/libraryfolder/libraryfoldersfeature.cpp", + "library/features/maintenance/dlghidden.cpp", "library/features/maintenance/dlgmissing.cpp", "library/features/maintenance/hiddentablemodel.cpp", diff --git a/src/library/libraryfoldermodel.cpp b/src/library/features/libraryfolder/libraryfoldermodel.cpp similarity index 99% rename from src/library/libraryfoldermodel.cpp rename to src/library/features/libraryfolder/libraryfoldermodel.cpp index cbcc7a6dc03..977be8126a0 100644 --- a/src/library/libraryfoldermodel.cpp +++ b/src/library/features/libraryfolder/libraryfoldermodel.cpp @@ -1,6 +1,6 @@ #include -#include "library/libraryfoldermodel.h" +#include "library/features/libraryfolder/libraryfoldermodel.h" #include "library/libraryfeature.h" #include "library/queryutil.h" diff --git a/src/library/libraryfoldermodel.h b/src/library/features/libraryfolder/libraryfoldermodel.h similarity index 100% rename from src/library/libraryfoldermodel.h rename to src/library/features/libraryfolder/libraryfoldermodel.h diff --git a/src/library/libraryfoldersfeature.cpp b/src/library/features/libraryfolder/libraryfoldersfeature.cpp similarity index 93% rename from src/library/libraryfoldersfeature.cpp rename to src/library/features/libraryfolder/libraryfoldersfeature.cpp index 6c4f1b5d71b..1d53c43c60b 100644 --- a/src/library/libraryfoldersfeature.cpp +++ b/src/library/features/libraryfolder/libraryfoldersfeature.cpp @@ -2,9 +2,9 @@ #include #include -#include "library/libraryfoldersfeature.h" +#include "library/features/libraryfolder/libraryfoldersfeature.h" -#include "library/libraryfoldermodel.h" +#include "library/features/libraryfolder/libraryfoldermodel.h" #include "widget/wlibrarysidebar.h" LibraryFoldersFeature::LibraryFoldersFeature(UserSettingsPointer pConfig, diff --git a/src/library/libraryfoldersfeature.h b/src/library/features/libraryfolder/libraryfoldersfeature.h similarity index 100% rename from src/library/libraryfoldersfeature.h rename to src/library/features/libraryfolder/libraryfoldersfeature.h diff --git a/src/library/library.cpp b/src/library/library.cpp index b6d67974454..cab0806f24c 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -13,12 +13,13 @@ #include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" #include "library/features/itunes/itunesfeature.h" +#include "library/features/libraryfolder/libraryfoldersfeature.h" #include "library/features/maintenance/maintenancefeature.h" #include "library/features/mixxxlibrary/mixxxlibraryfeature.h" #include "library/features/recording/recordingfeature.h" #include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/features/traktor/traktorfeature.h" -#include "library/libraryfoldersfeature.h" + #include "library/historyfeature.h" #include "library/librarycontrol.h" #include "library/libraryfeature.h" From 7f1d02c0a8c8e569331c654a4c139928bc875aa6 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 17:21:18 +0200 Subject: [PATCH 486/552] Move HistoryFeature --- build/depends.py | 6 ++++-- src/library/{ => features/history}/historyfeature.cpp | 4 ++-- src/library/{ => features/history}/historyfeature.h | 0 src/library/{ => features/history}/historytreemodel.cpp | 4 ++-- src/library/{ => features/history}/historytreemodel.h | 0 src/library/library.cpp | 7 +++---- 6 files changed, 11 insertions(+), 10 deletions(-) rename src/library/{ => features/history}/historyfeature.cpp (99%) rename src/library/{ => features/history}/historyfeature.h (100%) rename src/library/{ => features/history}/historytreemodel.cpp (98%) rename src/library/{ => features/history}/historytreemodel.h (100%) diff --git a/build/depends.py b/build/depends.py index 1373a254cd8..c220f0413a6 100644 --- a/build/depends.py +++ b/build/depends.py @@ -868,11 +868,9 @@ def sources(self, build): "library/libraryfeature.cpp", "library/dao/directorydao.cpp", "library/playlistfeature.cpp", - "library/historyfeature.cpp", "library/dlgcoverartfullsize.cpp", "library/dlgtagfetcher.cpp", "library/dlgtrackinfo.cpp", - "library/historytreemodel.cpp", "library/dao/savedqueriesdao.cpp", "library/export/trackexportdlg.cpp", @@ -905,6 +903,9 @@ def sources(self, build): "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", + "library/features/history/historyfeature.cpp", + "library/features/history/historytreemodel.cpp", + "library/features/libraryfolder/libraryfoldermodel.cpp", "library/features/libraryfolder/libraryfoldersfeature.cpp", @@ -921,6 +922,7 @@ def sources(self, build): "library/features/baseexternalfeature/baseexternallibraryfeature.cpp", "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", "library/features/baseexternalfeature/baseexternalplaylistmodel.cpp", + "library/features/itunes/itunesfeature.cpp", "library/features/recording/recordingfeature.cpp", "library/features/recording/dlgrecording.cpp", diff --git a/src/library/historyfeature.cpp b/src/library/features/history/historyfeature.cpp similarity index 99% rename from src/library/historyfeature.cpp rename to src/library/features/history/historyfeature.cpp index 88251474311..968170f75ef 100644 --- a/src/library/historyfeature.cpp +++ b/src/library/features/history/historyfeature.cpp @@ -2,10 +2,10 @@ #include #include -#include "library/historyfeature.h" +#include "library/features/history/historyfeature.h" #include "control/controlobject.h" -#include "library/historytreemodel.h" +#include "library/features/history/historytreemodel.h" #include "library/playlisttablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" diff --git a/src/library/historyfeature.h b/src/library/features/history/historyfeature.h similarity index 100% rename from src/library/historyfeature.h rename to src/library/features/history/historyfeature.h diff --git a/src/library/historytreemodel.cpp b/src/library/features/history/historytreemodel.cpp similarity index 98% rename from src/library/historytreemodel.cpp rename to src/library/features/history/historytreemodel.cpp index 58f6ccac7f4..cbcb19697e7 100644 --- a/src/library/historytreemodel.cpp +++ b/src/library/features/history/historytreemodel.cpp @@ -1,10 +1,10 @@ #include -#include "library/historyfeature.h" +#include "library/features/history/historyfeature.h" #include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/historytreemodel.h" +#include "library/features/history/historytreemodel.h" HistoryTreeModel::HistoryTreeModel(HistoryFeature* pFeature, TrackCollection* pTrackCollection, diff --git a/src/library/historytreemodel.h b/src/library/features/history/historytreemodel.h similarity index 100% rename from src/library/historytreemodel.h rename to src/library/features/history/historytreemodel.h diff --git a/src/library/library.cpp b/src/library/library.cpp index cab0806f24c..7da7f15f6b1 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -7,11 +7,14 @@ #include #include +#include "controllers/keyboard/keyboardeventfilter.h" + #include "library/features/analysis/analysisfeature.h" #include "library/features/autodj/autodjfeature.h" #include "library/features/banshee/bansheefeature.h" #include "library/features/browse/browsefeature.h" #include "library/features/crates/cratefeature.h" +#include "library/features/history/historyfeature.h" #include "library/features/itunes/itunesfeature.h" #include "library/features/libraryfolder/libraryfoldersfeature.h" #include "library/features/maintenance/maintenancefeature.h" @@ -20,7 +23,6 @@ #include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/features/traktor/traktorfeature.h" -#include "library/historyfeature.h" #include "library/librarycontrol.h" #include "library/libraryfeature.h" #include "library/library.h" @@ -36,12 +38,9 @@ #include "util/assert.h" #include "util/sandbox.h" - #include "widget/wbuttonbar.h" #include "widget/wfeatureclickbutton.h" -#include "controllers/keyboard/keyboardeventfilter.h" - // The default row height of the library. const int Library::kDefaultRowHeightPx = 20; From 8b31577214eb0473091ae97bd328a68e7b3652a2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 18:47:05 +0200 Subject: [PATCH 487/552] Move Playlist Feature --- build/depends.py | 17 +++++++++-------- .../features/autodj/autodjprocessor.cpp | 4 ++-- src/library/features/autodj/autodjprocessor.h | 4 ++-- src/library/features/autodj/dlgautodj.cpp | 6 +++--- .../baseplaylist/baseplaylistfeature.cpp | 6 +++--- .../baseplaylist/baseplaylistfeature.h | 2 +- .../features/history/historyfeature.cpp | 6 +++--- .../playlist}/playlistfeature.cpp | 18 ++++++++---------- .../{ => features/playlist}/playlistfeature.h | 0 .../playlist}/playlisttablemodel.cpp | 2 +- .../playlist}/playlisttablemodel.h | 0 src/library/library.cpp | 10 +++++----- 12 files changed, 37 insertions(+), 38 deletions(-) rename src/library/{ => features/playlist}/playlistfeature.cpp (98%) rename src/library/{ => features/playlist}/playlistfeature.h (100%) rename src/library/{ => features/playlist}/playlisttablemodel.cpp (99%) rename src/library/{ => features/playlist}/playlisttablemodel.h (100%) diff --git a/build/depends.py b/build/depends.py index c220f0413a6..6af1231d861 100644 --- a/build/depends.py +++ b/build/depends.py @@ -864,10 +864,8 @@ def sources(self, build): "library/coverartcache.cpp", "library/coverartutils.cpp", - "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", "library/dao/directorydao.cpp", - "library/playlistfeature.cpp", "library/dlgcoverartfullsize.cpp", "library/dlgtagfetcher.cpp", "library/dlgtrackinfo.cpp", @@ -889,20 +887,20 @@ def sources(self, build): "library/features/autodj/autodjprocessor.cpp", "library/features/autodj/dlgautodj.cpp", + "library/features/banshee/bansheedbconnection.cpp", "library/features/banshee/bansheefeature.cpp", "library/features/banshee/bansheeplaylistmodel.cpp", - "library/features/banshee/bansheedbconnection.cpp", "library/features/baseplaylist/baseplaylistfeature.cpp", + "library/features/browse/browsefeature.cpp", "library/features/browse/browsetablemodel.cpp", "library/features/browse/browsethread.cpp", - "library/features/browse/browsefeature.cpp", "library/features/browse/foldertreemodel.cpp", "library/features/crates/cratefeature.cpp", "library/features/crates/cratetablemodel.cpp", - + "library/features/history/historyfeature.cpp", "library/features/history/historytreemodel.cpp", @@ -918,21 +916,24 @@ def sources(self, build): "library/features/mixxxlibrary/mixxxlibraryfeature.cpp", "library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp", + "library/features/playlist/playlistfeature.cpp", + "library/features/playlist/playlisttablemodel.cpp", + # External Library Features "library/features/baseexternalfeature/baseexternallibraryfeature.cpp", - "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", "library/features/baseexternalfeature/baseexternalplaylistmodel.cpp", + "library/features/baseexternalfeature/baseexternaltrackmodel.cpp", "library/features/itunes/itunesfeature.cpp", - "library/features/recording/recordingfeature.cpp", "library/features/recording/dlgrecording.cpp", + "library/features/recording/recordingfeature.cpp", "library/features/rhythmbox/rhythmboxfeature.cpp", "library/features/traktor/traktorfeature.cpp", - "library/sidebarmodel.cpp", "library/library.cpp", "library/librarypanemanager.cpp", "library/librarysidebarexpandedmanager.cpp", + "library/sidebarmodel.cpp", "library/scanner/libraryscanner.cpp", "library/scanner/libraryscannerdlg.cpp", diff --git a/src/library/features/autodj/autodjprocessor.cpp b/src/library/features/autodj/autodjprocessor.cpp index 4f09d15c740..011f0b6bb54 100644 --- a/src/library/features/autodj/autodjprocessor.cpp +++ b/src/library/features/autodj/autodjprocessor.cpp @@ -1,5 +1,3 @@ -#include "library/features/autodj/autodjprocessor.h" - #include "control/controlproxy.h" #include "control/controlpushbutton.h" #include "library/trackcollection.h" @@ -7,6 +5,8 @@ #include "mixer/playermanager.h" #include "util/math.h" +#include "library/features/autodj/autodjprocessor.h" + #define kConfigKey "[Auto DJ]" const char* kTransitionPreferenceName = "Transition"; const double kTransitionPreferenceDefault = 10.0; diff --git a/src/library/features/autodj/autodjprocessor.h b/src/library/features/autodj/autodjprocessor.h index d9a8e768bbd..c50f9a94402 100644 --- a/src/library/features/autodj/autodjprocessor.h +++ b/src/library/features/autodj/autodjprocessor.h @@ -1,13 +1,13 @@ #ifndef AUTODJPROCESSOR_H #define AUTODJPROCESSOR_H +#include #include #include -#include #include "control/controlproxy.h" #include "engine/enginechannel.h" -#include "library/playlisttablemodel.h" +#include "library/features/playlist/playlisttablemodel.h" #include "preferences/usersettings.h" #include "track/track.h" #include "util/class.h" diff --git a/src/library/features/autodj/dlgautodj.cpp b/src/library/features/autodj/dlgautodj.cpp index bec2c3bd8ec..7817f781807 100644 --- a/src/library/features/autodj/dlgautodj.cpp +++ b/src/library/features/autodj/dlgautodj.cpp @@ -1,12 +1,12 @@ #include -#include "library/features/autodj/dlgautodj.h" - -#include "library/playlisttablemodel.h" +#include "library/features/playlist/playlisttablemodel.h" #include "util/assert.h" #include "util/duration.h" #include "widget/wtracktableview.h" +#include "library/features/autodj/dlgautodj.h" + DlgAutoDJ::DlgAutoDJ(QWidget* parent, AutoDJProcessor* pProcessor) : QFrame(parent), diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index 906021499a2..bf44004be61 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -7,17 +7,17 @@ #include "controllers/keyboard/keyboardeventfilter.h" #include "library/export/trackexportwizard.h" +#include "library/features/playlist/playlisttablemodel.h" #include "library/library.h" #include "library/parser.h" +#include "library/parsercsv.h" #include "library/parserm3u.h" #include "library/parserpls.h" -#include "library/parsercsv.h" -#include "library/playlisttablemodel.h" #include "library/trackcollection.h" #include "library/treeitemmodel.h" +#include "util/assert.h" #include "widget/wlibrarystack.h" #include "widget/wlibrarytextbrowser.h" -#include "util/assert.h" BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, Library* pLibrary, diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index ddc0dc99ec4..db30ac0d2a3 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -11,9 +11,9 @@ #include #include -#include "library/libraryfeature.h" #include "library/dao/playlistdao.h" #include "library/dao/trackdao.h" +#include "library/libraryfeature.h" #include "track/track.h" class KeyboardEventFilter; diff --git a/src/library/features/history/historyfeature.cpp b/src/library/features/history/historyfeature.cpp index 968170f75ef..019b9240bab 100644 --- a/src/library/features/history/historyfeature.cpp +++ b/src/library/features/history/historyfeature.cpp @@ -2,17 +2,17 @@ #include #include -#include "library/features/history/historyfeature.h" - #include "control/controlobject.h" #include "library/features/history/historytreemodel.h" -#include "library/playlisttablemodel.h" +#include "library/features/playlist/playlisttablemodel.h" #include "library/queryutil.h" #include "library/trackcollection.h" #include "mixer/playerinfo.h" #include "mixer/playermanager.h" #include "widget/wlibrarysidebar.h" +#include "library/features/history/historyfeature.h" + HistoryFeature::HistoryFeature(UserSettingsPointer pConfig, Library* pLibrary, QObject* parent, diff --git a/src/library/playlistfeature.cpp b/src/library/features/playlist/playlistfeature.cpp similarity index 98% rename from src/library/playlistfeature.cpp rename to src/library/features/playlist/playlistfeature.cpp index fc08d40c751..f85173dcc1f 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/features/playlist/playlistfeature.cpp @@ -1,22 +1,20 @@ -#include -#include +#include #include #include +#include -#include "library/playlistfeature.h" +#include "library/features/playlist/playlistfeature.h" -#include "widget/wlibrary.h" -#include "widget/wlibrarysidebar.h" -#include "widget/wlibrarytextbrowser.h" +#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/features/playlist/playlisttablemodel.h" +#include "library/parser.h" +#include "library/queryutil.h" #include "library/trackcollection.h" -#include "library/playlisttablemodel.h" #include "library/treeitemmodel.h" -#include "library/queryutil.h" -#include "library/parser.h" -#include "controllers/keyboard/keyboardeventfilter.h" #include "sources/soundsourceproxy.h" #include "util/dnd.h" #include "util/duration.h" +#include "widget/wlibrarytextbrowser.h" PlaylistFeature::PlaylistFeature(UserSettingsPointer pConfig, Library* pLibrary, diff --git a/src/library/playlistfeature.h b/src/library/features/playlist/playlistfeature.h similarity index 100% rename from src/library/playlistfeature.h rename to src/library/features/playlist/playlistfeature.h diff --git a/src/library/playlisttablemodel.cpp b/src/library/features/playlist/playlisttablemodel.cpp similarity index 99% rename from src/library/playlisttablemodel.cpp rename to src/library/features/playlist/playlisttablemodel.cpp index 4c702cfbb41..5b290c1c656 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/features/playlist/playlisttablemodel.cpp @@ -1,6 +1,6 @@ #include -#include "library/playlisttablemodel.h" +#include "library/features/playlist/playlisttablemodel.h" #include "library/queryutil.h" #include "mixer/playermanager.h" diff --git a/src/library/playlisttablemodel.h b/src/library/features/playlist/playlisttablemodel.h similarity index 100% rename from src/library/playlisttablemodel.h rename to src/library/features/playlist/playlisttablemodel.h diff --git a/src/library/library.cpp b/src/library/library.cpp index 7da7f15f6b1..2c1a2cce4b0 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -1,11 +1,11 @@ // library.cpp // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) +#include +#include #include #include #include -#include -#include #include "controllers/keyboard/keyboardeventfilter.h" @@ -19,18 +19,18 @@ #include "library/features/libraryfolder/libraryfoldersfeature.h" #include "library/features/maintenance/maintenancefeature.h" #include "library/features/mixxxlibrary/mixxxlibraryfeature.h" +#include "library/features/playlist/playlistfeature.h" #include "library/features/recording/recordingfeature.h" #include "library/features/rhythmbox/rhythmboxfeature.h" #include "library/features/traktor/traktorfeature.h" +#include "library/library_preferences.h" +#include "library/library.h" #include "library/librarycontrol.h" #include "library/libraryfeature.h" -#include "library/library.h" #include "library/librarypanemanager.h" -#include "library/library_preferences.h" #include "library/librarysidebarexpandedmanager.h" #include "library/librarytablemodel.h" -#include "library/playlistfeature.h" #include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" From 45c3adb92707d83697afa40cd7cdb46b9830f91c Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 18:52:38 +0200 Subject: [PATCH 488/552] Refactor includes --- src/library/library.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 2c1a2cce4b0..43001a7fd88 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -25,7 +25,6 @@ #include "library/features/traktor/traktorfeature.h" #include "library/library_preferences.h" -#include "library/library.h" #include "library/librarycontrol.h" #include "library/libraryfeature.h" #include "library/librarypanemanager.h" @@ -41,6 +40,8 @@ #include "widget/wbuttonbar.h" #include "widget/wfeatureclickbutton.h" +#include "library/library.h" + // The default row height of the library. const int Library::kDefaultRowHeightPx = 20; From 0a8e843299f490d4f7812a89dc216cd3309d22af Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 18:58:36 +0200 Subject: [PATCH 489/552] Remove unused variable --- src/library/features/maintenance/maintenancefeature.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/library/features/maintenance/maintenancefeature.cpp b/src/library/features/maintenance/maintenancefeature.cpp index 9ce4eb2474c..d4b8fe7fba4 100644 --- a/src/library/features/maintenance/maintenancefeature.cpp +++ b/src/library/features/maintenance/maintenancefeature.cpp @@ -67,7 +67,6 @@ void MaintenanceFeature::selectionChanged(const QItemSelection&, } else if (*it == Pane::Missing) { m_pMissingView->setSelectedIndexes(selection); } - const QModelIndexList& selection2 = pTable->selectionModel()->selectedRows(); } void MaintenanceFeature::selectAll() { From d207cf33985a3e179ce8a235d40f02e796f0e509 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Sep 2016 22:11:20 +0200 Subject: [PATCH 490/552] Begin creating saved Queries editor --- build/depends.py | 3 + .../savedqueries/dlgsavedquerieseditor.cpp | 23 +++++++ .../savedqueries/dlgsavedquerieseditor.h | 23 +++++++ .../savedqueries/dlgsavedquerieseditor.ui | 67 +++++++++++++++++++ .../savedqueries/savedqueriestablemodel.cpp | 27 ++++++++ .../savedqueries/savedqueriestablemodel.h | 22 ++++++ src/library/dao/savedqueriesdao.h | 27 ++++++++ src/library/library.cpp | 1 + src/widget/wsearchlineedit.cpp | 37 ++++++---- src/widget/wsearchlineedit.h | 4 ++ 10 files changed, 222 insertions(+), 12 deletions(-) create mode 100644 src/dialog/savedqueries/dlgsavedquerieseditor.cpp create mode 100644 src/dialog/savedqueries/dlgsavedquerieseditor.h create mode 100644 src/dialog/savedqueries/dlgsavedquerieseditor.ui create mode 100644 src/dialog/savedqueries/savedqueriestablemodel.cpp create mode 100644 src/dialog/savedqueries/savedqueriestablemodel.h diff --git a/build/depends.py b/build/depends.py index 6af1231d861..ae7cce13b3d 100644 --- a/build/depends.py +++ b/build/depends.py @@ -630,6 +630,8 @@ def sources(self, build): "controllers/dlgprefcontrollers.cpp", "dialog/dlgabout.cpp", "dialog/dlgdevelopertools.cpp", + "dialog/savedqueries/dlgsavedquerieseditor.cpp", + "dialog/savedqueries/savedqueriestablemodel.cpp", "preferences/configobject.cpp", "preferences/dialog/dlgprefautodj.cpp", @@ -1126,6 +1128,7 @@ def sources(self, build): 'controllers/dlgprefcontrollersdlg.ui', 'dialog/dlgaboutdlg.ui', 'dialog/dlgdevelopertoolsdlg.ui', + 'dialog/savedqueries/dlgsavedquerieseditor.ui', 'library/dlgcoverartfullsize.ui', 'library/dlgtagfetcher.ui', 'library/dlgtrackinfo.ui', diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp new file mode 100644 index 00000000000..0057d39c0de --- /dev/null +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp @@ -0,0 +1,23 @@ +#include + +#include "dialog/savedqueries/dlgsavedquerieseditor.h" +#include "dialog/savedqueries/savedqueriestablemodel.h" +#include "library/libraryfeature.h" +#include "library/trackcollection.h" + +DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, + QWidget* parent) + : QDialog(parent), + m_pTrackCollection(pTrackCollection), + m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), + m_pFeature(pFeature) { + setupUi(this); + SavedQueriesTableModel* pTableModel = + new SavedQueriesTableModel(m_pFeature, parent, + m_pTrackCollection->getDatabase()); + tableView->setModel(pTableModel); + for (int i = 0; i < SavedQueryColums::NUM_COLUMNS; ++i) { + tableView->setColumnHidden(i, pTableModel->isColumnInternal(i)); + } +} diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.h b/src/dialog/savedqueries/dlgsavedquerieseditor.h new file mode 100644 index 00000000000..9f27835599f --- /dev/null +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.h @@ -0,0 +1,23 @@ +#ifndef DLGSAVEDQUERIESEDITOR_H +#define DLGSAVEDQUERIESEDITOR_H + +#include "dialog/savedqueries/ui_dlgsavedquerieseditor.h" +#include "library/dao/savedqueriesdao.h" + +class TrackCollection; + +class DlgSavedQueriesEditor : public QDialog, private Ui::DlgSavedQueriesEditor +{ + Q_OBJECT + + public: + explicit DlgSavedQueriesEditor(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, + QWidget* parent = nullptr); + + TrackCollection* m_pTrackCollection; + SavedQueriesDAO& m_savedDAO; + LibraryFeature* m_pFeature; +}; + +#endif // DLGSAVEDQUERIESEDITOR_H diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.ui b/src/dialog/savedqueries/dlgsavedquerieseditor.ui new file mode 100644 index 00000000000..954ddeac745 --- /dev/null +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.ui @@ -0,0 +1,67 @@ + + + DlgSavedQueriesEditor + + + + 0 + 0 + 499 + 376 + + + + Dialog + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + acceptButtons + accepted() + DlgSavedQueriesEditor + accept() + + + 248 + 254 + + + 157 + 274 + + + + + acceptButtons + rejected() + DlgSavedQueriesEditor + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/dialog/savedqueries/savedqueriestablemodel.cpp b/src/dialog/savedqueries/savedqueriestablemodel.cpp new file mode 100644 index 00000000000..e3abe2bd0f6 --- /dev/null +++ b/src/dialog/savedqueries/savedqueriestablemodel.cpp @@ -0,0 +1,27 @@ +#include + +#include "library/dao/savedqueriesdao.h" + +#include "dialog/savedqueries/savedqueriestablemodel.h" + +SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, + QObject* parent, + QSqlDatabase db) + : QSqlTableModel(parent, db), + m_pFeature(pFeature) { + QString filter = "libraryFeature='%1'"; + filter = filter.arg(m_pFeature->getSettingsName()); + + setTable(SAVEDQUERYTABLE); + setEditStrategy(QSqlTableModel::OnManualSubmit); + setFilter(filter); + + + select(); +} + +bool SavedQueriesTableModel::isColumnInternal(int column) { + return column != SavedQueryColums::QUERY && + column != SavedQueryColums::TITLE && + column != SavedQueryColums::PINNED; +} diff --git a/src/dialog/savedqueries/savedqueriestablemodel.h b/src/dialog/savedqueries/savedqueriestablemodel.h new file mode 100644 index 00000000000..cf17ee1c9bc --- /dev/null +++ b/src/dialog/savedqueries/savedqueriestablemodel.h @@ -0,0 +1,22 @@ +#ifndef SAVEDQUERIESTABLEMODEL_H +#define SAVEDQUERIESTABLEMODEL_H + +#include + +#include "library/libraryfeature.h" + +class SavedQueriesTableModel : public QSqlTableModel +{ + public: + SavedQueriesTableModel(LibraryFeature* pFeature, + QObject* parent = nullptr, + QSqlDatabase db = QSqlDatabase()); + + bool isColumnInternal(int column); + + private: + + LibraryFeature* m_pFeature; +}; + +#endif // SAVEDQUERIESTABLEMODEL_H diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 840d1229a64..7c0053ed612 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -10,6 +10,33 @@ #define SAVEDQUERYTABLE "savedQueries" +enum SavedQueryColums { + ID, + LIBRARYFEATURE, + QUERY, + TITLE, + SELECTEDITEMS, + SORTORDER, + VSCROLLBARPOS, + SORTCOLUMN, + SORTASCENDINGORDER, + PINNED, + + // NUM_COLUMNS should be always the last item + NUM_COLUMNS +}; + +const QString SAVEDQUERYTABLE_ID = "id"; +const QString SAVEDQUERYTABLE_LIBRARYFEATURE = "libraryFeature"; +const QString SAVEDQUERYTABLE_QUERY = "query"; +const QString SAVEDQUERYTABLE_TITLE = "title"; +const QString SAVEDQUERYTABLE_SELECTEDITEMS = "selectedItems"; +const QString SAVEDQUERYTABLE_SORTORDER = "sortOrder"; +const QString SAVEDQUERYTABLE_VSCROLLBARPOS = "vScrollbarPos"; +const QString SAVEDQUERYTABLE_SORTCOLUMN = "sortColumn"; +const QString SAVEDQUERYTABLE_SORTASCENDINGORDER = "sortAscendingOrder"; +const QString SAVEDQUERYTABLE_PINNED = "pinned"; + // This struct allows to save some data to allow interaction between // the search bar and the library features struct SavedSearchQuery { diff --git a/src/library/library.cpp b/src/library/library.cpp index 43001a7fd88..b5d23e02a38 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -114,6 +114,7 @@ Library::~Library() { void Library::bindSearchBar(WSearchLineEdit* searchLine, int id) { // Get the value once to avoid searching again in the hash LibraryPaneManager* pPane = getOrCreatePane(id); + searchLine->setTrackCollection(m_pTrackCollection); pPane->bindSearchBar(searchLine); } diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 624c74d3fd4..cf8f9190b5e 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -1,7 +1,3 @@ -#include "wwidget.h" -#include "wskincolor.h" -#include "wsearchlineedit.h" - #include #include #include @@ -12,6 +8,11 @@ #include #include +#include "dialog/savedqueries/dlgsavedquerieseditor.h" +#include "widget/wsearchlineedit.h" +#include "widget/wskincolor.h" +#include "widget/wwidget.h" + WSearchLineEdit::WSearchLineEdit(QWidget* pParent) : QLineEdit(pParent), WBaseWidget(this) { @@ -113,6 +114,10 @@ void WSearchLineEdit::setup(const QDomNode& node, const SkinContext& context) { setPalette(pal); } +void WSearchLineEdit::setTrackCollection(TrackCollection* pTrackCollection) { + m_pTrackCollection = pTrackCollection; +} + void WSearchLineEdit::slotRestoreSaveButton() { m_pSaveButton->setEnabled(true); } @@ -327,21 +332,29 @@ void WSearchLineEdit::restoreQuery() { QAction* action = menu.addAction(query.title); action->setData(query.id); } + { + menu.addSeparator(); + QAction* action = menu.addAction(tr("Queries editor")); + action->setData(-2); + } QPoint position = m_pDropButton->pos(); position += QPoint(0, m_pDropButton->height()); QAction* selected = menu.exec(mapToGlobal(position)); - if (selected == nullptr) { - return; - } + if (selected == nullptr) return; - int index = selected->data().toInt(); - if (index < 0) { - return; - } + bool ok; + int index = selected->data().toInt(&ok); + if (!ok) return; - m_pCurrentFeature->restoreQuery(index); + if (index >= 0) { + m_pCurrentFeature->restoreQuery(index); + } else if (index == -2 && !m_pTrackCollection.isNull()) { + DlgSavedQueriesEditor editor(m_pCurrentFeature, + m_pTrackCollection, this); + editor.exec(); + } } void WSearchLineEdit::slotTextChanged(const QString& text) { diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 79445e0e87a..6e061089c55 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -10,7 +10,9 @@ #include #include +#include "library/dao/savedqueriesdao.h" #include "library/libraryfeature.h" +#include "library/trackcollection.h" #include "preferences/usersettings.h" #include "skin/skincontext.h" #include "widget/wbasewidget.h" @@ -22,6 +24,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { explicit WSearchLineEdit(QWidget* pParent = nullptr); void setup(const QDomNode& node, const SkinContext& context); + void setTrackCollection(TrackCollection* pTrackCollection); protected: void resizeEvent(QResizeEvent* /*unused*/) override; @@ -59,6 +62,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { QToolButton* m_pDropButton; bool m_place; QColor m_fgc; //Foreground color + QPointer m_pTrackCollection; }; #endif From e6c326e5836482a60019de9ff5fc97b1879e20be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 31 Aug 2016 23:05:45 +0200 Subject: [PATCH 491/552] Enable keybord navigation for the search box. --- src/library/library.cpp | 13 ++++++++++ src/library/library.h | 2 ++ src/library/librarypanemanager.cpp | 24 +++++++++++++++++- src/library/librarypanemanager.h | 3 +++ src/mixxx.cpp | 9 +++++++ src/mixxx.h | 2 ++ src/widget/wbaselibrary.h | 6 ++--- src/widget/wsearchlineedit.cpp | 39 ++++++++++++++++-------------- src/widget/wsearchlineedit.h | 8 +++--- src/widget/wtracktableview.cpp | 10 +++----- 10 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 43001a7fd88..d27e9d7ce92 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -682,3 +682,16 @@ void Library::handlePreselection() { m_panes[m_previewPreselectedPane]->setPreviewed(true); } } + +void Library::focusSearch() { + LibraryPaneManager* pFocusPane = m_panes[m_focusedPane]; + if (pFocusPane == nullptr) return; + bool ok = pFocusPane->focusSearch(); + if (ok) return; + for (LibraryPaneManager* pPane : m_panes) { + if (pPane == nullptr) continue; + ok = pPane->focusSearch(); + if (ok) break; + } +} + diff --git a/src/library/library.h b/src/library/library.h index d9e4a1931c5..609ada6e819 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -102,6 +102,8 @@ class Library : public QObject { int getFocusedPaneId(); int getPreselectedPaneId(); + void focusSearch(); + public slots: void slotActivateFeature(LibraryFeature* pFeature); diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 8953419c9d2..52f8ac8a129 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -58,7 +58,9 @@ void LibraryPaneManager::bindSearchBar(WSearchLineEdit* pSearchBar) { this, SLOT(slotSearchStarting())); connect(pSearchBar, SIGNAL(focused()), this, SLOT(slotPaneFocused())); - + connect(pSearchBar, SIGNAL(cancel()), + this, SLOT(slotSearchCancel())); + m_pSearchBar = pSearchBar; } @@ -176,6 +178,15 @@ void LibraryPaneManager::slotPaneFocused() { m_pLibrary->paneFocused(this); } +void LibraryPaneManager::slotSearchCancel() { + if (!m_pPaneWidget.isNull()) { + QWidget* cw = m_pPaneWidget->currentWidget(); + if (cw != nullptr) { + cw->setFocus(); + } + } +} + void LibraryPaneManager::slotSearch(const QString& text) { DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull()) { return; @@ -209,3 +220,14 @@ bool LibraryPaneManager::eventFilter(QObject*, QEvent* event) { } return false; } + +bool LibraryPaneManager::focusSearch() { + if (m_pSearchBar.isNull()) { + return false; + } + if (!m_pSearchBar->isEnabled()) { + return false; + } + m_pSearchBar->setFocus(); + return true; +} diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 6c963d277a0..40471f77356 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -54,6 +54,8 @@ class LibraryPaneManager : public QObject { void setPreviewed(bool value); + bool focusSearch(); + signals: void searchCleared(); @@ -68,6 +70,7 @@ class LibraryPaneManager : public QObject { void slotSearch(const QString& text); void slotSearchStarting(); void slotSearchCleared(); + void slotSearchCancel(); protected: diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 58713548f18..92d2f1d950d 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "analyzer/analyzerqueue.h" #include "dialog/dlgabout.h" @@ -268,6 +269,10 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pRecordingManager); m_pPlayerManager->bindToLibrary(m_pLibrary); + new QShortcut( + QKeySequence(tr("Ctrl+F", "Search|Focus")), + this, SLOT(slotFocusSearch())); + launchProgress(35); // Get Music dir @@ -1229,3 +1234,7 @@ void MixxxMainWindow::launchProgress(int progress) { m_pLaunchImage->progress(progress); qApp->processEvents(); } + +void MixxxMainWindow::slotFocusSearch() { + m_pLibrary->focusSearch(); +} diff --git a/src/mixxx.h b/src/mixxx.h index 5ca96f3b4b0..c4ba8feaa84 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -94,6 +94,8 @@ class MixxxMainWindow : public QMainWindow { void slotNoDeckPassthroughInputConfigured(); void slotNoVinylControlInputConfigured(); + void slotFocusSearch(); + signals: void newSkinLoaded(); // used to uncheck the menu when the dialog of develeoper tools is closed diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 38cd7b0c167..9430c47c9f0 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -30,7 +30,7 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget void focused(); void collapsed(); - void uncollapsed(); + void uncollapsed(); public slots: @@ -42,9 +42,9 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget protected: - bool eventFilter(QObject*, QEvent* pEvent); + bool eventFilter(QObject*, QEvent* pEvent) override; bool event(QEvent* pEvent) override; - void resizeEvent(QResizeEvent* pEvent); + void resizeEvent(QResizeEvent* pEvent) override; QHash m_featureMap; diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 624c74d3fd4..3f02d91d283 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -17,7 +16,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) WBaseWidget(this) { setAcceptDrops(false); - QSize iconSize(height()/2, height()/2); + QSize iconSize(height() / 2, height() / 2); m_pClearButton = new QToolButton(this); m_pClearButton->setIcon(QIcon(":/skins/cross_2.png")); @@ -54,10 +53,6 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) showPlaceholder(); setFocusPolicy(Qt::ClickFocus); - QShortcut* setFocusShortcut = new QShortcut( - QKeySequence(tr("Ctrl+F", "Search|Focus")), this); - connect(setFocusShortcut, SIGNAL(activated()), - this, SLOT(setFocus())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged(const QString&))); @@ -117,8 +112,8 @@ void WSearchLineEdit::slotRestoreSaveButton() { m_pSaveButton->setEnabled(true); } -void WSearchLineEdit::resizeEvent(QResizeEvent* e) { - QLineEdit::resizeEvent(e); +void WSearchLineEdit::resizeEvent(QResizeEvent* event) { + QLineEdit::resizeEvent(event); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -148,9 +143,9 @@ void WSearchLineEdit::resizeEvent(QResizeEvent* e) { int posXSave = posXDrop + sizeDrop.width() + space; int posXClear = posXSave + sizeSave.width() + space; - int posYDrop = (height - sizeDrop.height())/2 + Ydeviation; - int posYSave = (height - sizeSave.height())/2 + Ydeviation; - int posYClear = (height - sizeClear.height())/2 + Ydeviation; + int posYDrop = (height - sizeDrop.height()) / 2 + Ydeviation; + int posYSave = (height - sizeSave.height()) / 2 + Ydeviation; + int posYClear = (height - sizeClear.height()) / 2 + Ydeviation; if (layoutDirection() == Qt::LeftToRight) { posXDrop += sizeDrop.width(); @@ -175,8 +170,8 @@ void WSearchLineEdit::focusInEvent(QFocusEvent* event) { if (m_place) { // This gets rid of the blue mac highlight. setAttribute(Qt::WA_MacShowFocusRect, false); - //Must block signals here so that we don't emit a search() signal via - //textChanged(). + // Must block signals here so that we don't emit a search() signal via + // textChanged(). blockSignals(true); setText(""); blockSignals(false); @@ -199,6 +194,17 @@ void WSearchLineEdit::focusOutEvent(QFocusEvent* event) { } } +void WSearchLineEdit::keyPressEvent(QKeyEvent* event) { + switch(event->key()) + { + case Qt::Key_Escape: + emit cancel(); + break; + default: + QLineEdit::keyPressEvent(event); + } +} + // slot void WSearchLineEdit::restoreSearch(const QString& text, QPointer pFeature) { if(text.isNull()) { @@ -243,8 +249,8 @@ void WSearchLineEdit::triggerSearch() } void WSearchLineEdit::showPlaceholder() { - //Must block signals here so that we don't emit a search() signal via - //textChanged(). + // Must block signals here so that we don't emit a search() signal via + // textChanged(). blockSignals(true); setText(tr("Search..." , "noun")); setToolTip(tr("Search" , "noun") + "\n" + tr("Enter a string to search for") + "\n\n" @@ -254,9 +260,6 @@ void WSearchLineEdit::showPlaceholder() { + tr("Esc") + " " + tr("Exit search" , "Exit search bar and leave focus") ); blockSignals(false); - QPalette pal = palette(); - pal.setColor(foregroundRole(), Qt::lightGray); - setPalette(pal); } void WSearchLineEdit::updateButtons(const QString& text) diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 79445e0e87a..9b9f2ac5c3c 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -24,9 +24,10 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void setup(const QDomNode& node, const SkinContext& context); protected: - void resizeEvent(QResizeEvent* /*unused*/) override; - void focusInEvent(QFocusEvent* /*unused*/) override; - void focusOutEvent(QFocusEvent* /*unused*/) override; + void resizeEvent(QResizeEvent* event) override; + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; bool event(QEvent* pEvent) override; signals: @@ -34,6 +35,7 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void searchCleared(); void searchStarting(); void focused(); + void cancel(); public slots: void restoreSearch(const QString& text, QPointer pFeature = nullptr); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 9b41c86be9c..8ae855dcb99 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "widget/wtracktableview.h" @@ -100,11 +99,6 @@ WTrackTableView::WTrackTableView(QWidget * parent, connect(this, SIGNAL(scrollValueChanged(int)), this, SLOT(slotScrollValueChanged(int))); - QShortcut *setFocusShortcut = new QShortcut( - QKeySequence(tr("ESC", "Focus")), this); - connect(setFocusShortcut, SIGNAL(activated()), - this, SLOT(setFocus())); - QScrollBar* pScroll = verticalScrollBar(); connect(pScroll, SIGNAL(valueChanged(int)), this, SIGNAL(tableChanged())); } @@ -1282,6 +1276,10 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { // causes a track to load since we allow in-line editing // of table items in general return; + } else if ((event->modifiers() & Qt::ControlModifier) || + event->key() == Qt::Key_F) { + qDebug() << "Ctrl+f Table"; + QTableView::keyPressEvent(event); } else { QTableView::keyPressEvent(event); } From 48401b4e9846fd2c5ecd3a1e30dcbc61313701b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 6 Sep 2016 23:16:24 +0200 Subject: [PATCH 492/552] Improving Input focus visiblr --- res/skins/LateNight/style.qss | 9 +++++++-- src/widget/wlibrarysidebar.cpp | 2 ++ src/widget/wverticalscrollarea.cpp | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 523fdce7d74..3acf0ad90e6 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1256,7 +1256,10 @@ #LibrarySidebarButtons:focus, #LibrarySidebarButtons QToolButton:focus, #LibrarySidebarExpanded > QWidget:focus, -#LibrarySidebarExpanded QAbstractScrollArea > QWidget:focus { +#LibrarySidebarExpanded QAbstractScrollArea > QWidget:focus, +WLibrarySidebar:focus, +WLibrary:focus, +QTableView:focus { border: 1px solid #8E5C00; } @@ -1406,12 +1409,14 @@ WSearchLineEdit { color: #cfb32c; } + WSearchLineEdit:focus { - border: 2px solid #FF6600; + border: 1px solid #8E5C00; background: #0f0f0f; color: #eece33; } + /* cover art */ WCoverArt { background: transparent; color: #ACACAC; } diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 175fd5c1448..8da3afb7c13 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -65,6 +65,8 @@ WLibrarySidebar::WLibrarySidebar(QWidget* parent) setAttribute(Qt::WA_MacShowFocusRect, false); header()->setStretchLastSection(false); header()->setResizeMode(QHeaderView::Stretch); + + setFocusPolicy(Qt::StrongFocus); } void WLibrarySidebar::contextMenuEvent(QContextMenuEvent *event) { diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index a0e54910df8..900a182c9bc 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -10,6 +10,7 @@ WVerticalScrollArea::WVerticalScrollArea(QWidget* parent) setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setAlignment(Qt::AlignTop); setWidgetResizable(true); + setFocusPolicy(Qt::NoFocus); } void WVerticalScrollArea::setWidget(QWidget* widget) { From 7e745bc46225e973c71c93df8d1d7c7368b1a10f Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 7 Sep 2016 09:02:16 +0200 Subject: [PATCH 493/552] Fix wrong include --- src/test/autodjprocessor_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/autodjprocessor_test.cpp b/src/test/autodjprocessor_test.cpp index 81686be89f5..6deb6d852a1 100644 --- a/src/test/autodjprocessor_test.cpp +++ b/src/test/autodjprocessor_test.cpp @@ -5,7 +5,7 @@ #include #include "test/librarytest.h" -#include "library/autodj/autodjprocessor.h" +#include "library/features/autodj/autodjprocessor.h" #include "control/controlpushbutton.h" #include "control/controlpotmeter.h" #include "control/controllinpotmeter.h" From 48ccdeafdf4cc493b04d1a08a7b252597c978e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 7 Sep 2016 21:32:37 +0200 Subject: [PATCH 494/552] Allow skins without LibrarySidebarExpanded --- src/library/library.cpp | 16 ++++++++++++---- src/library/librarypanemanager.cpp | 8 +++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index d27e9d7ce92..98c6384fa25 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -170,6 +170,7 @@ void Library::bindBreadCrumb(WLibraryBreadCrumb* pBreadCrumb, int paneId) { void Library::destroyInterface() { m_pSidebarExpanded->deleteLater(); + m_pSidebarExpanded = nullptr; for (LibraryPaneManager* p : m_panes) { p->deleteLater(); @@ -210,7 +211,9 @@ void Library::addFeature(LibraryFeature* feature) { } void Library::switchToFeature(LibraryFeature* pFeature) { - m_pSidebarExpanded->switchToFeature(pFeature); + if (m_pSidebarExpanded) { + m_pSidebarExpanded->switchToFeature(pFeature); + } LibraryPaneManager* pPane = getPreselectedPane(); if (pPane == nullptr) { @@ -488,7 +491,7 @@ void Library::paneUncollapsed(int paneId) { void Library::slotActivateFeature(LibraryFeature* pFeature) { if (m_preselectedPane < 0) { - // No pane is preselcted, use the saved pane instead + // No pane is preselected, use the saved pane instead m_preselectedPane = pFeature->getSavedPane(); } @@ -499,7 +502,10 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { m_panes[m_preselectedPane]->setCurrentFeature(pFeature); pFeature->activate(); } else { - m_pSidebarExpanded->switchToFeature(pFeature); + // Feature already in a pane, we need only switch the SidebarExpanded + if (m_pSidebarExpanded) { + m_pSidebarExpanded->switchToFeature(pFeature); + } } m_preselectedPane = -1; handlePreselection(); @@ -508,7 +514,9 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { void Library::slotHoverFeature(LibraryFeature *pFeature) { // This function only changes the sidebar expanded to allow dropping items // directly in some features sidebar panes - m_pSidebarExpanded->switchToFeature(pFeature); + if (m_pSidebarExpanded) { + m_pSidebarExpanded->switchToFeature(pFeature); + } } void Library::slotSetTrackTableFont(const QFont& font) { diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 52f8ac8a129..9a2227fb440 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -103,12 +103,10 @@ void LibraryPaneManager::setFocused(bool value) { } void LibraryPaneManager::switchToFeature(LibraryFeature* pFeature) { - DEBUG_ASSERT_AND_HANDLE(!m_pPaneWidget.isNull() && pFeature) { - return; - } - m_pCurrentFeature = pFeature; - m_pPaneWidget->switchToFeature(pFeature); + if (!m_pPaneWidget.isNull()) { + m_pPaneWidget->switchToFeature(pFeature); + } } void LibraryPaneManager::restoreSearch(const QString& text) { From 958af177cc6bfaecbb2213969bf510922a101941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 7 Sep 2016 21:33:56 +0200 Subject: [PATCH 495/552] Allow skins without LibraryPanes --- src/library/library.cpp | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 98c6384fa25..d9a6e947157 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -490,18 +490,28 @@ void Library::paneUncollapsed(int paneId) { } void Library::slotActivateFeature(LibraryFeature* pFeature) { - if (m_preselectedPane < 0) { + int selectedPane = m_preselectedPane; + if (selectedPane < 0) { // No pane is preselected, use the saved pane instead - m_preselectedPane = pFeature->getSavedPane(); + selectedPane = pFeature->getSavedPane(); } - pFeature->setSavedPane(m_preselectedPane); - pFeature->setFeaturePane(m_preselectedPane); + bool featureActivated = false; + auto it = m_panes.find(selectedPane); + if (it != m_panes.end()) { + LibraryPaneManager* pSelectedPane = *it; + + pFeature->setSavedPane(m_preselectedPane); + pFeature->setFeaturePane(m_preselectedPane); + + if (pSelectedPane->getCurrentFeature() != pFeature) { + pSelectedPane->setCurrentFeature(pFeature); + pFeature->activate(); + featureActivated = true; + } + } - if (m_panes[m_preselectedPane]->getCurrentFeature() != pFeature) { - m_panes[m_preselectedPane]->setCurrentFeature(pFeature); - pFeature->activate(); - } else { + if (!featureActivated) { // Feature already in a pane, we need only switch the SidebarExpanded if (m_pSidebarExpanded) { m_pSidebarExpanded->switchToFeature(pFeature); @@ -684,10 +694,15 @@ void Library::handlePreselection() { pPane->setPreselected(false); pPane->setPreviewed(false); } - if (m_preselectedPane >= 0) { - m_panes[m_preselectedPane]->setPreselected(true); - } else if (m_previewPreselectedPane >= 0) { - m_panes[m_previewPreselectedPane]->setPreviewed(true); + auto it = m_panes.find(m_preselectedPane); + if (it != m_panes.end()) { + (*it)->setPreselected(true); + } + else { + auto it = m_panes.find(m_previewPreselectedPane); + if (it != m_panes.end()) { + (*it)->setPreselected(true); + } } } From c4aa5000292668a4f4ddc6bf79bd2a2e6afb9f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 7 Sep 2016 22:51:36 +0200 Subject: [PATCH 496/552] Preselect icons are now radio buttons --- .../library/ic_library_notpreselect.png | Bin 10169 -> 5519 bytes res/images/library/ic_library_preselect.png | Bin 10947 -> 5460 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/res/images/library/ic_library_notpreselect.png b/res/images/library/ic_library_notpreselect.png index 4180e63a3263c1e71b0e17ef179a7c4840267cf6..705eb81942cbe14b9634dbd1cc83bb971976a1cc 100644 GIT binary patch literal 5519 zcmb7IRZtwjvIT+$2)?*m(8Vn{EbbnHyDuIzIN3nZMHVNx1&847?(Rrb)VxMOAmUV%mD2H9Im>d6*O^Zn3_A3_Rr$O* zEHu&78x7^qmU3mYX(+Ohwm_vF34s^-e) zqDkS&7jf{R@FXJ2|8qnrg=r{XDk>;q-C?n%Wu6v-zT19ZP^i0$zhbb*ZT}9nPv>Fc z4px9ALEP0AJQ9V(;96=+>zN76LX=g-(bk?*L)^3q<@378PYm1M+_VkQ(rrDPWq+7$ z5hA%2dN>Jp8Xh25O6cv%xTvi+TX7)! zuh^>)(y;mIW(p$gClFq>q2etQ?W2P@SbQuxjaLPIZH!Si-3QnfDZKJ>>F-96 zLTAx2)TYi^EXSR=uuTS=8`5Q5W_ClAbRhh>PyuWdZ)NNFWu}pPiti6{^rq;3U zY&W>JcA;M+1R*SKnu_o_R{QGV3pnQPR~d$!@H@H`2vc4I&gFh?BCt4Xd<6~0kq#Lk zt_lBP*ULpBvG?mgwS|ack`BU@3m*-mscJB$t;cXw4*1`jktwGF*4D#e$Y)mrm0?lSbq~wx80Mv2hS(nni=52IO%OdY8EQ2n%F-#Ueh{C3}q+5A8 zyb?dPL8?PT&0e(cbVK5t>SA3P-ayMJA3z`rZ-b++Dqc1Ec&bmhSbuyRy8KBa*Eh}Y zeMqtK<`&!x75;oa>0BE2BrMG%KJ`NIV`nFdv%NPZt33?uF)=9os@No()^SNj`Fy!D z^^Wx(9a|8Usb5#RKdu}J#Z4qKsz^M1OLHePu~i(x@F~$EgG=uVIG`)i-Esj0`i>$& zI!U9uAIJkZo8x;ULZKS4KQ*=xR)RJ4j(tx;nU15tdKP#yy7pn*^rIb{&KNjtt|(>p z2fBi{|G0>`@c2WVZWni6*Pe?BE8$$k1qi6mqQA^%cI0Kk zrqCfEzzUC%Y_)r8F^gi#g!bFb1P^GrK&fli|I#K~ags(U>P0J$Xn#CwMNLYCoVqdR z=uO&#I%a;jU_$Ht)LKUhzn*CUhGcc#AU-z2>&rJ9Xl{fSSyz$(HG|Cy{5*iETY@h- z^TGy~gLpf6hI8oxsN5QISeW#G;=mpR zI_tze#T5z~Tt%P7DzWM%=AW<9=bb@X<_h9t+^x|VvEAE+r*UG##ARx4M%u^fCq$s? zhPaMaY9D6-Rdi!n=RoUqJ*yXWQ2LJCfda9%Q+G$^vTlRo#cDwatEGnE%%1$3EDw0uT)UB@`zicjEfAUd0w?e z6kZ~DzDGYO>eOgqlZQ)D{ubMA?9f`UOg@#n(+CYBM}ChGo-5e${oci47&fUUF|ecF zDf$awk1q}NHRnSYS3p#;;{nq64rp@U%`HrLV85rf$XPwS>Srg#9&g1=0J;&U{{{2i zm7vVN=G>Ckm2ULvao*qJ^L&wBso^b+WJ!nob_`vP^`^0Jn=@*@m@XJ+oPM7wFYq|) zH*O%MkWGKKgeq(H8}nO~V>>ji7`dLkQhB}iOYtPV{?%p!4%cd2zjzREdu6;5MM;V# zU??$MLRUt1Rk|nD%QrKX_u}%iTFzj$jbTa38zRN7Kcjb>DuO|0W=N117zB3%ng=H3 zIGnsnz$L+bqA@4xyC2D!d-aOjGO6#`ma{_H=N)3$Vo2u7Jo0i7WpC* z4)yv(a`6|*)|>bFNx;G`69tPTTex(t&qFi)Ga~a4*913XU94YKW&9=kTQ#s{9{oMT z(XYCZ6VKv%ZRz76<}~^o(2aL&8Plw5?&bvRZt>Imsy11*luH{Bs5`-s%6qo;3*T3j z_E6Moq_mcw2FYy^2lfnpY~*WB=CZey``g2Hn28VJ^eSTu_tiiUi+rnZ zINJeZBTPWVah)5w3oSukU_0vRfszv%k|D0~z^KXL3;bRKbk}1MUv#DFcyoagbn1pT zGR%}n4n^F!AOT(MT3ce@9{$~|^XJJ4nYl?~3B-jXJM-*WC>Z*dXD&yIzHqpYI_`(B zRoOe`3^KYGU}F2=@ksLAR^0++*ucW=Ej-8-?EgXv6CJy(fE=-lYmQtqt&35A%PB%b zLRnIIq*~GpI@b_rkEoLJ$nHpoH)a;mQ!;}sL@oDn;6Zw`W3A$7R74>(F%7Rk;c>z> z0_yZeUGisw&1y)nx3Vu%JYsBn1)uu^c58$h1$qhpjFEdslF^$lM@HLp&M!EbheMyc ze`)QpZDBSI4XHMEV@M}XSnt1L4HFI{_+yh#wyZlc7W;i9UbDZ9q#!Aya*$Q-HCgrI zk4mg~46G`ETDix+r7=(<(IMIaz0HFn&WVt*)gIGo*Ih7=Ds*&DbX6mfSpu*`W4;n> ztTy`rCM!d;+SR^|spyt)?PA-fD(6y*jfKctG+G!MNX4W*4hO*^(DhD9P$dqN@Tc3H z@($?e^_Nj2g7>9QhvVptIvte49|*V_k5teD;~(3?j8h4nrXBrS;G5 z#BBU*xc=V`VsS`{2i@GMtY#j~jg9incQsVD^5c9o`Bm2!q6cTyOOWttQtUc4GAwRh z#Qs3Ol2s?zY>>A&g+U{mlL%s=vrTK|5z(gJS9+iFD0!JBxz|eOM$HN!wvV4(cO*Bv zgiLQQ`5H35uUV0k5ID73%`{XZ>AS}ukKzS2pAr12`2$MWm+cg$yxW!3$Z&#-j&HeF zpta3zxbW19Ee*4_ql#_^PzGx!gA_N6LXw*@(lZ;I%p5$@8ItUPLDGIChBIpQP^wdj zx7+I!YyZ7JyDlFwW3@oJYAGc$u~C`;F|f43JD=rxq>$d~hV;Skzl>Q7j4^7~O@8xrsm$}{B0RCWbEbJu_IR;2Ld5};3oTXSBL-aB9giL> zsdvf63O~=|7UaMyDKiW}MGKy%$F_*x9nN(Ld&p>QhD34K+GF0LlUd2fId3lByp<9O z1j61edoJ%7)6gN$d_n0B5-u_wIhc%*?S0t)H3BfqdJl+|Dpl|E%|}E$v&r^&y5!?+ zGmIe*b@p>RVR{ptPp9A(^ z(8324{jvY0z&qGZms9-Oy2zwgDHvrpFI~$~;g?8W$BdrtCmZxltmadXp|a_61CU-NLq3}0@Nk$t_#+|{beRL)_d z`+E90KvHM7UqDL>yf!Q!J0R$o%=EUqrfe!$+EwLj3p4F-u0Vm+;SvoJ#QH z$R{yN7ps_0NGg58J81U-v%$>}pQ0=F*37q5g(zM*hu}W^XAS3~oBSX-JHU^l)S6y= zmgm9%GTq9<^u7zxIbiBR`GrasP@n7JD-@=rplLmxJk$d=R%k7-T=XD9-7~E&?#QA_lhS2YJ zuAM;(=hi9~i1LKaN_$^9w;*iy2-95@ox}P7B&4I0JL@xscTM6+=6L}KdfM#*4Q2wm6eKN~s zbdvUjf>)|W=r;iyRc`D)B+QCLUET5+Ffw7ai#b1xJc?nEr$j{TBixu8_><=tKpMFx z{VoISyY#Vq#H<74=uZ39cr=jFZr4{+#jRAYY~Z~Rwbtly^#loa**KCnQtSEu zC2vw>oq&22qMUuNSAJ$~iicwhgBkUd(wtNJKj+=dB)-NL!^J>ro2emU1#BS=0#y2K zUc_H?Sa^OmZ4AJjD+ROne#y8v7MRO1!86kL$FB00y}$99G=VufM=197e#N51b`Shp z(>QNmFJq>W{6B)i^KAu@sf{rW@j{g(0X1N#!ulIRY-` zF@;U_CD`(~Sns(2?Bu-oxPWw&a~fppDgFUA^5qqbZQqd{TRA+i*o*=Uh5I=grLOaC zQe`62#3Xe*h@(d|<*LwO>Qk>Q&}7tO;bRdVYd7_2=aO<*y3Izzr=uhR>LHhjA>>Gv z_yVB*tg(#293HXPQC@=054Yw8kmDw4Wz*D5t*qr+)rtc(byC!9Jqk`#q1OF>E>25#v(Y9RM!Z?t>mTRi%DtAQ>H6^wW*jF-} ziIo}`Sp2pWqS3qRcSs#Cp`i&DRTy%yj=JZPn9O8x2hQ8_lG`8n-1!G+uTEa{tLEoB zUzN~qfojjUwU3=uz8{GuZ46SJ;-g^5gk%~2JBo3dB&mp<*e^+4KYG=!REDxt{)6c6 zSYP$GG~1$D>-!E<=K|anKCU! oKPcx&?ezcD8&M*D_q@Cz!WkXC*jhn;6;lxuL29y<(q^Im0|PR5umAu6 literal 10169 zcmd5?hcg`R^VT^noQU3g_Yu7ly~gRiL@#m5A&7cN)F6o7i7rZXPOs5h)H}U95pnv@ z_rLhfJNxd;zB9WsJM%uXJJ0j^t&S=YJ~ciX8XA$hniA;QBmQT2IM26i<80uw!?Dv; zRYH6E-zn%SPkoL6z-p#GXlMjv|1)&7tQ^YcAg-^vwlXdpkCFnwcE4rqjE2UDrmm!5 z5U_HZ>sD=VoVFQyY_RTh?XkN4)9db`Pt?ZUJ)6;)bb>TM; z!#~*;ztfd{gY}@}jc$nBL+RWCr0PieI<)S|Ea2i>WH;U;4|TH^(r;_`V(=#&V4htwj&3-Xkb1d0pBMVHZPLf| z1}h#L5@mbH51-PX@Z?Y12m;Tnc>-SMV}opZX(Ml-9f?(8`xm|R1Uo149PQ-lmBU9; zeJ(T@nK;0_zVc2g^y_p1mnl1q;6AqC*%s1i8&+vulU{EfB9*?&*jYShL15l~Yq*SE zWb$)v;UbR~Sbcek=F{|`fmW^%@Jzs+17Q0V#MtqH&d_eKo1<`4j|HB0QK--JNub77 zw$Rr5>zZiGj$Duop}(m3Ag<@%;uG-Bnr_EKfvm~1bqnT!muv8Pz+R`zzwrTuO;XiFB}kH zL1H1_F6Y4nYB9U_CU;TzzN&rQB45r87*7dcaj03w+yjfMg=A~Ifkmym89jXQQX}w6 zoNOlBnrUCNB1^4kghe&)I0TjeQ-;yOv|(&8p0L54o2CeCH=-ZQnzkJ;TdBlJKeds3 z@`s2IDcU73^WK*4d>y8;05!4>1eN=bd>b1YH~~mb9@$~xpAQ8o&Jry z76oG>f7+Z9WAtEIkm3EHr2de7O3qp9$mn~(C$N-oKNNKkJhy3R2E zVJ8m>QY`G4MGkB>x;Sr3hxHzt9}n~(cko{b_i%Z!dz5M4MT#eY;rBfWG8^?@r!vd> z2L$O?#3Pbc9(;mbGnHliU*Jam4aJO*TK)S>a}PR-E?8-v7k<+i-GgI6LprC{I;B_ot&1Gx538z&kKcsQ*Y)BK5^GiY zNNa!VO+xR+W%$%aK2E(t(2CZID;M@;*$BO(xI~>~gc98AU!q^>zTI+mE9G-08kq8&;((n- z?S)`S->IHEV@TcjEKS%Z#s*MQmjxl)+WiJK5pTSG{9)3>d~;45t&h-87`aWi1FhF;R3fLv9Js)VMdWV`Qq=X1IW|E#PX2icZBw;1z26Yx}UXq_31aq^t-zjoL?axC3Qkv zuFq&J$8}2(oF?2Dfy09M(5Jjdki{wj%(JFMzZN4MRBLT1{a)iy|Ma6^_@8mg=Ns*4 z^?p-$#DkI&OQ9{$>ves}@ITeN_2xK1E>}vH5UPAK=^ln)rABD9`oKAQ3%tCF3P2Qn z30;D7xU|GW*_Da*ahEVC&T!w@rB4f1paetyV`zlp^nVyoM%_f)u?lm!ItR+Hw73K~ zN=7?fU@%70BP0hzBDucD;DT8}d|lKt7ygd zQV+oH9{Wk8d-4%u62X!Ic{HO^Yi-vC_Ca<2&~@BwU~@@E=1+ehGBWjG-ucdbNi!6vF5!7sr+z+zB-Bn4`IuRN;(Lpo)mqlJJNcL&j9>RGvpnTNktv&Hip6__nEQ7UHJ zn1-{w#J>fg+s!J@e^;;Ah7aq~|3)*ekpLyjNK%y)OC|b5Yu}X+wPl_EjMo*ar5@|8 z=Ob)OqUME@-r`nOMK1w_#NRiKqkbRse0mH4$R6A0ydL3^pe;{mE_QQGIHb%4=QJRs z(uBVJC#%YWARfuWJXu33iIh6ZGQqjKDQD(Tipoy?A3LyGv#hxO`SpJ=?snHW+sCW` zVLZ}W-ycxHwU(cDQSOCRF(i7bO`jH)*9cIRP8@v~8A#<10{A7K35d4lXp-ubnYec# zNu8vNR@!|P76eK?z!w+u^)VIIBGJGdDN+W`Q8+V+Ewo0wMn!#EuabUeE_GzU9p?qi zzw!!Y-125b5cNtEbW!pK9T$LOZ3^`gor^m1CRrNbnR1NRV%`WBoPyd+K> zy)~j+^EK(S#2+J}ho_yK$UnFb3CYsop&;;>aJ(9uOl}^?r&~noywKp|lAU6oL$La_ zDh43*74Nws)2E5f~x% z3%!h9_iPvaOj5R|^2^?e=1}kV3tyg!ewSNFk-*2obL0GFU{#&|AlfH{*TR~EWtX17 z`)ZAH?bFS)I^W`#HtmpLzm61N4K>Od84B|udu>Tw&Qs51{ttC4Pa1MutLoGCVqktH zPF*3Bz`~RyUEIStrC9F!4dF=>W$uj8B{*+?+dXUW8FiuvKEOIwt&Hjk6$M_edgnZS z%D775##<=(xFSf_s4-`P`I=^DCPY<EXL}`Y-29RXV1K&CwVLn;<#FLmUFsBOO$3*KsPM8Lo<4SXr9^PsM}s#)+uyd0 zp-#q5r$;GFKi^?5l}AHs*^e02dB&94Dh*;$X%pxDPg0P5p0@1+#$s0Hmbu>HJd%bi z=i3z5C(MMA8vNtRud`b9wcMp6(Jxb}L)#13%Y}WZsqK%l@G5V7rcz|gsvD2ga$MzX zi>HJwd{kNgR;`56*7SHnSgXr~$wiXt$5GxcX{Uyld7ZF$wfysFHRltdgS#skrNgeF zV6|OmgxvY}*-_KhfXyt4y7q0uS7Ik}d_o4%xNZ2p&D~xvVb!8)K^F@{v1$$fh@1@i zm~!%}jt!VATF>S~>-K_gYlXV4lRMyOhx$A#98Xdh4&plJLG7h*3lW{xFSpP_neW{E zzJ!OHr8@oP9!y6{+&ps1;ZzCtZJ(4R}KI+EnJ~qZB%O!eMWbGTUK^45z}O~+oO3>e+2W-&W7U;)f-+#fkj)GnEJ3S5xt$Z@;XE3u7_6U zI&p5)RMb=Y&C6NOk9IraxhhAg1VFy1xjfepNE612qNT0%>KSyb4dekF2vQU?6-gsw2Ty16({XOeg zOlZmReRe~j5kic48u;{76e#-mu6)c#$b)qP+YU6!NfcV;)=9M`o%kodPrEWRx*#)A zA$v+@R6mtHt5Yw0LPkgD3D_$HsPUoCDL-v`_w8Qavg_f8#)P)%hD-2&*hn8C4qx0FQ z6iseCUB|=T9mOP;y%ua_N>;-VP4RhNxZJYt%+Jrqb#4Y*OZf3Y_AJ3^(ktJr=B5u; zfOm$U7wU=BPD8%OMZEqP8C!dFgTW=TbBixG#KEGKPpi$~EWMbKnoIck zCy|MXgEr!rlYug3-s8&5ckOkD{kOgfM;c=0Pux+9gu2dCeG=5b&eRYk%o`=Dc*&TD zv>z8^YCA)?dqpUNH{jZ=zUE!q$N)}Uu=CS}FPKu5yorX_Mz!lDgsO1`$T=uiP_$dz zbu@KN^>ujR#jX}Ez{iNAS*J4cam8`B_TS3X<@T3$H09(pZwFurmz}Ygi~Yh%(Co7M z?s`Q|v%e1M@X$A#%_}J4W!eVsU%jD&+oC>)(1G?5Uqvob)iHajblUKw#7T^r=?{Y$ zONOEAW`P)E?QbMM1HW)~TBvA@U+r9K!lvfSw`z2V06yKITu7Yxf@ACVhsY6uq&G)K zX1uTEdkO>lBszpQdF`Av-&~1}n!rA>@=-fh87ttGH(3gV>0ev&rCli=>QDrANup;S2jfR8JZov#fc%C z4oJWrC0zZhrTwm;|JTxTbAbUlEkg06->(uJmG2YsVq1RP zl;DgF>^~1grv$vAi>sV)6@DJWo4)%;8NHPxHXyK95si>HqlikgxgkIY$YzLY{&JO^ zHe308AgIob>Ef;YrAU)GKYz?wOEvZ^%5L-{g8mLBl!hPR$dK+tw87dyt`#DV?=zpTnj1&VbFumG7s>M|5YVHYi2_P%U*Gr_M&?N1v+IF+H!r+5dMI6!Lg zJK2hGHS;H%Kbn%!lQ!!&dWfG4$b~*JNeZt(9R&EWRSO}1xj*su2ftVQRK?tO2@s3rW-Z= z6(AbRj-FNN0VOW4(J+5N1@gGOxzuTE+BP{csBjh8>#VD8eX^<;tK`<@k>>7mDc3jg z(2ha*_RDIPYL_Vth~r9!3n(`6RUG$;8??yBS`Dd`lQ^1Tzb@V0O58Rpx1hyPWP7Nv zzC;~3cQh!vR9dJiCfEWX!MZmF_G0vpLB^LLSRimnj?kVE$wgBC?wo%^?gDoTDIa*Ie_ zbtDpWur;oG>tEgF!l{zrRRpAEfyL%A`h`A{cA1X*$V z!oh0GUeXez+qPC}Z;=+)SaWX@l4;G?R#LSF6%Z6jHNbScwk$PxhVgjuiOZoOki6=WEM zI5&{vQ}ECliXRjl1db1x9kzgGK!@pL-o_s)j!mrn>p_8Xt%M4USC3~ra-t1IXQ5;4R_q_zN_f*4Dy{Kv?NYB9tt`TL8nFkDzPm_q^d3y#zv3>3D z(p*MnJu}T<4j7)kW09~q45uRbRcw5Jyfq+(c!XoE@?~07D*UTP9p|D81-rQBd1pES z0{1k60YXP1wK=mZX-$r(M*T_6$9>d*$GpZKhi3At%1V@`BOBx*oa8{BSF?Wrhpkrb ze6s^5wVK|2f!0q}c=^_{zU?403S}Irur<#nj&**lGc+q2ukwWXsTW#(55Ipi3BFBy zgHhp$@hIB$=MIbDgBUm?Kz$`$Yq%&|pEnM_4n4#&7`)v}5}*0PzGt;}0jQz9$DCe~ z#FT`ihRo)BWT9XBA z!3f7w)jEHq3SNi#kSVDCFp%IW{Q#1~k}e$EHBWEPlCwUT`ckonimFap86EE5*%LIS zUoh^X4q$i;u*Ubetzo_|;}&z_q|WK6gFuW&)YYte&wy|bCUkfKo*cRrcJSM@rO)8- zA^kicd1`WAo0H`NSf*4KQ+0cj0VTek@rbUAX-!hfhn)QBtzAJ&__@3aL-#XM+pycD z4|DS3gy>pFCwz0A$@UN2vX+VU6<1mj)%bJ8iWBq>vmQGwCDR79I=gA?18@dI++>=ia?^XE*yix0BO3 zwUCk~?-u+~UMVJ?Y0nj=rW-qtFvjlwda0iEPhzZXrvVJTbpdG)Z|ZEmGGt7(opB%a z^~P*#z6xnqQ7*#2Uv~N#>5;>ktE!q-_Zg`N=c(jfdZ^`_py&h2N)&Ma3zqb4ALlSW z*a$wiAD^OYgf`3ArYwHt(Og~{SJ_PJzgCvTJ*oT218HP}92pyqp8CwoPZ&v#GE%uo z@d_!VphJp?6e>3SE1TM?+edFswH-)O@AONLu7a>LHzBsoZzX;Bbei#>E@ulh8^tBM zdq!GVSSKbwEd>XXjbcua@2ABFkEyNq810^#r?qSN!0caIx7HT55L3xkq_Rs+411s~ zf5N?hf=tDPM=1>zzcYvrM^X}tC?=@AKUX4S~yLFr6c=N)3@O4ISEtTa9{uB2zQCwZzKl{rYL zxgFxeZXX zrQph*@+bw(6tgDOUBv=rz4%{qL3owU2j*ssL$7V;-7w{q66}>p(TSC^KT=))n(l4S z==Xw6GE7N%oMsv{?C!ETX?@3R%XvKvcsSf#2GzuIEbfLQ6I5s-#I*l3t+bo*K&H6w z2mMO;MgA;_XjUgL+Ett9|2PYB0X!KL{Yz#|8zxMD(v>PSh!~aCeGIo5@q4u0X6YgZX@uQh3o*)Scch!>Ujt(bft2BJsw&e zl%E$=vok-#8-pIPF7&Jpko=z(U{1lVG%C%fn^(jhdU5+R`|#TV14}i#ZZXWRL%^=< zmE-6$=N3gHCu0VGH%}7kVY1otRI4xh)38FyRo=mXCzEd}W7JeTQt-L#;u{`X}6xvSBm@5@J)6N};%&|CIK zM?32JSz%B`q?>f*-mtU}oyq!Bix48P>Q0?`ip_RmTYkX1xF}#q!}@wyrSHdf*_7}L z;TM;w4GQ_4^B*k`*Dc%-|A_bsffMgH1esy6Re-FLCr|u8@gN=h`APeOhq>Ep)Xr%} zcq)uQzJ=ucUdD&t6OjOw3d=sP@xS*0v9i6TK0Rr#p10KBeX%u5k)75q*l_>r-=mJI z36r?Tcgaq7=v-%h)};)tB>g(Zp(sLkiByjIFHa=)Jz!=cBkc@+Ui;LP3|93T@5&}X z><128d||)2^U=Anj7nYQ!x5=JFN5Q~!Rb04x^I&GmImBdAVhUA0U=+BM??q#yBqt_ zc{quy4DmP2$P9A14t%%w;3r3bKYCre|E1B0!w^N)d3t1mTDWe-9|41pbseS^*);eg ziE^TZ9L|o`5L2GRX?&s?vkWSMC{mm!Dw!VzXDzktJ{&~64z4q@X!k)y4s9Y7qj@0a zycUHSRoQ7NbPw@D3!_l}a-rAz^=Qu&t!8+OL9>mD*?!!8TWM%U^yT<38CuaPut}}+ zy6o|u#QRDn;TA z``XO=AW~#q*b4+l?4+p3Up=*Nk3ZjIAUSu&NcH?K5XbCNWqOk3mALLVQT`hXz(>V{ zw2J-8IE`d~*%+H+)Rt=?5ey?XQl?@+7kW&UXiQLD<8kVJ2 z{QD7X{2UIWNd$|f^QS{3n$!>o;Z)9H$Nrm${}58TzF+;rIc#<@{hC__hqH_@&H$Q} z+lcEW&8{-j6UeTh5a_xFwu!p|uxK=`5}5!kYC{*Ot42SCu5yiL^38v}(Vlb4Y?m#+ zFkF3-{U-oRqt_2rv8FJCu(t@m1qD8$1n`9Tub%kidN` zuL@-j4q@sJJA-{3TQK=0GNLDVa+kfn>9@1*w~0fmC)XMeyE@XuoD`;$GJdP!w|u=iQL@~w z!*V(;M3;|YNor(pShCr5CCe|$efkbq768u+9G$mUz<2rD&MeyzYV;BNL<(tG&H$(a zbm_xoU{x0jEvt}4n{NYYe6pgDRpHZC#DerZ&_EHfodIL~=@H~lqxgs6XaKRqEz zq9g5}815uW5{Gb}5H zfBy0h)R&F6=FA$Pk&&%b*sv0cuv=>+4%Lixl_>XL3MIfFZ8OmNA%QZTDOJU)>WQ0{ zG=L7-g4C?AOi239FK7l*!tFWO%|}p#e-NcTvtMr5PnI}mgM%){%Pp(G+Kl_ZP`hiD zrEB!q-Gsp!!SDCY@cO{zq*H3G=B-a%#peC(^AgG3z7oB4`Cx1?%Z5|uenPt+QPpDhDi*7LU8&AC40ezTmIK|7cB^pFLGzfb$*t4sY z$|1giJ-m~Aq=n>B;G#VS;aP)x5+St;3rS)WH`=^! zn@O=b3-z2jD#H??1U!o&+JVpe_|5l6R3h4gu+qUO-ZiS~{h>Ls+C!DQOUpUTRTVL;+z*K|o?9 zyz4#p`*;6*bI#11d8g;hJM%nGqQ0I62_YjP78VwXmZqv9CNKRLAK+oqWTdkoCL?&M zY2k~7MMU*40kHSk&iQs!GOzUw*=0WEd|Njz{cX zPWfH2jC+eu;j9I|yD%i$?9^2# z4C!0)H*7X&Hpm8|@?VCE1<-HmTh2-@Qmcig;5f0B+A`BVq<)rhvbYt;Jn`h0 z5deq1A;%c6#b^lEUJjl2R~g-SdA*SGq(`*#sw5h*pm)w@RKM5=IGF~3phaFU~El}2!@;+^jPVytHRJFFxc zRSdT4&hU~6c?WA$qZFcew}P@GO)v>HrE2zLNu*fvu;CbQ&Z6Z~E$WVSReots)l8kx znU6rckOyZkhJxo zljU{ekA||Wxe#{P%@O zuUZyN9XnciZ^QzM&q<%6{xX1F|G z)KZgrW1-S{zRzAa6nZL5lj=g)GQVkXw8dMm3tG*)N8wJ0oD@pE*Vb`z0KL6dK$$Dr z$2NDXPJa9QH%XRs8!W~Pd#t4kS)7y|Xxf`?r+9T!U8l2jGSUc1e2?%WIIogV=~ z6N3awrItj9m&gLS(T~H+1WSRHd2=~(T4A3!JJ>r4R?E~&gcd*?-1fPCe`=MIV6WP!-KIj|Nr(dDRG|}QaFOAu`O)k|>2y2eBIo zU^_3K8#0|X)7IYFDjxh(Jk|$-KWy-@eB909Zd)bgq@6EB%wE3g%6j}dQf(+GRcmSZ zi1HIhUoGF4AMOmo<+rf_oWjk|3x+nnvm#vy&Z2Z;tMtezOk?x@Mw%m`xKLG>cVBf_ zu<5ORUD&54pql30Vu5)g`r{&oVw2A-n93LwnrK=S|?uvF? zzf;&d3%@IA4yNgv>nxFLNyfiY5u~wtm6!H7zul;65Yti3?v`Xv@i5DPp%wC%e<(ds$hH-F>mH znj3-c>&WevK_r zOZ;z0HYbkOnT>1Tou$ zP|x({krVG)be>L$I+>f2Ud@5FcnBE6pn;_-Yx)uxwRJaOW&(ciJH2m|P=4=!QTSxTTnAAgw z3RqZYe)M}zyeSuIPv*P}XF7(2QdTH;&Ts9y|CH(${}3hENEYML5L!Gn`GbC}LG^Wv zKIhY$VCvuUheo~Fkp5^q!w~5#^wWrRh;pj@&%%HsBMZ45zKp9@FzzcRFr%$x0*BlJ_|kGqYtM z5$1Upl{Ms)D|o~w-^h~9ZgNyR#Qae z&*Bw?;`(OH8WzESguPfY6Isqk#?+*faU5CAtYo!Et|tfaguIUMu>fk`79^0D7`TUZ z9KrtPj%D$xa+GaR_0d=~C`4&$4m-TJ@cNRzKSH#O@ zQWwg9pG@6_rIyMWmTi?zhWwz}j&}RSJ;waep8*Ex-)2>!k_J}WK#Sdd+HhKm<8zPi z1j2cVC-H_RrYe84Os#Hc50Y2H#2OtR&|?t6GM#A_bu`uF+wY`fHD6v)7_HQ>`O9%` zllo_FDgP?5@ATZ@e;=m<{N*=hTkwVc;IQD`M>~1Ue@QKZ7UW7ZESm>W z=xake#%CH`jEd|$F>W(SUGH@MITik=HZx#QaKlx-OBRHtWEwC)p~Le-DwWVfSkBx; zCU>Dna<^j_P>H5_{^+NJ7ZRGC-1=A-eT{Cwd4uXCA5REBNbtJ6^?TE}NeB@_Ciax*Xsm7Ft;`MU_zzyV@srS*N91%kbskR zVtuj&5i@{h@}TP9cyWGbD8;`*eZi>e|kSFG1#k-jlm-Z zz-dG^`Pzx7}y z!>p~2lkDGKZAQG!Hi?ByB)w4&E(2-Tc$qF~98J_9WGq4Zk3?|%&w>iL&?3RP9~k~!vKR1rDW54@6>cMfvd#(GdS z7BYlbUru)Szl-b>&D$so-zb|erI_=CHQjCbWoBftPxfsV1qvz@RP3k^UXwo?(e1-r zn(mR7m)5;UoNfo`hwOH@zJ14xj37v(Vg4E+xfnW0pyETRA1G%7TyKV;-rg z)v7U3hKR;GG!6)W{IzxAndvqy(bXe0=yV@;yDi!9vYrM*3}D>K)w_{N%OwT?pv%2i zIC=0CgLe`Rtba{ur8r6HeY>o?b1&u+^M$aV489$83vgBHp9rlo)z3(I3N=QY+=0cl zAH>!XQ~R+a4f3PfBgI`W>g7BhPx&lP60Pe!@xvp_bIgd2*&}8po-zJDG!>k;V{_5x zAnqzC159#LNLc7OVTzgIHmo1`kQ!bxO4H8F$4g23MM6~(3EgSRii!PM@{_i1r=Zr9 zE}~X~hbvUk_ME&J144J=6*%4LEh(y0^6;+C*0VzQD1bpMf!4NhC%dLqA^ug0{cm0c z{stmC#1@~So<6d46o2JFAq#v#z&*lo-*GUBv4=4XKYG1Ln`5R8!SDx}0<*{ReJ^im z+h-^K^4O2sk>X{=u)#FW5<{_0EelR^w_Hh4CZg&uTJsg}qMd_kt)jbgyWX&fizDAF zoa;2pK38}CRmv99pZ+2Wx+Gv|LtOi{zJ%?58#mtN{11+g*Qvj4?p+Y=xR;$VXqJE_ z;i+TJo9$Oa#mT-47IhX7UIzP_^2Li6j|vnwmD#0#9M!o{hs|1KvoDnuA zg+E%^X3KRXhe}@la6jo>=_*{3;Ks=wYQS&dxY|Lk)9OH=XU2i>RvglJx*3 zd1(m0WotC+8 z4OCxvEQS6P8;OM)KB}$#5xJ{kp+0%x)>}`OP!;f)2_g3RurNvXvWV<`h2q$<7mcAW zRpEkBp;|*?&}V~{*Y#f!yTASwO2}3-iYB)2865^FL@>n6mty(icd=ylE^~5&1Uwjj ze2dQ=jJ)V#6x`}rxwvPGyOIL{M(AxM<639LWx0tF-OL@fW<_&0dd;>q3Nrb_C7b<} zDPlb?tbm<*q|Ou`SM?9ir7B%9uDHzfJk=+EhM3r0CkF61+({t~~h08<7p?&V_3gIp7%L1Z8 z0dY0?Vkbu*08eGK-nXdEU}yR~tHDGl!db}CXKsQ{ljz#}iOW030E5C|nFOh3a9c_U z9uWN>c6UaAVRtylGu)C$wx0yfpR5)ha?|H~3xu=(~72S2{To!ufCI)qyHZ)U$sn&g)))#mKkFL zCGbRRu1@yN0_E#}^eTAd(Fm=$+``0scy;Kd=qa?j^Ex>Av1O7Fl!M*RTZFW53gbzL zlQZ$%u8?jrsaP)5d(Z_j(@cBSCxiKC>JP(-&a;_T=PXGWR95q@6*_a1^wba*u~J=2 z!5L=3)=LxrVeMuH9=+)THq!6YY@I9%zZ_OCz!aKG2Tov9C6QSBVO+`~D~sz}B^%p( z%~%Ym$LF@@JpF^iQJ`*UnzJjf)vV=q)z9RS| zdAi?=SOb@(=H_CN` zFqobbd{uoV%2JbF9P@1ufeb$i?r;_~9e@70zLoI<*e-(rO*w2N$3VwAnmTK9+-wvS zJ)wWU@kjou9Q_=r-oH~Pn#ptYyd>Rrm}zV3;ExwZBJ04W!f&+0y+9aQ3H?9%9r^)W zvmhtITif)Ml|Xh!jX6MXo;`iOq_#YDRKj5RlOajc+5ipaN{~g6lQr8@-a?uMmAkP@V85s@xQMd0K2 zKi`>i=gz#(%zNK==FYwM%=5%(X{zGm(BJ?70DQIQO0OR4&HoA%{J58GnhAKUz*a9* zl>iU_ZG}B$DUTLx#Pipl001uOe+3B0&ZT-ZLcG-A$`CY^iV}*oo}u~Zh6$jiq@e4! ze3a)H?=s@O5whcRUG4tlPkZdaQ_f_g=h|e-ui}*18|YSItzz{_92AId247&XL?;au zgfT&hSfC#;72b7I#ny;7!e3BqFCr{z(rtJ@DZOf@NM=@k_4DbUa@F55lg4(XxAUV> zl`E!goo>EU<40L$`vBj7fDY%mzR3q3Z}m*(Z%<7ixmcn|Q47GO=$pE?UEq`9+dd#H z6w3nJ5Uk(h3jBifMw6ql&}4|oBlk=*&V0pR`Gd>|fH;e)e=1AYGISQut3v>FWx7UE zzJqg_L1aLE!gdS-v~FKlCB)VM(`Shl!ruvp@Fn9=vK9q&+h>?565x*vo35y@sO*D( z{?mKjLxJC2rEz2a)sdqMTJE**p7FNve$h5lM`Q^T?Gvx#b^qKgdnuE0sM*KS`i?%D z&Q?YyTLSnIf@%SN7al#H(e;*x?KO;xLocE3ScyP;=@o7uLg=qLaOgXOh`OjHpnIaY za1d7bGAsG;**RHV0Ew z(#TUimoZ}uw9Qg-1@EsRw$=CWznTDzWchYgkHl2ZY?e^OOV*eFGmHd>eIHUIfu^vi z329~T5wm1*?7t!~9UuN)fjO|0oX7Gc{uPdm*h%s8>P&wkHpy&&xS*(4IaWi7NHRRr zCLnW_psj~dIWaxfp1RssDpWu%S%ywm@*Gh-%BCUoI(OM|&_8=UT|Uz$xnG>}&AO86 zV@pgL$t3t$&De3Y9nZ?^5Jr9oSQS;VI{UJiU-)h&Z#NRoKsl=`kS_{fjC4Y45fn% z2k+(q?w-bBW&_^9`SG_tG{&RypR4v@); z_Us6fAM{c}pf}$1$FaABB%|;X5~%Nk{~v;+frf_N!`8^M7z$(onX*WR^BVvdJqBbn$KDXIYU0P*8-912!j|Mrb_Fo1kx z8*syoYRRV;ud|?qSsa1Zap=5s@A`I$^V5sZwOg4T2Lk%r7!Q{Iahxi+;JLGgy4j32 z5ac}I{Ubzs;pniy#rFX%yQphfbOur?6qod-l?NaF3jK6ZBY*0Ec#@Tg4KBW$)m#re zU#VZ8xV8-2zkU9vRVoQyy>QV7G{;C}rxgqp_>8xXoG|MkZ3pFedth%X?XyS~mrel+ zz_QrVvL~We7?yutn*jeQqIZyDR*HCW*g=!?HrHFs@}Onvd?jbTr`1(;{*;sM#z0ju`(_;W!E}I2F3}h1TguO zXoom_f9>`NRc9?zqy{?96a9yUrXkG44j1NAj$P^s4Z-b>`5ClyaOHk$$KzMhM|ShbB|*@4%H4 zzzyF*J>`erwq^Z6?L>ZZrw0MyIi%1s0|G#s75i2%qj4-VtIf-oecjL-TNf1_j7@PH zO6g)T(6#t&QMqSwGy3BBY!)G7b`))%UdM`Kzw>iXj50l=#l|}|Qq79hLzNjNg)(D` zOK1*u_$)i)$Yip)`ddFcm=(rm>QY$S2RoI=QE*kK1Gfui=rJ@Ny_>XDqaa+BcL9%y zWqU-Vxc&;eq&0uSN?{>7PRcEC=~q%Cg`F=8-^=tHS-^OPmdt==`_NyOlApW zaqrihabqE3 zEL`*Ph_9cIBZZZSO-%@Z1Ta%YBx+BVH-f8yIg7UYt=ta`2f11MsJBLVtfPy{n4nx@ z@g(l4nA6I|USHN$jDddoi{Y=xvd{#~0VU;>p<%!dvP}8rtA-zu-{NJDuk}Jf``nW6 z%HI10!25mT`JcO9S5b}&;W?ku(%AB1TSG}vVW=G?zr`Micw%1ATZUHV_25>9pobHb z7&0SNvk}|ZT(hKBc1av_K6D2OL7rgee&LZ3Aqd~V3`Q?|bTM_Na+>YhyD+U{as7RR zPWwK^o*$bJ%*V>d(0t`H)Ev6A=F7f%d-P=+HP#%-Rr;E=7p=0ylHyL-8_O#-ljty} zgKD668h9x%d}&)o9sXi`k7h^5p{+0R(#&c2x=xa))fbU}r{Q=tZYbZ5tLp{qviQ>b zeT3a8Jpa5-{j2xm0s{A^%f{AQB&Rn_vx?1RxU*&I#a$2=auI{362y7%8uI1n-6?<8 zjQZLv&cN3Oy;dDRtKY!(=t~p*CFc&%=3fE@sE*`lo6ltru5NQg-n73+MdPyWw6*`Noab5j?rOFi+j!BNP5%{R0RmHffz5>MBUbctvT#>bRbQNeBfB*g zA~);iE*9-?oc$j^#MEO}N9$g-;RlSaN_|Wr6pYZxY2>7X@eT65&4X=TG%pFwr_??X5VtCYN7eb$1{*FQsfOVS^ z+q7T<8Y#%3pV_tJ<`e){BTYODFc^6*7HeZg3beDwK?yk;)qh9_{a}JSIAK~gVvmRq z@C&T}LnYESG=1qfrvZ@A-nIO)Pu1ZogmD(S;O)70tn5=|n&q$&X&U?Vk7XY9D_28A z-z@rOYc1`IAI5M0F}uvG-V~#3j#rGj+s_<_aiT%mLMQ)!Ql}3J`@j zz#AQxvtml*?D35|$`0351T$K)NQKABv(BO_pWb(8<2~WC%Wywm;-+m{FbQbg>#5$=HH-h1yA3i*=uL{Bn7(h+b6u2E%SJ;UeD6%;v}32 zi5_eLAwwdNfrDHhli#_jjS)ZWa7|1%xl^)t0!1Wg_0=PpTE6If zK!u*ZF7wZz7pKev%gX&gp7qx#${VIK|06yvLmA|?ZVaX4`LEBSv36}COw#iFqtBSH zc1V2SF>^Go-xhWt;ZhbG%x8CTQ+EadOF~VNq2NCNog9Z2(YD2VL5SC2T1$Fa(2x=%>{u2)?l*YW76w)`lbK&K>YPIVR} z;<7e^wO81s>+u3Lf=5yct!W{LlxrQDv*(|G<);UYYyZe&A@o`mk=s13qyOmfQoJ*u z6)bEuivNn6+`^6I{nT-4@+3C2r)4K-f~s209$2!?;P~#ka@%06&;_iSvi6~AQt^+_ zT?r-5U%zqf0);}3)swIv@eySn34ZvKtEOLHu3p=rI#ht0oP;(s4e!n0T=$qMM!88Y z_rCgw9r4$BP-B7%-Xdw&iT>93q$pG~x+epg@mQjB_9Mkgj&huqQ;-8QDC=Pl1?6uvgCvfx_FcLnYpKzJ0 z#nQ_b#NS~we!8IN-TQ3IZifCPOJT^-0B6x$-ct~T7odgG*p=s;!{@Cq-Lp2DlrKv3;{jo1>>H5cO^5EA zn|gk~u;(AQcQC_&cNd(cPOnLc@Aad^tiG{T@^J9HkJ+b4V0d>*S6}>XQ9gvnG~Yb~DoJ;(djF#H?NM>980ZCR zs?NL{Hf=t&TX^xO=u>;0;lityr@C!2!wE2jhne++X7AYai7IxbC)=OTS_-jgxV+kj zV8(mb${;1p= zbMD_TO7PN{=3x0iQB#W;_6pW_4p+_~ha@1p&2E@Hv85DhMRvKoFW-H!{i(kw!n=^)s zi<5#S5Oy60{unSJTustS!7WqY;@vo!Iq?ZD{^|woVIV@S<`@2o^4x?P3xpy?K)#El=Uh(juS6^4kqMPL$Jdo+b<^At@@$gNOezz|Z z5mQypKG@%hr2VfL60SI z)WtRZH=?a!piN6W{{w>`3ueKUb86)alB9d=o_kLL{hpXNvEfekUrRw6$A(|7{wkj= z=J9Mf?zqlF4^Vkuz2v1NT)4dOoTPU&ILjSklcqvnnby{wl8I7V-tRgr7WRTzRHUeX zxSqqRIdb27)N59*d`PyI4=aB`Tq;nxjX*ARD5q&~50Ea;A|ip<>;2+I1VKd?fq83Z z9_Iea9KTUu;htX=-?J}D5v~$0)9_A#HG3vzF9B)ZnYb4L6V@hFs^raEFbiW|auMQ| zWuh;`qFVFy>t-zrw-{q7PKpxez=6zp?3NU#zMfX)PHr57$_bh3hIKh_embOc@9Sj{WW|``m(=x^ z;oQ$4ic?Qux*aCr+nwcZ{lm<_zkCO8c7!Z@v!bRWJNMo7&H%puz#zLSN=;}n3_caA zb7?%0HleXQ^utH*dmA9KAzQ2D+FxG~@dx(iXRy2+ATErT0~W-e>K?*fy`w&_pG~hg zFKF84#YjFuA91oA6FZuAso|&R8hrHPRfu=@sPB0AV1=$$la_VDA_^ZZecfqYnR7|U zw&{+WQ#l=puSesg^>+}vyzlcnr2$bHJ>hBX8Nm<6V=JaAJk1Gfg+(37v?aXHq(H9F z89jTFvQH5P4cb>6IZOeHED+}GMt$2VH_>UB%Zj-0pPvpia&^Z_iz-3|Tx*i@;m&Iq=HkDW7&ab8i*;RG+3 zgl#F?H`+4jm5+^aI&XReKiJO2Zd}j_{CGys%_sPg_T2}M8+J?gc?lA+CG zxW<_6!oWA883d)-!(N362%>MqB34XssEEawv64)W5ep=~wZl*KU#-32A!m7}S#MkE zR~+cW6UN!v`w4v@ALZ9Mrrt60q)R7nE7T(7U7`!KbpM8N71X={@i>_23*L}7DVae;S)Qjx zH!ujdGxAvNn8{8L8*EaOe5bmqXq?f0p)7TbG1pc9Y9(-fAHyNNp#t$Ne5-O+I1Iz* zjqGN5&bKf2^W%oNvs~RLF%mA7ttNqI>vMb6g$@_-9U(02P{1&yF&2-DPK39gp);pjhjorCa#J^ z?PaySpsiQ)ueklV6YP$G7v9>Y^~5)c&t}0vB2B`Oc(G}IE|U+me0qlXM|i#~FZR`S zb^Yy3A-q9(IZmX-20=>M3|cvcv0c0Gv4Pwi%-o+Ho3+oy-m)7FI*6^+auW0Y>Ta?R zrPMYvFrF)X=^WXl4Q^J%ZO6@7t!DsiP}z348ah%|IFT2tRaCck0*zi9Y-bKwGv~r2 zqvqzlqTynPT_2Wpy`mF3QAbngDSR&>mIGUtX5o)>UmUh0aaSUp<2|1E5Pjh+3+A=# zDV`Xhz}4Aa#<8l#PLXQkZCl22E(T#sv0)Pec&i7u%d{Wc6M9fQBjThY~HDhTgTPkuvN+LnC zx8(1g3c7hf7>AI`PbjPj5)wEm@3+amX&(~eobC95ZMNMya-gto#fSIZ*zs!^IRzGx zqE1>InH!O@#r~OEd7R+xppRby!tsEl5!1_M9E4 z%e#*&ii|?c^Tnu8hHA(3E`zGfuY3vluPVp2BQxvg%?66U%HEP`2K?#V4^%4&djHYY z^i!IebXjeQvWGwM)@bMYCcD(wXNuC(DyV&Z8o0Oi6hC51r7SM?INQ3^DLv4!oq#>A z^DRx!+ddhJ$^$9cZckc8wgI3XK^1TH1$+muf03-yIl&_bnnC_CCDyC!UQhE~W@Xu) zkzuT#w(^S2b z`-`S%-?Jg{@>C|DP!4wBwdqFeB_3{}N5mJG}BfM^Nge87F(K!);-W%`>}WgPNy z6mY6}w{JkB=gjAXia9m6A$1bVnzZY$+2<0(W!0Ow@TzgTaoZOcy*QBP}6kh}}y^{s|0 z&*{6>9$6LPV+W&8&HXwr4Dla*gt`~ zq%YZPb7uRQg&?`9TZL*mBXy3S}Kp##S!EmaUjRnotVhC z%>OX`NKc8a+x5c3hKDxlS!_2i&qT7zmaL{qlqij}@X2d}F*NT$qM`gT9v@NsB575g zwgt202N+Xvr>=VU(os zMnL(EIYj*;!m7`}olu-9&%}}p(^%7MLs|*DhJGEVc7Es6cEN7=rd64)IejSo;P%ewmm&@&WeL}N+wqdRh-rOtN`9(uSWro^5MOjO{eqj615Q2Z{+`!QQ zKuKwRD)w!|C{Vd!CuQ-Xqa|bNTgO@NUTJ~#Z20E$>QH?iN5;P*Q8VToWABS4nDQT2 z$)AJkbn7Zfq<)nrW**@s-;XD8?H?BCS|2Jw#7hGDIDe_6SCtFH2t@<%$-f6;-{_%r zP)1sxD$!L3Su;4WTj9 z$0^FTe$a-@xV;jykN~?Np2R9o(qMh zm*jWWJ}D_(PqGT{y*+NZIcFQ4O%uVPlxpj2w&dy>l|L$u=12UI-!q^LEcDKRd#eor z35nMH$e5swG8yopdE?jSIvdNZd&kRchPONCR|)I5cOrfR&O$T~!BzXJkoPwD%tv*` zfWVpXr_nKFAvhw$LfxqW4y%;It_PnwEng>Uv(veEH9263%x}_YGt*=u6?An0REMK; zu>sO62mvp#3{J8=3tG$)b}xn`F+MmHaalI@l=H$l8KKPfaQ$(9cUJtA+B{6bA6tZU zX(9D%*R}H}UZ=u5m%(P&-5xw3NxEFT%pjEvEQ!3~U+c8%^b{9Mte?o;E#XC_=QLWK z)~#da8OA2mW8&n}mxdnQO|A4Yu4cB1!De^sv!7n1s+D1F!G z`FoH$4Q)7Bds>^$^y$jz9N9UGLZhF!xXkr8B~@qd8C{^eF|Ui`Pe)=+?!&5-{Yc%; z#6-i(;OQ^?ieN$v_OFF=^|0T@HSPHdoNpTwXbB5qD!#Dpqzf!uBxkUTP^QAFT}iqH^QtL^F6_$#n+F3udOKms^i>K4-Zf)=@+m7pd|LjJKgrTW zip-TS#Qb?$RINJAfG^p)_D%v`c7b6UlZ?a0VtfLkbmYU({*1forAE|FP5GZ0(~Xx- z7?#(WGsXkex4pjk?4j2{eu}t|e8<7a1~!e~iHX{7o$k%wmhnzgv6?TgIxF119~a5# zi+#x=0gn#CIux>Hn-5^sCl!O{im^1-G(EpvFEJ3)KdnxtDJA(GL%LZaI6m{cce)=O z2a>+&BuV-8oBJQd+rM{& z5FhObQ(N$or6H3YiTjj7g`p6-OIvRC$;KXq)bDzU*g@H;dQztzWvwpU{+;CFplzfcNs>F<>*I~SQx&>I=(P>_KG*wsb{OC#bt7~!3Q(@m{4id z&G;3w;JeImuZ+8pmk&t1s{ZnQ%%TB^dmLDy1`+L`AXJ3KMSwzi_vJW+bwJQXSk9jdn zN7jU)%89@tDQHcw8Uq%-LAGh6=Y~4Ldx)Co^iq}nHinRf05e3_A;uTCq}jZbZ5dz zS=)k3|J`o}LaI0Dz6o^vmOc$)`$u*2ZaH>2OISw}#6DMhoFY}(MR-A9iBX*48lyk1Z(Q&{nPQc3@MJ2mf@vGQ0X~lZ_?E56v8AHwou%1`CX2`{-tMkj=<5G2GO!=mwpuW8 z5MSB$Pt{rU=8ym8wh@f)rr})%Xt-fjO2Tx03md2N^L)3Zx zFeybuoL{M>>CX^LRe%0RyIiM**=FN4@BBsWd$f0y!lO<^Ykjl%hp#N`#<#;Xt#wtf z1rJILYg+y-Jn2JrSj5HnnQzgfqtf&^fL30>i5o5#WtvnG-EA`&*$Hje2!FdjHrp23 z?Rqp25$QUuwtsrh!v^=uF(;z%xV1kz2xF{leGS(1Dk1ZeT_G|S!4oe%H4QZm?Ta*3 zKjMO9+eWe|x1YB(G~wQpbwS7D6#85N1|UWy{{myhUfWbwP>p8d&)8#kc;<*PhVkoC z6l;OJc(8vNXbW_$t21mEV3H}h@a@kcw$d@CFYe+9g1!=X{iqAvm33~Ps})o7 z!!q21l!NPrOMLWndtB2|Y_Ey(I<~?~F)zO+5sJ!dzkgJ-& zF(aXL6?6H1m92=1P z1%j9@aRI|l_mHe`lTlB2=_4r)=s38i*IrXm;8gw8N#kTcMd3nKVk((x_yK(PmU+SD zT8A(pbalOth88?V3QdWR+yBKd*Yn*m+r(mml)w$p4UQ|`rZ;|4g8?L_9SqI$V&Z$foacS z8ioK9P}g#CpTt?(`lB}K5NB@g2})#gv?;AOc-}GNGqi8bn@L48mmQudFYYYVkj<+9 z`%N7<9CLuhlatf9)Tr?S`ilb6xWfKYUgQ6TPWiEiX%vt0t4y0%jbVRo*ChE&7PUwI z{eSfSWU%T2=I6)T|5JFesTm18Dx=n8SeX7h@v%<+55Q%6JZ7qv?0d9j*)JVr9Zg^k zJOXZdEi#h6PeTPl5$h!_BTQc&S$gP>=@kvY-|5{W9>_f^l_Q@i8PM7KpBobB?9=B) z?(gfw^o(EJ`IG_{2_#!IfPfTV*yUOlF(}ujQ#vuOg0K`K@S+hYJsi%5Lz)Ce5YbjW zCL$#4burS;+E<1dUWFb0_z6F)RbLt-TQY=Oc*eqfAG1la>35xF>X=<-d(41G%{o>d zT7TSZ`G{mCHR;$5ivAa!J>1MP;2GHu*dybr)0f970qGW3W(tZ<6-<#A5BojG**RbL z>6bcFu81J203PGx4;9bLew=VAwxv)Fob8j4%>1GMQZr80L1mPoCC%A~|MRLVi3-y} z2{>jpj#Yu$?Z?hsr&% z9edQ(g$7~WR3BWVFiV{Jmkz#3eSA|Rzwr=^r;C`Tv!19Ezy^HcF}{=^zsUanhMvl0 z#kX%tRI6U(RFsfFchod73NY?T=V?0(o`g1Og6<*c2wps9&nFej%Rzv%w)(Td5THo| zWak0%lo0|%kE%h{VO%FFaLYo1z&CXBf?gg`VXFT*><9hG(}m7QxhX(RSyQR@nZ>*R14?tV6#xJL From 026e87bd3491b1cfeca78b2d0c97eae1dbe8ab9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 7 Sep 2016 22:57:25 +0200 Subject: [PATCH 497/552] Skip some widgeds when changing focus by tab --- src/library/previewbuttondelegate.cpp | 6 ++++-- src/widget/wlibrarybreadcrumb.cpp | 1 + src/widget/wsearchlineedit.cpp | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/library/previewbuttondelegate.cpp b/src/library/previewbuttondelegate.cpp index 6c09f594298..c01d03dc72b 100644 --- a/src/library/previewbuttondelegate.cpp +++ b/src/library/previewbuttondelegate.cpp @@ -10,8 +10,8 @@ PreviewButtonDelegate::PreviewButtonDelegate(QObject *parent, int column) : QStyledItemDelegate(parent), - m_pTableView(NULL), - m_pButton(NULL), + m_pTableView(nullptr), + m_pButton(nullptr), m_isOneCellInEditMode(false), m_column(column) { m_pPreviewDeckPlay = new ControlProxy( @@ -31,6 +31,7 @@ PreviewButtonDelegate::PreviewButtonDelegate(QObject *parent, int column) m_pButton->setObjectName("LibraryPreviewButton"); m_pButton->setCheckable(true); m_pButton->setChecked(false); + m_pButton->setFocusPolicy(Qt::ClickFocus); m_pButton->hide(); connect(m_pTableView, SIGNAL(entered(QModelIndex)), this, SLOT(cellEntered(QModelIndex))); @@ -47,6 +48,7 @@ QWidget* PreviewButtonDelegate::createEditor(QWidget *parent, QPushButton* btn = new QPushButton(parent); btn->setObjectName("LibraryPreviewButton"); btn->setCheckable(true); + btn->setFocusPolicy(Qt::ClickFocus); bool playing = m_pPreviewDeckPlay->toBool(); // Check-state is whether the track is loaded (index.data()) and whether // it's playing. diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index a193d198305..a5c82a8bdb7 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -28,6 +28,7 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) m_preselectIcon.addPixmap(preOn, QIcon::Active, QIcon::Off); m_pPreselectButton->setIcon(m_preselectIcon); m_pPreselectButton->setChecked(m_preselected); + m_pPreselectButton->setFocusPolicy(Qt::ClickFocus); connect(m_pPreselectButton, SIGNAL(clicked(bool)), this, SIGNAL(preselected(bool))); diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 3f02d91d283..58be86c9534 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -22,6 +22,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) m_pClearButton->setIcon(QIcon(":/skins/cross_2.png")); m_pClearButton->setIconSize(iconSize); m_pClearButton->setCursor(Qt::ArrowCursor); + m_pClearButton->setFocusPolicy(Qt::ClickFocus); m_pClearButton->setToolTip(tr("Clear input" , "Clear the search bar input field")); m_pClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); m_pClearButton->hide(); @@ -36,6 +37,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) m_pSaveButton->setIcon(saveIcon); m_pSaveButton->setIconSize(iconSize); m_pSaveButton->setCursor(Qt::ArrowCursor); + m_pSaveButton->setFocusPolicy(Qt::ClickFocus); m_pSaveButton->setToolTip(tr("Save query", "Save the current query for later use")); m_pSaveButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); m_pSaveButton->hide(); @@ -44,6 +46,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) m_pDropButton->setIcon(QIcon(":/skins/downArrow.png")); m_pDropButton->setIconSize(iconSize); m_pDropButton->setCursor(Qt::ArrowCursor); + m_pDropButton->setFocusPolicy(Qt::ClickFocus); m_pDropButton->setToolTip(tr("Restore query", "Restore the search with one of the selected queries")); m_pDropButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); From feaee1490856264e73a6aa41a4dd1f7a3b04db52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 8 Sep 2016 22:18:09 +0200 Subject: [PATCH 498/552] check if m_focusPane is valid --- src/library/library.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index d9a6e947157..7b9630e701f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -686,7 +686,10 @@ void Library::handleFocus() { for (LibraryPaneManager* pPane : m_panes) { pPane->setFocused(false); } - m_panes[m_focusedPane]->setFocused(true); + auto it = m_panes.find(m_focusedPane); + if (it != m_panes.end()) { + (*it)->setFocused(true); + } } void Library::handlePreselection() { From d1a1dc548b52e07507b40d36aa1475b43d888fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 8 Sep 2016 22:28:59 +0200 Subject: [PATCH 499/552] fix regression --- src/library/library.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 7b9630e701f..2315824114a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -501,8 +501,8 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { if (it != m_panes.end()) { LibraryPaneManager* pSelectedPane = *it; - pFeature->setSavedPane(m_preselectedPane); - pFeature->setFeaturePane(m_preselectedPane); + pFeature->setSavedPane(selectedPane); + pFeature->setFeaturePane(selectedPane); if (pSelectedPane->getCurrentFeature() != pFeature) { pSelectedPane->setCurrentFeature(pFeature); @@ -700,8 +700,7 @@ void Library::handlePreselection() { auto it = m_panes.find(m_preselectedPane); if (it != m_panes.end()) { (*it)->setPreselected(true); - } - else { + } else { auto it = m_panes.find(m_previewPreselectedPane); if (it != m_panes.end()) { (*it)->setPreselected(true); From f8a2181664a4ca02a9dc43555c84fc7840fdc4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 8 Sep 2016 22:53:58 +0200 Subject: [PATCH 500/552] don't use [] QHash overload since it adds missng elements. --- src/library/library.cpp | 68 +++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/library/library.cpp b/src/library/library.cpp index 2315824114a..fc484f4031c 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -183,8 +183,12 @@ void Library::destroyInterface() { } LibraryView* Library::getActiveView() { - WBaseLibrary* pPane = m_panes[m_focusedPane]->getPaneWidget(); - WLibrary* pLibrary = qobject_cast(pPane); + LibraryPaneManager* pPane = m_panes.value(m_focusedPane); + DEBUG_ASSERT_AND_HANDLE(pPane) { + return nullptr; + } + WBaseLibrary* pPaneWidget = pPane->getPaneWidget(); + WLibrary* pLibrary = qobject_cast(pPaneWidget); DEBUG_ASSERT_AND_HANDLE(pLibrary) { return nullptr; } @@ -450,7 +454,11 @@ void Library::paneCollapsed(int paneId) { m_collapsedPanes.insert(paneId); // Automatically switch the focus to a non collapsed pane - m_panes[paneId]->setFocused(false); + LibraryPaneManager* pPane = m_panes.value(paneId); + if (pPane) { + pPane->setFocused(false); + } + bool focused = false; for (LibraryPaneManager* pPane : m_panes) { @@ -472,11 +480,15 @@ void Library::paneUncollapsed(int paneId) { // If the current shown feature in some pane is the same as the uncollapsed // pane feature, switch the feature from one pane to the other and set // instead the saved feature - LibraryFeature* pFeature = m_panes[paneId]->getCurrentFeature(); + LibraryPaneManager* pPane = m_panes.value(paneId); + if (pPane == nullptr) { + return; + } + LibraryFeature* pFeature = pPane->getCurrentFeature(); if (pFeature == nullptr) { return; } - pFeature->setFeaturePane(m_panes[paneId]->getPaneId()); + pFeature->setFeaturePane(pPane->getPaneId()); for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); @@ -497,10 +509,8 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { } bool featureActivated = false; - auto it = m_panes.find(selectedPane); - if (it != m_panes.end()) { - LibraryPaneManager* pSelectedPane = *it; - + LibraryPaneManager* pSelectedPane = m_panes.value(selectedPane); + if (pSelectedPane) { pFeature->setSavedPane(selectedPane); pFeature->setFeaturePane(selectedPane); @@ -578,9 +588,9 @@ void Library::slotResetFocusedFeature(LibraryFeature* pFeature) { LibraryPaneManager* Library::getOrCreatePane(int paneId) { //qDebug() << "Library::createPane" << id; // Get the value once to avoid searching again in the hash - auto it = m_panes.find(paneId); - if (it != m_panes.end()) { - return *it; + LibraryPaneManager* pPane = m_panes.value(paneId); + if (pPane) { + return pPane; } // The paneId must be non negative @@ -594,7 +604,7 @@ LibraryPaneManager* Library::getOrCreatePane(int paneId) { return nullptr; } - LibraryPaneManager* pPane = new LibraryPaneManager(paneId, this); + pPane = new LibraryPaneManager(paneId, this); pPane->addFeatures(m_features); m_panes.insert(paneId, pPane); @@ -604,19 +614,11 @@ LibraryPaneManager* Library::getOrCreatePane(int paneId) { LibraryPaneManager* Library::getFocusedPane() { //qDebug() << "Focused" << m_focusedPane; - auto it = m_panes.find(m_focusedPane); - if (it == m_panes.end()) { - return nullptr; - } - return *it; + return m_panes.value(m_focusedPane); } LibraryPaneManager* Library::getPreselectedPane() { - auto it = m_panes.find(m_preselectedPane); - if (it == m_panes.end()) { - return nullptr; - } - return *it; + return m_panes.value(m_preselectedPane); } void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { @@ -686,9 +688,9 @@ void Library::handleFocus() { for (LibraryPaneManager* pPane : m_panes) { pPane->setFocused(false); } - auto it = m_panes.find(m_focusedPane); - if (it != m_panes.end()) { - (*it)->setFocused(true); + LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPane); + if (pFocusPane) { + pFocusPane->setFocused(true); } } @@ -697,19 +699,19 @@ void Library::handlePreselection() { pPane->setPreselected(false); pPane->setPreviewed(false); } - auto it = m_panes.find(m_preselectedPane); - if (it != m_panes.end()) { - (*it)->setPreselected(true); + LibraryPaneManager* pSelectedPane = m_panes.value(m_preselectedPane); + if (pSelectedPane) { + pSelectedPane->setPreselected(true); } else { - auto it = m_panes.find(m_previewPreselectedPane); - if (it != m_panes.end()) { - (*it)->setPreselected(true); + pSelectedPane = m_panes.value(m_previewPreselectedPane); + if (pSelectedPane) { + pSelectedPane->setPreselected(true); } } } void Library::focusSearch() { - LibraryPaneManager* pFocusPane = m_panes[m_focusedPane]; + LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPane); if (pFocusPane == nullptr) return; bool ok = pFocusPane->focusSearch(); if (ok) return; From d719dd6181fbec333768a41c0fe72ed92c35d584 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 12 Sep 2016 09:24:44 +0200 Subject: [PATCH 501/552] Avoid using CSS in a child dialog --- src/widget/wsearchlineedit.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index cf8f9190b5e..ce3f9b0a199 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -351,8 +351,10 @@ void WSearchLineEdit::restoreQuery() { if (index >= 0) { m_pCurrentFeature->restoreQuery(index); } else if (index == -2 && !m_pTrackCollection.isNull()) { + // If we don't pass a nullptr as parent it uses the parent's style sheet + // and the table shown is weird DlgSavedQueriesEditor editor(m_pCurrentFeature, - m_pTrackCollection, this); + m_pTrackCollection, nullptr); editor.exec(); } } From 4c727679b6705a26e0fef6b4fcaab6863b7e17a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 13 Sep 2016 22:55:26 +0200 Subject: [PATCH 502/552] Allow back-tab --- src/widget/wbuttonbar.cpp | 44 +++++++++++++++++++++++++----- src/widget/wbuttonbar.h | 2 ++ src/widget/wverticalscrollarea.cpp | 8 +++++- src/widget/wverticalscrollarea.h | 1 + 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 984f14fd3c6..3aaf14b1b1b 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -7,7 +7,8 @@ WButtonBar::WButtonBar(QWidget* parent) : QFrame(parent), - m_focusItem(0) { + m_focusItem(0), + m_focusFromButton(false) { QHBoxLayout* pHb = new QHBoxLayout(this); pHb->setContentsMargins(0,0,0,0); @@ -116,13 +117,42 @@ void WButtonBar::keyPressEvent(QKeyEvent* event) { void WButtonBar::focusInEvent(QFocusEvent* event) { QWidget::focusInEvent(event); - QLayoutItem* item = m_pLayout->itemAt(m_focusItem); - if (item) { - QWidget* widget = item->widget(); - if (widget) { - widget->setFocus(); - emit ensureVisible(widget); + if (m_focusFromButton) { + // don't re-focus buttons, when the focus was just there before + focusPreviousChild(); + m_focusFromButton = false; + } else { + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + widget->setFocus(); + emit ensureVisible(widget); + } } } } +bool WButtonBar::focusNextPrevChild(bool next) { + // focus changing by keyboard + // Old item has still the focus, save it if it is one of our buttons + m_focusFromButton = false; + for (int i = 0; i < m_pLayout->count(); ++i) { + QLayoutItem* item = m_pLayout->itemAt(i); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + if (widget->hasFocus()) { + m_focusItem = i; + if (!next) { + // WButtonBar::focusInEvent() is called short after. + m_focusFromButton = true; + } + break; + } + } + } + } + + return QFrame::focusNextPrevChild(next); +} diff --git a/src/widget/wbuttonbar.h b/src/widget/wbuttonbar.h index 3c295825d47..9372552519a 100644 --- a/src/widget/wbuttonbar.h +++ b/src/widget/wbuttonbar.h @@ -23,10 +23,12 @@ class WButtonBar : public QFrame protected: void keyPressEvent(QKeyEvent* event) override; void focusInEvent(QFocusEvent* event) override; + bool focusNextPrevChild(bool next) override; private: QLayout* m_pLayout; int m_focusItem; + bool m_focusFromButton; }; #endif // WBUTTONBAR_H diff --git a/src/widget/wverticalscrollarea.cpp b/src/widget/wverticalscrollarea.cpp index 900a182c9bc..32e1e5e9eaa 100644 --- a/src/widget/wverticalscrollarea.cpp +++ b/src/widget/wverticalscrollarea.cpp @@ -41,6 +41,12 @@ void WVerticalScrollArea::calcSize() { } void WVerticalScrollArea::slotEnsureVisible(QWidget* widget) { - qDebug() << "WVerticalScrollArea::slotEnsureVisible"; + //qDebug() << "WVerticalScrollArea::slotEnsureVisible"; ensureWidgetVisible(widget, 0, 0); } + +bool WVerticalScrollArea::focusNextPrevChild(bool next) { + // QScrollArea::focusNextPrevChild scrolls to center + // of focused child. Sip scrolling here. + return QWidget::focusNextPrevChild(next); +} diff --git a/src/widget/wverticalscrollarea.h b/src/widget/wverticalscrollarea.h index 9b16c05f254..65b68634aa6 100644 --- a/src/widget/wverticalscrollarea.h +++ b/src/widget/wverticalscrollarea.h @@ -17,6 +17,7 @@ class WVerticalScrollArea : public QScrollArea protected: bool eventFilter(QObject* o, QEvent* e) override; void resizeEvent(QResizeEvent* e) override; + bool focusNextPrevChild(bool next) override; private: void calcSize(); From d6e55f9e21419f62ab2b92cffc53e0a749b4dec2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 14 Sep 2016 17:12:53 +0200 Subject: [PATCH 503/552] Add header and checkboxes --- .../savedqueries/savedqueriestablemodel.cpp | 30 ++++++++++++++++++- .../savedqueries/savedqueriestablemodel.h | 3 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/dialog/savedqueries/savedqueriestablemodel.cpp b/src/dialog/savedqueries/savedqueriestablemodel.cpp index e3abe2bd0f6..a96adcfe43f 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.cpp +++ b/src/dialog/savedqueries/savedqueriestablemodel.cpp @@ -16,7 +16,6 @@ SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, setEditStrategy(QSqlTableModel::OnManualSubmit); setFilter(filter); - select(); } @@ -25,3 +24,32 @@ bool SavedQueriesTableModel::isColumnInternal(int column) { column != SavedQueryColums::TITLE && column != SavedQueryColums::PINNED; } + +QVariant SavedQueriesTableModel::data(const QModelIndex& index, int role) const { + if (index.column() == SavedQueryColums::PINNED) { + if (role == Qt::DisplayRole) return QVariant(); + else if (role == Qt::CheckStateRole) { + QVariant baseData = QSqlTableModel::data(index, Qt::DisplayRole); + return baseData.toBool() ? Qt::Checked : Qt::Unchecked; + } + } + + return QSqlTableModel::data(index, role); +} + +QVariant SavedQueriesTableModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role != Qt::DisplayRole || orientation != Qt::Horizontal) { + return QSqlTableModel::headerData(section, orientation, role); + } + + switch (section) { + case SavedQueryColums::QUERY: + return tr("Query"); + case SavedQueryColums::TITLE: + return tr("Title"); + case SavedQueryColums::PINNED: + return tr("Pinned"); + } + return ""; +} + diff --git a/src/dialog/savedqueries/savedqueriestablemodel.h b/src/dialog/savedqueries/savedqueriestablemodel.h index cf17ee1c9bc..e7ea38dfc64 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.h +++ b/src/dialog/savedqueries/savedqueriestablemodel.h @@ -13,7 +13,8 @@ class SavedQueriesTableModel : public QSqlTableModel QSqlDatabase db = QSqlDatabase()); bool isColumnInternal(int column); - + QVariant data(const QModelIndex& index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: LibraryFeature* m_pFeature; From fd1b7787146a614cf281beb41a484a445e32a52d Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 17:50:36 +0200 Subject: [PATCH 504/552] Fix mispelling in SavedQueriesColumns name --- src/dialog/savedqueries/dlgsavedquerieseditor.cpp | 2 +- src/library/dao/savedqueriesdao.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp index 0057d39c0de..1438033f06a 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp @@ -17,7 +17,7 @@ DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, new SavedQueriesTableModel(m_pFeature, parent, m_pTrackCollection->getDatabase()); tableView->setModel(pTableModel); - for (int i = 0; i < SavedQueryColums::NUM_COLUMNS; ++i) { + for (int i = 0; i < SavedQueryColumns::NUM_COLUMNS; ++i) { tableView->setColumnHidden(i, pTableModel->isColumnInternal(i)); } } diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 7c0053ed612..ba2a9e9b319 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -10,7 +10,7 @@ #define SAVEDQUERYTABLE "savedQueries" -enum SavedQueryColums { +enum SavedQueryColumns { ID, LIBRARYFEATURE, QUERY, From d7b9d1b1c4a4f14d8f04f9eeaca252dfe499d53a Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 18:38:02 +0200 Subject: [PATCH 505/552] Change pinned datatype --- res/schema.xml | 4 ++-- src/library/dao/savedqueriesdao.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/schema.xml b/res/schema.xml index 7338e5cc97d..36da5556791 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -441,8 +441,8 @@ METADATA sortOrder TEXT, vScrollbarPos INTEGER, sortColumn INTEGER, - sortAscendingOrder BOOLEAN, - pinned BOOLEAN + sortAscendingOrder NUMERIC, + pinned NUMERIC );
diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 2240bfbed7d..0f9f0cc1c4b 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -36,8 +36,8 @@ SavedSearchQuery SavedQueriesDAO::saveQuery(LibraryFeature* pFeature, query.bindValue(":sortOrder", sQuery.sortOrder); query.bindValue(":vScrollbarPos", sQuery.vScrollBarPos); query.bindValue(":sortColumn", sQuery.sortColumn); - query.bindValue(":sortAscendingOrder", sQuery.sortAscendingOrder); - query.bindValue(":pinned", sQuery.pinned); + query.bindValue(":sortAscendingOrder", (int) sQuery.sortAscendingOrder); + query.bindValue(":pinned", (int) sQuery.pinned); if (!query.exec()) { LOG_FAILED_QUERY(query); From f487f0f490ebc30a0b5162a17b1bf5e81553e9bd Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 19:30:28 +0200 Subject: [PATCH 506/552] Add update function to Saved Queries DAO --- src/library/dao/savedqueriesdao.cpp | 23 +++++++++++++++++++++++ src/library/dao/savedqueriesdao.h | 1 + 2 files changed, 24 insertions(+) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 0f9f0cc1c4b..37f1b545487 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -110,6 +110,29 @@ SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) return moveToFirst(pFeature, getSavedQuery(id)); } +bool SavedQueriesDAO::updateSavedQuery(const SavedSearchQuery& sQuery) { + QSqlQuery query(m_database); + query.prepare("UPDATE FROM " SAVEDQUERYTABLE " WHERE id = :id SET " + "query = :query, title = :title, selectedItems = :selectedItems, " + "sortOrder = :sortOrder, vScrollbarPos = :vScrollbarPos, " + "sortColumn = :sortColumn, " + "sortAscendingOrder = :sortAscendingOrder, pinned = :pinned"); + + query.bindValue(":id", sQuery.id); + query.bindValue(":query", sQuery.query); + query.bindValue(":title", sQuery.title); + query.bindValue(":selectedItems", serializeItems(sQuery.selectedItems)); + query.bindValue(":sortOrder", sQuery.sortOrder); + query.bindValue(":vScrollbarPos", sQuery.vScrollBarPos); + query.bindValue(":sortColumn", sQuery.sortColumn); + query.bindValue(":sortAscendingOrder", (int) sQuery.sortAscendingOrder); + query.bindValue(":pinned", (int) sQuery.pinned); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } +} + bool SavedQueriesDAO::deleteSavedQuery(int id) { QSqlQuery query(m_database); query.prepare("DELETE FROM " SAVEDQUERYTABLE " WHERE id=:id"); diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index ba2a9e9b319..6a5033765a7 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -80,6 +80,7 @@ class SavedQueriesDAO : public DAO SavedSearchQuery getSavedQuery(int id) const; SavedSearchQuery moveToFirst(LibraryFeature* pFeature, const SavedSearchQuery& sQuery); SavedSearchQuery moveToFirst(LibraryFeature* pFeature, int id); + bool updateSavedQuery(const SavedSearchQuery& sQuery); bool deleteSavedQuery(int id); bool exists(const SavedSearchQuery& sQuery); int getQueryId(const SavedSearchQuery& sQuery); From f1f05a44232f8e664d4b3326bb508c6acd497cc8 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 19:31:11 +0200 Subject: [PATCH 507/552] Redo saved queries table model to allow checkboxes --- .../savedqueries/savedqueriestablemodel.cpp | 109 ++++++++++++++---- .../savedqueries/savedqueriestablemodel.h | 16 ++- 2 files changed, 99 insertions(+), 26 deletions(-) diff --git a/src/dialog/savedqueries/savedqueriestablemodel.cpp b/src/dialog/savedqueries/savedqueriestablemodel.cpp index a96adcfe43f..be3d1c0aa81 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.cpp +++ b/src/dialog/savedqueries/savedqueriestablemodel.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include "library/dao/savedqueriesdao.h" @@ -7,49 +9,108 @@ SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, QObject* parent, QSqlDatabase db) - : QSqlTableModel(parent, db), - m_pFeature(pFeature) { - QString filter = "libraryFeature='%1'"; - filter = filter.arg(m_pFeature->getSettingsName()); - - setTable(SAVEDQUERYTABLE); - setEditStrategy(QSqlTableModel::OnManualSubmit); - setFilter(filter); - - select(); + : QAbstractTableModel(parent), + m_pFeature(pFeature), + m_savedDao(db) { + m_cachedData = m_savedDao.getSavedQueries(m_pFeature); } bool SavedQueriesTableModel::isColumnInternal(int column) { - return column != SavedQueryColums::QUERY && - column != SavedQueryColums::TITLE && - column != SavedQueryColums::PINNED; + return column != SavedQueryColumns::QUERY && + column != SavedQueryColumns::TITLE && + column != SavedQueryColumns::PINNED; } QVariant SavedQueriesTableModel::data(const QModelIndex& index, int role) const { - if (index.column() == SavedQueryColums::PINNED) { - if (role == Qt::DisplayRole) return QVariant(); - else if (role == Qt::CheckStateRole) { - QVariant baseData = QSqlTableModel::data(index, Qt::DisplayRole); - return baseData.toBool() ? Qt::Checked : Qt::Unchecked; - } + if (!index.isValid()) return QVariant(); + + const SavedSearchQuery& sQuery = m_cachedData.at(index.row()); + switch (index.column()) { + case SavedQueryColumns::QUERY: + if (role == Qt::DisplayRole || role == Qt::EditRole) return sQuery.query; + break; + + case SavedQueryColumns::TITLE: + if (role == Qt::DisplayRole || role == Qt::EditRole) return sQuery.title; + break; + + case SavedQueryColumns::PINNED: + if (role == Qt::CheckStateRole) { + return sQuery.pinned ? Qt::Checked : Qt::Unchecked; + } + break; } + return QVariant(); +} + +bool SavedQueriesTableModel::setData(const QModelIndex& index, const QVariant& value, int role) { + if (!index.isValid()) return false; - return QSqlTableModel::data(index, role); + SavedSearchQuery& sQuery = m_cachedData[index.row()]; + switch (index.column()) { + case SavedQueryColumns::QUERY: + if (role == Qt::EditRole) { + sQuery.query = value.toString(); + return true; + } + break; + + case SavedQueryColumns::TITLE: + if (role == Qt::EditRole) { + sQuery.title = value.toString(); + return true; + } + break; + + case SavedQueryColumns::PINNED: + if (role == Qt::CheckStateRole) { + sQuery.pinned = !sQuery.pinned; + return true; + } + } + return false; } QVariant SavedQueriesTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole || orientation != Qt::Horizontal) { - return QSqlTableModel::headerData(section, orientation, role); + return QAbstractTableModel::headerData(section, orientation, role); } switch (section) { - case SavedQueryColums::QUERY: + case SavedQueryColumns::QUERY: return tr("Query"); - case SavedQueryColums::TITLE: + case SavedQueryColumns::TITLE: return tr("Title"); - case SavedQueryColums::PINNED: + case SavedQueryColumns::PINNED: return tr("Pinned"); } return ""; } +Qt::ItemFlags SavedQueriesTableModel::flags(const QModelIndex& index) const { + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + flags |= Qt::ItemIsSelectable; + flags |= Qt::ItemIsEnabled; + flags |= Qt::ItemIsEditable; + + if (index.column() == SavedQueryColumns::PINNED) { + flags |= Qt::ItemIsUserCheckable; + } + return flags; +} + +int SavedQueriesTableModel::rowCount(const QModelIndex& parent) const { + if (parent.isValid()) return 0; + return m_cachedData.length(); +} + +int SavedQueriesTableModel::columnCount(const QModelIndex& parent) const { + if (parent.isValid()) return 0; + return SavedQueryColumns::NUM_COLUMNS; +} + +bool SavedQueriesTableModel::submit() { + for (const SavedSearchQuery& sQuery : m_cachedData) { + m_savedDao.updateSavedQuery(sQuery); + } +} diff --git a/src/dialog/savedqueries/savedqueriestablemodel.h b/src/dialog/savedqueries/savedqueriestablemodel.h index e7ea38dfc64..9a8300f0860 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.h +++ b/src/dialog/savedqueries/savedqueriestablemodel.h @@ -1,11 +1,11 @@ #ifndef SAVEDQUERIESTABLEMODEL_H #define SAVEDQUERIESTABLEMODEL_H -#include +#include #include "library/libraryfeature.h" -class SavedQueriesTableModel : public QSqlTableModel +class SavedQueriesTableModel : public QAbstractTableModel { public: SavedQueriesTableModel(LibraryFeature* pFeature, @@ -14,10 +14,22 @@ class SavedQueriesTableModel : public QSqlTableModel bool isColumnInternal(int column); QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + int rowCount(const QModelIndex& parent) const; + int columnCount(const QModelIndex& parent) const; + +public slots: + + bool submit() override; + private: + QList m_cachedData; LibraryFeature* m_pFeature; + SavedQueriesDAO m_savedDao; }; #endif // SAVEDQUERIESTABLEMODEL_H From 97aef476790a8d1f63cceafb589e9165281454d2 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 19:31:26 +0200 Subject: [PATCH 508/552] Add submit button to Saved Queries editor --- src/dialog/savedqueries/dlgsavedquerieseditor.cpp | 4 ++++ src/dialog/savedqueries/dlgsavedquerieseditor.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp index 1438033f06a..31d9cac02fd 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp @@ -21,3 +21,7 @@ DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, tableView->setColumnHidden(i, pTableModel->isColumnInternal(i)); } } + +void DlgSavedQueriesEditor::accept() { + tableView->model()->submit(); +} diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.h b/src/dialog/savedqueries/dlgsavedquerieseditor.h index 9f27835599f..9e2a5d9df26 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.h +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.h @@ -14,6 +14,12 @@ class DlgSavedQueriesEditor : public QDialog, private Ui::DlgSavedQueriesEditor explicit DlgSavedQueriesEditor(LibraryFeature* pFeature, TrackCollection* pTrackCollection, QWidget* parent = nullptr); + + public slots: + + void accept() override; + + private: TrackCollection* m_pTrackCollection; SavedQueriesDAO& m_savedDAO; From 246432076ce1cc5b4fe4cdfa9fa6052750b1b436 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 21 Sep 2016 20:00:22 +0200 Subject: [PATCH 509/552] Fix null pointer error --- src/dialog/savedqueries/dlgsavedquerieseditor.cpp | 7 ++++--- src/dialog/savedqueries/dlgsavedquerieseditor.h | 1 - src/dialog/savedqueries/savedqueriestablemodel.cpp | 9 +++++---- src/dialog/savedqueries/savedqueriestablemodel.h | 6 +++--- src/library/dao/savedqueriesdao.cpp | 11 +++++++---- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp index 31d9cac02fd..6cfba3fd643 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp @@ -10,12 +10,12 @@ DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, QWidget* parent) : QDialog(parent), m_pTrackCollection(pTrackCollection), - m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), m_pFeature(pFeature) { setupUi(this); SavedQueriesTableModel* pTableModel = - new SavedQueriesTableModel(m_pFeature, parent, - m_pTrackCollection->getDatabase()); + new SavedQueriesTableModel(m_pFeature, + m_pTrackCollection->getSavedQueriesDAO(), + parent); tableView->setModel(pTableModel); for (int i = 0; i < SavedQueryColumns::NUM_COLUMNS; ++i) { tableView->setColumnHidden(i, pTableModel->isColumnInternal(i)); @@ -24,4 +24,5 @@ DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, void DlgSavedQueriesEditor::accept() { tableView->model()->submit(); + QDialog::accept(); } diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.h b/src/dialog/savedqueries/dlgsavedquerieseditor.h index 9e2a5d9df26..76a6ed69f81 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.h +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.h @@ -22,7 +22,6 @@ class DlgSavedQueriesEditor : public QDialog, private Ui::DlgSavedQueriesEditor private: TrackCollection* m_pTrackCollection; - SavedQueriesDAO& m_savedDAO; LibraryFeature* m_pFeature; }; diff --git a/src/dialog/savedqueries/savedqueriestablemodel.cpp b/src/dialog/savedqueries/savedqueriestablemodel.cpp index be3d1c0aa81..2cff959ba2a 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.cpp +++ b/src/dialog/savedqueries/savedqueriestablemodel.cpp @@ -6,12 +6,12 @@ #include "dialog/savedqueries/savedqueriestablemodel.h" -SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, - QObject* parent, - QSqlDatabase db) +SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, + SavedQueriesDAO& savedDao, + QObject* parent) : QAbstractTableModel(parent), m_pFeature(pFeature), - m_savedDao(db) { + m_savedDao(savedDao) { m_cachedData = m_savedDao.getSavedQueries(m_pFeature); } @@ -113,4 +113,5 @@ bool SavedQueriesTableModel::submit() { for (const SavedSearchQuery& sQuery : m_cachedData) { m_savedDao.updateSavedQuery(sQuery); } + QAbstractTableModel::submit(); } diff --git a/src/dialog/savedqueries/savedqueriestablemodel.h b/src/dialog/savedqueries/savedqueriestablemodel.h index 9a8300f0860..228a47ecae8 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.h +++ b/src/dialog/savedqueries/savedqueriestablemodel.h @@ -9,8 +9,8 @@ class SavedQueriesTableModel : public QAbstractTableModel { public: SavedQueriesTableModel(LibraryFeature* pFeature, - QObject* parent = nullptr, - QSqlDatabase db = QSqlDatabase()); + SavedQueriesDAO& savedDao, + QObject* parent = nullptr); bool isColumnInternal(int column); QVariant data(const QModelIndex& index, int role) const override; @@ -29,7 +29,7 @@ public slots: QList m_cachedData; LibraryFeature* m_pFeature; - SavedQueriesDAO m_savedDao; + SavedQueriesDAO& m_savedDao; }; #endif // SAVEDQUERIESTABLEMODEL_H diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index 37f1b545487..a14f0a49983 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -112,13 +112,13 @@ SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) bool SavedQueriesDAO::updateSavedQuery(const SavedSearchQuery& sQuery) { QSqlQuery query(m_database); - query.prepare("UPDATE FROM " SAVEDQUERYTABLE " WHERE id = :id SET " + query.prepare("UPDATE " SAVEDQUERYTABLE " SET " "query = :query, title = :title, selectedItems = :selectedItems, " "sortOrder = :sortOrder, vScrollbarPos = :vScrollbarPos, " "sortColumn = :sortColumn, " - "sortAscendingOrder = :sortAscendingOrder, pinned = :pinned"); + "sortAscendingOrder = :sortAscendingOrder, pinned = :pinned " + "WHERE id = :id"); - query.bindValue(":id", sQuery.id); query.bindValue(":query", sQuery.query); query.bindValue(":title", sQuery.title); query.bindValue(":selectedItems", serializeItems(sQuery.selectedItems)); @@ -127,10 +127,13 @@ bool SavedQueriesDAO::updateSavedQuery(const SavedSearchQuery& sQuery) { query.bindValue(":sortColumn", sQuery.sortColumn); query.bindValue(":sortAscendingOrder", (int) sQuery.sortAscendingOrder); query.bindValue(":pinned", (int) sQuery.pinned); + query.bindValue(":id", sQuery.id); if (!query.exec()) { LOG_FAILED_QUERY(query); - } + return false; + } + return true; } bool SavedQueriesDAO::deleteSavedQuery(int id) { From 1a38fde1779b5be6dce74f91bf881a9fcebaac41 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 23 Sep 2016 12:00:34 +0200 Subject: [PATCH 510/552] Allow removing some queries --- .../savedqueries/dlgsavedquerieseditor.cpp | 28 +++++++++++-- .../savedqueries/dlgsavedquerieseditor.h | 14 ++++--- .../savedqueries/dlgsavedquerieseditor.ui | 40 +++++++++++++++---- .../savedqueries/savedqueriestablemodel.cpp | 22 +++++++++- .../savedqueries/savedqueriestablemodel.h | 12 ++++-- src/library/dao/savedqueriesdao.cpp | 2 +- src/library/dao/savedqueriesdao.h | 3 +- 7 files changed, 96 insertions(+), 25 deletions(-) diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp index 6cfba3fd643..a71bc4adf10 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.cpp +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.cpp @@ -12,17 +12,39 @@ DlgSavedQueriesEditor::DlgSavedQueriesEditor(LibraryFeature* pFeature, m_pTrackCollection(pTrackCollection), m_pFeature(pFeature) { setupUi(this); - SavedQueriesTableModel* pTableModel = + SavedQueriesTableModel *pSaveModel = new SavedQueriesTableModel(m_pFeature, m_pTrackCollection->getSavedQueriesDAO(), parent); - tableView->setModel(pTableModel); + tableView->setModel(pSaveModel); for (int i = 0; i < SavedQueryColumns::NUM_COLUMNS; ++i) { - tableView->setColumnHidden(i, pTableModel->isColumnInternal(i)); + tableView->setColumnHidden(i, pSaveModel->isColumnInternal(i)); } + + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + tableView->verticalHeader()->hide(); + + connect(pushRemove, SIGNAL(pressed()), this, SLOT(removeQuery())); } void DlgSavedQueriesEditor::accept() { tableView->model()->submit(); QDialog::accept(); } + +void DlgSavedQueriesEditor::removeQuery() { + QItemSelectionModel* model = tableView->selectionModel(); + if (model == nullptr) return; + + QModelIndexList selected = model->selectedRows(); + + QSet removedRows; + for (const QModelIndex& index : selected) { + removedRows << index.row(); + } + + for (int row : removedRows) { + tableView->model()->removeRow(row); + } +} diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.h b/src/dialog/savedqueries/dlgsavedquerieseditor.h index 76a6ed69f81..4b27f14dc4d 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.h +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.h @@ -11,16 +11,20 @@ class DlgSavedQueriesEditor : public QDialog, private Ui::DlgSavedQueriesEditor Q_OBJECT public: - explicit DlgSavedQueriesEditor(LibraryFeature* pFeature, - TrackCollection* pTrackCollection, + explicit DlgSavedQueriesEditor(LibraryFeature* pFeature, + TrackCollection* pTrackCollection, QWidget* parent = nullptr); - + public slots: - + void accept() override; + + private slots: + void removeQuery(); + private: - + TrackCollection* m_pTrackCollection; LibraryFeature* m_pFeature; }; diff --git a/src/dialog/savedqueries/dlgsavedquerieseditor.ui b/src/dialog/savedqueries/dlgsavedquerieseditor.ui index 954ddeac745..bfb4b8f8abc 100644 --- a/src/dialog/savedqueries/dlgsavedquerieseditor.ui +++ b/src/dialog/savedqueries/dlgsavedquerieseditor.ui @@ -18,14 +18,38 @@ - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + Remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + diff --git a/src/dialog/savedqueries/savedqueriestablemodel.cpp b/src/dialog/savedqueries/savedqueriestablemodel.cpp index 2cff959ba2a..4d78b5e7b0a 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.cpp +++ b/src/dialog/savedqueries/savedqueriestablemodel.cpp @@ -15,7 +15,7 @@ SavedQueriesTableModel::SavedQueriesTableModel(LibraryFeature* pFeature, m_cachedData = m_savedDao.getSavedQueries(m_pFeature); } -bool SavedQueriesTableModel::isColumnInternal(int column) { +bool SavedQueriesTableModel::isColumnInternal(int column) const { return column != SavedQueryColumns::QUERY && column != SavedQueryColumns::TITLE && column != SavedQueryColumns::PINNED; @@ -109,9 +109,27 @@ int SavedQueriesTableModel::columnCount(const QModelIndex& parent) const { return SavedQueryColumns::NUM_COLUMNS; } +bool SavedQueriesTableModel::removeRows(int row, int count, const QModelIndex& parent) { + if (parent.isValid()) return false; + + beginRemoveRows(QModelIndex(), row, row + count - 1); + while (count > 0 && row < m_cachedData.size()) { + m_removedQueries << m_cachedData.takeAt(row).id; + --count; + } + endRemoveRows(); + + return true; +} + bool SavedQueriesTableModel::submit() { for (const SavedSearchQuery& sQuery : m_cachedData) { m_savedDao.updateSavedQuery(sQuery); } - QAbstractTableModel::submit(); + + for (int id : m_removedQueries) { + m_savedDao.deleteSavedQuery(id); + } + + return QAbstractTableModel::submit(); } diff --git a/src/dialog/savedqueries/savedqueriestablemodel.h b/src/dialog/savedqueries/savedqueriestablemodel.h index 228a47ecae8..62bb72e488a 100644 --- a/src/dialog/savedqueries/savedqueriestablemodel.h +++ b/src/dialog/savedqueries/savedqueriestablemodel.h @@ -12,21 +12,25 @@ class SavedQueriesTableModel : public QAbstractTableModel SavedQueriesDAO& savedDao, QObject* parent = nullptr); - bool isColumnInternal(int column); + bool isColumnInternal(int column) const; QVariant data(const QModelIndex& index, int role) const override; bool setData(const QModelIndex& index, const QVariant& value, int role) override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - int rowCount(const QModelIndex& parent) const; - int columnCount(const QModelIndex& parent) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + int columnCount(const QModelIndex& parent = QModelIndex()) const; + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); public slots: bool submit() override; + void removeQuery(const QModelIndex& index); private: + QList m_cachedData; + QList m_removedQueries; LibraryFeature* m_pFeature; SavedQueriesDAO& m_savedDao; diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index a14f0a49983..c2edbf16274 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -110,7 +110,7 @@ SavedSearchQuery SavedQueriesDAO::moveToFirst(LibraryFeature* pFeature, int id) return moveToFirst(pFeature, getSavedQuery(id)); } -bool SavedQueriesDAO::updateSavedQuery(const SavedSearchQuery& sQuery) { +bool SavedQueriesDAO::updateSavedQuery(const SavedSearchQuery& sQuery) { QSqlQuery query(m_database); query.prepare("UPDATE " SAVEDQUERYTABLE " SET " "query = :query, title = :title, selectedItems = :selectedItems, " diff --git a/src/library/dao/savedqueriesdao.h b/src/library/dao/savedqueriesdao.h index 6a5033765a7..a172977c061 100644 --- a/src/library/dao/savedqueriesdao.h +++ b/src/library/dao/savedqueriesdao.h @@ -68,8 +68,7 @@ struct SavedSearchQuery { class LibraryFeature; -class SavedQueriesDAO : public DAO -{ +class SavedQueriesDAO : public DAO { public: SavedQueriesDAO(QSqlDatabase& database); From 4f44fca4ccbc647838efddec9be674726d58b462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 24 Sep 2016 12:24:00 +0200 Subject: [PATCH 511/552] Reject invalid pane ids first --- res/skins/LateNight/library.xml | 26 ++++++++++++++++++++------ src/skin/legacyskinparser.cpp | 15 +++++---------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index 8fbf1419962..8514a73ef9a 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -56,13 +56,13 @@ vertical - 1 + 2 - 1 + 2 - 1 + 2 @@ -70,13 +70,27 @@ vertical - 2 + -1 - 2 + -1 - 2 + -1 + + + + + vertical + + + 3 + + + 3 + + + 3 diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index b782f76a984..356a16b7153 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1162,7 +1162,6 @@ QWidget* LegacySkinParser::parseSpinny(const QDomElement& node) { } QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { - int id = -1; if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { SKIN_WARNING(node, *m_pContext) << "SearchBox Id not found"; @@ -1173,7 +1172,6 @@ QWidget* LegacySkinParser::parseSearchBox(const QDomElement& node) { return nullptr; } //qDebug() << "SearchBox ID:" << id; - WSearchLineEdit* pSearchLineEdit = new WSearchLineEdit(m_pParent); m_pLibrary->bindSearchBar(pSearchLineEdit, id); pSearchLineEdit->setup(node, *m_pContext); @@ -1266,10 +1264,6 @@ void LegacySkinParser::parseSingletonDefinition(const QDomElement& node) { } QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { - WLibrary* pLibraryWidget = new WLibrary(m_pParent); - pLibraryWidget->installEventFilter(m_pKeyboard); - pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); - int id = -1; if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { SKIN_WARNING(node, *m_pContext) << "Pane Id not found"; @@ -1279,8 +1273,11 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { SKIN_WARNING(node, *m_pContext) << "The pane Id cannot be negative"; return nullptr; } - //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; + WLibrary* pLibraryWidget = new WLibrary(m_pParent); + pLibraryWidget->installEventFilter(m_pKeyboard); + pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); + m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, id); // This must come after the bindWidget or we will not style any of the @@ -1378,8 +1375,6 @@ QWidget *LegacySkinParser::parseLibrarySidebarExpanded(const QDomElement &node) } QWidget* LegacySkinParser::parseLibraryBreadCrumb(const QDomElement& node) { - WLibraryBreadCrumb* pLibraryBreacrumb = new WLibraryBreadCrumb(m_pParent); - int id = -1; if (!m_pContext->hasNodeSelectInt(node, "Id", &id)) { SKIN_WARNING(node, *m_pContext) << "BreadCrumb Id not found"; @@ -1389,8 +1384,8 @@ QWidget* LegacySkinParser::parseLibraryBreadCrumb(const QDomElement& node) { SKIN_WARNING(node, *m_pContext) << "The BreadCrumb Id cannot be negative"; return nullptr; } - //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; + WLibraryBreadCrumb* pLibraryBreacrumb = new WLibraryBreadCrumb(m_pParent); m_pLibrary->bindBreadCrumb(pLibraryBreacrumb, id); setupWidget(node, pLibraryBreacrumb); From 6ab6635f8837ea4a35f8cbd5959c0dc1f46e652c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 24 Sep 2016 13:33:12 +0200 Subject: [PATCH 512/552] fix some warnings --- src/widget/wbaselibrary.cpp | 7 ++++--- src/widget/wlibrary.cpp | 3 +-- src/widget/wlibrary.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index f68e05b6f7e..c3056a26187 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -10,12 +10,14 @@ WBaseLibrary::WBaseLibrary(QWidget* parent) : QStackedWidget(parent), WBaseWidget(this), + m_pCurrentFeature(nullptr), m_mutex(QMutex::Recursive), - m_showFocus(0) { + m_showFocus(0), + m_isCollapsed(false) { } -bool WBaseLibrary::registerView(LibraryFeature *pFeature, QWidget *view) { +bool WBaseLibrary::registerView(LibraryFeature* pFeature, QWidget* view) { QMutexLocker lock(&m_mutex); if (m_featureMap.contains(pFeature)) { return false; @@ -74,7 +76,6 @@ bool WBaseLibrary::event(QEvent* pEvent) { } void WBaseLibrary::resizeEvent(QResizeEvent *pEvent) { - // Detect whether the library is collapsed to change the focus behaviour if (pEvent->size().isEmpty()) { m_isCollapsed = true; diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrary.cpp index fe1d4dc2d4e..3569c8bd35d 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrary.cpp @@ -18,10 +18,9 @@ void showLibraryWarning() { WLibrary::WLibrary(QWidget* parent) : WBaseLibrary(parent), m_mutex(QMutex::Recursive) { - } -bool WLibrary::registerView(LibraryFeature *pFeature, QWidget* pView) { +bool WLibrary::registerView(LibraryFeature* pFeature, QWidget* pView) { QMutexLocker lock(&m_mutex); if (pFeature == nullptr || dynamic_cast(pView) == nullptr) { showLibraryWarning(); diff --git a/src/widget/wlibrary.h b/src/widget/wlibrary.h index 7ed14f02c82..ce6b332c3b2 100644 --- a/src/widget/wlibrary.h +++ b/src/widget/wlibrary.h @@ -26,7 +26,7 @@ class WLibrary : public WBaseLibrary { // the view and is in charge of deleting it. Returns whether or not the // registration was successful. Registered widget must implement the // LibraryView interface. - bool registerView(LibraryFeature* pFeature, QWidget *pView); + bool registerView(LibraryFeature* pFeature, QWidget* pView); LibraryView* getActiveView() const; From 50b215b3b15cb4c48543e9d0829c37cdd96e588f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 24 Sep 2016 13:47:16 +0200 Subject: [PATCH 513/552] WLibrary -> WLibaryPane --- build/depends.py | 2 +- .../features/analysis/analysisfeature.cpp | 2 +- .../features/baseplaylist/baseplaylistfeature.h | 2 +- src/library/features/browse/browsefeature.cpp | 2 +- .../features/recording/recordingfeature.cpp | 2 +- src/library/library.cpp | 6 +++--- src/library/library.h | 4 ++-- src/library/librarycontrol.cpp | 2 +- src/library/librarycontrol.h | 2 +- src/library/libraryfeature.h | 2 +- src/library/librarypanemanager.cpp | 6 +++--- src/library/librarypanemanager.h | 2 +- src/skin/legacyskinparser.cpp | 17 +++++++++-------- src/widget/{wlibrary.cpp => wlibrarypane.cpp} | 16 ++++++++-------- src/widget/{wlibrary.h => wlibrarypane.h} | 4 ++-- src/widget/wsingletoncontainer.cpp | 2 +- 16 files changed, 37 insertions(+), 36 deletions(-) rename src/widget/{wlibrary.cpp => wlibrarypane.cpp} (80%) rename src/widget/{wlibrary.h => wlibrarypane.h} (93%) diff --git a/build/depends.py b/build/depends.py index 6af1231d861..319219f6d2a 100644 --- a/build/depends.py +++ b/build/depends.py @@ -847,7 +847,7 @@ def sources(self, build): "widget/wtracktableview.cpp", "widget/wtracktableviewheader.cpp", "widget/wlibrarysidebar.cpp", - "widget/wlibrary.cpp", + "widget/wlibrarypane.cpp", "widget/wbaselibrary.cpp", "widget/wlibrarytableview.cpp", "widget/wanalysislibrarytableview.cpp", diff --git a/src/library/features/analysis/analysisfeature.cpp b/src/library/features/analysis/analysisfeature.cpp index 4234c7efcd2..cd0a63975af 100644 --- a/src/library/features/analysis/analysisfeature.cpp +++ b/src/library/features/analysis/analysisfeature.cpp @@ -2,6 +2,7 @@ // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) // Forked 11/11/2009 by Albert Santoni (alberts@mixxx.org) +#include #include #include "analyzer/analyzerqueue.h" @@ -14,7 +15,6 @@ #include "util/debug.h" #include "util/dnd.h" #include "widget/wanalysislibrarytableview.h" -#include "widget/wlibrary.h" #include "widget/wtracktableview.h" AnalysisFeature::AnalysisFeature(UserSettingsPointer pConfig, diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index db30ac0d2a3..2531ce582ab 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -20,7 +20,7 @@ class KeyboardEventFilter; class PlaylistTableModel; class TrackCollection; class TreeItem; -class WLibrary; +class WLibraryPane; class WLibraryStack; class BasePlaylistFeature : public LibraryFeature { diff --git a/src/library/features/browse/browsefeature.cpp b/src/library/features/browse/browsefeature.cpp index d8029ba4f3a..80ca4c117b3 100644 --- a/src/library/features/browse/browsefeature.cpp +++ b/src/library/features/browse/browsefeature.cpp @@ -1,6 +1,7 @@ // browsefeature.cpp // Created 9/8/2009 by RJ Ryan (rryan@mit.edu) +#include #include #include #include @@ -13,7 +14,6 @@ #include "library/features/browse/browsefeature.h" #include "library/trackcollection.h" #include "util/sandbox.h" -#include "widget/wlibrary.h" #include "widget/wlibrarystack.h" #include "widget/wlibrarytextbrowser.h" diff --git a/src/library/features/recording/recordingfeature.cpp b/src/library/features/recording/recordingfeature.cpp index bbba89e9aac..f9900ef68ac 100644 --- a/src/library/features/recording/recordingfeature.cpp +++ b/src/library/features/recording/recordingfeature.cpp @@ -1,13 +1,13 @@ // recordingfeature.cpp // Created 03/26/2010 by Tobias Rafreider +#include #include "controllers/keyboard/keyboardeventfilter.h" #include "library/features/recording/dlgrecording.h" #include "library/features/recording/recordingfeature.h" #include "library/library.h" #include "library/trackcollection.h" #include "track/track.h" -#include "widget/wlibrary.h" #include "widget/wtracktableview.h" RecordingFeature::RecordingFeature(UserSettingsPointer pConfig, diff --git a/src/library/library.cpp b/src/library/library.cpp index fc484f4031c..64dfab64c7f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -138,7 +138,7 @@ void Library::bindSidebarButtons(WButtonBar* sidebar) { } } -void Library::bindPaneWidget(WLibrary* pLibraryWidget, +void Library::bindPaneWidget(WLibraryPane* pPaneWidget, KeyboardEventFilter* pKeyboard, int paneId) { // Get the value once to avoid searching again in the hash @@ -146,7 +146,7 @@ void Library::bindPaneWidget(WLibrary* pLibraryWidget, if (pPane == nullptr) { return; } - pPane->bindPaneWidget(pLibraryWidget, pKeyboard); + pPane->bindPaneWidget(pPaneWidget, pKeyboard); // Set the current font and row height on all the WTrackTableViews that were // just connected to us. @@ -188,7 +188,7 @@ LibraryView* Library::getActiveView() { return nullptr; } WBaseLibrary* pPaneWidget = pPane->getPaneWidget(); - WLibrary* pLibrary = qobject_cast(pPaneWidget); + WLibraryPane* pLibrary = qobject_cast(pPaneWidget); DEBUG_ASSERT_AND_HANDLE(pLibrary) { return nullptr; } diff --git a/src/library/library.h b/src/library/library.h index 609ada6e819..37bdad891cd 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -34,7 +34,7 @@ class SidebarModel; class TrackModel; class TrackCollection; class WBaseLibrary; -class WLibrary; +class WLibraryPane; class WLibrarySidebar; class WLibraryBreadCrumb; class WButtonBar; @@ -60,7 +60,7 @@ class Library : public QObject { void bindSearchBar(WSearchLineEdit* searchLine, int id); void bindSidebarButtons(WButtonBar* sidebar); - void bindPaneWidget(WLibrary* libraryWidget, + void bindPaneWidget(WLibraryPane* libraryWidget, KeyboardEventFilter* pKeyboard, int paneId); void bindSidebarExpanded(WBaseLibrary* expandedPane, KeyboardEventFilter* pKeyboard); diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index a162fdaa830..21e5ebab471 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -1,3 +1,4 @@ +#include #include "library/librarycontrol.h" #include @@ -9,7 +10,6 @@ #include "control/controlobject.h" #include "control/controlpushbutton.h" #include "mixer/playermanager.h" -#include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" #include "library/library.h" #include "library/libraryview.h" diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h index 2356595e11c..ec9c28ee85d 100644 --- a/src/library/librarycontrol.h +++ b/src/library/librarycontrol.h @@ -8,7 +8,7 @@ class ControlObject; class ControlPushButton; class Library; -class WLibrary; +class WLibraryPane; class WLibrarySidebar; class KeyboardEventFilter; diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index ea34b5b4ea2..6bddfabd555 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -22,7 +22,7 @@ class TrackModel; class TreeItem; class TreeItemModel; class WBaseLibrary; -class WLibrary; +class WLibraryPane; class WLibrarySidebar; class WTrackTableView; diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 9a2227fb440..99dc7a6a630 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -19,10 +19,10 @@ LibraryPaneManager::LibraryPaneManager(int paneId, Library *pLibrary, QObject* p LibraryPaneManager::~LibraryPaneManager() { } -void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, +void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pPaneWidget, KeyboardEventFilter* pKeyboard) { //qDebug() << "LibraryPaneManager::bindLibraryWidget" << libraryWidget; - m_pPaneWidget = pLibraryWidget; + m_pPaneWidget = pPaneWidget; connect(m_pPaneWidget, SIGNAL(focused()), this, SLOT(slotPaneFocused())); @@ -31,7 +31,7 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pLibraryWidget, connect(m_pPaneWidget, SIGNAL(uncollapsed()), this, SLOT(slotPaneUncollapsed())); - WLibrary* lib = qobject_cast(m_pPaneWidget); + WLibraryPane* lib = qobject_cast(m_pPaneWidget); if (lib == nullptr) { return; } diff --git a/src/library/librarypanemanager.h b/src/library/librarypanemanager.h index 40471f77356..52cd0f9a8f0 100644 --- a/src/library/librarypanemanager.h +++ b/src/library/librarypanemanager.h @@ -4,7 +4,7 @@ #include #include -#include "widget/wlibrary.h" +#include "../widget/wlibrarypane.h" #include "widget/wsearchlineedit.h" #include "widget/wtracktableview.h" diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 356a16b7153..87d0d730027 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1,6 +1,7 @@ // legacyskinparser.cpp // Created 9/19/2010 by RJ Ryan (rryan@mit.edu) +#include #include "skin/legacyskinparser.h" #include @@ -66,7 +67,6 @@ #include "widget/wwaveformviewer.h" #include "waveform/waveformwidgetfactory.h" #include "widget/wsearchlineedit.h" -#include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" #include "widget/wlibrarybreadcrumb.h" #include "widget/wbuttonbar.h" @@ -1274,16 +1274,17 @@ QWidget* LegacySkinParser::parseLibraryPane(const QDomElement& node) { return nullptr; } //qDebug() << "LegacySkinParser::parseLibrary:ID" << id; - WLibrary* pLibraryWidget = new WLibrary(m_pParent); - pLibraryWidget->installEventFilter(m_pKeyboard); - pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); + WLibraryPane* pLibraryPaneWidget = new WLibraryPane(m_pParent); + pLibraryPaneWidget->installEventFilter(m_pKeyboard); + pLibraryPaneWidget->installEventFilter( + m_pControllerManager->getControllerLearningEventFilter()); - m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, id); + m_pLibrary->bindPaneWidget(pLibraryPaneWidget, m_pKeyboard, id); // This must come after the bindWidget or we will not style any of the // LibraryView's because they have not been added yet. - commonWidgetSetup(node, pLibraryWidget, false); - return pLibraryWidget; + commonWidgetSetup(node, pLibraryPaneWidget, false); + return pLibraryPaneWidget; } QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { @@ -1303,7 +1304,7 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { commonWidgetSetup(node, pSearchBox); pLayout->addWidget(pSearchBox); - WLibrary* pLibraryWidget = new WLibrary(pContainer); + WLibraryPane* pLibraryWidget = new WLibraryPane(pContainer); pLibraryWidget->installEventFilter(m_pKeyboard); pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); pLayout->addWidget(pLibraryWidget); diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrarypane.cpp similarity index 80% rename from src/widget/wlibrary.cpp rename to src/widget/wlibrarypane.cpp index 3569c8bd35d..0e395dba41a 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrarypane.cpp @@ -1,10 +1,10 @@ // wlibrary.cpp // Created 8/28/2009 by RJ Ryan (rryan@mit.edu) +#include #include #include -#include "widget/wlibrary.h" #include "library/libraryview.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -15,12 +15,12 @@ void showLibraryWarning() { } } -WLibrary::WLibrary(QWidget* parent) +WLibraryPane::WLibraryPane(QWidget* parent) : WBaseLibrary(parent), m_mutex(QMutex::Recursive) { } -bool WLibrary::registerView(LibraryFeature* pFeature, QWidget* pView) { +bool WLibraryPane::registerView(LibraryFeature* pFeature, QWidget* pView) { QMutexLocker lock(&m_mutex); if (pFeature == nullptr || dynamic_cast(pView) == nullptr) { showLibraryWarning(); @@ -29,7 +29,7 @@ bool WLibrary::registerView(LibraryFeature* pFeature, QWidget* pView) { return WBaseLibrary::registerView(pFeature, pView); } -LibraryView* WLibrary::getActiveView() const { +LibraryView* WLibraryPane::getActiveView() const { LibraryView* pView = dynamic_cast(currentWidget()); if (pView == nullptr) { showLibraryWarning(); @@ -38,7 +38,7 @@ LibraryView* WLibrary::getActiveView() const { } -void WLibrary::switchToFeature(LibraryFeature *pFeature) { +void WLibraryPane::switchToFeature(LibraryFeature *pFeature) { QMutexLocker lock(&m_mutex); auto it = m_featureMap.find(pFeature); if (it != m_featureMap.end()) { @@ -52,7 +52,7 @@ void WLibrary::switchToFeature(LibraryFeature *pFeature) { } } -void WLibrary::search(const QString& name) { +void WLibraryPane::search(const QString& name) { QMutexLocker lock(&m_mutex); LibraryView* view = getActiveView(); if (view == nullptr) { @@ -62,7 +62,7 @@ void WLibrary::search(const QString& name) { view->onSearch(name); } -void WLibrary::searchCleared() { +void WLibraryPane::searchCleared() { LibraryView* view = getActiveView(); if (view == nullptr) { return; @@ -70,7 +70,7 @@ void WLibrary::searchCleared() { view->onSearchCleared(); } -void WLibrary::searchStarting() { +void WLibraryPane::searchStarting() { LibraryView* view = getActiveView(); if (view == nullptr) { return; diff --git a/src/widget/wlibrary.h b/src/widget/wlibrarypane.h similarity index 93% rename from src/widget/wlibrary.h rename to src/widget/wlibrarypane.h index ce6b332c3b2..f1d44f2e5b0 100644 --- a/src/widget/wlibrary.h +++ b/src/widget/wlibrarypane.h @@ -15,10 +15,10 @@ class KeyboardEventFilter; -class WLibrary : public WBaseLibrary { +class WLibraryPane : public WBaseLibrary { Q_OBJECT public: - explicit WLibrary(QWidget* parent); + explicit WLibraryPane(QWidget* parent); // registerView is used to add a view to the LibraryWidget which the widget // can disply on request via showView(). To switch to a given view, call diff --git a/src/widget/wsingletoncontainer.cpp b/src/widget/wsingletoncontainer.cpp index 11f50737396..ee3e7805689 100644 --- a/src/widget/wsingletoncontainer.cpp +++ b/src/widget/wsingletoncontainer.cpp @@ -1,10 +1,10 @@ +#include #include "widget/wsingletoncontainer.h" #include #include "util/assert.h" #include "skin/skincontext.h" -#include "widget/wlibrary.h" WSingletonContainer::WSingletonContainer(QWidget* pParent) From 51891aeb38f3de5596335ed5f509c0a042c4250d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 24 Sep 2016 14:08:16 +0200 Subject: [PATCH 514/552] some more renaming --- src/library/librarypanemanager.cpp | 19 +++++++++---------- src/widget/wbaselibrary.cpp | 8 ++++---- src/widget/wbaselibrary.h | 2 +- src/widget/wlibrarypane.cpp | 4 ++-- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index 99dc7a6a630..eede9c26f6d 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -24,26 +24,25 @@ void LibraryPaneManager::bindPaneWidget(WBaseLibrary* pPaneWidget, //qDebug() << "LibraryPaneManager::bindLibraryWidget" << libraryWidget; m_pPaneWidget = pPaneWidget; - connect(m_pPaneWidget, SIGNAL(focused()), + connect(pPaneWidget, SIGNAL(focused()), this, SLOT(slotPaneFocused())); - connect(m_pPaneWidget, SIGNAL(collapsed()), + connect(pPaneWidget, SIGNAL(collapsed()), this, SLOT(slotPaneCollapsed())); - connect(m_pPaneWidget, SIGNAL(uncollapsed()), + connect(pPaneWidget, SIGNAL(uncollapsed()), this, SLOT(slotPaneUncollapsed())); - WLibraryPane* lib = qobject_cast(m_pPaneWidget); - if (lib == nullptr) { + if (qobject_cast(pPaneWidget) == nullptr) { return; } for (LibraryFeature* f : m_features) { - //f->bindPaneWidget(lib, pKeyboard, m_paneId); + //f->bindPaneWidget(pPaneWidget, pKeyboard, m_paneId); - QWidget* pPane = f->createPaneWidget(pKeyboard, m_paneId); - if (pPane == nullptr) { + QWidget* pFeaturePaneWidget = f->createPaneWidget(pKeyboard, m_paneId); + if (pFeaturePaneWidget == nullptr) { continue; } - pPane->setParent(lib); - lib->registerView(f, pPane); + pFeaturePaneWidget->setParent(pPaneWidget); + pPaneWidget->registerView(f, pFeaturePaneWidget); } } diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index c3056a26187..e65430dd8c2 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -19,7 +19,7 @@ WBaseLibrary::WBaseLibrary(QWidget* parent) bool WBaseLibrary::registerView(LibraryFeature* pFeature, QWidget* view) { QMutexLocker lock(&m_mutex); - if (m_featureMap.contains(pFeature)) { + if (m_viewsByFeature.contains(pFeature)) { return false; } @@ -27,7 +27,7 @@ bool WBaseLibrary::registerView(LibraryFeature* pFeature, QWidget* view) { int index = addWidget(view); setCurrentIndex(index); m_pCurrentFeature = pFeature; - m_featureMap[pFeature] = view; + m_viewsByFeature.insert(pFeature, view); return true; } @@ -49,9 +49,9 @@ void WBaseLibrary::setShowFocus(int sFocus) { } void WBaseLibrary::switchToFeature(LibraryFeature *pFeature) { - auto it = m_featureMap.find(pFeature); + auto it = m_viewsByFeature.find(pFeature); // Only change the current feature if it's not shown already - if (it != m_featureMap.end() && currentWidget() != (*it)) { + if (it != m_viewsByFeature.end() && currentWidget() != (*it)) { m_pCurrentFeature = pFeature; setCurrentWidget(*it); } diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 9430c47c9f0..9130eeee6a0 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -46,7 +46,7 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget bool event(QEvent* pEvent) override; void resizeEvent(QResizeEvent* pEvent) override; - QHash m_featureMap; + QHash m_viewsByFeature; private: diff --git a/src/widget/wlibrarypane.cpp b/src/widget/wlibrarypane.cpp index 0e395dba41a..7c78d9111c8 100644 --- a/src/widget/wlibrarypane.cpp +++ b/src/widget/wlibrarypane.cpp @@ -40,8 +40,8 @@ LibraryView* WLibraryPane::getActiveView() const { void WLibraryPane::switchToFeature(LibraryFeature *pFeature) { QMutexLocker lock(&m_mutex); - auto it = m_featureMap.find(pFeature); - if (it != m_featureMap.end()) { + auto it = m_viewsByFeature.find(pFeature); + if (it != m_viewsByFeature.end()) { LibraryView* pView = dynamic_cast(*it); if (pView == nullptr) { showLibraryWarning(); From dcd7be0e71278ab7f805ab4d085620a20ffcba1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 24 Sep 2016 14:12:34 +0200 Subject: [PATCH 515/552] revert testing library.xml --- res/skins/LateNight/library.xml | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/res/skins/LateNight/library.xml b/res/skins/LateNight/library.xml index 8514a73ef9a..8fbf1419962 100644 --- a/res/skins/LateNight/library.xml +++ b/res/skins/LateNight/library.xml @@ -56,13 +56,13 @@ vertical - 2 + 1 - 2 + 1 - 2 + 1 @@ -70,27 +70,13 @@ vertical - -1 - - - -1 - - - -1 - - - - - vertical - - - 3 + 2 - 3 + 2 - 3 + 2 From f51f20e408616a96053a233b9d4b055c7e198153 Mon Sep 17 00:00:00 2001 From: jmigual Date: Mon, 26 Sep 2016 08:13:46 +0200 Subject: [PATCH 516/552] Add pinned icon --- res/images/library/ic_library_pinned.png | Bin 0 -> 6707 bytes res/mixxx.qrc | 1 + src/widget/wsearchlineedit.cpp | 13 ++++++++----- 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 res/images/library/ic_library_pinned.png diff --git a/res/images/library/ic_library_pinned.png b/res/images/library/ic_library_pinned.png new file mode 100644 index 0000000000000000000000000000000000000000..e296c37ba319182905409c4f948404a4faac26f4 GIT binary patch literal 6707 zcmW+*2{@G97oRbVtdlT?EPazL218`YlA;oln5 zWNV0zY}rPZzQz_M#!~;c|MNcgz0Y&+d(S!d+;h)4zwE*cnz_I{N{OjWHrBdhy3!jEbUZ?11W-CvgK-v zvr-%y`*b6nVK3AXNM^n?w@n@Yai|JgSj44(V4<*u@kLctRi-!>3KG{G)SXxknfkqL zR6GFASokq%YHg1X>pD}yDc)2h>k4D<2zuAP`f%M-og0Fvq5QYECQj7f`8H?-eC9Va zK@un$6dCkJHt@@nFN@J~d&u(+XJbKuk#b5T^l<2Plp`dI%1d>i{^2OuiXCCiz1vg`ZIB3Bg8RfpkCU`P3> zLS4;}*69VHOzrjVL1yz%*PZQkpZf~9&vXuapbW5q)LQdu!yoxPO_t9*ibl}dZtrTh zYe{SKu=xIr7mEE=YIo%ub~Lb~Qg*8TPzL^tT%hpxry-*4-zc5;B1IuGGBQEUUU$W7 z>y{o$RjQvM@#yiB`Q;hLtlFaU+!+rv3rr)kIwNvB-KcHFx<_3#N$d8GAX&3y`Jg?a zu`HDVU$_qSvxE z+%ylsRcphoB8nx`Nnz^IBL%Kifs)OijKW_zgH%W=Gxknb1M1c0UTbR?-gPxod2#y$ zfjuPd_f7|A{7lp_Cc2Q7TXf?b1#0KbUS7t8T>BgZ?;Xe}{L<_VQf0VJ9l|_{P(ws3rOX|{ zpMa#qbW(~Ek3j;^&MqFNsO>gH>8Vv6$p;Xu&W4fWm?C)J?dx2P za1@pkvtWvg$m|gkEa$z^x%^_Bt5RA;Ch@-NbOH0O#6+58z6m9oafOiZXI~Dxf!40V za_kclo#3USnnHv3{-G@T&-YvcCod8)6m) zv_F$RwAhpCfwE3qWq`4awP?&)qGXlqp0qb82j7N7SZjD`+hvi0vK42zV$}3oEx1+9 z9PI(H^9CquAM8rA&+^$*B|2~rCB#g;Bl2!SWm}^=BBlAEMs*%Q|zI$UV=!4|-)My4=KG0*h(t?35CuMsz+ z3&OJS!6>Xg#p?+^4Pd8NMk~jc2&ZT|$~p`Ov&>n>gcy7#05mQ`K<)}^zuHwtvPhYS z_65m8WEt+ZZ>Mt!>P}Zck8-OH?X2q0AK#{>GqR8x_gp3ILd12qN*EK((!}XF7G5-g zUQ6g6t@7?)jojZHt;jJsOviZUOmFb}i!a=4)EbWE8G}A|t|PidaS(m)KKVawrBE;Y z_PdS;%C1p{WN8{y8T9S2P4=)a!}E-Q5w_p?sfhxe3|r=Ifn4M<9l$G#T{!b67i#xx zMBzb!c=5c0i#IiZYK^WmI&d##Wo0FzcBcz&wbG#`VCI>I*bt(z&+i8!$AoUee;Y|* zz!@hR2VKcu%U%;Ifz>-3e4R_fGt$wOq9}1BtT5)&__%&omr8jN&~_Q`7@Xdrs$^e% zGXB+c#hy3p`i8pw(K2%{#rB(TRM5JVX{_M6z0>wOGVcf2QP}|wweBj=h&mm$U5YyE zxQIS7X1030>8aY0!}~pQZ`c?@A#g&tzQ+<>DOjtrw(4R?X`mkejap4;`UhP_Rl;q` z)fH)MeNHRC(R5o_Z^3OGN>)Xm>k>$C%J@@*e0S>PmKEZ?;Uw29TCPom$g$axLMyS1 z!we_ft&J-R0lU^CT$mypr#5yWBW_Pi#8D9C@83F=diqOSoj_eXEYOnB^q@}0@k^Tz zYEdmx?PLs3XKPeKy}LN6tqj@<+ojs<1 z0{(t+hsp?bD93o08fS~m*|VH{gvPV&%aX+#Cy8QX8t7}#aLQ3P)YZ)8gi#r6pmcxR z@Cn%s|4&kgp4)OwGplYDN)adA^w;q8eqtv5D0;&M6_c*I4kyhflSrh#%foj8gHhg3 zYIU@f#z67S3A#m+)2IT187WszUdGc+R5^OIPiNe7Jg-R* zcN@vEep!20ajL?WW%x?HCtu^c+kqXde>a}L_qLp>W7AVa_EyeKo)#`)n9(prA)O&_ zp=E=UU;&Gz)0<&quu2G1a8Zc1e=0qW{0fLI=DDy+u}JnT1JpNiCIt*1yO1~O_4s;j zg$G`|>Rx2M_*cx~$T?TTTM;E22VqC!R)0iYy}#+PVC{3u%S2ru*b$c~me9epTVKqq z!5W)4p>#i1iHF8eeL2!G-&VA|q*CAd{z)@=0!deLc~l}GFei|R*#7rSscb4Qkt7CF zxOTyGe5v$<2u&#;^3Ilf>S!O#~O=OyO=*WR#`E*IU|EUlep7pEbdh8TCi z6Xpif3a)s#r9Vk_+t%zCYh*l1l)J6sbS|-a#Q27XP`g&1y~%t9lFkhK_mt=R)^G-S_qSjg#q6_d zSx(X^*8AT|KbTHlIdqZ=vlZJq`4Rjo({<>jyhRF7sA=73dVGa0?MBdEGG@8Ty7geN(?)*3n5mAiRPV|`{1F65FK3EN%97h&f+n|DAv&7% z2ak%8V9(A6X>uy_^75R_2EP<~^#iXhWm6OF94P`$rJqODu+xLuX--nng&R3PQ=QTh ziOmEF_R8sbU({Wv>_smVO#9~>D&9C@)=rynTz4*3Fr2;aKJOpa8hiagKPW{?tir7> zo5M=suaq0?%O&K~ciZ0wKL3by={mKRsV0PKeZmP{z!O4@8VG07m_Pl*%t!4vQQwcz zCCB={H=>@M9nlxjS3#ePyOR z@JY`lwlCkH+=BPr&-aRbXz(WPob4T$o-kRs2|bRv5B#<&_SDfQ8SI+@V;*64~*3z zxFBgHzs{{a#(2_~vBC(y?sGPAmkQ4@H7oJBXRyo`YNu-)xM#;`?K3(qiS@XYd+9&X zBs=s*0KC$hb^t4hJ?fMd6BA=+T&Q`&3f_Ce*UxVWc5&8#SbEk&i_q!rLwUL9wsKq% zc3obqcDoF#VfwPzF7r;DsJ;`bcZM7(UDfEpaP(UrS^zt2PCg|YrN8{Fm4jj z#N7m$6mXnq=(+cM_S4Kv>nE4A6O+V89l-(_f*G^;3Vrm(K{}0^RH>K(JuZ!5oQW*A zN^t2c^J934)C>NcSa=hSD$L9CQ2&no4*&it(M4*dST5ybe76rvo7k>?PG(XMJ;?R; z3tKG_ny~CASM?F{;aY_FwMB_8Msm>)q5pY9gS<<`-U-YgXK^K#s z{z1_PT2}d{7sNC4o=89v->}12`YiulpsUmp2!rYctXn>zeq*yQC~dcLHSrnp zV;D8fsE|E0dg@dyaJ811WJj>y6vjmy3Y84y&Iq{nSl1@T5zubJQf%V9OG~LC_U4-*G?xtvx z=rIhdbMX32+7BM`A4gP-gJ9Bg2#9%+kYeKFw5V*jV&AT{s6wOO1H=8G-Vvwz#GN7R_C8C@4%}30c zKKI=bK5f&#uF8tV3JPVEz)~9AhYm0s8LcV{ zWoEXY1fGi}^_%B=WaWNqBPoQykjvgv3JG&{lA#Af;SM21i|*JCA#&Y+ZXDDYm-M4o zZ(ixziJ9vr%j-kq;^KfWbCpHQ(TxYBxmw`DnWUcB2ghpFi-}7vK!GL0lu#VfR>Kvm zB4i0*1q0%``B*_B52;3VJ0I<}jeuHplP^0ny$#^*?`+DKZF;E?^ts8Y@6hO2(EU30 z1^vw$qL1ha-~3@dFlEQx_wqNnwP^87n`>oJv_dsTgDVkM>+r2~XTL9KpzD|%z}~VI z+q4?4uc@uQwzRx#c$MaVajL2V7e-H`%$UvJ2VPtrHW7^dH*Kd+r{Lqqi?+iYpn*UA z^wqVtq8L*BmzRsN#1++-P&x_lo+o1bJjHBpotSmC-C~sEOl1y# zj_c3$4;NjL%coE=I-99N?caURo$CrrG96#&Y4DB@SX=+eDNS{<^w@r$~>tp*<9cU=zGrx1^qaUi|Fmb1hAZc zsSYcRT!S-PDcR@^qXE&F*$(I5_rPNq{P*9$UY9Jf)ODn8HO3#bf;`~s@~{3H%V6Cy zEJyMCr3Y>toLP&*aANaXB>j@Ir{ZI046?j4kZfh9%=CRCo|RmS38x|`Hq^Z7u*}N; zl67=-XW)j^XVI<}%t4s6Xp#-}$&mv!aot-T?wUb5yf2L`MWNYVtCAj&MH5CkLkS4G zqxCrNx?7=1ck5L9hG80Be>{4LXBRo9j*h)|L~nd#gf@Om*;Wkycy8M<^I4iA*V)fJ zJI`a6ECZZw@>^Z`n*dhCD!ljVa8}{|u*QJO6_X!Y%3T9v8FTMZsd9W7CqpsYEKd-V ze;BydtXc!pYw@2lh*n@S-uNc)F5pY2Gp}eDd)q$U;R@d2+NL*pp-&DpR6Gm~Hb#XV_ zg=WV(7@?o5rp2c)=$Fv0JmpI27x96&Ka)EGpTFBcOlIVZr-arg)bU|>o0lr^xK<5h zg2d9SfK{?*VZhNazEEak^;BKj^9kIhS%u?UH?k9tqD686up@TqCw;R2{nsO}tJ4CE zFudmTo~Rho@ZG~;5&_ot96|*AH|K*{o)wPE)f0vjn!VYKs^1UmxH9zHMlHhIYQDrL z@$SEPL<)%p-NOWU{8|UNaKnpvvpiJia1b(aq_Do5h3+JJRS} zvb?Sw#SQgqd?nkBkSy;Mb6DwT4bU==k6TxiQ4jyK$2;jt2kWEw=6XV&VQSo~Zgn#n z6~qliaV78*v^Fh|=NdsgddnVQ(rbPHwO@7Mpr>Z<{b(}F2N%KQEfA$Hs1UigxzC$< zw$99sdVatUw0>%IFRgnt7D}jJ#M6(~S;q$h?B7_y{s{-~4}T%$Yr3H>)Uj-CPL_|d{_dS`0#uq zQ1*k-E7ies5=z!Up9~aAjTJ=Nty0IE?gkAE4A8klFXLXe>ENDlGf4>M*U0A1G7#n5 z3J9o0O4zmh|FeVKZI{>L3rv5Px>or8)_XExsR<8uDRBn`2-8u2_H%M`|53Zx!stGO z85Ak#BKoatLBfTQb~NqTMW(!k6h#5p(H{87aHo$SWo$^6-EKW+_VIz+_Ol3{!Uj4P zJy-%DxR!_=J+p-R_=%7OJ^zDe(&Lu-+6VZP3U{D||F5K{Yt`xLOJlkM{Tzb7gtfIC zceEn$fC%d`SjHHwe2G+g<_~3hgLh&I*qHz?Oo_sb{WV5hH-=CEl(pT;3z;~0DU5h* z4h)Xh80t792Mp3OxZWD1kt`3TKX1c#SAF2x6|H-ia&1;oU6%hI%QZZ_vCSRO0Fy9b zGf#b3M^AVxbs=c-&USNMPePOwrmz8a9jxU;>66iei_!ZX?TkU5W%kn2?&ez5pYT@v zRl8|zUm3+G9&LSx!r{8)05u|_jJfT=%1?Btfz1Hyapm}4AcNii?&eg3&VhS`OrXqm z_<%#7jhjBt^7SKL}uAueJ$uPa)79|(jGZ}X7J>bE8%AIC2_90pbmtrz^I(f zkiuDS`Ew+skins/save_disabled.png images/library/ic_library_preselect.png images/library/ic_library_notpreselect.png + images/library/ic_library_pinned.png diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index ce3f9b0a199..219e98134bc 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -264,8 +264,7 @@ void WSearchLineEdit::showPlaceholder() { setPalette(pal); } -void WSearchLineEdit::updateButtons(const QString& text) -{ +void WSearchLineEdit::updateButtons(const QString& text) { bool visible = !text.isEmpty() && !m_place; m_pDropButton->setVisible(true); m_pSaveButton->setVisible(true); @@ -328,9 +327,13 @@ void WSearchLineEdit::restoreQuery() { action->setData(-1); } - for (const SavedSearchQuery& query : savedQueries) { - QAction* action = menu.addAction(query.title); - action->setData(query.id); + for (const SavedSearchQuery& sQuery : savedQueries) { + QAction* action = menu.addAction(sQuery.title); + action->setData(sQuery.id); + if (sQuery.pinned) { + action->setIcon(QIcon(":/images/ic_library_pinned.png")); + action->setIconVisibleInMenu(true); + } } { menu.addSeparator(); From dcc8773b710f66fc43e2a71ff1bfedc2972deccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 28 Sep 2016 22:43:47 +0200 Subject: [PATCH 517/552] Remove unneded locking and slot keywords --- src/widget/wbaselibrary.cpp | 2 -- src/widget/wbaselibrary.h | 16 ++++++---------- src/widget/wlibrarypane.cpp | 7 +------ src/widget/wlibrarypane.h | 9 ++------- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/widget/wbaselibrary.cpp b/src/widget/wbaselibrary.cpp index e65430dd8c2..a5192ed9699 100644 --- a/src/widget/wbaselibrary.cpp +++ b/src/widget/wbaselibrary.cpp @@ -11,14 +11,12 @@ WBaseLibrary::WBaseLibrary(QWidget* parent) : QStackedWidget(parent), WBaseWidget(this), m_pCurrentFeature(nullptr), - m_mutex(QMutex::Recursive), m_showFocus(0), m_isCollapsed(false) { } bool WBaseLibrary::registerView(LibraryFeature* pFeature, QWidget* view) { - QMutexLocker lock(&m_mutex); if (m_viewsByFeature.contains(pFeature)) { return false; } diff --git a/src/widget/wbaselibrary.h b/src/widget/wbaselibrary.h index 9130eeee6a0..594f5fdf26f 100644 --- a/src/widget/wbaselibrary.h +++ b/src/widget/wbaselibrary.h @@ -26,20 +26,17 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget // Sets the widget to the focused state, it's not the same as Qt focus void setShowFocus(int sFocus); - signals: - - void focused(); - void collapsed(); - void uncollapsed(); - - public slots: - virtual void switchToFeature(LibraryFeature* pFeature); - virtual void search(const QString&) {} virtual void searchStarting() {} virtual void searchCleared() {} + signals: + + void focused(); + void collapsed(); + void uncollapsed(); + protected: bool eventFilter(QObject*, QEvent* pEvent) override; @@ -51,7 +48,6 @@ class WBaseLibrary : public QStackedWidget, public WBaseWidget private: LibraryFeature* m_pCurrentFeature; - QMutex m_mutex; int m_showFocus; bool m_isCollapsed; }; diff --git a/src/widget/wlibrarypane.cpp b/src/widget/wlibrarypane.cpp index 7c78d9111c8..8fc8cb79a69 100644 --- a/src/widget/wlibrarypane.cpp +++ b/src/widget/wlibrarypane.cpp @@ -16,12 +16,10 @@ void showLibraryWarning() { } WLibraryPane::WLibraryPane(QWidget* parent) - : WBaseLibrary(parent), - m_mutex(QMutex::Recursive) { + : WBaseLibrary(parent) { } bool WLibraryPane::registerView(LibraryFeature* pFeature, QWidget* pView) { - QMutexLocker lock(&m_mutex); if (pFeature == nullptr || dynamic_cast(pView) == nullptr) { showLibraryWarning(); return false; @@ -39,7 +37,6 @@ LibraryView* WLibraryPane::getActiveView() const { void WLibraryPane::switchToFeature(LibraryFeature *pFeature) { - QMutexLocker lock(&m_mutex); auto it = m_viewsByFeature.find(pFeature); if (it != m_viewsByFeature.end()) { LibraryView* pView = dynamic_cast(*it); @@ -53,12 +50,10 @@ void WLibraryPane::switchToFeature(LibraryFeature *pFeature) { } void WLibraryPane::search(const QString& name) { - QMutexLocker lock(&m_mutex); LibraryView* view = getActiveView(); if (view == nullptr) { return; } - lock.unlock(); view->onSearch(name); } diff --git a/src/widget/wlibrarypane.h b/src/widget/wlibrarypane.h index f1d44f2e5b0..e38d9025d26 100644 --- a/src/widget/wlibrarypane.h +++ b/src/widget/wlibrarypane.h @@ -29,19 +29,14 @@ class WLibraryPane : public WBaseLibrary { bool registerView(LibraryFeature* pFeature, QWidget* pView); LibraryView* getActiveView() const; - - public slots: - // Show the view registered with the given name. Does nothing if the current + + // Show the view registered with the given feature. Does nothing if the current // view is the specified view, or if the name does not specify any // registered view. void switchToFeature(LibraryFeature* pFeature); - void search(const QString& name) override; void searchCleared() override; void searchStarting() override; - - private: - QMutex m_mutex; }; #endif /* WLIBRARY_H */ From 9fbc02e6da85ae169bda590bbda714fd3730d800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 2 Oct 2016 14:15:27 +0200 Subject: [PATCH 518/552] clean up som library slots --- .../baseplaylist/baseplaylistfeature.cpp | 7 ------- .../baseplaylist/baseplaylistfeature.h | 1 - .../mixxxlibrary/mixxxlibraryfeature.cpp | 6 +++--- src/library/library.cpp | 18 ++++++++++++------ src/widget/wlibrarypane.cpp | 3 ++- src/widget/wlibrarypane.h | 2 +- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index bf44004be61..a9563d5b045 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -94,8 +94,6 @@ BasePlaylistFeature::BasePlaylistFeature(UserSettingsPointer pConfig, connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), this, SLOT(slotTrackSelected(TrackPointer))); - connect(pLibrary, SIGNAL(switchToView(const QString&)), - this, SLOT(slotResetSelectedTrack())); } BasePlaylistFeature::~BasePlaylistFeature() { @@ -812,8 +810,3 @@ void BasePlaylistFeature::slotTrackSelected(TrackPointer pTrack) { m_childModel->triggerRepaint(); } - - -void BasePlaylistFeature::slotResetSelectedTrack() { - slotTrackSelected(TrackPointer()); -} diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index 2531ce582ab..85f90bc2f40 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -126,7 +126,6 @@ class BasePlaylistFeature : public LibraryFeature { private slots: void slotTrackSelected(TrackPointer pTrack); - void slotResetSelectedTrack(); private: virtual QString getRootViewHtml() const = 0; diff --git a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp index 10327d99c9c..91046654973 100644 --- a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp @@ -172,11 +172,11 @@ void MixxxLibraryFeature::setChildModel(TreeItemModel* pChild) { m_pChildModel = pChild; connect(&m_trackDao, SIGNAL(trackChanged(TrackId)), - m_pChildModel, SLOT(reloadTracksTree())); + m_pChildModel, SLOT(reloadTree())); connect(&m_trackDao, SIGNAL(tracksRemoved(QSet)), - m_pChildModel, SLOT(reloadTracksTree())); + m_pChildModel, SLOT(reloadTree())); connect(&m_trackDao, SIGNAL(tracksAdded(QSet)), - m_pChildModel, SLOT(reloadTracksTree())); + m_pChildModel, SLOT(reloadTree())); } void MixxxLibraryFeature::activate() { diff --git a/src/library/library.cpp b/src/library/library.cpp index 64dfab64c7f..38950d01b6a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -621,18 +621,24 @@ LibraryPaneManager* Library::getPreselectedPane() { return m_panes.value(m_preselectedPane); } -void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { - m_pMixxxLibraryFeature = new MixxxLibraryFeature(pConfig, this, this, m_pTrackCollection); +void Library::createFeatures(UserSettingsPointer pConfig, + PlayerManagerInterface* pPlayerManager) { + m_pMixxxLibraryFeature = new MixxxLibraryFeature( + pConfig, this, this, m_pTrackCollection); addFeature(m_pMixxxLibraryFeature); - addFeature(new AutoDJFeature(pConfig, this, this, pPlayerManager, m_pTrackCollection)); + addFeature(new AutoDJFeature( + pConfig, this, this, pPlayerManager, m_pTrackCollection)); - addFeature(new LibraryFoldersFeature(pConfig, this, this, m_pTrackCollection)); + addFeature(new LibraryFoldersFeature( + pConfig, this, this, m_pTrackCollection)); - m_pPlaylistFeature = new PlaylistFeature(pConfig, this, this, m_pTrackCollection); + m_pPlaylistFeature = new PlaylistFeature( + pConfig, this, this, m_pTrackCollection); addFeature(m_pPlaylistFeature); - m_pCrateFeature = new CrateFeature(pConfig, this, this, m_pTrackCollection); + m_pCrateFeature = new CrateFeature( + pConfig, this, this, m_pTrackCollection); addFeature(m_pCrateFeature); BrowseFeature* browseFeature = new BrowseFeature( diff --git a/src/widget/wlibrarypane.cpp b/src/widget/wlibrarypane.cpp index 8fc8cb79a69..a032a2a3423 100644 --- a/src/widget/wlibrarypane.cpp +++ b/src/widget/wlibrarypane.cpp @@ -36,7 +36,8 @@ LibraryView* WLibraryPane::getActiveView() const { } -void WLibraryPane::switchToFeature(LibraryFeature *pFeature) { +void WLibraryPane::switchToFeature(LibraryFeature* pFeature) { + qDebug() << "switchToFeature" << pFeature; auto it = m_viewsByFeature.find(pFeature); if (it != m_viewsByFeature.end()) { LibraryView* pView = dynamic_cast(*it); diff --git a/src/widget/wlibrarypane.h b/src/widget/wlibrarypane.h index e38d9025d26..60049f8a809 100644 --- a/src/widget/wlibrarypane.h +++ b/src/widget/wlibrarypane.h @@ -33,7 +33,7 @@ class WLibraryPane : public WBaseLibrary { // Show the view registered with the given feature. Does nothing if the current // view is the specified view, or if the name does not specify any // registered view. - void switchToFeature(LibraryFeature* pFeature); + void switchToFeature(LibraryFeature* pFeature) override; void search(const QString& name) override; void searchCleared() override; void searchStarting() override; From ea5e0ac58714358caae5c325ad27e367ea42149f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 2 Oct 2016 20:46:26 +0200 Subject: [PATCH 519/552] Removed unused SidebarModel --- build/depends.py | 1 - src/library/library.cpp | 11 +- src/library/library.h | 4 +- src/library/sidebarmodel.cpp | 427 --------------------------------- src/library/sidebarmodel.h | 72 ------ src/mixxx.cpp | 2 +- src/widget/wlibrarysidebar.cpp | 47 +--- 7 files changed, 10 insertions(+), 554 deletions(-) delete mode 100644 src/library/sidebarmodel.cpp delete mode 100644 src/library/sidebarmodel.h diff --git a/build/depends.py b/build/depends.py index 319219f6d2a..cdd9092c802 100644 --- a/build/depends.py +++ b/build/depends.py @@ -933,7 +933,6 @@ def sources(self, build): "library/library.cpp", "library/librarypanemanager.cpp", "library/librarysidebarexpandedmanager.cpp", - "library/sidebarmodel.cpp", "library/scanner/libraryscanner.cpp", "library/scanner/libraryscannerdlg.cpp", diff --git a/src/library/library.cpp b/src/library/library.cpp index 38950d01b6a..b1d547d3e57 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -30,7 +30,6 @@ #include "library/librarypanemanager.h" #include "library/librarysidebarexpandedmanager.h" #include "library/librarytablemodel.h" -#include "library/sidebarmodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" #include "mixer/playermanager.h" @@ -45,11 +44,10 @@ // The default row height of the library. const int Library::kDefaultRowHeightPx = 20; -Library::Library(QObject* parent, UserSettingsPointer pConfig, +Library::Library(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager, RecordingManager* pRecordingManager) : m_pConfig(pConfig), - m_pSidebarModel(new SidebarModel(parent)), m_pTrackCollection(new TrackCollection(pConfig)), m_pLibraryControl(new LibraryControl(this)), m_pRecordingManager(pRecordingManager), @@ -96,9 +94,6 @@ Library::Library(QObject* parent, UserSettingsPointer pConfig, } Library::~Library() { - // Delete the sidebar model first since it depends on the LibraryFeatures. - delete m_pSidebarModel; - qDeleteAll(m_features); m_features.clear(); @@ -201,9 +196,7 @@ void Library::addFeature(LibraryFeature* feature) { return; } m_features.append(feature); - - m_pSidebarModel->addLibraryFeature(feature); - + connect(feature, SIGNAL(loadTrack(TrackPointer)), this, SLOT(slotLoadTrack(TrackPointer))); connect(feature, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), diff --git a/src/library/library.h b/src/library/library.h index 37bdad891cd..88a76728db1 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -52,8 +52,7 @@ class Library : public QObject { static const int kDefaultRowHeightPx; - Library(QObject* parent, - UserSettingsPointer pConfig, + Library(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager, RecordingManager* pRecordingManager); virtual ~Library(); @@ -160,7 +159,6 @@ class Library : public QObject { void handlePreselection(); UserSettingsPointer m_pConfig; - SidebarModel* m_pSidebarModel; TrackCollection* m_pTrackCollection; MixxxLibraryFeature* m_pMixxxLibraryFeature; PlaylistFeature* m_pPlaylistFeature; diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp deleted file mode 100644 index 5204cf1a854..00000000000 --- a/src/library/sidebarmodel.cpp +++ /dev/null @@ -1,427 +0,0 @@ -#include -#include -#include - -#include "library/libraryfeature.h" -#include "library/sidebarmodel.h" -#include "library/treeitem.h" -#include "library/features/browse/browsefeature.h" -#include "util/assert.h" - -SidebarModel::SidebarModel(QObject* parent) - : QAbstractItemModel(parent), - m_iDefaultSelectedIndex(0) { -} - -SidebarModel::~SidebarModel() { - -} - -void SidebarModel::addLibraryFeature(LibraryFeature* feature) { - m_sFeatures.push_back(feature); - connect(feature, SIGNAL(featureIsLoading(LibraryFeature*, bool)), - this, SLOT(slotFeatureIsLoading(LibraryFeature*, bool))); - connect(feature, SIGNAL(featureLoadingFinished(LibraryFeature*)), - this, SLOT(slotFeatureLoadingFinished(LibraryFeature*))); - connect(feature, SIGNAL(featureSelect(LibraryFeature*, const QModelIndex&)), - this, SLOT(slotFeatureSelect(LibraryFeature*, const QModelIndex&))); - - QAbstractItemModel* model = feature->getChildModel(); - - connect(model, SIGNAL(modelReset()), - this, SLOT(slotModelReset())); - connect(model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)), - this, SLOT(slotDataChanged(const QModelIndex&,const QModelIndex&))); - - connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)), - this, SLOT(slotRowsAboutToBeInserted(const QModelIndex&, int, int))); - connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), - this, SLOT(slotRowsAboutToBeRemoved(const QModelIndex&, int, int))); - connect(model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), - this, SLOT(slotRowsInserted(const QModelIndex&, int, int))); - connect(model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), - this, SLOT(slotRowsRemoved(const QModelIndex&, int, int))); - -} - -QModelIndex SidebarModel::getDefaultSelection() { - if (m_sFeatures.size() == 0) - return QModelIndex(); - return createIndex(m_iDefaultSelectedIndex, 0, (void*)this); -} - -void SidebarModel::setDefaultSelection(unsigned int index) { - m_iDefaultSelectedIndex = index; -} - -void SidebarModel::activateDefaultSelection() { - if (m_iDefaultSelectedIndex < - static_cast(m_sFeatures.size())) { - emit(selectIndex(getDefaultSelection())); - // Selecting an index does not activate it. - m_sFeatures[m_iDefaultSelectedIndex]->activate(); - } -} - -QModelIndex SidebarModel::index(int row, int column, - const QModelIndex& parent) const { - // qDebug() << "SidebarModel::index row=" << row - // << "column=" << column << "parent=" << parent.data(); - if (parent.isValid()) { - /* If we have selected the root of a library feature at position 'row' - * its internal pointer is the current sidebar object model - * we return its associated childmodel - */ - if (parent.internalPointer() == this) { - const QAbstractItemModel* childModel = m_sFeatures[parent.row()]->getChildModel(); - QModelIndex childIndex = childModel->index(row, column); - TreeItem* tree_item = (TreeItem*)childIndex.internalPointer(); - if (tree_item && childIndex.isValid()) { - return createIndex(childIndex.row(), childIndex.column(), (void*)tree_item); - } else { - return QModelIndex(); - } - } else { - // We have selected an item within the childmodel - // This item has always an internal pointer of (sub)type TreeItem - TreeItem* tree_item = (TreeItem*)parent.internalPointer(); - return createIndex(row, column, (void*) tree_item->child(row)); - } - } - return createIndex(row, column, (void*)this); -} - -QModelIndex SidebarModel::parent(const QModelIndex& index) const { - //qDebug() << "SidebarModel::parent index=" << index.data(); - if (index.isValid()) { - // If we have selected the root of a library feature - // its internal pointer is the current sidebar object model - // A root library feature has no parent and thus we return - // an invalid QModelIndex - if (index.internalPointer() == this) { - return QModelIndex(); - } else { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item == NULL) - return QModelIndex(); - TreeItem* tree_item_parent = tree_item->parent(); - // if we have selected an item at the first level of a childnode - - if (tree_item_parent) { - if (tree_item_parent->data() == "$root") { - LibraryFeature* feature = tree_item->getFeature(); - for (int i = 0; i < m_sFeatures.size(); ++i) { - if (feature == m_sFeatures[i]) { - // create a ModelIndex for parent 'this' having a - // library feature at position 'i' - return createIndex(i, 0, (void*)this); - } - } - } - // if we have selected an item at some deeper level of a childnode - return createIndex(tree_item_parent->row(), 0 , tree_item_parent); - } - } - } - return QModelIndex(); -} - -int SidebarModel::rowCount(const QModelIndex& parent) const { - //qDebug() << "SidebarModel::rowCount parent=" << parent.data(); - if (parent.isValid()) { - if (parent.internalPointer() == this) { - return m_sFeatures[parent.row()]->getChildModel()->rowCount(); - } else { - // We support tree models deeper than 1 level - TreeItem* tree_item = (TreeItem*)parent.internalPointer(); - if (tree_item) { - return tree_item->childCount(); - } - return 0; - } - } - return m_sFeatures.size(); -} - -int SidebarModel::columnCount(const QModelIndex& parent) const { - Q_UNUSED(parent); - //qDebug() << "SidebarModel::columnCount parent=" << parent; - // TODO(rryan) will we ever have columns? I don't think so. - return 1; -} - -bool SidebarModel::hasChildren(const QModelIndex& parent) const { - if (parent.isValid()) { - if (parent.internalPointer() == this) { - return QAbstractItemModel::hasChildren(parent); - } - else - { - TreeItem* tree_item = (TreeItem*)parent.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - return feature->getChildModel()->hasChildren(parent); - } - } - } - - return QAbstractItemModel::hasChildren(parent); -} - -QVariant SidebarModel::data(const QModelIndex& index, int role) const { - // qDebug("SidebarModel::data row=%d column=%d pointer=%8x, role=%d", - // index.row(), index.column(), index.internalPointer(), role); - if (!index.isValid()) { - return QVariant(); - } - - if (index.internalPointer() == this) { - //If it points to SidebarModel - if (role == Qt::DisplayRole) { - return m_sFeatures[index.row()]->title(); - } else if (role == Qt::DecorationRole) { - return m_sFeatures[index.row()]->getIcon(); - } - } - - if (index.internalPointer() != this) { - // If it points to a TreeItem - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - if (role == Qt::DisplayRole) { - return tree_item->data(); - } else if (role == Qt::ToolTipRole) { - // If it's the "Quick Links" node, display it's name - if (tree_item->dataPath() == QUICK_LINK_NODE) { - return tree_item->data(); - } else { - return tree_item->dataPath(); - } - } else if (role == AbstractRole::RoleDataPath) { - // We use Qt::UserRole to ask for the datapath. - return tree_item->dataPath(); - } else if (role == Qt::FontRole) { - QFont font; - font.setBold(tree_item->isBold()); - return font; - } else if (role == Qt::DecorationRole) { - return tree_item->getIcon(); - } - } - } - - return QVariant(); -} - -void SidebarModel::clicked(const QModelIndex& index) { - //qDebug() << "SidebarModel::clicked() index=" << index; - - // We use clicked() for keyboard and mouse control, and the - // following code breaks that for us: - /*if (QApplication::mouseButtons() != Qt::LeftButton) { - return; - }*/ - - if (index.isValid()) { - if (index.internalPointer() == this) { - m_sFeatures[index.row()]->activate(); - } else { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - feature->activateChild(index); - } - } - } -} -void SidebarModel::doubleClicked(const QModelIndex& index) { - if (index.isValid()) { - if (index.internalPointer() == this) { - return; - } else { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - feature->onLazyChildExpandation(index); - } - } - } -} - -void SidebarModel::rightClicked(const QPoint& globalPos, const QModelIndex& index) { - //qDebug() << "SidebarModel::rightClicked() index=" << index; - if (index.isValid()) { - if (index.internalPointer() == this) { - m_sFeatures[index.row()]->activate(); - m_sFeatures[index.row()]->onRightClick(globalPos); - } - else - { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - feature->activateChild(index); - feature->onRightClickChild(globalPos, index); - } - } - } -} - -bool SidebarModel::dropAccept(const QModelIndex& index, QList urls, - QObject* pSource) { - //qDebug() << "SidebarModel::dropAccept() index=" << index << url; - bool result = false; - if (index.isValid()) { - if (index.internalPointer() == this) { - result = m_sFeatures[index.row()]->dropAccept(urls, pSource); - } else { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - result = feature->dropAcceptChild(index, urls, pSource); - } - } - } - return result; -} - -bool SidebarModel::dragMoveAccept(const QModelIndex& index, QUrl url) { - //qDebug() << "SidebarModel::dragMoveAccept() index=" << index << url; - bool result = false; - - if (index.isValid()) { - if (index.internalPointer() == this) { - result = m_sFeatures[index.row()]->dragMoveAccept(url); - } else { - TreeItem* tree_item = (TreeItem*)index.internalPointer(); - if (tree_item) { - LibraryFeature* feature = tree_item->getFeature(); - result = feature->dragMoveAcceptChild(index, url); - } - } - } - return result; -} - -// Translates an index from the child models to an index of the sidebar models -QModelIndex SidebarModel::translateSourceIndex(const QModelIndex& index) { - QModelIndex translatedIndex; - - /* These method is called from the slot functions below. - * QObject::sender() return the object which emitted the signal - * handled by the slot functions. - - * For child models, this always the child models itself - */ - - const QAbstractItemModel* model = dynamic_cast(sender()); - DEBUG_ASSERT_AND_HANDLE(model != NULL) { - return QModelIndex(); - } - - if (index.isValid()) { - TreeItem* item = (TreeItem*)index.internalPointer(); - translatedIndex = createIndex(index.row(), index.column(), item); - } - else - { - //Comment from Tobias Rafreider --> Dead Code???? - - for (int i = 0; i < m_sFeatures.size(); ++i) { - if (m_sFeatures[i]->getChildModel() == model) { - translatedIndex = createIndex(i, 0, (void*)this); - } - } - } - return translatedIndex; -} - -void SidebarModel::slotDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - //qDebug() << "slotDataChanged topLeft:" << topLeft << "bottomRight:" << bottomRight; - QModelIndex topLeftTranslated = translateSourceIndex(topLeft); - QModelIndex bottomRightTranslated = translateSourceIndex(bottomRight); - emit(dataChanged(topLeftTranslated, bottomRightTranslated)); -} - -void SidebarModel::slotRowsAboutToBeInserted(const QModelIndex& parent, int start, int end) { - //qDebug() << "slotRowsABoutToBeInserted" << parent << start << end; - - QModelIndex newParent = translateSourceIndex(parent); - beginInsertRows(newParent, start, end); -} - -void SidebarModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - //qDebug() << "slotRowsABoutToBeRemoved" << parent << start << end; - - QModelIndex newParent = translateSourceIndex(parent); - beginRemoveRows(newParent, start, end); -} - -void SidebarModel::slotRowsInserted(const QModelIndex& parent, int start, int end) { - Q_UNUSED(parent); - Q_UNUSED(start); - Q_UNUSED(end); - //qDebug() << "slotRowsInserted" << parent << start << end; - //QModelIndex newParent = translateSourceIndex(parent); - endInsertRows(); -} - -void SidebarModel::slotRowsRemoved(const QModelIndex& parent, int start, int end) { - Q_UNUSED(parent); - Q_UNUSED(start); - Q_UNUSED(end); - //qDebug() << "slotRowsRemoved" << parent << start << end; - //QModelIndex newParent = translateSourceIndex(parent); - endRemoveRows(); -} - -void SidebarModel::slotModelReset() { - // If a child model is reset, we can't really do anything but reset(). This - // will close any open items. - reset(); -} - -/* - * Call this slot whenever the title of the feature has changed. - * See RhythmboxFeature for an example, in which the title becomes '(loading) Rhythmbox' - * If selectFeature is true, the feature is selected when the title change occurs. - */ -void SidebarModel::slotFeatureIsLoading(LibraryFeature * feature, bool selectFeature) { - featureRenamed(feature); - if (selectFeature) { - slotFeatureSelect(feature); - } -} - -/* Tobias: This slot is somewhat redundant but I decided - * to leave it for code readability reasons - */ -void SidebarModel::slotFeatureLoadingFinished(LibraryFeature * feature) { - featureRenamed(feature); - slotFeatureSelect(feature); -} - -void SidebarModel::featureRenamed(LibraryFeature* pFeature) { - for (int i=0; i < m_sFeatures.size(); ++i) { - if (m_sFeatures[i] == pFeature) { - QModelIndex ind = index(i, 0); - emit(dataChanged(ind, ind)); - } - } -} - -void SidebarModel::slotFeatureSelect(LibraryFeature* pFeature, const QModelIndex& featureIndex) { - QModelIndex ind; - if (featureIndex.isValid()) { - TreeItem* item = (TreeItem*)featureIndex.internalPointer(); - ind = createIndex(featureIndex.row(), featureIndex.column(), item); - } else { - for (int i=0; i < m_sFeatures.size(); ++i) { - if (m_sFeatures[i] == pFeature) { - ind = index(i, 0); - break; - } - } - } - emit(selectIndex(ind)); -} diff --git a/src/library/sidebarmodel.h b/src/library/sidebarmodel.h deleted file mode 100644 index ef234a95604..00000000000 --- a/src/library/sidebarmodel.h +++ /dev/null @@ -1,72 +0,0 @@ -// sidebarmodel.h -// Created 8/21/09 by RJ Ryan (rryan@mit.edu) - -#ifndef SIDEBARMODEL_H -#define SIDEBARMODEL_H - -#include -#include -#include -#include - -class LibraryFeature; - -class SidebarModel : public QAbstractItemModel { - Q_OBJECT - public: - explicit SidebarModel(QObject* parent = 0); - virtual ~SidebarModel(); - - void addLibraryFeature(LibraryFeature* feature); - QModelIndex getDefaultSelection(); - void setDefaultSelection(unsigned int index); - void activateDefaultSelection(); - - // Required for QAbstractItemModel - QModelIndex index(int row, int column, - const QModelIndex& parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index) const; - int rowCount(const QModelIndex& parent = QModelIndex()) const; - int columnCount(const QModelIndex& parent = QModelIndex()) const; - QVariant data(const QModelIndex& index, - int role = Qt::DisplayRole) const; - bool dropAccept(const QModelIndex& index, QList urls, QObject* pSource); - bool dragMoveAccept(const QModelIndex& index, QUrl url); - virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const; - - public slots: - void clicked(const QModelIndex& index); - void doubleClicked(const QModelIndex& index); - void rightClicked(const QPoint& globalPos, const QModelIndex& index); - void slotFeatureSelect(LibraryFeature* pFeature, const QModelIndex& index = QModelIndex()); - - // Slots for every single QAbstractItemModel signal - // void slotColumnsAboutToBeInserted(const QModelIndex& parent, int start, int end); - // void slotColumnsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - // void slotColumnsInserted(const QModelIndex& parent, int start, int end); - // void slotColumnsRemoved(const QModelIndex& parent, int start, int end); - void slotDataChanged(const QModelIndex& topLeft, const QModelIndex & bottomRight); - //void slotHeaderDataChanged(Qt::Orientation orientation, int first, int last); - // void slotLayoutAboutToBeChanged(); - // void slotLayoutChanged(); - // void slotModelAboutToBeReset(); - // void slotModelReset(); - void slotRowsAboutToBeInserted(const QModelIndex& parent, int start, int end); - void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void slotRowsInserted(const QModelIndex& parent, int start, int end); - void slotRowsRemoved(const QModelIndex& parent, int start, int end); - void slotModelReset(); - void slotFeatureIsLoading(LibraryFeature*, bool selectFeature); - void slotFeatureLoadingFinished(LibraryFeature*); - - signals: - void selectIndex(const QModelIndex& index); - - private: - QModelIndex translateSourceIndex(const QModelIndex& parent); - void featureRenamed(LibraryFeature*); - QList m_sFeatures; - unsigned int m_iDefaultSelectedIndex; /** Index of the item in the sidebar model to select at startup. */ -}; - -#endif /* SIDEBARMODEL_H */ diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 92d2f1d950d..6e2c67b72f7 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -264,7 +264,7 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { CoverArtCache::create(); // (long) - m_pLibrary = new Library(this, pConfig, + m_pLibrary = new Library(pConfig, m_pPlayerManager, m_pRecordingManager); m_pPlayerManager->bindToLibrary(m_pLibrary); diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 8da3afb7c13..14d1550b417 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -8,7 +8,6 @@ #include #include "library/treeitemmodel.h" -#include "library/sidebarmodel.h" #include "util/dnd.h" const int expand_time = 250; @@ -117,37 +116,17 @@ void WLibrarySidebar::dragMoveEvent(QDragMoveEvent * event) { // Do nothing. event->ignore(); } else { - SidebarModel* sidebarModel = dynamic_cast(model()); bool accepted = true; - if (sidebarModel) { + TreeItemModel* treeModel = dynamic_cast(model()); + if (treeModel) { accepted = false; for (const QUrl& url : urls) { QModelIndex destIndex = this->indexAt(event->pos()); - if (sidebarModel->dragMoveAccept(destIndex, url)) { - // We only need one URL to be valid for us - // to accept the whole drag... - // consider we have a long list of valid files, checking all will - // take a lot of time that stales Mixxx and this makes the drop feature useless - // Eg. you may have tried to drag two MP3's and an EXE, the drop is accepted here, - // but the EXE is sorted out later after dropping + if (treeModel->dragMoveAccept(destIndex, url)) { accepted = true; break; } } - } else { - TreeItemModel* treeModel = dynamic_cast(model()); - if (treeModel) { - accepted = false; - - for (const QUrl& url : urls) { - QModelIndex destIndex = this->indexAt(event->pos()); - if (treeModel->dragMoveAccept(destIndex, url)) { - accepted = true; - break; - } - } - - } } if (accepted) { event->acceptProposedAction(); @@ -188,29 +167,15 @@ void WLibrarySidebar::dropEvent(QDropEvent * event) { //this->selectionModel()->clear(); //Drag-and-drop from an external application or the track table widget //eg. dragging a track from Windows Explorer onto the sidebar - SidebarModel* sidebarModel = dynamic_cast(model()); - - if (sidebarModel) { + TreeItemModel* pTreeModel = dynamic_cast(model()); + if (pTreeModel) { QModelIndex destIndex = indexAt(event->pos()); - // event->source() will return NULL if something is droped from - // a different application QList urls(event->mimeData()->urls()); - if (sidebarModel->dropAccept(destIndex, urls, event->source())) { + if (pTreeModel->dropAccept(destIndex, urls, event->source())) { event->acceptProposedAction(); } else { event->ignore(); } - } else { - TreeItemModel* pTreeModel = dynamic_cast(model()); - if (pTreeModel) { - QModelIndex destIndex = indexAt(event->pos()); - QList urls(event->mimeData()->urls()); - if (pTreeModel->dropAccept(destIndex, urls, event->source())) { - event->acceptProposedAction(); - } else { - event->ignore(); - } - } } } //emit(trackDropped(name)); From 2685e73634399d848ae4bfede5041badf6d29835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 2 Oct 2016 22:55:42 +0200 Subject: [PATCH 520/552] Fix issue, not changing track table --- .../baseplaylist/baseplaylistfeature.cpp | 31 ++++++++++++------- .../baseplaylist/baseplaylistfeature.h | 4 +-- src/library/features/crates/cratefeature.cpp | 15 ++++++--- src/library/library.cpp | 28 ++++++++--------- src/library/library.h | 2 +- src/library/libraryfeature.cpp | 12 +++---- src/library/libraryfeature.h | 6 ++-- src/widget/wsearchlineedit.cpp | 1 - src/widget/wsearchlineedit.h | 10 +++--- 9 files changed, 61 insertions(+), 48 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index a9563d5b045..caa17329528 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -125,11 +125,19 @@ QPointer BasePlaylistFeature::getPlaylistTableModel(int pane } void BasePlaylistFeature::activate() { - if (m_lastChildClicked[m_featurePane].isValid()) { - activateChild(m_lastChildClicked[m_featurePane]); + int preselectedPane = getPreselectedPane(); + if (preselectedPane >= 0) { + m_featurePane = preselectedPane; + } + + auto modelIt = m_lastChildClicked.find(m_featurePane); + if (modelIt != m_lastChildClicked.end() && (*modelIt).isValid()) { + qDebug() << "BasePlaylistFeature::activate" << "m_lastChildClicked found"; + // Open last clicked Playlist in the preselectded pane + activateChild(*modelIt); return; } - + showBrowse(m_featurePane); switchToFeature(); showBreadCrumb(); @@ -138,8 +146,9 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { - if (getPreselectedPane() >= 0) { - m_featurePane = getPreselectedPane(); + int preselectedPane = getPreselectedPane(); + if (preselectedPane >= 0) { + m_featurePane = preselectedPane; } if (index == m_lastChildClicked[m_featurePane]) { @@ -654,8 +663,8 @@ int BasePlaylistFeature::playlistIdFromIndex(const QModelIndex& index) const { void BasePlaylistFeature::showTable(int paneId) { auto it = m_panes.find(paneId); - auto itId = m_idTable.find(paneId); - if (it == m_panes.end() || it->isNull() || itId == m_idTable.end()) { + auto itId = m_tableIndexByPaneId.find(paneId); + if (it == m_panes.end() || it->isNull() || itId == m_tableIndexByPaneId.end()) { return; } @@ -664,8 +673,8 @@ void BasePlaylistFeature::showTable(int paneId) { void BasePlaylistFeature::showBrowse(int paneId) { auto it = m_panes.find(paneId); - auto itId = m_idBrowse.find(paneId); - if (it == m_panes.end() || it->isNull() || itId == m_idBrowse.end()) { + auto itId = m_browseIndexByPaneId.find(paneId); + if (it == m_panes.end() || it->isNull() || itId == m_browseIndexByPaneId.end()) { return; } @@ -698,11 +707,11 @@ QWidget* BasePlaylistFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, edit->installEventFilter(pKeyboard); connect(edit, SIGNAL(anchorClicked(const QUrl)), this, SLOT(htmlLinkClicked(const QUrl))); - m_idBrowse[paneId] = pStack->addWidget(edit); + m_browseIndexByPaneId[paneId] = pStack->addWidget(edit); QWidget* pTable = LibraryFeature::createPaneWidget(pKeyboard, paneId); pTable->setParent(pStack); - m_idTable[paneId] = pStack->addWidget(pTable); + m_tableIndexByPaneId[paneId] = pStack->addWidget(pTable); return pStack; } diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index 85f90bc2f40..e19901ca18e 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -133,8 +133,8 @@ class BasePlaylistFeature : public LibraryFeature { QSet m_playlistsSelectedTrackIsIn; QHash > m_panes; - QHash m_idBrowse; - QHash m_idTable; + QHash m_browseIndexByPaneId; + QHash m_tableIndexByPaneId; }; #endif /* BASEPLAYLISTFEATURE_H */ diff --git a/src/library/features/crates/cratefeature.cpp b/src/library/features/crates/cratefeature.cpp index bb2f8916420..81215d465d3 100644 --- a/src/library/features/crates/cratefeature.cpp +++ b/src/library/features/crates/cratefeature.cpp @@ -219,8 +219,14 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { - if (m_lastClickedIndex[m_featurePane].isValid()) { - activateChild(m_lastClickedIndex[m_featurePane]); + int preselectedPane = getPreselectedPane(); + if (preselectedPane >= 0) { + m_featurePane = preselectedPane; + } + + auto modelIt = m_lastClickedIndex.find(m_featurePane); + if (modelIt != m_lastClickedIndex.end() && (*modelIt).isValid()) { + activateChild(*modelIt); return; } @@ -231,8 +237,9 @@ void CrateFeature::activate() { } void CrateFeature::activateChild(const QModelIndex& index) { - if (getPreselectedPane() >= 0) { - m_featurePane = getPreselectedPane(); + int preselectedPane = getPreselectedPane(); + if (preselectedPane >= 0) { + m_featurePane = preselectedPane; } m_lastClickedIndex[m_featurePane] = index; diff --git a/src/library/library.cpp b/src/library/library.cpp index b1d547d3e57..530d8c18b9e 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -55,7 +55,7 @@ Library::Library(UserSettingsPointer pConfig, m_pSidebarExpanded(nullptr), m_hoveredFeature(nullptr), m_focusedFeature(nullptr), - m_focusedPane(-1), + m_focusedPaneId(-1), m_preselectedPane(-1), m_previewPreselectedPane(-1) { qRegisterMetaType("Library::RemovalType"); @@ -178,7 +178,7 @@ void Library::destroyInterface() { } LibraryView* Library::getActiveView() { - LibraryPaneManager* pPane = m_panes.value(m_focusedPane); + LibraryPaneManager* pPane = m_panes.value(m_focusedPaneId); DEBUG_ASSERT_AND_HANDLE(pPane) { return nullptr; } @@ -216,9 +216,9 @@ void Library::switchToFeature(LibraryFeature* pFeature) { if (pPane == nullptr) { // No pane is preselected so we are handling an activateChild() method // or similar. We only change the input focus to the feature one. - m_focusedPane = pFeature->getFeaturePane(); + m_focusedPaneId = pFeature->getFeaturePaneId(); handleFocus(); - return; + pPane = getFocusedPane(); } pPane->switchToFeature(pFeature); @@ -283,9 +283,9 @@ void Library::paneFocused(LibraryPaneManager* pPane) { } if (pPane != m_pSidebarExpanded) { - m_focusedPane = pPane->getPaneId(); - pPane->getCurrentFeature()->setFeaturePane(m_focusedPane); - DEBUG_ASSERT_AND_HANDLE(m_focusedPane != -1) { + m_focusedPaneId = pPane->getPaneId(); + pPane->getCurrentFeature()->setFeaturePane(m_focusedPaneId); + DEBUG_ASSERT_AND_HANDLE(m_focusedPaneId != -1) { return; } handleFocus(); @@ -306,7 +306,7 @@ void Library::panePreselected(LibraryPaneManager* pPane, bool value) { } int Library::getFocusedPaneId() { - return m_focusedPane; + return m_focusedPaneId; } int Library::getPreselectedPaneId() { @@ -359,7 +359,7 @@ void Library::onSkinLoadFinished() { } // The first pane always shows the Mixxx Library feature on start - m_preselectedPane = m_focusedPane = m_panes.begin().key(); + m_preselectedPane = m_focusedPaneId = m_panes.begin().key(); handleFocus(); (*m_features.begin())->setFeaturePane(m_preselectedPane); slotActivateFeature(*m_features.begin()); @@ -457,7 +457,7 @@ void Library::paneCollapsed(int paneId) { for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); if (!m_collapsedPanes.contains(auxId) && !focused) { - m_focusedPane = pPane->getPaneId(); + m_focusedPaneId = pPane->getPaneId(); pPane->setFocused(true); focused = true; } @@ -601,13 +601,13 @@ LibraryPaneManager* Library::getOrCreatePane(int paneId) { pPane->addFeatures(m_features); m_panes.insert(paneId, pPane); - m_focusedPane = paneId; + m_focusedPaneId = paneId; return pPane; } LibraryPaneManager* Library::getFocusedPane() { //qDebug() << "Focused" << m_focusedPane; - return m_panes.value(m_focusedPane); + return m_panes.value(m_focusedPaneId); } LibraryPaneManager* Library::getPreselectedPane() { @@ -687,7 +687,7 @@ void Library::handleFocus() { for (LibraryPaneManager* pPane : m_panes) { pPane->setFocused(false); } - LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPane); + LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPaneId); if (pFocusPane) { pFocusPane->setFocused(true); } @@ -710,7 +710,7 @@ void Library::handlePreselection() { } void Library::focusSearch() { - LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPane); + LibraryPaneManager* pFocusPane = m_panes.value(m_focusedPaneId); if (pFocusPane == nullptr) return; bool ok = pFocusPane->focusSearch(); if (ok) return; diff --git a/src/library/library.h b/src/library/library.h index 88a76728db1..c87f4cef152 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -180,7 +180,7 @@ class Library : public QObject { LibraryFeature* m_focusedFeature; // Can be any integer as it's used with a HashMap - int m_focusedPane; + int m_focusedPaneId; int m_preselectedPane; int m_previewPreselectedPane; }; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 473be268760..17623fe493e 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -107,7 +107,7 @@ void LibraryFeature::setFeaturePane(int paneId) { m_featurePane = paneId; } -int LibraryFeature::getFeaturePane() { +int LibraryFeature::getFeaturePaneId() { return m_featurePane; } @@ -201,7 +201,7 @@ WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboar pTrackTableView, SLOT(setTrackTableFont(QFont))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - m_trackTables[paneId] = pTrackTableView; + m_trackTablesByPaneId[paneId] = pTrackTableView; return pTrackTableView; } @@ -236,8 +236,8 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* } void LibraryFeature::showTrackModel(QAbstractItemModel *model) { - auto it = m_trackTables.find(m_featurePane); - if (it == m_trackTables.end() || it->isNull()) { + auto it = m_trackTablesByPaneId.find(m_featurePane); + if (it == m_trackTablesByPaneId.end() || it->isNull()) { return; } (*it)->loadTrackModel(model); @@ -274,8 +274,8 @@ void LibraryFeature::showBreadCrumb() { } WTrackTableView* LibraryFeature::getFocusedTable() { - auto it = m_trackTables.find(m_featurePane); - if (it == m_trackTables.end() || it->isNull()) { + auto it = m_trackTablesByPaneId.find(m_featurePane); + if (it == m_trackTablesByPaneId.end() || it->isNull()) { return nullptr; } return *it; diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 6bddfabd555..33f857708b2 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -26,7 +26,7 @@ class WLibraryPane; class WLibrarySidebar; class WTrackTableView; -// pure virtual (abstract) class to provide an interface for libraryfeatures +// abstract class to provide an interface for library features class LibraryFeature : public QObject { Q_OBJECT public: @@ -70,7 +70,7 @@ class LibraryFeature : public QObject { virtual TreeItemModel* getChildModel() = 0; virtual void setFeaturePane(int paneId); - int getFeaturePane(); + int getFeaturePaneId(); void setSavedPane(int paneId); int getSavedPane(); @@ -162,7 +162,7 @@ class LibraryFeature : public QObject { private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); - QHash > m_trackTables; + QHash > m_trackTablesByPaneId; }; #endif /* LIBRARYFEATURE_H */ diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 58be86c9534..b7bff7e4376 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -208,7 +208,6 @@ void WSearchLineEdit::keyPressEvent(QKeyEvent* event) { } } -// slot void WSearchLineEdit::restoreSearch(const QString& text, QPointer pFeature) { if(text.isNull()) { // disable diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 9b9f2ac5c3c..417bf8949a6 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -18,10 +18,12 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { Q_OBJECT public: - explicit WSearchLineEdit(QWidget* pParent = nullptr); void setup(const QDomNode& node, const SkinContext& context); + void restoreSearch(const QString& text, + QPointer pFeature = nullptr); + void slotRestoreSaveButton(); protected: void resizeEvent(QResizeEvent* event) override; @@ -37,12 +39,8 @@ class WSearchLineEdit : public QLineEdit, public WBaseWidget { void focused(); void cancel(); - public slots: - void restoreSearch(const QString& text, QPointer pFeature = nullptr); - void slotTextChanged(const QString& text); - void slotRestoreSaveButton(); - private slots: + void slotTextChanged(const QString& text); void updateButtons(const QString& text); void slotSetupTimer(const QString&); void triggerSearch(); From 93f09876e3142d79caa4beebc3266b5aa624a737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 7 Oct 2016 17:00:49 +0200 Subject: [PATCH 521/552] Improve Keyboard interaction in WTrackTableView Enabled "Del" for removing and "Enter" for loading tracks --- src/library/libraryfeature.cpp | 4 +- src/mixxx.cpp | 5 ++- src/skin/legacyskinparser.cpp | 3 +- src/widget/wlibrarysidebar.cpp | 5 +-- src/widget/wtracktableview.cpp | 72 ++++++++++++++++++++++++++++------ src/widget/wtracktableview.h | 3 ++ 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 17623fe493e..3b52297d678 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -182,9 +182,7 @@ WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboar int paneId) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, true); - - pTrackTableView->installEventFilter(pKeyboard); - + WMiniViewScrollBar* pScrollBar = new WMiniViewScrollBar(pTrackTableView); pTrackTableView->setScrollBar(pScrollBar); diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 6e2c67b72f7..3eaff44df35 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -659,8 +659,9 @@ void MixxxMainWindow::initializeKeyboard() { // initialization into KeyboardEventFilter // Workaround for today: KeyboardEventFilter calls delete bool keyboardShortcutsEnabled = pConfig->getValueString( - ConfigKey("[Keyboard]", "Enabled")) == "1"; - m_pKeyboard = new KeyboardEventFilter(keyboardShortcutsEnabled ? m_pKbdConfig : m_pKbdConfigEmpty); + ConfigKey("[Keyboard]", "Enabled")) == "1"; + m_pKeyboard = new KeyboardEventFilter( + keyboardShortcutsEnabled ? m_pKbdConfig : m_pKbdConfigEmpty); } int MixxxMainWindow::noSoundDlg(void) { diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 87d0d730027..13e1573ba71 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1306,7 +1306,8 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) { WLibraryPane* pLibraryWidget = new WLibraryPane(pContainer); pLibraryWidget->installEventFilter(m_pKeyboard); - pLibraryWidget->installEventFilter(m_pControllerManager->getControllerLearningEventFilter()); + pLibraryWidget->installEventFilter( + m_pControllerManager->getControllerLearningEventFilter()); pLayout->addWidget(pLibraryWidget); m_pLibrary->bindPaneWidget(pLibraryWidget, m_pKeyboard, m_paneId); diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 14d1550b417..e8d6e001f79 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -194,19 +194,16 @@ void WLibrarySidebar::toggleSelectedItem() { emit(pressed(index)); // Expand or collapse the item as necessary. setExpanded(index, !isExpanded(index)); - } } void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { - qDebug() << event->text() << (bool) (event->key() == Qt::Key_Return); - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { toggleSelectedItem(); return; } - // Fall through to deafult handler. + // Fall through to default handler. QTreeView::keyPressEvent(event); } diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 8ae855dcb99..d9e7bd15bc8 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -78,7 +78,7 @@ WTrackTableView::WTrackTableView(QWidget * parent, this, SLOT(slotReloadCoverArt())); // Disable editing - //setEditTriggers(QAbstractItemView::NoEditTriggers); + setEditTriggers(QAbstractItemView::NoEditTriggers); // Create all the context m_pMenu->actions (stuff that shows up when you //right-click) @@ -1271,17 +1271,47 @@ bool WTrackTableView::modelHasCapabilities(TrackModel::CapabilitiesFlags capabil } void WTrackTableView::keyPressEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Return) { - // It is not a good idea if 'key_return' - // causes a track to load since we allow in-line editing - // of table items in general - return; - } else if ((event->modifiers() & Qt::ControlModifier) || - event->key() == Qt::Key_F) { - qDebug() << "Ctrl+f Table"; - QTableView::keyPressEvent(event); + qDebug() << "WTrackTableView::keyPressEvent" << event; + if (event == QKeySequence::Copy) { + copy(); + } else if (event == QKeySequence::Paste) { + paste(); + } else if (event == QKeySequence::Cut) { + cut(); + } else if (event == QKeySequence::SelectAll) { + selectAll(); + event->accept(); + } else if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && + event->modifiers() == Qt::NoModifier) { + loadSelectedTrack(); + event->accept(); + } else if (event == QKeySequence::Delete) { + slotRemove(); + event->accept(); } else { - QTableView::keyPressEvent(event); + // QTableView::keyPressEvent(event) will consume all key events due to + // it's keyboardSearch feature. + // In Mixxx, we prefer that most keyboard mappings are working, so we + // pass only some basic keys to the base class + switch (event->key()) { + case Qt::Key_Down: + case Qt::Key_Up: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Space: + case Qt::Key_Select: + case Qt::Key_F2: + QTableView::keyPressEvent(event); + break; + default: + event->ignore(); + } } } @@ -1701,3 +1731,23 @@ void WTrackTableView::slotReloadCoverArt() { pCache->requestGuessCovers(selectedTracks); } } + +void WTrackTableView::cut() { + qDebug() << "QKeySequence::Copy"; + /* + QVariant variant; + if (d->model) + variant = d->model->data(currentIndex(), Qt::DisplayRole); + if (variant.type() == QVariant::String) + QApplication::clipboard()->setText(variant.toString()); + event->accept(); + */ +} + +void WTrackTableView::paste() { + qDebug() << "QKeySequence::Paste"; +} + +void WTrackTableView::copy(){ + qDebug() << "QKeySequence::Copy"; +} diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 724f8d0763e..bf6358c5417 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -93,6 +93,9 @@ class WTrackTableView : public WLibraryTableView { void dragMoveEvent(QDragMoveEvent * event) override; void dragEnterEvent(QDragEnterEvent * event) override; void dropEvent(QDropEvent * event) override; + void cut(); + void paste(); + void copy(); void lockBpm(bool lock); int getVisibleColumn(); From 8b55071912278af199518a2e01adc396e9b3695a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 7 Oct 2016 19:30:11 +0200 Subject: [PATCH 522/552] Added Ctrl+C copy action --- src/widget/wtracktableview.cpp | 56 ++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d9e7bd15bc8..aecbefe8d1c 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "widget/wtracktableview.h" @@ -1274,10 +1275,13 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { qDebug() << "WTrackTableView::keyPressEvent" << event; if (event == QKeySequence::Copy) { copy(); + event->accept(); } else if (event == QKeySequence::Paste) { paste(); + event->accept(); } else if (event == QKeySequence::Cut) { cut(); + event->accept(); } else if (event == QKeySequence::SelectAll) { selectAll(); event->accept(); @@ -1470,7 +1474,7 @@ void WTrackTableView::addSelectionToPlaylist(int iPlaylistId) { trackIds.append(trackId); } } - if (iPlaylistId == -1) { // i.e. a new playlist is suppose to be created + if (iPlaylistId == -1) { // i.e. a new playlist is suppose to be created QString name; bool validNameGiven = false; @@ -1505,7 +1509,7 @@ void WTrackTableView::addSelectionToPlaylist(int iPlaylistId) { +name); return; } - } + } if (trackIds.size() > 0) { // TODO(XXX): Care whether the append succeeded. m_pTrackCollection->getTrackDAO().unhideTracks(trackIds); @@ -1733,7 +1737,7 @@ void WTrackTableView::slotReloadCoverArt() { } void WTrackTableView::cut() { - qDebug() << "QKeySequence::Copy"; + qDebug() << "QKeySequence::Cut"; /* QVariant variant; if (d->model) @@ -1746,8 +1750,54 @@ void WTrackTableView::cut() { void WTrackTableView::paste() { qDebug() << "QKeySequence::Paste"; + + qDebug() << QApplication::clipboard(); + qDebug() << QApplication::clipboard()->mimeData()->data("text/plain;charset=utf-8"); + qDebug() << QApplication::clipboard()->mimeData()->urls(); + qDebug() << QApplication::clipboard()->mimeData()->text(); + qDebug() << QApplication::clipboard()->mimeData()->formats(); } void WTrackTableView::copy(){ qDebug() << "QKeySequence::Copy"; + + TrackModel* trackModel = getTrackModel(); + if (!trackModel) { + return; + } + + QList locationUrls; + QString locations; + QByteArray gnomeFormat = QByteArray("copy"); + QModelIndexList indices = selectionModel()->selectedRows(); + QList trackIds; + for (const QModelIndex& index : indices) { + TrackPointer pTrack = trackModel->getTrack(index); + if (!pTrack) { + continue; + } + if (!locations.isEmpty()) { + locations += "\n"; + } + locations += pTrack->getLocation(); + QUrl fileUrl = QUrl::fromLocalFile(pTrack->getLocation()); + locationUrls.append(fileUrl); + gnomeFormat += "\n" + fileUrl.toEncoded(); + } + + if (locationUrls.isEmpty()) { + return; + } + + QMimeData* mimeData = new QMimeData(); + mimeData->setUrls(locationUrls); + // According to RFC 6657 this should be "US-ASCII" + // However this is used by Gedit and Utf8 character are accepted + mimeData->setText(locations); + // This is the correct way to pass unicode strings (not used by Gedit) + mimeData->setData("text/plain;charset=utf-8", locations.toUtf8()); + // This is accepted by Nautilus and Co + mimeData->setData("x-special/gnome-copied-files", gnomeFormat); + + QApplication::clipboard()->setMimeData(mimeData); } From 04b804ce457eec3d9112ef480cc312034c7831eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 8 Oct 2016 18:07:19 +0200 Subject: [PATCH 523/552] Consider modifiers when passing keys to QTableView --- src/widget/wtracktableview.cpp | 46 +++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index aecbefe8d1c..86b6b8331d9 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1297,23 +1297,35 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { // it's keyboardSearch feature. // In Mixxx, we prefer that most keyboard mappings are working, so we // pass only some basic keys to the base class - switch (event->key()) { - case Qt::Key_Down: - case Qt::Key_Up: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - case Qt::Key_Tab: - case Qt::Key_Backtab: - case Qt::Key_Space: - case Qt::Key_Select: - case Qt::Key_F2: - QTableView::keyPressEvent(event); - break; - default: + if (event->modifiers() == Qt::NoModifier) { + switch (event->key()) { + case Qt::Key_Down: + case Qt::Key_Up: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Space: + case Qt::Key_Select: + case Qt::Key_F2: + QTableView::keyPressEvent(event); + break; + default: + event->ignore(); + } + } else if (event->modifiers() == Qt::SHIFT) { + switch (event->key()) { + case Qt::Key_Tab: + QTableView::keyPressEvent(event); + break; + default: + event->ignore(); + } + } else { event->ignore(); } } From 6a5553361d7744cea2efc75965a8395e144c8a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 9 Oct 2016 13:25:34 +0200 Subject: [PATCH 524/552] Enable Ctrl+V to paste tracks. --- src/widget/wtracktableview.cpp | 101 ++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 15 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 86b6b8331d9..64128c75403 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1320,6 +1320,8 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { } else if (event->modifiers() == Qt::SHIFT) { switch (event->key()) { case Qt::Key_Tab: + case Qt::Key_Down: + case Qt::Key_Up: QTableView::keyPressEvent(event); break; default: @@ -1749,25 +1751,94 @@ void WTrackTableView::slotReloadCoverArt() { } void WTrackTableView::cut() { - qDebug() << "QKeySequence::Cut"; - /* - QVariant variant; - if (d->model) - variant = d->model->data(currentIndex(), Qt::DisplayRole); - if (variant.type() == QVariant::String) - QApplication::clipboard()->setText(variant.toString()); - event->accept(); - */ + copy(); + slotRemove(); } void WTrackTableView::paste() { - qDebug() << "QKeySequence::Paste"; + qDebug() << "WTrackTableView::paste()" + << QApplication::clipboard()->mimeData()->formats(); + + TrackModel* trackModel = getTrackModel(); + + // We only do things to the TrackModel in this method so if we don't have + // one we should just bail. + if (!trackModel) { + return; + } + + const QMimeData* pMimeData = QApplication::clipboard()->mimeData(); + + if (!pMimeData->hasUrls() || trackModel->isLocked()) { + return; + } + + // Save the vertical scrollbar position. Adding new tracks and moving tracks in + // the SQL data models causes a select() (ie. generation of a new result set), + // which causes view to reset itself. A view reset causes the widget to scroll back + // up to the top, which is confusing when you're dragging and dropping. :) + saveView(); - qDebug() << QApplication::clipboard(); - qDebug() << QApplication::clipboard()->mimeData()->data("text/plain;charset=utf-8"); - qDebug() << QApplication::clipboard()->mimeData()->urls(); - qDebug() << QApplication::clipboard()->mimeData()->text(); - qDebug() << QApplication::clipboard()->mimeData()->formats(); + QModelIndex destIndex; + QModelIndexList indexes = selectionModel()->selectedRows(); + if (indexes.size() > 0) { + destIndex = indexes.at(0); + } else { + destIndex = currentIndex(); + } + + // Reset the selected tracks (if you had any tracks highlighted, it + // clears them) + selectionModel()->clear(); + + // Add all the dropped URLs/tracks to the track model (playlist/crate) + QList fileList = DragAndDropHelper::supportedTracksFromUrls( + pMimeData->urls(), false, true); + + QList fileLocationList; + for (const QFileInfo& fileInfo : fileList) { + // TODO(uklotzde): Replace with TrackRef::location() + fileLocationList.append(fileInfo.absoluteFilePath()); + } + + int numNewRows = fileLocationList.count(); + + // Have to do this here because the index is invalid after + // addTrack + int selectionStartRow = destIndex.row(); + + // Make a new selection starting from where the first track was + // dropped, and select all the dropped tracks + + // If the track was dropped into an empty playlist, start at row + // 0 not -1 :) + if ((destIndex.row() == -1) && (model()->rowCount() == 0)) { + selectionStartRow = 0; + } else if ((destIndex.row() == -1) && (model()->rowCount() > 0)) { + // If the track was dropped beyond the end of a playlist, then + // we need to fudge the destination a bit... + //qDebug() << "Beyond end of playlist"; + //qDebug() << "rowcount is:" << model()->rowCount(); + selectionStartRow = model()->rowCount(); + } + + // calling the addTracks returns number of failed additions + int tracksAdded = trackModel->addTracks(destIndex, fileLocationList); + + // Decrement # of rows to select if some were skipped + numNewRows -= (fileLocationList.size() - tracksAdded); + + // Create the selection, but only if the track model supports + // reordering. (eg. crates don't support reordering/indexes) + if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_REORDER)) { + for (int i = selectionStartRow; i < selectionStartRow + numNewRows; i++) { + this->selectionModel()->select(model()->index(i, 0), + QItemSelectionModel::Select | + QItemSelectionModel::Rows); + } + } + + restoreView(); } void WTrackTableView::copy(){ From 4573c522ace025b138543b3be0e7e80c2891ee50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 9 Oct 2016 13:55:42 +0200 Subject: [PATCH 525/552] Added common insert and move functions --- src/widget/wtracktableview.cpp | 382 +++++++++++++++------------------ src/widget/wtracktableview.h | 3 + 2 files changed, 178 insertions(+), 207 deletions(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 64128c75403..af1920081f1 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1073,26 +1073,6 @@ void WTrackTableView::dragMoveEvent(QDragMoveEvent * event) { // Drag-and-drop "drop" event. Occurs when something is dropped onto the track table view void WTrackTableView::dropEvent(QDropEvent * event) { - TrackModel* trackModel = getTrackModel(); - - // We only do things to the TrackModel in this method so if we don't have - // one we should just bail. - if (!trackModel) { - return; - } - - if (!event->mimeData()->hasUrls() || trackModel->isLocked()) { - event->ignore(); - return; - } - - // Save the vertical scrollbar position. Adding new tracks and moving tracks in - // the SQL data models causes a select() (ie. generation of a new result set), - // which causes view to reset itself. A view reset causes the widget to scroll back - // up to the top, which is confusing when you're dragging and dropping. :) - saveView(); - - // Calculate the model index where the track or tracks are destined to go. // (the "drop" position in a drag-and-drop) // The user usually drops on the seam between two rows. @@ -1104,155 +1084,18 @@ void WTrackTableView::dropEvent(QDropEvent * event) { //qDebug() << "destIndex.row() is" << destIndex.row(); - // Drag and drop within this widget (track reordering) - if (event->source() == this && modelHasCapabilities(TrackModel::TRACKMODELCAPS_REORDER)) { - // Note the above code hides an ambiguous case when a - // playlist is empty. For that reason, we can't factor that - // code out to be common for both internal reordering - // and external drag-and-drop. With internal reordering, - // you can't have an empty playlist. :) - - //qDebug() << "track reordering" << __FILE__ << __LINE__; - - // Save a list of row (just plain ints) so we don't get screwed over - // when the QModelIndexes all become invalid (eg. after moveTrack() - // or addTrack()) - QModelIndexList indices = selectionModel()->selectedRows(); - - QList selectedRows; - for (const QModelIndex& idx : indices) { - selectedRows.append(idx.row()); - } - - // Note: The biggest subtlety in the way I've done this track reordering code - // is that as soon as we've moved ANY track, all of our QModelIndexes probably - // get screwed up. The starting point for the logic below is to say screw it to - // the QModelIndexes, and just keep a list of row numbers to work from. That - // ends up making the logic simpler and the behavior totally predictable, - // which lets us do nice things like "restore" the selection model. - - // The model indices are sorted so that we remove the tracks from the table - // in ascending order. This is necessary because if track A is above track B in - // the table, and you remove track A, the model index for track B will change. - // Sorting the indices first means we don't have to worry about this. - //qSort(m_selectedIndices); - //qSort(m_selectedIndices.begin(), m_selectedIndices.end(), qGreater()); - qSort(selectedRows); - int maxRow = 0; - int minRow = 0; - if (!selectedRows.isEmpty()) { - maxRow = selectedRows.last(); - minRow = selectedRows.first(); - } - - // Destination row, if destIndex is invalid we set it to last row + 1 - int destRow = destIndex.row() < 0 ? model()->rowCount() : destIndex.row(); - int selectedRowCount = selectedRows.count(); - int selectionRestoreStartRow = destRow; - - // Adjust first row of new selection - if (destRow >= minRow && destRow <= maxRow) { - // If you drag a contiguous selection of multiple tracks and drop - // them somewhere inside that same selection, do nothing. + // Drag and drop within this widget (track reordering) + if (event->source() == this && + modelHasCapabilities(TrackModel::TRACKMODELCAPS_REORDER)) { + if (!move(event->mimeData(), destIndex)) { + event->ignore(); return; - } else { - if (destRow < minRow) { - // If we're moving the tracks _up_, - // then reverse the order of the row selection - // to make the algorithm below work as it is - qSort(selectedRows.begin(), - selectedRows.end(), - qGreater()); - } else { - if (destRow > maxRow) { - // If we're moving the tracks _down_, - // adjust the first row to reselect - selectionRestoreStartRow = - selectionRestoreStartRow - selectedRowCount; - } - } - } - - // For each row that needs to be moved... - while (!selectedRows.isEmpty()) { - int movedRow = selectedRows.takeFirst(); // Remember it's row index - // Move it - trackModel->moveTrack(model()->index(movedRow, 0), destIndex); - - // Move the row indices for rows that got bumped up - // into the void we left, or down because of the new spot - // we're taking. - for (int i = 0; i < selectedRows.count(); i++) { - if ((selectedRows[i] > movedRow) && ( - (destRow > selectedRows[i]) )) { - selectedRows[i] = selectedRows[i] - 1; - } else if ((selectedRows[i] < movedRow) && - (destRow < selectedRows[i])) { - selectedRows[i] = selectedRows[i] + 1; - } - } - } - - - // Highlight the moved rows again (restoring the selection) - //QModelIndex newSelectedIndex = destIndex; - for (int i = 0; i < selectedRowCount; i++) { - this->selectionModel()->select(model()->index(selectionRestoreStartRow + i, 0), - QItemSelectionModel::Select | QItemSelectionModel::Rows); } } else { // Drag and drop inside Mixxx is only for few rows, bulks happen here - // Reset the selected tracks (if you had any tracks highlighted, it - // clears them) - this->selectionModel()->clear(); - - // Add all the dropped URLs/tracks to the track model (playlist/crate) - QList fileList = DragAndDropHelper::supportedTracksFromUrls( - event->mimeData()->urls(), false, true); - - QList fileLocationList; - for (const QFileInfo& fileInfo : fileList) { - // TODO(uklotzde): Replace with TrackRef::location() - fileLocationList.append(fileInfo.absoluteFilePath()); - } - - // Drag-and-drop from an external application - // eg. dragging a track from Windows Explorer onto the track table. - int numNewRows = fileLocationList.count(); - - // Have to do this here because the index is invalid after - // addTrack - int selectionStartRow = destIndex.row(); - - // Make a new selection starting from where the first track was - // dropped, and select all the dropped tracks - - // If the track was dropped into an empty playlist, start at row - // 0 not -1 :) - if ((destIndex.row() == -1) && (model()->rowCount() == 0)) { - selectionStartRow = 0; - } else if ((destIndex.row() == -1) && (model()->rowCount() > 0)) { - // If the track was dropped beyond the end of a playlist, then - // we need to fudge the destination a bit... - //qDebug() << "Beyond end of playlist"; - //qDebug() << "rowcount is:" << model()->rowCount(); - selectionStartRow = model()->rowCount(); - } - - // calling the addTracks returns number of failed additions - int tracksAdded = trackModel->addTracks(destIndex, fileLocationList); - - // Decrement # of rows to select if some were skipped - numNewRows -= (fileLocationList.size() - tracksAdded); - - // Create the selection, but only if the track model supports - // reordering. (eg. crates don't support reordering/indexes) - if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_REORDER)) { - for (int i = selectionStartRow; i < selectionStartRow + numNewRows; i++) { - this->selectionModel()->select(model()->index(i, 0), - QItemSelectionModel::Select | - QItemSelectionModel::Rows); - } + if (!insert(event->mimeData(), destIndex)) { + event->ignore(); + return; } } @@ -1759,18 +1602,73 @@ void WTrackTableView::paste() { qDebug() << "WTrackTableView::paste()" << QApplication::clipboard()->mimeData()->formats(); + QModelIndex destIndex; + QModelIndexList indexes = selectionModel()->selectedRows(); + if (indexes.size() > 0) { + destIndex = indexes.at(0); + } else { + destIndex = currentIndex(); + } + + insert(QApplication::clipboard()->mimeData(), destIndex); +} + +void WTrackTableView::copy(){ + qDebug() << "QKeySequence::Copy"; + + TrackModel* trackModel = getTrackModel(); + if (!trackModel) { + return; + } + + QList locationUrls; + QString locations; + QByteArray gnomeFormat = QByteArray("copy"); + QModelIndexList indices = selectionModel()->selectedRows(); + QList trackIds; + for (const QModelIndex& index : indices) { + TrackPointer pTrack = trackModel->getTrack(index); + if (!pTrack) { + continue; + } + if (!locations.isEmpty()) { + locations += "\n"; + } + locations += pTrack->getLocation(); + QUrl fileUrl = QUrl::fromLocalFile(pTrack->getLocation()); + locationUrls.append(fileUrl); + gnomeFormat += "\n" + fileUrl.toEncoded(); + } + + if (locationUrls.isEmpty()) { + return; + } + + QMimeData* mimeData = new QMimeData(); + mimeData->setUrls(locationUrls); + // According to RFC 6657 this should be "US-ASCII" + // However this is used by Gedit and Utf8 character are accepted + mimeData->setText(locations); + // This is the correct way to pass unicode strings (not used by Gedit) + mimeData->setData("text/plain;charset=utf-8", locations.toUtf8()); + // This is accepted by Nautilus and Co + mimeData->setData("x-special/gnome-copied-files", gnomeFormat); + + QApplication::clipboard()->setMimeData(mimeData); +} + +bool WTrackTableView::insert( + const QMimeData* pMimeData, const QModelIndex& destIndex) { TrackModel* trackModel = getTrackModel(); // We only do things to the TrackModel in this method so if we don't have // one we should just bail. if (!trackModel) { - return; + return false; } - const QMimeData* pMimeData = QApplication::clipboard()->mimeData(); - if (!pMimeData->hasUrls() || trackModel->isLocked()) { - return; + return false; } // Save the vertical scrollbar position. Adding new tracks and moving tracks in @@ -1779,14 +1677,6 @@ void WTrackTableView::paste() { // up to the top, which is confusing when you're dragging and dropping. :) saveView(); - QModelIndex destIndex; - QModelIndexList indexes = selectionModel()->selectedRows(); - if (indexes.size() > 0) { - destIndex = indexes.at(0); - } else { - destIndex = currentIndex(); - } - // Reset the selected tracks (if you had any tracks highlighted, it // clears them) selectionModel()->clear(); @@ -1839,48 +1729,126 @@ void WTrackTableView::paste() { } restoreView(); + + return true; } -void WTrackTableView::copy(){ - qDebug() << "QKeySequence::Copy"; + +bool WTrackTableView::move( + const QMimeData* pMimeData, const QModelIndex& destIndex) { TrackModel* trackModel = getTrackModel(); + + // We only do things to the TrackModel in this method so if we don't have + // one we should just bail. if (!trackModel) { - return; + return false; } - QList locationUrls; - QString locations; - QByteArray gnomeFormat = QByteArray("copy"); + if (!pMimeData->hasUrls() || trackModel->isLocked()) { + return false; + } + + // Save the vertical scrollbar position. Adding new tracks and moving tracks in + // the SQL data models causes a select() (ie. generation of a new result set), + // which causes view to reset itself. A view reset causes the widget to scroll back + // up to the top, which is confusing when you're dragging and dropping. :) + saveView(); + + // Note the above code hides an ambiguous case when a + // playlist is empty. For that reason, we can't factor that + // code out to be common for both internal reordering + // and external drag-and-drop. With internal reordering, + // you can't have an empty playlist. :) + + //qDebug() << "track reordering" << __FILE__ << __LINE__; + + // Save a list of row (just plain ints) so we don't get screwed over + // when the QModelIndexes all become invalid (eg. after moveTrack() + // or addTrack()) QModelIndexList indices = selectionModel()->selectedRows(); - QList trackIds; - for (const QModelIndex& index : indices) { - TrackPointer pTrack = trackModel->getTrack(index); - if (!pTrack) { - continue; - } - if (!locations.isEmpty()) { - locations += "\n"; + + QList selectedRows; + for (const QModelIndex& idx : indices) { + selectedRows.append(idx.row()); + } + + // Note: The biggest subtlety in the way I've done this track reordering code + // is that as soon as we've moved ANY track, all of our QModelIndexes probably + // get screwed up. The starting point for the logic below is to say screw it to + // the QModelIndexes, and just keep a list of row numbers to work from. That + // ends up making the logic simpler and the behavior totally predictable, + // which lets us do nice things like "restore" the selection model. + + // The model indices are sorted so that we remove the tracks from the table + // in ascending order. This is necessary because if track A is above track B in + // the table, and you remove track A, the model index for track B will change. + // Sorting the indices first means we don't have to worry about this. + //qSort(m_selectedIndices); + //qSort(m_selectedIndices.begin(), m_selectedIndices.end(), qGreater()); + qSort(selectedRows); + int maxRow = 0; + int minRow = 0; + if (!selectedRows.isEmpty()) { + maxRow = selectedRows.last(); + minRow = selectedRows.first(); + } + + // Destination row, if destIndex is invalid we set it to last row + 1 + int destRow = destIndex.row() < 0 ? model()->rowCount() : destIndex.row(); + + int selectedRowCount = selectedRows.count(); + int selectionRestoreStartRow = destRow; + + // Adjust first row of new selection + if (destRow >= minRow && destRow <= maxRow) { + // If you drag a contiguous selection of multiple tracks and drop + // them somewhere inside that same selection, do nothing. + return true; + } else { + if (destRow < minRow) { + // If we're moving the tracks _up_, + // then reverse the order of the row selection + // to make the algorithm below work as it is + qSort(selectedRows.begin(), + selectedRows.end(), + qGreater()); + } else { + if (destRow > maxRow) { + // If we're moving the tracks _down_, + // adjust the first row to reselect + selectionRestoreStartRow = + selectionRestoreStartRow - selectedRowCount; + } } - locations += pTrack->getLocation(); - QUrl fileUrl = QUrl::fromLocalFile(pTrack->getLocation()); - locationUrls.append(fileUrl); - gnomeFormat += "\n" + fileUrl.toEncoded(); } - if (locationUrls.isEmpty()) { - return; + // For each row that needs to be moved... + while (!selectedRows.isEmpty()) { + int movedRow = selectedRows.takeFirst(); // Remember it's row index + // Move it + trackModel->moveTrack(model()->index(movedRow, 0), destIndex); + + // Move the row indices for rows that got bumped up + // into the void we left, or down because of the new spot + // we're taking. + for (int i = 0; i < selectedRows.count(); i++) { + if ((selectedRows[i] > movedRow) && ( + (destRow > selectedRows[i]) )) { + selectedRows[i] = selectedRows[i] - 1; + } else if ((selectedRows[i] < movedRow) && + (destRow < selectedRows[i])) { + selectedRows[i] = selectedRows[i] + 1; + } + } } - QMimeData* mimeData = new QMimeData(); - mimeData->setUrls(locationUrls); - // According to RFC 6657 this should be "US-ASCII" - // However this is used by Gedit and Utf8 character are accepted - mimeData->setText(locations); - // This is the correct way to pass unicode strings (not used by Gedit) - mimeData->setData("text/plain;charset=utf-8", locations.toUtf8()); - // This is accepted by Nautilus and Co - mimeData->setData("x-special/gnome-copied-files", gnomeFormat); - QApplication::clipboard()->setMimeData(mimeData); + // Highlight the moved rows again (restoring the selection) + //QModelIndex newSelectedIndex = destIndex; + for (int i = 0; i < selectedRowCount; i++) { + this->selectionModel()->select(model()->index(selectionRestoreStartRow + i, 0), + QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + return true; } diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index bf6358c5417..28f23e09c22 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -111,6 +111,9 @@ class WTrackTableView : public WLibraryTableView { TrackModel* getTrackModel() const; bool modelHasCapabilities(TrackModel::CapabilitiesFlags capabilities); + bool insert(const QMimeData* pMimeData, const QModelIndex& destIndex); + bool move(const QMimeData* pMimeData, const QModelIndex& destIndex); + UserSettingsPointer m_pConfig; TrackCollection* m_pTrackCollection; From 8cf4483b4ddcd2d9487ae2761e780b9834849380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 9 Oct 2016 21:28:57 +0200 Subject: [PATCH 526/552] move the keyboard event filter of the button bar to the parent class --- src/skin/legacyskinparser.cpp | 6 +- src/widget/wbuttonbar.cpp | 110 +++++++++++++++++----------------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index 13e1573ba71..a86eb119566 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1332,10 +1332,10 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { m_pConfig->set(confKey, QString::number(1.0)); WVerticalScrollArea* scroll = new WVerticalScrollArea(pContainer); + scroll->installEventFilter(m_pKeyboard); pLayout->addWidget(scroll); WButtonBar* pLibrarySidebar = new WButtonBar(scroll); - pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); connect(pLibrarySidebar, SIGNAL(ensureVisible(QWidget*)), @@ -1354,10 +1354,10 @@ QWidget* LegacySkinParser::parseLibrarySidebar(const QDomElement& node) { QWidget* LegacySkinParser::parseLibrarySidebarButtons(const QDomElement& node) { WVerticalScrollArea* scroll = new WVerticalScrollArea(m_pParent); - + scroll->installEventFilter(m_pKeyboard); + WButtonBar* pLibrarySidebar = new WButtonBar(scroll); pLibrarySidebar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); - pLibrarySidebar->installEventFilter(m_pKeyboard); m_pLibrary->bindSidebarButtons(pLibrarySidebar); scroll->setWidget(pLibrarySidebar); connect(pLibrarySidebar, SIGNAL(ensureVisible(QWidget*)), diff --git a/src/widget/wbuttonbar.cpp b/src/widget/wbuttonbar.cpp index 3aaf14b1b1b..0c9e0affb75 100644 --- a/src/widget/wbuttonbar.cpp +++ b/src/widget/wbuttonbar.cpp @@ -44,79 +44,81 @@ WFeatureClickButton* WButtonBar::addButton(LibraryFeature* pFeature) { void WButtonBar::keyPressEvent(QKeyEvent* event) { bool focusFound = false; - switch(event->key()) { - case Qt::Key_Up: - for (int i = m_pLayout->count() - 1; i >= 0; --i) { - QLayoutItem* item = m_pLayout->itemAt(i); - if (item) { - QWidget* widget = item->widget(); - if (widget) { - if (widget->hasFocus()) { - m_focusItem = i; - focusFound = true; - } else if (focusFound == true) { + if (event->modifiers() == Qt::NoModifier) { + switch(event->key()) { + case Qt::Key_Up: + for (int i = m_pLayout->count() - 1; i >= 0; --i) { + QLayoutItem* item = m_pLayout->itemAt(i); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + if (widget->hasFocus()) { + m_focusItem = i; + focusFound = true; + } else if (focusFound == true) { + widget->setFocus(); + emit ensureVisible(widget); + m_focusItem = i; + qDebug() << "Focus to" << i; + event->accept(); + return; + } + } + } + } + if (focusFound == false) { + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { widget->setFocus(); emit ensureVisible(widget); - m_focusItem = i; - qDebug() << "Focus to" << i; + event->accept(); return; } } } - } - if (focusFound == false) { - QLayoutItem* item = m_pLayout->itemAt(m_focusItem); - if (item) { - QWidget* widget = item->widget(); - if (widget) { - widget->setFocus(); - emit ensureVisible(widget); - return; + break; + case Qt::Key_Down: + for (int i = 0; i < m_pLayout->count(); ++i) { + QLayoutItem* item = m_pLayout->itemAt(i); + if (item) { + QWidget* widget = item->widget(); + if (widget) { + if (widget->hasFocus()) { + m_focusItem = i; + focusFound = true; + } else if (focusFound == true) { + widget->setFocus(); + emit ensureVisible(widget); + m_focusItem = i; + qDebug() << "Focus to" << i; + event->accept(); + return; + } + } } } - } - QWidget::keyPressEvent(event); - break; - case Qt::Key_Down: - for (int i = 0; i < m_pLayout->count(); ++i) { - QLayoutItem* item = m_pLayout->itemAt(i); - if (item) { - QWidget* widget = item->widget(); - if (widget) { - if (widget->hasFocus()) { - m_focusItem = i; - focusFound = true; - } else if (focusFound == true) { + if (focusFound == false) { + QLayoutItem* item = m_pLayout->itemAt(m_focusItem); + if (item) { + QWidget* widget = item->widget(); + if (widget) { widget->setFocus(); emit ensureVisible(widget); - m_focusItem = i; - qDebug() << "Focus to" << i; + event->accept(); return; } } } + break; } - if (focusFound == false) { - QLayoutItem* item = m_pLayout->itemAt(m_focusItem); - if (item) { - QWidget* widget = item->widget(); - if (widget) { - widget->setFocus(); - emit ensureVisible(widget); - return; - } - } - } - QWidget::keyPressEvent(event); - break; - default: - QWidget::keyPressEvent(event); - break; } + QFrame::keyPressEvent(event); } void WButtonBar::focusInEvent(QFocusEvent* event) { - QWidget::focusInEvent(event); + QFrame::focusInEvent(event); if (m_focusFromButton) { // don't re-focus buttons, when the focus was just there before focusPreviousChild(); From 877099dfca74b6011bf2bd452c27f9c4288cf837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sun, 9 Oct 2016 22:20:48 +0200 Subject: [PATCH 527/552] Key_Down selects the first row, if there is nothing else selected --- src/widget/wtracktableview.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index af1920081f1..401335937b1 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1135,6 +1135,17 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { } else if (event == QKeySequence::Delete) { slotRemove(); event->accept(); + } else if (event->key() == Qt::Key_Down && event->modifiers() == Qt::NoModifier) { + // If there is no row selected, select the first + // Qt fails to do it for us when there is only a single row + QModelIndexList indexes = selectionModel()->selectedRows(); + if (indexes.size() == 0) { + selectionModel()->select(model()->index(0, 0), + QItemSelectionModel::Select | QItemSelectionModel::Rows); + event->accept(); + } else { + QTableView::keyPressEvent(event); + } } else { // QTableView::keyPressEvent(event) will consume all key events due to // it's keyboardSearch feature. From 440d458a2c2cd35b7d00065c6a7007db2ffa17fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 12 Oct 2016 22:05:24 +0200 Subject: [PATCH 528/552] Keyboard control in WLibrarySidebar improved --- .../features/analysis/analysisfeature.cpp | 8 +- src/library/features/autodj/autodjfeature.cpp | 2 +- .../maintenance/maintenancefeature.cpp | 3 +- .../features/recording/recordingfeature.cpp | 12 ++- src/library/libraryfeature.cpp | 6 +- src/library/libraryfeature.h | 15 ++- src/widget/wlibrarysidebar.cpp | 95 ++++++++++++++++++- src/widget/wlibrarysidebar.h | 2 + 8 files changed, 118 insertions(+), 25 deletions(-) diff --git a/src/library/features/analysis/analysisfeature.cpp b/src/library/features/analysis/analysisfeature.cpp index cd0a63975af..222dae67661 100644 --- a/src/library/features/analysis/analysisfeature.cpp +++ b/src/library/features/analysis/analysisfeature.cpp @@ -61,7 +61,7 @@ QString AnalysisFeature::getSettingsName() const { } QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTable = createTableWidget(pKeyboard, paneId); + WTrackTableView* pTable = createTableWidget(paneId); pTable->loadTrackModel(getAnalysisTableModel()); connect(pTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), @@ -194,9 +194,11 @@ void AnalysisFeature::tableSelectionChanged(const QItemSelection&, bool AnalysisFeature::dropAccept(QList urls, QObject* pSource) { Q_UNUSED(pSource); - QList files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true); + QList files = + DragAndDropHelper::supportedTracksFromUrls(urls, false, true); // Adds track, does not insert duplicates, handles unremoving logic. - QList trackIds = m_pTrackCollection->getTrackDAO().addMultipleTracks(files, true); + QList trackIds = + m_pTrackCollection->getTrackDAO().addMultipleTracks(files, true); analyzeTracks(trackIds); return trackIds.size() > 0; } diff --git a/src/library/features/autodj/autodjfeature.cpp b/src/library/features/autodj/autodjfeature.cpp index 9834d1f2575..0b508fe073a 100644 --- a/src/library/features/autodj/autodjfeature.cpp +++ b/src/library/features/autodj/autodjfeature.cpp @@ -101,7 +101,7 @@ QString AutoDJFeature::getSettingsName() const { } QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTrackTableView = createTableWidget(pKeyboard, paneId); + WTrackTableView* pTrackTableView = createTableWidget(paneId); pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); connect(pTrackTableView->selectionModel(), diff --git a/src/library/features/maintenance/maintenancefeature.cpp b/src/library/features/maintenance/maintenancefeature.cpp index d4b8fe7fba4..5d42030d3b5 100644 --- a/src/library/features/maintenance/maintenancefeature.cpp +++ b/src/library/features/maintenance/maintenancefeature.cpp @@ -104,7 +104,8 @@ QWidget* MaintenanceFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyb QWidget* MaintenanceFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); + Q_UNUSED(pKeyboard); + WTrackTableView* pTable = LibraryFeature::createTableWidget(paneId); return pTable; } diff --git a/src/library/features/recording/recordingfeature.cpp b/src/library/features/recording/recordingfeature.cpp index f9900ef68ac..9afb871d8c6 100644 --- a/src/library/features/recording/recordingfeature.cpp +++ b/src/library/features/recording/recordingfeature.cpp @@ -47,13 +47,16 @@ TreeItemModel* RecordingFeature::getChildModel() { return &m_childModel; } -QWidget* RecordingFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - WTrackTableView* pTable = LibraryFeature::createTableWidget(pKeyboard, paneId); +QWidget* RecordingFeature::createPaneWidget( + KeyboardEventFilter* pKeyboard, int paneId) { + Q_UNUSED(pKeyboard); + WTrackTableView* pTable = LibraryFeature::createTableWidget(paneId); pTable->setSorting(false); return pTable; } -QWidget *RecordingFeature::createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) { +QWidget *RecordingFeature::createInnerSidebarWidget( + KeyboardEventFilter* pKeyboard) { m_pRecordingView = new DlgRecording(nullptr, m_pTrackCollection, m_pRecordingManager); @@ -79,7 +82,8 @@ void RecordingFeature::activate() { BrowseTableModel* RecordingFeature::getBrowseTableModel() { if (m_pBrowseModel.isNull()) { - m_pBrowseModel = new BrowseTableModel(this, m_pTrackCollection, m_pRecordingManager); + m_pBrowseModel = new BrowseTableModel( + this, m_pTrackCollection, m_pRecordingManager); } return m_pBrowseModel; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 3b52297d678..c09335854ac 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -69,7 +69,8 @@ bool LibraryFeature::dragMoveAcceptChild(const QModelIndex &, QUrl) { QWidget* LibraryFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { - return createTableWidget(pKeyboard, paneId); + Q_UNUSED(pKeyboard); + return createTableWidget(paneId); } QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { @@ -178,8 +179,7 @@ QList LibraryFeature::getSavedQueries() const { return m_savedDAO.getSavedQueries(this); } -WTrackTableView* LibraryFeature::createTableWidget(KeyboardEventFilter* pKeyboard, - int paneId) { +WTrackTableView* LibraryFeature::createTableWidget(int paneId) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, true); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 33f857708b2..6a4104f1331 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -51,12 +51,12 @@ class LibraryFeature : public QObject { QObject* /* pSource */) { return false; } - virtual bool dropAcceptChild(const QModelIndex& /* index */, - QList /* urls */, - QObject* /* pSource */); - virtual bool dragMoveAccept(QUrl /* url */); - virtual bool dragMoveAcceptChild(const QModelIndex& /* index */, - QUrl /* url */); + virtual bool dropAcceptChild(const QModelIndex& index, + QList urls, + QObject* pSource); + virtual bool dragMoveAccept(QUrl url); + virtual bool dragMoveAcceptChild(const QModelIndex& index, + QUrl url); // Reimplement this to register custom views with the library widget // at the right pane. @@ -131,8 +131,7 @@ class LibraryFeature : public QObject { } // Creates a table widget with no model - WTrackTableView* createTableWidget(KeyboardEventFilter* pKeyboard, - int paneId); + WTrackTableView* createTableWidget(int paneId); // Creates a WLibrarySidebar widget with the getChildModel() function as // model diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index e8d6e001f79..70b148fd523 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "library/treeitemmodel.h" #include "util/dnd.h" @@ -198,13 +199,72 @@ void WLibrarySidebar::toggleSelectedItem() { } void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + qDebug() << "WLibrarySidebar::keyPressEvent" << event; + if (event == QKeySequence::Copy) { + event->ignore(); + } else if (event == QKeySequence::Paste) { + if (paste()) { + event->accept(); + } else { + event->ignore(); + } + } else if (event == QKeySequence::Cut) { + // TODO(XXX) allow delete by key but with a safety pop up + // or an undo feature + event->ignore(); + } else if (event == QKeySequence::SelectAll) { + selectAll(); + event->accept(); + } else if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && + event->modifiers() == Qt::NoModifier) { toggleSelectedItem(); - return; - } + event->accept(); + } else if (event == QKeySequence::Delete) { + // TODO(XXX) allow delete by key but with a safety pop up + // or an undo feature + event->ignore(); + } else { + // QTreeView::keyPressEvent(event) will consume all key events due to + // it's keyboardSearch feature. + // In Mixxx, we prefer that most keyboard mappings are working, so we + // pass only some basic keys to the base class + if (event->modifiers() == Qt::NoModifier) { + switch (event->key()) { + case Qt::Key_Down: + case Qt::Key_Up: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Space: + case Qt::Key_Select: + case Qt::Key_F2: + QTreeView::keyPressEvent(event); + break; - // Fall through to default handler. - QTreeView::keyPressEvent(event); + // Ignored even though used in default QT: + case Qt::Key_Asterisk: + case Qt::Key_Plus: + case Qt::Key_Minus: + default: + event->ignore(); + } + } else if (event->modifiers() == Qt::SHIFT) { + switch (event->key()) { + case Qt::Key_Tab: + QTreeView::keyPressEvent(event); + break; + default: + event->ignore(); + } + } else { + event->ignore(); + } + } } void WLibrarySidebar::selectIndex(const QModelIndex& index) { @@ -228,3 +288,28 @@ bool WLibrarySidebar::event(QEvent* pEvent) { void WLibrarySidebar::slotSetFont(const QFont& font) { setFont(font); } + +bool WLibrarySidebar::paste() { + qDebug() << "WTrackTableView::paste()" + << QApplication::clipboard()->mimeData()->formats(); + + QModelIndex destIndex; + QModelIndexList indexes = selectionModel()->selectedRows(); + if (indexes.size() > 0) { + destIndex = indexes.at(0); + } else { + destIndex = currentIndex(); + } + + TreeItemModel* pTreeModel = qobject_cast(model()); + if (!pTreeModel) { + return false; + } + + const QMimeData* pMimeData = QApplication::clipboard()->mimeData(); + if (!pMimeData->hasUrls()) { + return false; + } + + return pTreeModel->dropAccept(destIndex, pMimeData->urls(), nullptr); +} diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index 26e0852405b..8d79cc9ab2d 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -49,6 +49,8 @@ class WLibrarySidebar : public QTreeView, public WBaseWidget { bool event(QEvent* pEvent) override; private: + bool paste(); + QBasicTimer m_expandTimer; QModelIndex m_hoverIndex; }; From 3800e894959d8d7c3b0467f6abdab4b54fb0ab9f Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 14 Oct 2016 10:41:35 +0200 Subject: [PATCH 529/552] Fix warning about unused variable --- src/library/features/analysis/analysisfeature.cpp | 2 +- src/library/features/analysis/analysisfeature.h | 2 +- src/library/features/autodj/autodjfeature.cpp | 2 +- src/library/features/autodj/autodjfeature.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/library/features/analysis/analysisfeature.cpp b/src/library/features/analysis/analysisfeature.cpp index 222dae67661..31c4bebeedf 100644 --- a/src/library/features/analysis/analysisfeature.cpp +++ b/src/library/features/analysis/analysisfeature.cpp @@ -60,7 +60,7 @@ QString AnalysisFeature::getSettingsName() const { return "AnalysisFeature"; } -QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { +QWidget* AnalysisFeature::createPaneWidget(KeyboardEventFilter*, int paneId) { WTrackTableView* pTable = createTableWidget(paneId); pTable->loadTrackModel(getAnalysisTableModel()); connect(pTable->selectionModel(), diff --git a/src/library/features/analysis/analysisfeature.h b/src/library/features/analysis/analysisfeature.h index c97bf30f9ef..8e9e5e15dbf 100644 --- a/src/library/features/analysis/analysisfeature.h +++ b/src/library/features/analysis/analysisfeature.h @@ -36,7 +36,7 @@ class AnalysisFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) override; + QWidget* createPaneWidget(KeyboardEventFilter*, int paneId) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; TreeItemModel* getChildModel(); diff --git a/src/library/features/autodj/autodjfeature.cpp b/src/library/features/autodj/autodjfeature.cpp index 0b508fe073a..17d085225cd 100644 --- a/src/library/features/autodj/autodjfeature.cpp +++ b/src/library/features/autodj/autodjfeature.cpp @@ -100,7 +100,7 @@ QString AutoDJFeature::getSettingsName() const { return "AutoDJFeature"; } -QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) { +QWidget* AutoDJFeature::createPaneWidget(KeyboardEventFilter*, int paneId) { WTrackTableView* pTrackTableView = createTableWidget(paneId); pTrackTableView->loadTrackModel(m_pAutoDJProcessor->getTableModel()); diff --git a/src/library/features/autodj/autodjfeature.h b/src/library/features/autodj/autodjfeature.h index e6289d53791..c3212325d9f 100644 --- a/src/library/features/autodj/autodjfeature.h +++ b/src/library/features/autodj/autodjfeature.h @@ -45,7 +45,7 @@ class AutoDJFeature : public LibraryFeature { bool dropAccept(QList urls, QObject* pSource); bool dragMoveAccept(QUrl url); - QWidget* createPaneWidget(KeyboardEventFilter* pKeyboard, int paneId) override; + QWidget* createPaneWidget(KeyboardEventFilter*, int paneId) override; QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; TreeItemModel* getChildModel(); From 73fcdaf9e3208b5206a9b95223dba69f6426aac1 Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 14 Oct 2016 12:26:19 +0200 Subject: [PATCH 530/552] Fix sort order in pinned queries --- src/library/dao/savedqueriesdao.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/dao/savedqueriesdao.cpp b/src/library/dao/savedqueriesdao.cpp index c2edbf16274..f3f58dc0691 100644 --- a/src/library/dao/savedqueriesdao.cpp +++ b/src/library/dao/savedqueriesdao.cpp @@ -58,7 +58,7 @@ QList SavedQueriesDAO::getSavedQueries(const QString& settings QString queryStr = kSelectStart + "FROM " SAVEDQUERYTABLE " WHERE libraryFeature = :featureName " - "ORDER BY id DESC"; + "ORDER BY pinned DESC, id DESC"; query.prepare(queryStr); query.bindValue(":featureName", settingsName); From 6b11a85b830f5b0a023eae5e829e5858cfcbfb2f Mon Sep 17 00:00:00 2001 From: jmigual Date: Fri, 14 Oct 2016 12:26:36 +0200 Subject: [PATCH 531/552] Add pinned icon to queries --- src/widget/wsearchlineedit.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index 423bedf6145..1f4b3ec1326 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -326,21 +326,28 @@ void WSearchLineEdit::restoreQuery() { const QList& savedQueries = m_pCurrentFeature->getSavedQueries(); QMenu menu; - if (savedQueries.size() <= 0) { QAction* action = menu.addAction(tr("No saved queries")); action->setData(-1); } + QActionGroup* group = new QActionGroup(&menu); + group->setExclusive(false); for (const SavedSearchQuery& sQuery : savedQueries) { QAction* action = menu.addAction(sQuery.title); - action->setData(sQuery.id); if (sQuery.pinned) { + action->setActionGroup(group); + action->setIcon(QIcon(":/images/ic_library_pinned.png")); action->setIconVisibleInMenu(true); + action->setCheckable(true); + action->setChecked(true); } + action->setData(sQuery.id); } - { + + // There's no need to show the queries editor if there are not saved queries + if (savedQueries.size() > 0) { menu.addSeparator(); QAction* action = menu.addAction(tr("Queries editor")); action->setData(-2); @@ -353,6 +360,10 @@ void WSearchLineEdit::restoreQuery() { if (selected == nullptr) return; bool ok; + + // index >= 0 -> Normal data + // index == -1 -> No saved queries selected + // index == -2 -> Saved queries editor selected int index = selected->data().toInt(&ok); if (!ok) return; From 2c2f13e01d5e569d07923611b44cd2b89ce31a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 29 Nov 2016 23:48:24 +0100 Subject: [PATCH 532/552] Fix selected row background for cover and preview buttion --- res/skins/LateNight/style.qss | 35 +++++++++++++++++---------- src/library/coverartdelegate.cpp | 18 +++++++++----- src/library/previewbuttondelegate.cpp | 25 ++++++++++++------- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 3acf0ad90e6..38f7dc98885 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1270,9 +1270,8 @@ QTableView:focus { #LibrarySidebarButtons, QTableView, QTextBrowser, QTreeView { border: 1px solid #585858; - /*font: 15px/18px;*/ color: #cfb32c; - background-color: #191919; + background-color: #0f0f0f; alternate-background-color: #1a1a1a; selection-color: #cfb32c; @@ -1296,14 +1295,24 @@ WBaseLibrary QLabel { border: 0px solid blue; } +QTableView::item:selected:active { + color: #cfb32c; + background-color: #725309; +} + +QTableView::item:selected:!active { + color: #cfb32c; + background-color: #4c3b11; +} + +QTableView:!focus { + selection-background-color: #4c3b11; +} + /* checkbox in library "Played" column */ QTableView::indicator { width: 12px; height: 12px;} QTableView::indicator:checked { background: url(skin:/style/style_checkbox_checked.png);} QTableView::indicator:unchecked { background: url(skin:/style/style_checkbox_unchecked.png);} -QTableView::item:selected { - color: #cfb32c; - background-color: #725309; -} /* BPM lock icon in the library "BPM" column. */ #LibraryBPMButton::indicator:checked { image: url(:/images/library/ic_library_checked.png); } @@ -1314,18 +1323,18 @@ QTableView::item:selected { } /* Button in library "Preview" column */ -QPushButton#LibraryPreviewButton { + +#LibraryPreviewButton { width: 23px; height: 12px; - background: transparent; + image: url(skin:/style/style_library_preview_play.png); + background-color: transparent; border: 0px; } -/*QPushButton#LibraryPreviewButton:focus { - background-color: #725309; -}*/ -QPushButton#LibraryPreviewButton:!checked{ image: url(skin:/style/style_library_preview_play.png); } -QPushButton#LibraryPreviewButton:checked{ image: url(skin:/style/style_library_preview_pause.png); } +#LibraryPreviewButton:checked { + image: url(skin:/style/style_library_preview_pause.png); +} QHeaderView { font: 13px/15px; diff --git a/src/library/coverartdelegate.cpp b/src/library/coverartdelegate.cpp index d93639d62d6..41ea79d761f 100644 --- a/src/library/coverartdelegate.cpp +++ b/src/library/coverartdelegate.cpp @@ -81,12 +81,18 @@ void CoverArtDelegate::slotCoverFound(const QObject* pRequestor, } } -void CoverArtDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const { - if (option.state & QStyle::State_Selected) { - painter->fillRect(option.rect, option.palette.highlight()); - } +void CoverArtDelegate::paint(QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const { + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + + // Draw original item without text as background + opt.text = QString(); + const QWidget *widget = opt.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); CoverArtCache* pCache = CoverArtCache::instance(); if (pCache == NULL || m_iIdColumn == -1 || m_iCoverSourceColumn == -1 || diff --git a/src/library/previewbuttondelegate.cpp b/src/library/previewbuttondelegate.cpp index c01d03dc72b..964934fe366 100644 --- a/src/library/previewbuttondelegate.cpp +++ b/src/library/previewbuttondelegate.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "library/previewbuttondelegate.h" #include "library/trackmodel.h" @@ -48,7 +49,7 @@ QWidget* PreviewButtonDelegate::createEditor(QWidget *parent, QPushButton* btn = new QPushButton(parent); btn->setObjectName("LibraryPreviewButton"); btn->setCheckable(true); - btn->setFocusPolicy(Qt::ClickFocus); + btn->setFocusPolicy(Qt::NoFocus); bool playing = m_pPreviewDeckPlay->toBool(); // Check-state is whether the track is loaded (index.data()) and whether // it's playing. @@ -74,10 +75,20 @@ void PreviewButtonDelegate::setModelData(QWidget *editor, Q_UNUSED(index); } -void PreviewButtonDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const { - // Let the editor paint in this case +void PreviewButtonDelegate::paint(QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const { + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + + // Draw original item without text as background + opt.text = QString(); + const QWidget *widget = opt.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); + + // Let the editor paint the button in this case if (index == m_currentEditedCellIndex) { return; } @@ -92,10 +103,6 @@ void PreviewButtonDelegate::paint(QPainter *painter, // it's playing. m_pButton->setChecked(index.data().toBool() && playing); - if (option.state == QStyle::State_Selected) { - painter->fillRect(option.rect, option.palette.base()); - } - painter->save(); // Render button at the desired position painter->translate(option.rect.topLeft()); From 2b83603e8933441f006f7de8e24cdf22611155bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 30 Nov 2016 23:05:52 +0100 Subject: [PATCH 533/552] Do not highlight table header --- src/widget/wtracktableview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 401335937b1..27a3d50a9ae 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -269,7 +269,6 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) { setHorizontalHeader(header); header->setMovable(true); header->setClickable(true); - header->setHighlightSections(true); header->setSortIndicatorShown(m_sorting); header->setDefaultAlignment(Qt::AlignLeft); From 20e314323efccbfe9545114a64795b36cbd447be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 30 Nov 2016 23:28:58 +0100 Subject: [PATCH 534/552] Fix selection style in Treeview of LateNight --- res/skins/LateNight/style.qss | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 38f7dc98885..64dbec14bba 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1295,11 +1295,13 @@ WBaseLibrary QLabel { border: 0px solid blue; } +QTreeView::item:selected:active, QTableView::item:selected:active { color: #cfb32c; background-color: #725309; } +QTreeView::item:selected:!active, QTableView::item:selected:!active { color: #cfb32c; background-color: #4c3b11; @@ -1454,26 +1456,30 @@ WBaseLibrary QRadioButton#radioButtonRecentlyAdded { margin: 9px 3px 6px 12px; } QTreeView { margin: 0px 0px 0px 0px; } /* triangle for closed/opened branches in treeview */ -QTreeView { show-decoration-selected: 0; background-color: #151515; } /* Suppresses that selected sidebar items branch indicator shows wrong color when out of focus ; lp:880588 */ +QTreeView::branch, +QTreeView { + background-color: #0f0f0f; } /* Suppresses that selected sidebar items branch indicator shows wrong color when out of focus ; lp:880588 */ QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(skin:/style/style_branch_closed.png); +QTreeView::branch:closed:has-children:has-siblings { + border-image: none; + image: url(skin:/style/style_branch_closed.png); background-color:#0f0f0f; } QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(skin:/style/style_branch_open.png); +QTreeView::branch:open:has-children:has-siblings { + border-image: none; + image: url(skin:/style/style_branch_open.png); background-color:#0f0f0f; } QTreeView::branch:has-children:!has-siblings:closed:selected, -QTreeView::branch:closed:has-children:has-siblings:selected { border-image: none; image: url(skin:/style/style_branch_closed.png); - background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); +QTreeView::branch:closed:has-children:has-siblings:selected { + border-image: none; + image: url(skin:/style/style_branch_closed.png); } QTreeView::branch:open:has-children:!has-siblings:selected, -QTreeView::branch:open:has-children:has-siblings:selected { border-image: none; image: url(skin:/style/style_branch_open.png); - background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); -} -QTreeView::item:selected { - background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #585858, stop:1 #0f0f0f); - color: #cfb32c; +QTreeView::branch:open:has-children:has-siblings:selected { + border-image: none; + image: url(skin:/style/style_branch_open.png); } WLibrary[showFocus="0"] { From 3fe2902aeb5f36676a76d097fe2032a77d712269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 1 Dec 2016 00:23:31 +0100 Subject: [PATCH 535/552] Skip header when scrolling by up/down --- src/widget/wlibrarysidebar.cpp | 33 ++++++++++++++++++++++++--------- src/widget/wlibrarysidebar.h | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 70b148fd523..d5e77dc9a2a 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -47,7 +47,6 @@ void WSidebarItemDelegate::paint(QPainter* painter, painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); } - WLibrarySidebar::WLibrarySidebar(QWidget* parent) : QTreeView(parent), WBaseWidget(this) { @@ -122,7 +121,7 @@ void WLibrarySidebar::dragMoveEvent(QDragMoveEvent * event) { if (treeModel) { accepted = false; for (const QUrl& url : urls) { - QModelIndex destIndex = this->indexAt(event->pos()); + QModelIndex destIndex = indexAt(event->pos()); if (treeModel->dragMoveAccept(destIndex, url)) { accepted = true; break; @@ -165,7 +164,7 @@ void WLibrarySidebar::dropEvent(QDropEvent * event) { event->ignore(); } else { //Reset the selected items (if you had anything highlighted, it clears it) - //this->selectionModel()->clear(); + //selectionModel()->clear(); //Drag-and-drop from an external application or the track table widget //eg. dragging a track from Windows Explorer onto the sidebar TreeItemModel* pTreeModel = dynamic_cast(model()); @@ -186,9 +185,8 @@ void WLibrarySidebar::dropEvent(QDropEvent * event) { } } - void WLibrarySidebar::toggleSelectedItem() { - QModelIndexList selectedIndices = this->selectionModel()->selectedRows(); + QModelIndexList selectedIndices = selectionModel()->selectedRows(); if (selectedIndices.size() > 0) { QModelIndex index = selectedIndices.at(0); // Activate the item so its content shows in the main library. @@ -198,6 +196,14 @@ void WLibrarySidebar::toggleSelectedItem() { } } +bool WLibrarySidebar::isDividerSelected() { + QModelIndex current = currentIndex(); + if (current.isValid()) { + return current.data(AbstractRole::RoleDivider).toBool(); + } + return false; +} + void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { qDebug() << "WLibrarySidebar::keyPressEvent" << event; if (event == QKeySequence::Copy) { @@ -213,8 +219,7 @@ void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { // or an undo feature event->ignore(); } else if (event == QKeySequence::SelectAll) { - selectAll(); - event->accept(); + event->ignore(); } else if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && event->modifiers() == Qt::NoModifier) { toggleSelectedItem(); @@ -223,6 +228,18 @@ void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { // TODO(XXX) allow delete by key but with a safety pop up // or an undo feature event->ignore(); + } else if (event->key() == Qt::Key_Down && + event->modifiers() == Qt::NoModifier) { + QTreeView::keyPressEvent(event); + if (isDividerSelected()) { + QTreeView::keyPressEvent(event); + } + } else if (event->key() == Qt::Key_Up && + event->modifiers() == Qt::NoModifier) { + QTreeView::keyPressEvent(event); + if (isDividerSelected()) { + QTreeView::keyPressEvent(event); + } } else { // QTreeView::keyPressEvent(event) will consume all key events due to // it's keyboardSearch feature. @@ -230,8 +247,6 @@ void WLibrarySidebar::keyPressEvent(QKeyEvent* event) { // pass only some basic keys to the base class if (event->modifiers() == Qt::NoModifier) { switch (event->key()) { - case Qt::Key_Down: - case Qt::Key_Up: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Home: diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index 8d79cc9ab2d..aa0610d72b1 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -50,6 +50,7 @@ class WLibrarySidebar : public QTreeView, public WBaseWidget { private: bool paste(); + bool isDividerSelected(); QBasicTimer m_expandTimer; QModelIndex m_hoverIndex; From be6b81da6fc3c7f65cf805c28b0463afa0f75206 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Dec 2016 19:22:12 +0100 Subject: [PATCH 536/552] Remove foreach --- src/library/features/playlist/playlisttablemodel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library/features/playlist/playlisttablemodel.cpp b/src/library/features/playlist/playlisttablemodel.cpp index f1744a83fa0..a57e35d97f3 100644 --- a/src/library/features/playlist/playlisttablemodel.cpp +++ b/src/library/features/playlist/playlisttablemodel.cpp @@ -106,7 +106,7 @@ int PlaylistTableModel::addTracks(const QModelIndex& index, } QList fileInfoList; - foreach (QString fileLocation, locations) { + for (const QString& fileLocation : locations) { QFileInfo fileInfo(fileLocation); if (fileInfo.exists()) { fileInfoList.append(fileInfo); @@ -147,7 +147,7 @@ void PlaylistTableModel::removeTracks(const QModelIndexList& indices) { } QList trackPositions; - foreach (QModelIndex index, indices) { + for (const QModelIndex& index : indices) { trackPositions.append(getPosition(index)); } @@ -191,7 +191,7 @@ void PlaylistTableModel::shuffleTracks(const QModelIndexList& shuffle, const QMo } if (shuffle.count() > 1) { // if there is more then one track selected, shuffle selection only - foreach(QModelIndex shuffleIndex, shuffle) { + for (const QModelIndex& shuffleIndex : shuffle) { int oldPosition = getPosition(shuffleIndex); if (oldPosition != excludePos) { positions.append(oldPosition); From ac0098596ea56de0139197c5953f885269d0d3ff Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Dec 2016 19:33:28 +0100 Subject: [PATCH 537/552] Fix some compilation issues --- src/library/basesqltablemodel.h | 15 ++------------- .../features/playlist/playlisttablemodel.h | 2 -- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 0067d3ddd83..f64b8001a6b 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -29,23 +29,17 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { bool initialized() const { return m_bInitialized; } - TrackId getTrackId(const QModelIndex& index) const; - - void search(const QString& searchText, const QString& extraFilter = QString()) override; void setSearch(const QString& searchText, const QString& extraFilter = QString()); void onSearchStarting() override; void onSearchCleared() override; - const QString currentSearch() const; void setSort(int column, Qt::SortOrder order); - void hideTracks(const QModelIndexList& indices) override; - int fieldIndex(ColumnCache::Column column) const; - int fieldIndex(const QString& fieldName) const override; /////////////////////////////////////////////////////////////////////////// // Inherited from TrackModel /////////////////////////////////////////////////////////////////////////// + int fieldIndex(ColumnCache::Column column) const; int fieldIndex(const QString& fieldName) const final; // Methods reimplemented from QAbstractItemModel @@ -87,12 +81,7 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel { void search(const QString& searchText, const QString& extraFilter = QString()) override; const QString currentSearch() const override; QAbstractItemDelegate* delegateForColumn(const int i, QObject* pParent) override; - - /////////////////////////////////////////////////////////////////////////// - // Inherited from QAbstractItemModel - /////////////////////////////////////////////////////////////////////////// - bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; - + public slots: void select(); diff --git a/src/library/features/playlist/playlisttablemodel.h b/src/library/features/playlist/playlisttablemodel.h index 5f35813c201..56ba3d4f99f 100644 --- a/src/library/features/playlist/playlisttablemodel.h +++ b/src/library/features/playlist/playlisttablemodel.h @@ -14,7 +14,6 @@ class PlaylistTableModel : public BaseSqlTableModel { void setTableModel(int playlistId = -1); void setTableModel(const QSet& playlistIds); - void setTableModel(int playlistId = -1); int getPlaylist() const { return m_iPlaylistId; } @@ -24,7 +23,6 @@ class PlaylistTableModel : public BaseSqlTableModel { const QModelIndex& destIndex); void removeTrack(const QModelIndex& index); void shuffleTracks(const QModelIndexList& shuffle, const QModelIndex& exclude); - TrackModel::CapabilitiesFlags getCapabilities() const; void saveSelection(const QModelIndexList& selection); QModelIndexList getSavedSelectionIndices(); From f02a9969c4c2b465cdcacb77e8e59c2f89302727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 1 Dec 2016 19:58:01 +0100 Subject: [PATCH 538/552] Added new image for locked preselect button --- .../library/ic_library_lockpreselect.png | Bin 0 -> 2769 bytes res/mixxx.qrc | 1 + src/library/library.cpp | 7 ++++++- src/library/librarypanemanager.cpp | 1 + src/widget/wlibrarybreadcrumb.cpp | 8 +++++--- src/widget/wtristatebutton.cpp | 18 +++++++++++++----- 6 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 res/images/library/ic_library_lockpreselect.png diff --git a/res/images/library/ic_library_lockpreselect.png b/res/images/library/ic_library_lockpreselect.png new file mode 100644 index 0000000000000000000000000000000000000000..629097f13cbaafdb8c39b28e2fe19d2ba41ba994 GIT binary patch literal 2769 zcmZ`5cQo5=H$h5_D$!7>QMyQ|SgqATj1a44><(h@MvaoUYAdBx34#t$rDE@@YEi_f zw)Q9qsx~#NZ@-`O{r#Tj+0p>bD^ACaR2!NCN z2yy^9a??m31NwV-^4}Id1|(2_1AGt&!~;77FeocW1Q2otV~uq=zw?5R$+D^EsVIU# z+)h}`HOsrB%Tz~iOIPu@ypYSIdo8rs75kF>RzwAd=8u~5DdXA= z(UnEDwwb$}&RJHwf(r5*K7_B02K-MgG1rS&8fu=C-_4;S6M8qBccgx=Q4kC4*g*Mr zapxXRBcLLXb-e{7?`El7nS!c5;XO+&<2O6P_=2=xe_OJA*-Pb?{3y!ovx`DE#9r_h zjYOn{#%#^`Ha{i#;;P?R=rlQAZi$UASwj)S#-kQ~*hs#Oeg8DlNih}+9hPkBDXC^I z`HWUl;5d!NjmBMDwpfFOWA&_SdS^{5PF`EoPT7B3(pmCS5*+>SXNeabzm@WIZ#VFz zae3R#MHo| zRtK3jK9)VzG%r#)HBc&Yf@ficoFfIK5w1qxC(#-)_7s0BW$jkrhSp^$@6dkhvh=)TM7Mm#?K~x`i_J z`su^4bO55?7SS>udGO?DT5(fSVM^_LOUdelh!?)Ip0*I2IE%yzB7F^p_b5Zcv+)|C z>2Vp&2wX1fhM$sGw)Ryo>{!6IEU~tXxm2xspd|2&=aR}t4NvuPZ$sMT{DpFOzmp4g z4}^G9ll?^h?t6gohM@QqUbTN%jsk@oO)0ODKDBHxuuxzmP;F#qf`a4TDO`Vm=|EpzciMorz#SZ?jtK%(nf zw{#&J<`8#eHAGTgl88APT{d;50(#jSXXZu%R^oF=1^l-8*+->RCVG=8y^5Y}H2aZf zmeL>j5_Q%4YK}xKEw3{-hltv6^sAK0N&d4vS7q}j`kLk<+3gs#Y1!d>jHF~z+db5m zhn#3BXxkqYzyd{U=DBXiNrOWkdq{4EdBAEE3pAzGp?yCvua7H&HF4%U-0pIeM5peP zjiRcaI{w2BhRdvWT4kh_f~`V4S& z2A`|b$F^0m9eL#Q#}t$K!^{%BY{K>l(0+;xquVkAaLM6xc>ENJbCjK7WwkL*=_DmON2MAiPQ*qpxD9KpR+926om6XZG232I(n{| zRH^o65s7~Jbm3i&aKDIQQSwG2q6j4d`v-Xnl<;l3c?t8t3}kcotZdfpyNyywHwy!z zai$!H0yl|yo&);!SR)F%}wBQt{c=`fy#BQLd{bZ! zz?2IdlicA&e5MYpFm+b&sxeyu&!Fzs==7!}X~W_5f+@$7=wgusDhWh+y@Om?Q6^qT{Ws6pZi(H;-GZ)`8E3<$P!BqGEjU z0^*%V+bh^nzIQj7T_mB4*Vnqk+H}ru6v()RJPvyPo9L!jR(1Ce?&pEanuT9vy!9<| z;Pm39%G3-rZZ__RHQ}UpN4CWCvEzF=g8p``usv!?jYVL=N{k=(h6dh;_ngDNQ|~g1 zApYGYQt4iLS?`7qtxvP%+WZEQ*xy_*6#mc@i_IU)C5BXt>h9&h{TtAD)|L{jowctw zLu>!&WWP!E-!jWd9kjDE%oZ7v$r{z0o;wRO`u{X2h?N%fYN0eRmwW?(K(e+I6W*%A zFK$IW7E5;Bc@*H-Y{0b(1E$Hj71uf$NK;IxY`}#N@($DSJwg!^{0GRerYq}|tj8y^ z9?F%t|EiuC=HW6^$H<31O6z=#$_(vqc=RIjf|qEhjgbX(7dGiOI2y36>XYg16{0vF zvK{~{k)s%NlPCHzAyPtch(<> z=PJkg&5$iDP*cl9y|+ofT%;=ul`Vl(R`FYNAFuSt`uDTAG=AC5!>FOy>x9g z-+K%CruPgNut4;bXINO|wv;i)&G$)=1_I9||J@1VI-;aQXsIbat!14*g>Y89mwO#K24|LuwmjD0& literal 0 HcmV?d00001 diff --git a/res/mixxx.qrc b/res/mixxx.qrc index f52d71e5e96..d2f8c4412e4 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -116,6 +116,7 @@ skins/save_disabled.png images/library/ic_library_preselect.png images/library/ic_library_notpreselect.png + images/library/ic_library_lockpreselect.png images/library/ic_library_pinned.png diff --git a/src/library/library.cpp b/src/library/library.cpp index b830f7909ab..3d0d4d4f128 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -696,8 +696,13 @@ void Library::handleFocus() { void Library::handlePreselection() { for (LibraryPaneManager* pPane : m_panes) { + + pPane->setPreselected(false); pPane->setPreviewed(false); + + + } LibraryPaneManager* pSelectedPane = m_panes.value(m_preselectedPane); if (pSelectedPane) { @@ -705,7 +710,7 @@ void Library::handlePreselection() { } else { pSelectedPane = m_panes.value(m_previewPreselectedPane); if (pSelectedPane) { - pSelectedPane->setPreselected(true); + pSelectedPane->setPreviewed(true); } } } diff --git a/src/library/librarypanemanager.cpp b/src/library/librarypanemanager.cpp index eede9c26f6d..8e5ad4ad5e2 100644 --- a/src/library/librarypanemanager.cpp +++ b/src/library/librarypanemanager.cpp @@ -159,6 +159,7 @@ void LibraryPaneManager::setPreviewed(bool value) { } void LibraryPaneManager::slotPanePreselected(bool value) { + // Preselect button clicked setPreselected(value); m_pLibrary->panePreselected(this, value); } diff --git a/src/widget/wlibrarybreadcrumb.cpp b/src/widget/wlibrarybreadcrumb.cpp index a5c82a8bdb7..b9260fbf7f2 100644 --- a/src/widget/wlibrarybreadcrumb.cpp +++ b/src/widget/wlibrarybreadcrumb.cpp @@ -18,14 +18,16 @@ WLibraryBreadCrumb::WLibraryBreadCrumb(QWidget* parent) layout->addWidget(m_pIcon); layout->addWidget(m_pText); - QPixmap preOn(WPixmapStore::getLibraryPixmap( + QPixmap preHovered(WPixmapStore::getLibraryPixmap( ":/images/library/ic_library_preselect.png")); QPixmap preOff(WPixmapStore::getLibraryPixmap( ":/images/library/ic_library_notpreselect.png")); + QPixmap preLock(WPixmapStore::getLibraryPixmap( + ":/images/library/ic_library_lockpreselect.png")); - m_preselectIcon.addPixmap(preOn, QIcon::Normal, QIcon::On); + m_preselectIcon.addPixmap(preLock, QIcon::Normal, QIcon::On); m_preselectIcon.addPixmap(preOff, QIcon::Normal, QIcon::Off); - m_preselectIcon.addPixmap(preOn, QIcon::Active, QIcon::Off); + m_preselectIcon.addPixmap(preHovered, QIcon::Active, QIcon::Off); m_pPreselectButton->setIcon(m_preselectIcon); m_pPreselectButton->setChecked(m_preselected); m_pPreselectButton->setFocusPolicy(Qt::ClickFocus); diff --git a/src/widget/wtristatebutton.cpp b/src/widget/wtristatebutton.cpp index cce9237918f..a75a52c307a 100644 --- a/src/widget/wtristatebutton.cpp +++ b/src/widget/wtristatebutton.cpp @@ -1,5 +1,5 @@ #include "wtristatebutton.h" - +#include WTriStateButton::WTriStateButton(QWidget* parent) : QToolButton(parent), @@ -8,8 +8,10 @@ WTriStateButton::WTriStateButton(QWidget* parent) } void WTriStateButton::setChecked(bool value) { - m_state = value ? State::Active : State::Unactive; - updateButton(); + qDebug() << this << "setChecked" << value; + // This omits the Hovered state + State state = value ? State::Active : State::Unactive; + setState(state); } bool WTriStateButton::isChecked() const { @@ -17,6 +19,7 @@ bool WTriStateButton::isChecked() const { } void WTriStateButton::setState(State state) { + if (state == m_state) return; m_state = state; updateButton(); } @@ -26,8 +29,9 @@ WTriStateButton::State WTriStateButton::getState() const { } void WTriStateButton::setHovered(bool value) { - m_state = value ? State::Hovered : State::Unactive; - updateButton(); + qDebug() << this << "setHovered" << value; + State state = value ? State::Hovered : State::Unactive; + setState(state); } void WTriStateButton::setIcon(const QIcon& icon) { @@ -40,13 +44,17 @@ void WTriStateButton::updateButton() { switch (m_state) { case State::Unactive: pix = m_icon.pixmap(height(), QIcon::Normal, QIcon::Off); + QToolButton::setChecked(false); break; case State::Active: pix = m_icon.pixmap(height(), QIcon::Normal, QIcon::On); + QToolButton::setChecked(true); break; case State::Hovered: pix = m_icon.pixmap(height(), QIcon::Active, QIcon::Off); + QToolButton::setChecked(false); break; } + QToolButton::setIcon(QIcon(pix)); } From 645cd289af6943d3e4e727f556e3c2cfe795d028 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 1 Dec 2016 21:22:31 +0100 Subject: [PATCH 539/552] Fix build --- src/library/features/playlist/playlisttablemodel.cpp | 6 ++++-- src/library/features/playlist/playlisttablemodel.h | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/library/features/playlist/playlisttablemodel.cpp b/src/library/features/playlist/playlisttablemodel.cpp index a57e35d97f3..63cb817b990 100644 --- a/src/library/features/playlist/playlisttablemodel.cpp +++ b/src/library/features/playlist/playlisttablemodel.cpp @@ -138,7 +138,8 @@ void PlaylistTableModel::removeTrack(const QModelIndex& index) { return; } - m_playlistDao.removeTrackFromPlaylist(m_iPlaylistId, getPosition(index)); + m_pTrackCollection->getPlaylistDAO() + .removeTrackFromPlaylist(m_iPlaylistId, getPosition(index)); } void PlaylistTableModel::removeTracks(const QModelIndexList& indices) { @@ -151,7 +152,8 @@ void PlaylistTableModel::removeTracks(const QModelIndexList& indices) { trackPositions.append(getPosition(index)); } - m_playlistDao.removeTracksFromPlaylist(m_iPlaylistId, trackPositions); + m_pTrackCollection->getPlaylistDAO() + .removeTracksFromPlaylist(m_iPlaylistId, trackPositions); } void PlaylistTableModel::moveTrack(const QModelIndex& sourceIndex, diff --git a/src/library/features/playlist/playlisttablemodel.h b/src/library/features/playlist/playlisttablemodel.h index 56ba3d4f99f..0e5ae2d6c9c 100644 --- a/src/library/features/playlist/playlisttablemodel.h +++ b/src/library/features/playlist/playlisttablemodel.h @@ -46,7 +46,6 @@ class PlaylistTableModel : public BaseSqlTableModel { int getPosition(const QModelIndex& index); - PlaylistDAO& m_playlistDao; int m_iPlaylistId; QSet m_playlistIds; bool m_showAll; From 755afc49e980b2cd9edbec701534c30ccf86cd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 1 Dec 2016 22:05:59 +0100 Subject: [PATCH 540/552] LibrarySidebarExpanden now moved the preselected button as well --- .../baseplaylist/baseplaylistfeature.cpp | 6 +++--- src/library/features/crates/cratefeature.cpp | 4 ++-- .../maintenance/maintenancefeature.cpp | 4 ++-- src/library/library.cpp | 9 ++++++++ src/library/libraryfeature.cpp | 17 +++++++++++---- src/library/libraryfeature.h | 10 +++++++++ src/widget/wlibrarysidebar.cpp | 21 +++++++++++++++++++ src/widget/wlibrarysidebar.h | 9 ++++++++ 8 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index a4adc258a7b..ecf74c83acf 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -130,8 +130,8 @@ void BasePlaylistFeature::activate() { m_featurePane = preselectedPane; } - auto modelIt = m_lastChildClicked.find(m_featurePane); - if (modelIt != m_lastChildClicked.end() && (*modelIt).isValid()) { + auto modelIt = m_lastChildClicked.constFind(m_featurePane); + if (modelIt != m_lastChildClicked.constEnd() && (*modelIt).isValid()) { qDebug() << "BasePlaylistFeature::activate" << "m_lastChildClicked found"; // Open last clicked Playlist in the preselectded pane activateChild(*modelIt); @@ -151,7 +151,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { m_featurePane = preselectedPane; } - if (index == m_lastChildClicked[m_featurePane]) { + if (index == m_lastChildClicked.value(m_featurePane)) { restoreSearch(""); showTable(m_featurePane); switchToFeature(); diff --git a/src/library/features/crates/cratefeature.cpp b/src/library/features/crates/cratefeature.cpp index 253941efb7c..34798c0e13f 100644 --- a/src/library/features/crates/cratefeature.cpp +++ b/src/library/features/crates/cratefeature.cpp @@ -224,8 +224,8 @@ void CrateFeature::activate() { m_featurePane = preselectedPane; } - auto modelIt = m_lastClickedIndex.find(m_featurePane); - if (modelIt != m_lastClickedIndex.end() && (*modelIt).isValid()) { + auto modelIt = m_lastClickedIndex.constFind(m_featurePane); + if (modelIt != m_lastClickedIndex.constEnd() && (*modelIt).isValid()) { activateChild(*modelIt); return; } diff --git a/src/library/features/maintenance/maintenancefeature.cpp b/src/library/features/maintenance/maintenancefeature.cpp index 5d42030d3b5..c6a921e6ad3 100644 --- a/src/library/features/maintenance/maintenancefeature.cpp +++ b/src/library/features/maintenance/maintenancefeature.cpp @@ -56,8 +56,8 @@ void MaintenanceFeature::selectionChanged(const QItemSelection&, return; } - auto it = m_idPaneCurrent.find(m_featurePane); - if (it == m_idPaneCurrent.end()) { + auto it = m_idPaneCurrent.constFind(m_featurePane); + if (it == m_idPaneCurrent.constEnd()) { return; } diff --git a/src/library/library.cpp b/src/library/library.cpp index 87f7f31e7ae..9c0e04ee62c 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -208,6 +208,15 @@ void Library::addFeature(LibraryFeature* feature) { this, SIGNAL(enableCoverArtDisplay(bool))); connect(feature, SIGNAL(trackSelected(TrackPointer)), this, SIGNAL(trackSelected(TrackPointer))); + + connect(feature, SIGNAL(hovered(LibraryFeature*)), + this, SLOT(slotSetHoveredFeature(LibraryFeature*))); + connect(feature, SIGNAL(leaved(LibraryFeature*)), + this, SLOT(slotResetHoveredFeature(LibraryFeature*))); + connect(feature, SIGNAL(focusIn(LibraryFeature*)), + this, SLOT(slotSetFocusedFeature(LibraryFeature*))); + connect(feature, SIGNAL(focusOut(LibraryFeature*)), + this, SLOT(slotResetFocusedFeature(LibraryFeature*))); } void Library::switchToFeature(LibraryFeature* pFeature) { diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index c09335854ac..037b9775d84 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -230,12 +230,21 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* connect(this, SIGNAL(selectIndex(const QModelIndex&)), pSidebar, SLOT(selectIndex(const QModelIndex&))); + connect(pSidebar, SIGNAL(hovered()), + this, SLOT(slotSetHoveredSidebar())); + connect(pSidebar, SIGNAL(leaved()), + this, SLOT(slotResetHoveredSidebar())); + connect(pSidebar, SIGNAL(focusIn()), + this, SLOT(slotSetFocusedSidebar())); + connect(pSidebar, SIGNAL(focusOut()), + this, SLOT(slotResetFocusedSidebar())); + return pSidebar; } void LibraryFeature::showTrackModel(QAbstractItemModel *model) { - auto it = m_trackTablesByPaneId.find(m_featurePane); - if (it == m_trackTablesByPaneId.end() || it->isNull()) { + auto it = m_trackTablesByPaneId.constFind(m_featurePane); + if (it == m_trackTablesByPaneId.constEnd() || it->isNull()) { return; } (*it)->loadTrackModel(model); @@ -272,8 +281,8 @@ void LibraryFeature::showBreadCrumb() { } WTrackTableView* LibraryFeature::getFocusedTable() { - auto it = m_trackTablesByPaneId.find(m_featurePane); - if (it == m_trackTablesByPaneId.end() || it->isNull()) { + auto it = m_trackTablesByPaneId.constFind(m_featurePane); + if (it == m_trackTablesByPaneId.constEnd() || it->isNull()) { return nullptr; } return *it; diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 6a4104f1331..3eb21ca6f44 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -98,6 +98,11 @@ class LibraryFeature : public QObject { virtual void onSearch(const QString&) {} + void slotSetHoveredSidebar() { emit hovered(this); }; + void slotResetHoveredSidebar() { emit leaved(this); }; + void slotSetFocusedSidebar() { emit focusIn(this); }; + void slotResetFocusedSidebar() { emit focusOut(this); }; + signals: void loadTrack(TrackPointer); @@ -115,6 +120,11 @@ class LibraryFeature : public QObject { void enableCoverArtDisplay(bool); void trackSelected(TrackPointer); + void hovered(LibraryFeature* pLibraryFeature); + void leaved(LibraryFeature* pLibraryFeature); + void focusIn(LibraryFeature* pLibraryFeature); + void focusOut(LibraryFeature* pLibraryFeature); + protected slots: void restoreSaveButton(); diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index d5e77dc9a2a..5d1581bf4ae 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -328,3 +328,24 @@ bool WLibrarySidebar::paste() { return pTreeModel->dropAccept(destIndex, pMimeData->urls(), nullptr); } + +void WLibrarySidebar::enterEvent(QEvent* pEvent) { + QTreeView::enterEvent(pEvent); + emit(hovered()); +} + +void WLibrarySidebar::leaveEvent(QEvent* pEvent) { + QTreeView::leaveEvent(pEvent); + emit(leaved()); +} + +void WLibrarySidebar::focusInEvent(QFocusEvent* pEvent) { + QTreeView::focusInEvent(pEvent); + emit(focusIn()); +} + +void WLibrarySidebar::focusOutEvent(QFocusEvent* pEvent) { + QTreeView::focusOutEvent(pEvent); + emit(focusOut()); +} + diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index aa0610d72b1..49071a26a33 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -45,8 +45,17 @@ class WLibrarySidebar : public QTreeView, public WBaseWidget { signals: void rightClicked(const QPoint&, const QModelIndex&); + void hovered(); + void leaved(); + void focusIn(); + void focusOut(); + protected: bool event(QEvent* pEvent) override; + void enterEvent(QEvent*) override; + void leaveEvent(QEvent*) override; + void focusInEvent(QFocusEvent*) override; + void focusOutEvent(QFocusEvent*) override; private: bool paste(); From 0cb8452e0c7cc9e2221ea1f3b1b7e5dfee90ca78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 1 Dec 2016 23:26:01 +0100 Subject: [PATCH 541/552] joined featurePane and SavedPane, this allows better control for the plylist panes --- .../baseplaylist/baseplaylistfeature.cpp | 14 +++----- .../baseplaylist/baseplaylistfeature.h | 2 +- src/library/features/crates/cratefeature.cpp | 10 ++---- src/library/library.cpp | 33 ++++++++----------- src/library/libraryfeature.cpp | 23 ++++++------- src/library/libraryfeature.h | 8 ++--- 6 files changed, 32 insertions(+), 58 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index ecf74c83acf..7634e81590c 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -125,10 +125,7 @@ QPointer BasePlaylistFeature::getPlaylistTableModel(int pane } void BasePlaylistFeature::activate() { - int preselectedPane = getPreselectedPane(); - if (preselectedPane >= 0) { - m_featurePane = preselectedPane; - } + adoptPreselectedPane(); auto modelIt = m_lastChildClicked.constFind(m_featurePane); if (modelIt != m_lastChildClicked.constEnd() && (*modelIt).isValid()) { @@ -146,10 +143,7 @@ void BasePlaylistFeature::activate() { } void BasePlaylistFeature::activateChild(const QModelIndex& index) { - int preselectedPane = getPreselectedPane(); - if (preselectedPane >= 0) { - m_featurePane = preselectedPane; - } + adoptPreselectedPane(); if (index == m_lastChildClicked.value(m_featurePane)) { restoreSearch(""); @@ -317,9 +311,9 @@ void BasePlaylistFeature::slotCreatePlaylist() { } } -void BasePlaylistFeature::setFeaturePane(int focus) { +void BasePlaylistFeature::setFeaturePaneId(int focus) { m_pPlaylistTableModel = getPlaylistTableModel(focus); - LibraryFeature::setFeaturePane(focus); + LibraryFeature::setFeaturePaneId(focus); } void BasePlaylistFeature::slotDeletePlaylist() { diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index e19901ca18e..b4369c1f520 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -50,7 +50,7 @@ class BasePlaylistFeature : public LibraryFeature { virtual void slotPlaylistContentChanged(int playlistId) = 0; virtual void slotPlaylistTableRenamed(int playlistId, QString a_strName) = 0; void slotCreatePlaylist(); - void setFeaturePane(int focus); + void setFeaturePaneId(int focus); protected slots: void slotDeletePlaylist(); diff --git a/src/library/features/crates/cratefeature.cpp b/src/library/features/crates/cratefeature.cpp index 34798c0e13f..37de08595c5 100644 --- a/src/library/features/crates/cratefeature.cpp +++ b/src/library/features/crates/cratefeature.cpp @@ -219,10 +219,7 @@ TreeItemModel* CrateFeature::getChildModel() { } void CrateFeature::activate() { - int preselectedPane = getPreselectedPane(); - if (preselectedPane >= 0) { - m_featurePane = preselectedPane; - } + adoptPreselectedPane(); auto modelIt = m_lastClickedIndex.constFind(m_featurePane); if (modelIt != m_lastClickedIndex.constEnd() && (*modelIt).isValid()) { @@ -237,10 +234,7 @@ void CrateFeature::activate() { } void CrateFeature::activateChild(const QModelIndex& index) { - int preselectedPane = getPreselectedPane(); - if (preselectedPane >= 0) { - m_featurePane = preselectedPane; - } + adoptPreselectedPane(); m_lastClickedIndex[m_featurePane] = index; int crateId = crateIdFromIndex(index); diff --git a/src/library/library.cpp b/src/library/library.cpp index 9c0e04ee62c..dbb33819e1a 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -175,7 +175,7 @@ void Library::destroyInterface() { } for (LibraryFeature* f : m_features) { - f->setFeaturePane(-1); + f->setFeaturePaneId(-1); } m_panes.clear(); } @@ -296,7 +296,7 @@ void Library::paneFocused(LibraryPaneManager* pPane) { if (pPane != m_pSidebarExpanded) { m_focusedPaneId = pPane->getPaneId(); - pPane->getCurrentFeature()->setFeaturePane(m_focusedPaneId); + pPane->getCurrentFeature()->setFeaturePaneId(m_focusedPaneId); DEBUG_ASSERT_AND_HANDLE(m_focusedPaneId != -1) { return; } @@ -355,15 +355,14 @@ void Library::onSkinLoadFinished() { first = false; // Set the first pane as saved pane to all features for (LibraryFeature* pFeature : m_features) { - pFeature->setSavedPane(m_preselectedPane); + pFeature->setFeaturePaneId(m_preselectedPane); } } m_savedFeatures[m_preselectedPane] = *itF; (*itP)->setCurrentFeature(*itF); - (*itF)->setFeaturePane(m_preselectedPane); - (*itF)->setSavedPane(m_preselectedPane); + (*itF)->setFeaturePaneId(m_preselectedPane); (*itF)->activate(); ++itP; @@ -373,7 +372,7 @@ void Library::onSkinLoadFinished() { // The first pane always shows the Mixxx Library feature on start m_preselectedPane = m_focusedPaneId = m_panes.begin().key(); handleFocus(); - (*m_features.begin())->setFeaturePane(m_preselectedPane); + (*m_features.begin())->setFeaturePaneId(m_preselectedPane); slotActivateFeature(*m_features.begin()); } else { @@ -493,14 +492,14 @@ void Library::paneUncollapsed(int paneId) { if (pFeature == nullptr) { return; } - pFeature->setFeaturePane(pPane->getPaneId()); + pFeature->setFeaturePaneId(pPane->getPaneId()); for (LibraryPaneManager* pPane : m_panes) { int auxId = pPane->getPaneId(); if (auxId != paneId && pFeature == pPane->getCurrentFeature()) { LibraryFeature* pSaved = m_savedFeatures[auxId]; pPane->switchToFeature(pSaved); - pSaved->setFeaturePane(auxId); + pSaved->setFeaturePaneId(auxId); pSaved->activate(); } } @@ -510,14 +509,13 @@ void Library::slotActivateFeature(LibraryFeature* pFeature) { int selectedPane = m_preselectedPane; if (selectedPane < 0) { // No pane is preselected, use the saved pane instead - selectedPane = pFeature->getSavedPane(); + selectedPane = pFeature->getFeaturePaneId(); } bool featureActivated = false; LibraryPaneManager* pSelectedPane = m_panes.value(selectedPane); if (pSelectedPane) { - pFeature->setSavedPane(selectedPane); - pFeature->setFeaturePane(selectedPane); + pFeature->setFeaturePaneId(selectedPane); if (pSelectedPane->getCurrentFeature() != pFeature) { pSelectedPane->setCurrentFeature(pFeature); @@ -556,14 +554,14 @@ void Library::slotSetTrackTableRowHeight(int rowHeight) { void Library::slotSetHoveredFeature(LibraryFeature* pFeature) { m_hoveredFeature = pFeature; - m_previewPreselectedPane = pFeature->getSavedPane(); + m_previewPreselectedPane = pFeature->getFeaturePaneId(); handlePreselection(); } void Library::slotResetHoveredFeature(LibraryFeature* pFeature) { if (pFeature == m_hoveredFeature) { if (m_focusedFeature) { - m_previewPreselectedPane = m_focusedFeature->getSavedPane(); + m_previewPreselectedPane = m_focusedFeature->getFeaturePaneId(); } else { m_previewPreselectedPane = -1; } @@ -574,14 +572,14 @@ void Library::slotResetHoveredFeature(LibraryFeature* pFeature) { void Library::slotSetFocusedFeature(LibraryFeature* pFeature) { m_focusedFeature = pFeature; - m_previewPreselectedPane = pFeature->getSavedPane(); + m_previewPreselectedPane = pFeature->getFeaturePaneId(); handlePreselection(); } void Library::slotResetFocusedFeature(LibraryFeature* pFeature) { if (pFeature == m_focusedFeature) { if (m_hoveredFeature) { - m_previewPreselectedPane = m_hoveredFeature->getSavedPane(); + m_previewPreselectedPane = m_hoveredFeature->getFeaturePaneId(); } else { m_previewPreselectedPane = -1; } @@ -707,13 +705,8 @@ void Library::handleFocus() { void Library::handlePreselection() { for (LibraryPaneManager* pPane : m_panes) { - - pPane->setPreselected(false); pPane->setPreviewed(false); - - - } LibraryPaneManager* pSelectedPane = m_panes.value(m_preselectedPane); if (pSelectedPane) { diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 037b9775d84..4e0b3076f6a 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -36,8 +36,7 @@ LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, m_pLibrary(pLibrary), m_pTrackCollection(pTrackCollection), m_savedDAO(m_pTrackCollection->getSavedQueriesDAO()), - m_featurePane(-1), - m_savedPane(-1) { + m_featurePane(-1) { } LibraryFeature::~LibraryFeature() { @@ -104,7 +103,7 @@ QWidget *LibraryFeature::createSidebarWidget(KeyboardEventFilter* pKeyboard) { return pContainer; } -void LibraryFeature::setFeaturePane(int paneId) { +void LibraryFeature::setFeaturePaneId(int paneId) { m_featurePane = paneId; } @@ -112,20 +111,18 @@ int LibraryFeature::getFeaturePaneId() { return m_featurePane; } -void LibraryFeature::setSavedPane(int paneId) { - m_savedPane = paneId; -} - -int LibraryFeature::getSavedPane() { - return m_savedPane; -} - int LibraryFeature::getFocusedPane() { return m_pLibrary->getFocusedPaneId(); } -int LibraryFeature::getPreselectedPane() { - return m_pLibrary->getPreselectedPaneId(); +void LibraryFeature::adoptPreselectedPane() { + int preselectedPane = m_pLibrary->getPreselectedPaneId(); + if (preselectedPane >= 0 && + m_featurePane != preselectedPane) { + m_featurePane = preselectedPane; + // Refresh preselect button + emit focusIn(this); + } } SavedSearchQuery LibraryFeature::saveQuery(SavedSearchQuery sQuery) { diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index 3eb21ca6f44..f508b4b04c2 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -69,14 +69,11 @@ class LibraryFeature : public QObject { virtual TreeItemModel* getChildModel() = 0; - virtual void setFeaturePane(int paneId); + virtual void setFeaturePaneId(int paneId); int getFeaturePaneId(); - void setSavedPane(int paneId); - int getSavedPane(); - int getFocusedPane(); - int getPreselectedPane(); + void adoptPreselectedPane(); virtual SavedSearchQuery saveQuery(SavedSearchQuery sQuery); virtual void restoreQuery(int id); @@ -167,7 +164,6 @@ class LibraryFeature : public QObject { SavedQueriesDAO& m_savedDAO; int m_featurePane; - int m_savedPane; private: QStringList getPlaylistFiles(QFileDialog::FileMode mode); From d05ec063834f2d884f6438a1d5db1608cf3006d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 2 Dec 2016 21:37:30 +0100 Subject: [PATCH 542/552] Invalidate stored Index when skin is changing, fixes a crasher. --- .../features/baseplaylist/baseplaylistfeature.cpp | 4 ++++ src/library/features/baseplaylist/baseplaylistfeature.h | 6 ++++-- src/library/features/crates/cratefeature.cpp | 6 +++++- src/library/features/crates/cratefeature.h | 9 +++++---- .../features/mixxxlibrary/mixxxlibraryfeature.cpp | 6 ++++++ src/library/features/mixxxlibrary/mixxxlibraryfeature.h | 5 +++-- src/library/libraryfeature.cpp | 2 ++ src/library/libraryfeature.h | 2 ++ 8 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index 7634e81590c..77bc8864ddc 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -172,6 +172,10 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { } } +void BasePlaylistFeature::invalidateChild() { + m_lastChildClicked.clear(); +} + void BasePlaylistFeature::activatePlaylist(int playlistId) { //qDebug() << "BasePlaylistFeature::activatePlaylist()" << playlistId; if (playlistId != -1 && m_pPlaylistTableModel) { diff --git a/src/library/features/baseplaylist/baseplaylistfeature.h b/src/library/features/baseplaylist/baseplaylistfeature.h index b4369c1f520..35c6b8cd773 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.h +++ b/src/library/features/baseplaylist/baseplaylistfeature.h @@ -41,8 +41,10 @@ class BasePlaylistFeature : public LibraryFeature { void analyzeTracks(QList); public slots: - virtual void activate(); - virtual void activateChild(const QModelIndex& index); + void activate() override; + void activateChild(const QModelIndex& index) override; + void invalidateChild() override; + virtual void activatePlaylist(int playlistId); virtual void htmlLinkClicked(const QUrl& link); diff --git a/src/library/features/crates/cratefeature.cpp b/src/library/features/crates/cratefeature.cpp index 37de08595c5..0d938b1cdd2 100644 --- a/src/library/features/crates/cratefeature.cpp +++ b/src/library/features/crates/cratefeature.cpp @@ -250,6 +250,10 @@ void CrateFeature::activateChild(const QModelIndex& index) { showTrackModel(m_pCrateTableModel); } +void CrateFeature::invalidateChild() { + m_lastClickedIndex.clear(); +} + void CrateFeature::activateCrate(int crateId) { //qDebug() << "CrateFeature::activateCrate()" << crateId; m_pCrateTableModel = getTableModel(m_featurePane); @@ -274,7 +278,7 @@ void CrateFeature::onRightClick(const QPoint& globalPos) { menu.exec(globalPos); } -void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { +void CrateFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex& index) { //Save the model index so we can get it in the action slots... m_lastRightClickedIndex = index; int crateId = crateIdFromIndex(index); diff --git a/src/library/features/crates/cratefeature.h b/src/library/features/crates/cratefeature.h index 23817f0d7fb..85fce0a7dab 100644 --- a/src/library/features/crates/cratefeature.h +++ b/src/library/features/crates/cratefeature.h @@ -51,11 +51,12 @@ class CrateFeature : public LibraryFeature { void analyzeTracks(QList); public slots: - void activate(); - void activateChild(const QModelIndex& index); + void activate() override; + void activateChild(const QModelIndex& index) override; + void invalidateChild() override; void activateCrate(int crateId); - void onRightClick(const QPoint& globalPos); - void onRightClickChild(const QPoint& globalPos, QModelIndex index); + void onRightClick(const QPoint& globalPos) override; + void onRightClickChild(const QPoint& globalPos, const QModelIndex& index) override; void slotCreateCrate(); void slotDeleteCrate(); diff --git a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp index 91046654973..8063148142f 100644 --- a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp @@ -194,6 +194,8 @@ void MixxxLibraryFeature::activate() { void MixxxLibraryFeature::activateChild(const QModelIndex& index) { m_lastClickedIndex = index; + if (!index.isValid()) return; + QString query = index.data(AbstractRole::RoleQuery).toString(); //qDebug() << "MixxxLibraryFeature::activateChild" << query; @@ -209,6 +211,10 @@ void MixxxLibraryFeature::activateChild(const QModelIndex& index) { restoreSearch(query); } +void MixxxLibraryFeature::invalidateChild() { + m_lastClickedIndex = QModelIndex(); +} + void MixxxLibraryFeature::onRightClickChild(const QPoint& pos, const QModelIndex&) { diff --git a/src/library/features/mixxxlibrary/mixxxlibraryfeature.h b/src/library/features/mixxxlibrary/mixxxlibraryfeature.h index ae6ba93edd5..eb3d5cd4e95 100644 --- a/src/library/features/mixxxlibrary/mixxxlibraryfeature.h +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.h @@ -51,9 +51,10 @@ class MixxxLibraryFeature : public LibraryFeature { QWidget* createInnerSidebarWidget(KeyboardEventFilter* pKeyboard) override; public slots: - void activate(); - void activateChild(const QModelIndex& index); + void activate() override; + void activateChild(const QModelIndex& index) override; void onRightClickChild(const QPoint& pos, const QModelIndex&) override; + void invalidateChild() override; void refreshLibraryModels(); void onSearch(const QString&) override; diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index 4e0b3076f6a..c6de94972b3 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -215,6 +215,8 @@ WLibrarySidebar* LibraryFeature::createLibrarySidebarWidget(KeyboardEventFilter* pMiniView->setTreeView(pSidebar); pMiniView->setModel(pModel); pSidebar->setVerticalScrollBar(pMiniView); + // invalidate probably stored QModelIndex + invalidateChild(); connect(pSidebar, SIGNAL(pressed(const QModelIndex&)), this, SLOT(activateChild(const QModelIndex&))); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index f508b4b04c2..5f38dfac1ca 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -84,6 +84,8 @@ class LibraryFeature : public QObject { virtual void activate() = 0; // called when you single click on a child item, e.g., a concrete playlist or crate virtual void activateChild(const QModelIndex&) {} + // called when the QModelIndex passed by activateChild() becomes invalid. + virtual void invalidateChild() {} // called when you right click on the root item virtual void onRightClick(const QPoint&) {} // called when you right click on a child item, e.g., a concrete playlist or crate From 79d4876da1a9d5c885cbba0b3047e06b50174ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 2 Dec 2016 22:06:27 +0100 Subject: [PATCH 543/552] Fix invalid restoreSearch during skin setup --- src/library/libraryfeature.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index c6de94972b3..c4f21c3c574 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -259,7 +259,9 @@ void LibraryFeature::restoreSearch(const QString& search) { } void LibraryFeature::restoreSaveButton() { - m_pLibrary->restoreSaveButton(m_featurePane); + if (m_featurePane >= 0) { + m_pLibrary->restoreSaveButton(m_featurePane); + } } void LibraryFeature::showBreadCrumb(TreeItem *pTree) { From 4e974158af20f44217cd96afc380b327eb1bc6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 2 Dec 2016 22:36:02 +0100 Subject: [PATCH 544/552] Avoid to create the library base track chache twice. --- .../mixxxlibrary/mixxxlibraryfeature.cpp | 78 ++----------------- src/library/library.cpp | 69 ++++++++++++++++ src/library/library.h | 1 + 3 files changed, 77 insertions(+), 71 deletions(-) diff --git a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp index 8063148142f..7195129a18d 100644 --- a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp @@ -41,86 +41,22 @@ MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, TrackCollection* pTrackCollection) : LibraryFeature(pConfig, pLibrary, pTrackCollection, parent), m_trackDao(pTrackCollection->getTrackDAO()) { - QStringList columns; - columns << "library." + LIBRARYTABLE_ID - << "library." + LIBRARYTABLE_PLAYED - << "library." + LIBRARYTABLE_TIMESPLAYED - //has to be up here otherwise Played and TimesPlayed are not show - << "library." + LIBRARYTABLE_ALBUMARTIST - << "library." + LIBRARYTABLE_ALBUM - << "library." + LIBRARYTABLE_ARTIST - << "library." + LIBRARYTABLE_TITLE - << "library." + LIBRARYTABLE_YEAR - << "library." + LIBRARYTABLE_RATING - << "library." + LIBRARYTABLE_GENRE - << "library." + LIBRARYTABLE_COMPOSER - << "library." + LIBRARYTABLE_GROUPING - << "library." + LIBRARYTABLE_TRACKNUMBER - << "library." + LIBRARYTABLE_KEY - << "library." + LIBRARYTABLE_KEY_ID - << "library." + LIBRARYTABLE_BPM - << "library." + LIBRARYTABLE_BPM_LOCK - << "library." + LIBRARYTABLE_DURATION - << "library." + LIBRARYTABLE_BITRATE - << "library." + LIBRARYTABLE_REPLAYGAIN - << "library." + LIBRARYTABLE_FILETYPE - << "library." + LIBRARYTABLE_DATETIMEADDED - << "track_locations.location" - << "track_locations.fs_deleted" - << "track_locations.directory" - << "library." + LIBRARYTABLE_COMMENT - << "library." + LIBRARYTABLE_MIXXXDELETED - << "library." + LIBRARYTABLE_COVERART_SOURCE - << "library." + LIBRARYTABLE_COVERART_TYPE - << "library." + LIBRARYTABLE_COVERART_LOCATION - << "library." + LIBRARYTABLE_COVERART_HASH; - QSqlQuery query(pTrackCollection->getDatabase()); - QString tableName = "library_cache_view"; - QString queryString = QString( - "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " - "SELECT %2 FROM library " - "INNER JOIN track_locations ON library.location = track_locations.id") - .arg(tableName, columns.join(",")); - qDebug() << queryString; - query.prepare(queryString); - if (!query.exec()) { - LOG_FAILED_QUERY(query); - } - - // Strip out library. and track_locations. - for (QStringList::iterator it = columns.begin(); - it != columns.end(); ++it) { - if (it->startsWith("library.")) { - *it = it->replace("library.", ""); - } else if (it->startsWith("track_locations.")) { - *it = it->replace("track_locations.", ""); - } - } - - BaseTrackCache* pBaseTrackCache = new BaseTrackCache( - pTrackCollection, tableName, LIBRARYTABLE_ID, columns, true); + m_pBaseTrackCache = pTrackCollection->getTrackSource(); connect(&m_trackDao, SIGNAL(trackDirty(TrackId)), - pBaseTrackCache, SLOT(slotTrackDirty(TrackId))); + m_pBaseTrackCache.data(), SLOT(slotTrackDirty(TrackId))); connect(&m_trackDao, SIGNAL(trackClean(TrackId)), - pBaseTrackCache, SLOT(slotTrackClean(TrackId))); + m_pBaseTrackCache.data(), SLOT(slotTrackClean(TrackId))); connect(&m_trackDao, SIGNAL(trackChanged(TrackId)), - pBaseTrackCache, SLOT(slotTrackChanged(TrackId))); + m_pBaseTrackCache.data(), SLOT(slotTrackChanged(TrackId))); connect(&m_trackDao, SIGNAL(tracksAdded(QSet)), - pBaseTrackCache, SLOT(slotTracksAdded(QSet))); + m_pBaseTrackCache.data(), SLOT(slotTracksAdded(QSet))); connect(&m_trackDao, SIGNAL(tracksRemoved(QSet)), - pBaseTrackCache, SLOT(slotTracksRemoved(QSet))); + m_pBaseTrackCache.data(), SLOT(slotTracksRemoved(QSet))); connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), - pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); + m_pBaseTrackCache.data(), SLOT(slotDbTrackAdded(TrackPointer))); setChildModel(new MixxxLibraryTreeModel(this, m_pTrackCollection, m_pConfig)); - - m_pBaseTrackCache = QSharedPointer(pBaseTrackCache); - - - pTrackCollection->setTrackSource(m_pBaseTrackCache); - - // These rely on the 'default' track source being present. m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection, "mixxx.db.model.library"); } diff --git a/src/library/library.cpp b/src/library/library.cpp index dbb33819e1a..555de141967 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -32,6 +32,7 @@ #include "library/librarytablemodel.h" #include "library/trackcollection.h" #include "library/trackmodel.h" +#include "library/queryutil.h" #include "mixer/playermanager.h" #include "util/assert.h" #include "util/sandbox.h" @@ -70,6 +71,7 @@ Library::Library(UserSettingsPointer pConfig, connect(&m_scanner, SIGNAL(scanFinished()), this, SLOT(slotRefreshLibraryModels())); + createTrackCache(); createFeatures(pConfig, pPlayerManager); // On startup we need to check if all of the user's library folders are @@ -624,6 +626,73 @@ LibraryPaneManager* Library::getPreselectedPane() { return m_panes.value(m_preselectedPane); } +void Library::createTrackCache() { + QStringList columns; + columns << "library." + LIBRARYTABLE_ID + << "library." + LIBRARYTABLE_PLAYED + << "library." + LIBRARYTABLE_TIMESPLAYED + //has to be up here otherwise Played and TimesPlayed are not show + << "library." + LIBRARYTABLE_ALBUMARTIST + << "library." + LIBRARYTABLE_ALBUM + << "library." + LIBRARYTABLE_ARTIST + << "library." + LIBRARYTABLE_TITLE + << "library." + LIBRARYTABLE_YEAR + << "library." + LIBRARYTABLE_RATING + << "library." + LIBRARYTABLE_GENRE + << "library." + LIBRARYTABLE_COMPOSER + << "library." + LIBRARYTABLE_GROUPING + << "library." + LIBRARYTABLE_TRACKNUMBER + << "library." + LIBRARYTABLE_KEY + << "library." + LIBRARYTABLE_KEY_ID + << "library." + LIBRARYTABLE_BPM + << "library." + LIBRARYTABLE_BPM_LOCK + << "library." + LIBRARYTABLE_DURATION + << "library." + LIBRARYTABLE_BITRATE + << "library." + LIBRARYTABLE_REPLAYGAIN + << "library." + LIBRARYTABLE_FILETYPE + << "library." + LIBRARYTABLE_DATETIMEADDED + << "track_locations.location" + << "track_locations.fs_deleted" + << "track_locations.directory" + << "library." + LIBRARYTABLE_COMMENT + << "library." + LIBRARYTABLE_MIXXXDELETED + << "library." + LIBRARYTABLE_COVERART_SOURCE + << "library." + LIBRARYTABLE_COVERART_TYPE + << "library." + LIBRARYTABLE_COVERART_LOCATION + << "library." + LIBRARYTABLE_COVERART_HASH; + + QSqlQuery query(m_pTrackCollection->getDatabase()); + QString tableName = "library_cache_view"; + QString queryString = QString( + "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " + "SELECT %2 FROM library " + "INNER JOIN track_locations ON library.location = track_locations.id") + .arg(tableName, columns.join(",")); + qDebug() << queryString; + query.prepare(queryString); + if (!query.exec()) { + LOG_FAILED_QUERY(query); + } + + // Strip out library. and track_locations. + for (QStringList::iterator it = columns.begin(); + it != columns.end(); ++it) { + if (it->startsWith("library.")) { + *it = it->replace("library.", ""); + } else if (it->startsWith("track_locations.")) { + *it = it->replace("track_locations.", ""); + } + } + + QSharedPointer pBaseTrackCache( + new BaseTrackCache( + m_pTrackCollection, tableName, LIBRARYTABLE_ID, columns, true)); + + m_pTrackCollection->setTrackSource(pBaseTrackCache); +} + + + void Library::createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface* pPlayerManager) { m_pMixxxLibraryFeature = new MixxxLibraryFeature( diff --git a/src/library/library.h b/src/library/library.h index df061dc46c7..40d9bcad77e 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -153,6 +153,7 @@ class Library : public QObject { LibraryPaneManager* getFocusedPane(); LibraryPaneManager* getPreselectedPane(); + void createTrackCache(); void createFeatures(UserSettingsPointer pConfig, PlayerManagerInterface *pPlayerManager); void handleFocus(); From 993e87be8c3350b92b7dd97634db1e60e0afcb0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 2 Dec 2016 22:49:57 +0100 Subject: [PATCH 545/552] Remove unnecessary Assert --- src/library/features/maintenance/maintenancefeature.cpp | 7 ++++--- src/library/libraryfeature.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/library/features/maintenance/maintenancefeature.cpp b/src/library/features/maintenance/maintenancefeature.cpp index c6a921e6ad3..ba88809745d 100644 --- a/src/library/features/maintenance/maintenancefeature.cpp +++ b/src/library/features/maintenance/maintenancefeature.cpp @@ -19,7 +19,9 @@ MaintenanceFeature::MaintenanceFeature(UserSettingsPointer pConfig, kMissingTitle(tr("Missing Tracks")), m_pHiddenView(nullptr), m_pMissingView(nullptr), - m_pTab(nullptr) { + m_pTab(nullptr), + m_idExpandedHidden(-1), + m_idExpandedMissing(-1) { } @@ -112,8 +114,7 @@ QWidget* MaintenanceFeature::createPaneWidget(KeyboardEventFilter* pKeyboard, void MaintenanceFeature::slotTabIndexChanged(int index) { QPointer pTable = getFocusedTable(); - - DEBUG_ASSERT_AND_HANDLE(!pTable.isNull()) { + if (pTable.isNull()) { return; } pTable->setSortingEnabled(false); diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp index c4f21c3c574..1e9eaf56387 100644 --- a/src/library/libraryfeature.cpp +++ b/src/library/libraryfeature.cpp @@ -179,6 +179,7 @@ QList LibraryFeature::getSavedQueries() const { WTrackTableView* LibraryFeature::createTableWidget(int paneId) { WTrackTableView* pTrackTableView = new WTrackTableView(nullptr, m_pConfig, m_pTrackCollection, true); + m_trackTablesByPaneId[paneId] = pTrackTableView; WMiniViewScrollBar* pScrollBar = new WMiniViewScrollBar(pTrackTableView); pTrackTableView->setScrollBar(pScrollBar); @@ -196,7 +197,6 @@ WTrackTableView* LibraryFeature::createTableWidget(int paneId) { pTrackTableView, SLOT(setTrackTableFont(QFont))); connect(m_pLibrary, SIGNAL(setTrackTableRowHeight(int)), pTrackTableView, SLOT(setTrackTableRowHeight(int))); - m_trackTablesByPaneId[paneId] = pTrackTableView; return pTrackTableView; } From 696d5d37942579acd224dd56675eaa320f47fe5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 3 Dec 2016 00:13:12 +0100 Subject: [PATCH 546/552] Improved Deere syling a bit --- res/skins/Deere/style.qss | 42 +++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 11fa58b9d63..ab706eb0a5c 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -129,10 +129,24 @@ QTableView, QTreeView { border: 1px solid #1A1A1A; } -QTreeView::branch:selected, QTableView::item:selected, QTreeView::item:selected { +QTreeView::branch { + background-color: #1F1F1F; +} + +QTableView::item:selected:active, +QTreeView::item:selected:active { + color: #ffffff; + background-color: #006596; } + +QTableView::item:selected:!active, +QTreeView::item:selected:!active { + color: #d2d2d2; + background-color: #0d4866; +} + /* checkbox in library "Played" column */ QTableView::indicator { width: 12px; @@ -147,14 +161,6 @@ QTableView::indicator:unchecked { background: url(skin:/image/style_checkbox_unchecked.png); } -WBaseLibrary[showFocus="0"] { - border-top: 2px solid transparent; -} - -WBaseLibrary[showFocus="1"] { - border-top: 2px solid #0080BE; -} - /* BPM lock icon in the library "BPM" column. */ #LibraryBPMButton::indicator:checked { image: url(:/images/library/ic_library_checked.png); @@ -205,7 +211,8 @@ WBaseLibrary QLabel { border: 1px solid #1A1A1A; } -#LibraryCoverArtSplitter QTabWidget QTreeView, #DlgAutoDJ { +#LibraryCoverArtSplitter QTabWidget QTreeView, +#DlgAutoDJ { margin: 0; border: none; } @@ -282,6 +289,17 @@ QPushButton#LibraryPreviewButton:checked { image: url(skin:/image/style_library_preview_pause.png); } + +#LibrarySidebarButtons:focus, +#LibrarySidebarButtons QToolButton:focus, +#LibrarySidebarExpanded > QWidget:focus, +#LibrarySidebarExpanded QAbstractScrollArea > QWidget:focus, +WLibrarySidebar:focus, +WLibrary:focus, +QTableView:focus { + border: 1px solid #0080BE; +} + /* library header row */ QHeaderView { color: #d2d2d2; @@ -471,6 +489,10 @@ WBaseLibrary QPushButton { outline: none; } +WBaseLibrary QPushButton:focus { + background-color: #006596; +} + WBaseLibrary QPushButton:!enabled { /* buttons in "disabled" (not click-able) state. They are nearly invisible by default QT palette, so style accordingly */ From 6efa706c15dd226845dc2f2a37a3a2bb00210182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 3 Dec 2016 00:32:51 +0100 Subject: [PATCH 547/552] Add focus borders to Shade skin --- res/skins/Shade/skin.xml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/res/skins/Shade/skin.xml b/res/skins/Shade/skin.xml index 33e70bbc2cb..f4ecc35abf8 100644 --- a/res/skins/Shade/skin.xml +++ b/res/skins/Shade/skin.xml @@ -571,12 +571,14 @@ border: 2px solid #e74421; } - WBaseLibrary[showFocus="0"] { - border-top: 2px solid transparent; - } - - WBaseLibrary[showFocus="1"] { - border-top: 2px solid #e74421; + #LibrarySidebarButtons:focus, + #LibrarySidebarButtons QToolButton:focus, + #LibrarySidebarExpanded > QWidget:focus, + #LibrarySidebarExpanded QAbstractScrollArea > QWidget:focus, + WLibrarySidebar:focus, + WLibrary:focus, + QTableView:focus { + border: 1px solid #e74421; } WLibraryBreadCrumb QLabel { From e98b71962ce6daf21b023b2fc56d48e5f48c564e Mon Sep 17 00:00:00 2001 From: jmigual Date: Sat, 3 Dec 2016 22:02:11 +0100 Subject: [PATCH 548/552] Fix windows compilation --- src/library/features/baseplaylist/baseplaylistfeature.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/library/features/baseplaylist/baseplaylistfeature.cpp b/src/library/features/baseplaylist/baseplaylistfeature.cpp index a4adc258a7b..dcd9b7facaf 100644 --- a/src/library/features/baseplaylist/baseplaylistfeature.cpp +++ b/src/library/features/baseplaylist/baseplaylistfeature.cpp @@ -644,11 +644,11 @@ QString BasePlaylistFeature::getValidPlaylistName() const { QSet BasePlaylistFeature::playlistIdsFromIndex(const QModelIndex &index) const { bool ok = false; int playlistId = index.data(AbstractRole::RoleDataPath).toInt(&ok); - if (!ok) { - return QSet(); + QSet set; + if (ok) { + set.insert(playlistId); } - return QSet::fromList({ playlistId }); - + return set; } From 84f19291eb414ffff8f66487e69f3b008b0967b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 6 Dec 2016 00:12:20 +0100 Subject: [PATCH 549/552] Silence some debug messages --- src/widget/wtristatebutton.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/wtristatebutton.cpp b/src/widget/wtristatebutton.cpp index a75a52c307a..24541ff6d2c 100644 --- a/src/widget/wtristatebutton.cpp +++ b/src/widget/wtristatebutton.cpp @@ -8,7 +8,7 @@ WTriStateButton::WTriStateButton(QWidget* parent) } void WTriStateButton::setChecked(bool value) { - qDebug() << this << "setChecked" << value; + //qDebug() << this << "setChecked" << value; // This omits the Hovered state State state = value ? State::Active : State::Unactive; setState(state); @@ -29,7 +29,7 @@ WTriStateButton::State WTriStateButton::getState() const { } void WTriStateButton::setHovered(bool value) { - qDebug() << this << "setHovered" << value; + //qDebug() << this << "setHovered" << value; State state = value ? State::Hovered : State::Unactive; setState(state); } From d16b7c4ddac0d4e31d7eb6b20a37580de08b772a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 6 Dec 2016 01:18:01 +0100 Subject: [PATCH 550/552] Added beginResetModel endResetModel regions to avoid crashes due to an deleted index. --- src/library/features/libraryfolder/libraryfoldermodel.cpp | 6 +++++- src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp | 4 ++-- src/library/treeitemmodel.cpp | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/library/features/libraryfolder/libraryfoldermodel.cpp b/src/library/features/libraryfolder/libraryfoldermodel.cpp index 977be8126a0..2ce0a457cd8 100644 --- a/src/library/features/libraryfolder/libraryfoldermodel.cpp +++ b/src/library/features/libraryfolder/libraryfoldermodel.cpp @@ -32,7 +32,8 @@ LibraryFolderModel::LibraryFolderModel(LibraryFeature* pFeature, reloadTree(); } -bool LibraryFolderModel::setData(const QModelIndex& index, const QVariant& value, int role) { +bool LibraryFolderModel::setData( + const QModelIndex& index, const QVariant& value, int role) { if (role == AbstractRole::RoleSettings) { m_folderRecursive = value.toBool(); m_pConfig->set(ConfigKey("[Library]", "FolderRecursive"), @@ -75,6 +76,8 @@ QVariant LibraryFolderModel::data(const QModelIndex& index, int role) const { } void LibraryFolderModel::reloadTree() { + //qDebug() << "LibraryFolderModel::reloadTree()"; + beginResetModel(); // Remove current root setRootItem(new TreeItem(m_pFeature)); @@ -109,6 +112,7 @@ void LibraryFolderModel::reloadTree() { // For each source folder create the tree createTreeForLibraryDir(dir, query); } + endResetModel(); } void LibraryFolderModel::createTreeForLibraryDir(const QString& dir, QSqlQuery& query) { diff --git a/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp b/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp index 314715600eb..84b100b9483 100644 --- a/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibrarytreemodel.cpp @@ -133,7 +133,7 @@ bool MixxxLibraryTreeModel::setData(const QModelIndex& index, const QVariant& va void MixxxLibraryTreeModel::reloadTree() { //qDebug() << "LibraryTreeModel::reloadTracksTree"; - + beginResetModel(); // Create root item TreeItem* pRootItem = new TreeItem(); pRootItem->setLibraryFeature(m_pFeature); @@ -148,7 +148,7 @@ void MixxxLibraryTreeModel::reloadTree() { // Deletes the old root item if the previous root item was not null setRootItem(pRootItem); createTracksTree(); - triggerRepaint(); + endResetModel(); } void MixxxLibraryTreeModel::coverFound(const QObject* requestor, int requestReference, diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index 58938208fa8..a57d8b0385c 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -199,7 +199,8 @@ void TreeItemModel::setRootItem(TreeItem *item) { * Before you can resize the data model dynamically by using 'insertRows' and 'removeRows' * make sure you have initialized */ -bool TreeItemModel::insertRows(QList &data, int position, int rows, const QModelIndex &parent) { +bool TreeItemModel::insertRows( + QList& data, int position, int rows, const QModelIndex &parent) { if (rows == 0) { return true; } @@ -239,6 +240,7 @@ void TreeItemModel::triggerRepaint() { emit(dataChanged(left, right)); } +//static QString TreeItemModel::getBreadCrumbString(TreeItem* pTree) { // Base case if (pTree == nullptr || pTree->getFeature() == nullptr) { @@ -254,6 +256,7 @@ QString TreeItemModel::getBreadCrumbString(TreeItem* pTree) { return next % QLatin1String(" > ") % text; } +//static QSize TreeItemModel::getDefaultIconSize() { return QSize(32, 32); } From 8e4485bb7392d30128160da202d0accabc71eaa5 Mon Sep 17 00:00:00 2001 From: jmigual Date: Wed, 7 Dec 2016 22:52:29 +0100 Subject: [PATCH 551/552] Fix windows build --- src/library/coverartdelegate.cpp | 1 + src/library/features/history/historytreemodel.cpp | 7 ++++--- src/library/previewbuttondelegate.cpp | 1 + src/widget/wlibrarysidebar.cpp | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/library/coverartdelegate.cpp b/src/library/coverartdelegate.cpp index 41ea79d761f..7669a561335 100644 --- a/src/library/coverartdelegate.cpp +++ b/src/library/coverartdelegate.cpp @@ -1,3 +1,4 @@ +#include #include #include "library/coverartdelegate.h" diff --git a/src/library/features/history/historytreemodel.cpp b/src/library/features/history/historytreemodel.cpp index cbcb19697e7..334ad275563 100644 --- a/src/library/features/history/historytreemodel.cpp +++ b/src/library/features/history/historytreemodel.cpp @@ -128,11 +128,12 @@ QList HistoryTreeModel::idsFromItem(TreeItem* pTree) const { if (pTree->childCount() <= 0) { bool ok; int value = pTree->dataPath().toInt(&ok); + QList ret; if (!ok) { - return QList(); + return ret; } - - return { value }; + ret.append(value); + return ret; } QList res; diff --git a/src/library/previewbuttondelegate.cpp b/src/library/previewbuttondelegate.cpp index 964934fe366..0a8c1129011 100644 --- a/src/library/previewbuttondelegate.cpp +++ b/src/library/previewbuttondelegate.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index d5e77dc9a2a..b002421424d 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -1,5 +1,6 @@ #include "widget/wlibrarysidebar.h" +#include #include #include #include From 73094d0498a5725006a45eb8ddc8f005554944fb Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 8 Dec 2016 13:03:46 +0100 Subject: [PATCH 552/552] Fix windows compilation with Qt4 and initializer lists --- .../mixxxlibrary/mixxxlibraryfeature.cpp | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp index 91046654973..ef9c68ffe65 100644 --- a/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp +++ b/src/library/features/mixxxlibrary/mixxxlibraryfeature.cpp @@ -21,19 +21,22 @@ const QString MixxxLibraryFeature::kLibraryTitle = tr("Library"); -const QStringList MixxxLibraryFeature::kGroupingText = { - tr("Artist > Album"), - tr("Album"), - tr("Genre > Artist > Album"), - tr("Genre > Album") -}; +const QStringList MixxxLibraryFeature::kGroupingText = + QStringList::fromStdList({ + tr("Artist > Album"), + tr("Album"), + tr("Genre > Artist > Album"), + tr("Genre > Album") +}); -const QList MixxxLibraryFeature::kGroupingOptions = { - { LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }, - { LIBRARYTABLE_ALBUM }, - { LIBRARYTABLE_GENRE, LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }, - { LIBRARYTABLE_GENRE, LIBRARYTABLE_ALBUM } -}; +const QList MixxxLibraryFeature::kGroupingOptions = + QList::fromStdList({ + QStringList::fromStdList({ LIBRARYTABLE_ARTIST, LIBRARYTABLE_ALBUM }), + QStringList::fromStdList({ LIBRARYTABLE_ALBUM }), + QStringList::fromStdList({ LIBRARYTABLE_GENRE, LIBRARYTABLE_ARTIST, + LIBRARYTABLE_ALBUM }), + QStringList::fromStdList({ LIBRARYTABLE_GENRE, LIBRARYTABLE_ALBUM }) +}); MixxxLibraryFeature::MixxxLibraryFeature(UserSettingsPointer pConfig, Library* pLibrary,