From c50c80c5a3f7f65214cecef69ce20a072b7b521d Mon Sep 17 00:00:00 2001 From: Daniel Poelzleithner Date: Sun, 18 Oct 2020 21:37:08 +0200 Subject: [PATCH 1/6] [WIP] Infobar Add infobar which shows crate/playlist/history information about track selection --- CMakeLists.txt | 1 + res/skins/Deere/library.xml | 20 +- res/skins/Deere/style.qss | 54 +++++ res/skins/LateNight/style.qss | 33 +++ src/controllers/controlpickermenu.cpp | 5 + src/library/library.cpp | 8 + src/library/library.h | 1 + src/library/libraryfeature.h | 1 + src/library/trackset/crate/crate.h | 2 + src/library/trackset/crate/cratesummary.h | 2 + src/skin/legacyskinparser.cpp | 51 +++++ src/skin/legacyskinparser.h | 1 + src/skin/tooltips.cpp | 4 + src/track/track.h | 3 + src/widget/winfobar.cpp | 252 ++++++++++++++++++++++ src/widget/winfobar.h | 127 +++++++++++ src/widget/wlibrarytableview.h | 1 + src/widget/wmainmenubar.cpp | 13 ++ src/widget/wtrackproperty.cpp | 1 + src/widget/wtracktableview.cpp | 12 ++ 20 files changed, 588 insertions(+), 4 deletions(-) create mode 100644 src/widget/winfobar.cpp create mode 100644 src/widget/winfobar.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 26190df63fe6..d34090349ba7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -976,6 +976,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/widget/weffectselector.cpp src/widget/whotcuebutton.cpp src/widget/wimagestore.cpp + src/widget/winfobar.cpp src/widget/wkey.cpp src/widget/wknob.cpp src/widget/wknobcomposed.cpp diff --git a/res/skins/Deere/library.xml b/res/skins/Deere/library.xml index d327477f6d41..bbb4ea59317b 100644 --- a/res/skins/Deere/library.xml +++ b/res/skins/Deere/library.xml @@ -69,10 +69,22 @@ - - false - 0.175 - + + InfobarSplitter + vertical + me,me + [Skin],libraryInfobar_splitsize + 8,1 + + + false + 0.175 + + + [Library] + + + + + vertical me,me - [Skin],libraryInfobar_splitsize - 8,1 + vertical false 0.175 - - [Library] - + + + vertical + m,m + + [Library],show_infobar + visible + + + + Infobar + [Library] + + + - + + images/library/ic_library_crates.svg + images/library/ic_library_crates_half_grey.svg + images/library/ic_library_crates_grey.svg images/library/ic_library_cross_grey.svg images/library/ic_library_cross_orange.svg images/library/ic_library_history.svg + images/library/ic_library_history_half_grey.svg + images/library/ic_library_history_grey.svg images/library/ic_library_history_current.svg images/library/ic_library_itunes.svg images/library/ic_library_tracks.svg images/library/ic_library_playlist.svg + images/library/ic_library_playlist_half_grey.svg + images/library/ic_library_playlist_grey.svg images/library/ic_library_prepare.svg images/library/ic_library_preview_pause.svg images/library/ic_library_preview_play.svg From 9b5d7a59b3171f9db7614e1262621d0bba5c6d81 Mon Sep 17 00:00:00 2001 From: Daniel Poelzleithner Date: Sat, 5 Dec 2020 04:28:58 +0100 Subject: [PATCH 5/6] Major update to infobar Use a QStatusBar as basis. Properly encapsulate each category into one custom widget Add 3 states for the Widget, closed, normal, expanded query crates, playlists and history Update crates when track assignment change. --- res/skins/Deere/skin.xml | 1 + res/skins/Deere/style.qss | 114 +++-- res/skins/LateNight/style.qss | 10 - src/controllers/controlpickermenu.cpp | 9 +- src/library/dao/playlistdao.cpp | 23 +- src/library/dao/playlistdao.h | 6 +- src/library/library.cpp | 3 +- src/library/library.h | 11 + src/library/trackset/crate/cratefeature.h | 3 +- src/skin/legacyskinparser.cpp | 18 +- src/widget/winfobar.cpp | 495 ++++++++++++++++++---- src/widget/winfobar.h | 172 +++++++- src/widget/wmainmenubar.cpp | 23 +- 13 files changed, 714 insertions(+), 174 deletions(-) diff --git a/res/skins/Deere/skin.xml b/res/skins/Deere/skin.xml index a03d2764507a..b4d0c8c24feb 100644 --- a/res/skins/Deere/skin.xml +++ b/res/skins/Deere/skin.xml @@ -53,6 +53,7 @@ 0 0 1 + 1 0 0 diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 8f35b6c46e06..627d46c2a326 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -526,6 +526,9 @@ WLibrary QRadioButton::indicator:unchecked { } /* buttons in library (in hierarchical order of appearance) Style them just as the other regular buttons */ +#InfobarCratesContainer > QPushButton, +#InfobarPlaylistsContainer > QPushButton, +#InfobarHistoryContainer > QPushButton, #LibraryFeatureControls QPushButton { margin: 9px 3px 6px 3px; padding: 3px 4px; @@ -543,7 +546,12 @@ WLibrary QRadioButton::indicator:unchecked { QPushButton#pushButtonAutoDJ { width: 42px; } - + #InfobarCratesContainer > QPushButton, + #InfobarPlaylistsContainer > QPushButton, + #InfobarHistoryContainer > QPushButton { + padding: 0px 3px 0px 3px; + margin: 0px; + } #LibraryFeatureControls QPushButton:!enabled { /* buttons in "disabled" (not click-able) state. They are nearly invisible @@ -556,6 +564,9 @@ WLibrary QRadioButton::indicator:unchecked { outline: none; } +#InfobarCratesContainer > QPushButton:hover, +#InfobarPlaylistsContainer > QPushButton:hover, +#InfobarHistoryContainer > QPushButton:hover, #LibraryFeatureControls QPushButton:hover { color: #D2D2D2; background-color: #5F5F5F; @@ -593,6 +604,9 @@ QPushButton#pushButtonRecording:checked:hover { outline: none; } +#InfobarCratesContainer > QPushButton:pressed, +#InfobarPlaylistsContainer > QPushButton:pressed, +#InfobarHistoryContainer > QPushButton:pressed, #LibraryFeatureControls QPushButton:pressed { /* pushbuttons in "down" state */ margin: 9px 3px 6px 3px; @@ -601,7 +615,12 @@ QPushButton#pushButtonRecording:checked:hover { border: 1px solid #006596; outline: none; } - +#InfobarCratesContainer > QPushButton:pressed, +#InfobarPlaylistsContainer > QPushButton:pressed, +#InfobarHistoryContainer > QPushButton:pressed { + margin: 0px; + border-right: 1px ridge #015d8d; +} /* AutoDJ button icons */ QPushButton#pushButtonAutoDJ { @@ -1305,6 +1324,7 @@ WBeatSpinBox, qproperty-layoutSpacing: 0; } +#Infobar, #MainDecks, #MainDeckContainer { background-color: #333333; } @@ -2233,63 +2253,65 @@ WRateRange { qproperty-alignment: 'AlignRight | AlignTop'; } -#RateDisplayBottomPrefix { - qproperty-alignment: 'AlignLeft | AlignBottom'; -} -#RateDisplayBottomRate { - qproperty-alignment: 'AlignRight | AlignBottom'; -} - #InfobarSplitter { background-color: #222222; } -#infobarContainer { - background-color: #ff00ff; -} -#infobarCrates { - border: 1px solid #ffff00; - border-width: 0px 1px 0px 1px; - background-color: #006f00; - border-radius: 2px; +WInfoBarContainer, +WInfoBarContainer QWidget { + padding: 0; margin: 0; - padding: 0 3px 0 3px; - Text-align:left; } -WInfoBarItem { - background-color: #F0fff0; - margin: 0; - padding: 0; - Text-align:left; +WInfoBarButton { + /* tall button, about the same height as cue number + label edit box */ + padding: 1px; + margin: 0 2px 0 0; + width: 20px; + height: 20px; + /* make the icon slightly larger than default 16px */ + qproperty-iconSize: 20px; + background-color: #3B3B3B; + border-radius: 2px; + outline: none; } -WInfoBarCrateItem { - background-color: #F00ff0; +/* normal */ +#InfobarCratesFrame WInfoBarButton[state="0"] { + qproperty-icon: url(:/images/library/ic_library_crates_half_grey.svg); } - -#infobarCratesContainer { - margin: 0; - padding: 0; - spacing: 0; +/* hidden */ +#InfobarCratesFrame WInfoBarButton[state="1"] { + qproperty-icon: url(:/images/library/ic_library_crates_grey.svg); +} +/* extended */ +#InfobarCratesFrame WInfoBarButton[state="2"] { + qproperty-icon: url(:/images/library/ic_library_crates.svg); } - -#infobarPlaylists { - border: 1px solid #ffff00; - border-width: 0px 1px 0px 1px; - background-color: #00fff0; - border-radius: 2px; - margin: 0; - padding: 0 3px 0 3px; +/* normal */ +#InfobarPlaylistsFrame WInfoBarButton[state="0"] { + qproperty-icon: url(:/images/library/ic_library_playlist_half_grey.svg); +} +/* hidden */ +#InfobarPlaylistsFrame WInfoBarButton[state="1"] { + qproperty-icon: url(:/images/library/ic_library_playlist_grey.svg); +} +/* extended */ +#InfobarPlaylistsFrame WInfoBarButton[state="2"] { + qproperty-icon: url(:/images/library/ic_library_playlist.svg); } -#infobarHistory { - border: 1px solid #ffff00; - border-width: 0px 1px 0px 1px; - background-color: #f03f00; - border-radius: 2px; - margin: 0; - padding: 0 3px 0 3px; +/* normal */ +#InfobarHistoryFrame WInfoBarButton[state="0"] { + qproperty-icon: url(:/images/library/ic_library_history_half_grey.svg); +} +/* hidden */ +#InfobarHistoryFrame WInfoBarButton[state="1"] { + qproperty-icon: url(:/images/library/ic_library_history_grey.svg); +} +/* extended */ +#InfobarHistoryFrame WInfoBarButton[state="2"] { + qproperty-icon: url(:/images/library/ic_library_history.svg); } diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 1129718a76fc..c0b586ca592a 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1091,13 +1091,3 @@ QListView::branch:open:has-children:!has-siblings:selected, QListView::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); } - -WInfoBarCrateItem { - background-color: #FF0000; - color: black; -} - -WInfoBarCrateMixedItem { - background-color: #FF0000; - color: black; -} diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index eb49a67a750c..d40084b77fee 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -1129,9 +1129,9 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Show/hide cover art in the library"), guiMenu); addControl("[Library]", - "show_crates", + "show_infobar", tr("Crates List Show/Hide"), - tr("Show/hide list of crates"), + tr("Show/hide infobar"), guiMenu); addControl("[Master]", "maximize_library", @@ -1152,6 +1152,11 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Cover Art Show/Hide (Decks)"), tr("Show/hide cover art in the main decks"), guiMenu); + addControl("[Library]", + "show_infobar", + tr("Infobar Show/Hide (Decks)"), + tr("Show/hide the infobar in the library"), + guiMenu); addControl(VINYL_PREF_KEY, "show_vinylcontrol", tr("Vinyl Control Show/Hide"), diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index c6bc4a5c9ddc..27175f33f6dc 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -29,6 +29,7 @@ void PlaylistDAO::initialize(const QSqlDatabase& database) { "AS SELECT " " Playlists.id AS id, " " Playlists.name AS name, " + " Playlists.hidden AS hidden, " " LOWER(Playlists.name) AS sort_name, " " COUNT(case library.mixxx_deleted when 0 then 1 else null end) " " AS count, " @@ -39,7 +40,6 @@ void PlaylistDAO::initialize(const QSqlDatabase& database) { " ON PlaylistTracks.playlist_id = Playlists.id " "LEFT JOIN library " " ON PlaylistTracks.track_id = library.id " - " WHERE Playlists.hidden = 0 " " GROUP BY Playlists.id"); queryString.append( mixxx::DbConnection::collateLexicographically( @@ -1187,18 +1187,21 @@ void PlaylistDAO::getPlaylistsTrackIsIn(TrackId trackId, } } -QList PlaylistDAO::createPlaylistSummaryForTracks(QList tracks) { +QList PlaylistDAO::createPlaylistSummaryForTracks( + QList tracks, HiddenType type) { QSet allPlaylistIds; QSet playlistIds; QMap trackCount; for (TrackId trackId : qAsConst(tracks)) { PlaylistDAO::getPlaylistsTrackIsIn(trackId, &playlistIds); + qDebug() << "playlists for" << trackId << playlistIds; allPlaylistIds += playlistIds; for (int playlistId : playlistIds) { trackCount[playlistId] = trackCount.value(playlistId, 0) + 1; } } - QList summaries = PlaylistDAO::createPlaylistSummary(&allPlaylistIds); + QList summaries = PlaylistDAO::createPlaylistSummary(&allPlaylistIds, type); + qDebug() << allPlaylistIds << summaries.length(); for (PlaylistSummary summary : qAsConst(summaries)) { DEBUG_ASSERT(trackCount.contains(summary.id())); summary.setMatches(trackCount.value(summary.id())); @@ -1206,22 +1209,30 @@ QList PlaylistDAO::createPlaylistSummaryForTracks(QList PlaylistDAO::createPlaylistSummary(QSet* playlistIds) { +QList PlaylistDAO::createPlaylistSummary(QSet* playlistIds, HiddenType type) { QList playlistLabels; // Setup the sidebar playlist model QSqlTableModel playlistTableModel(this, m_database); playlistTableModel.setTable("PlaylistsCountsDurations"); + qDebug() << "createPlaylistSummary" << static_cast(type); if (playlistIds) { QStringList idList; for (const auto& playlistId : *playlistIds) { idList.append(QString::number(playlistId)); } - playlistTableModel.setFilter(QString("Playlists.id in [%1]").arg(idList.join(","))); + playlistTableModel.setFilter(QString("hidden=%1 AND id in (%2)") + .arg(static_cast(type)) + .arg(idList.join(","))); + } else { + playlistTableModel.setFilter(QString("hidden=%1").arg(static_cast(type))); + } + + if (!playlistTableModel.select()) { + qWarning() << "Error querying database: " << playlistTableModel.lastError(); } - playlistTableModel.select(); while (playlistTableModel.canFetchMore()) { playlistTableModel.fetchMore(); } diff --git a/src/library/dao/playlistdao.h b/src/library/dao/playlistdao.h index 0fb5c54de075..438cd54f0cd4 100644 --- a/src/library/dao/playlistdao.h +++ b/src/library/dao/playlistdao.h @@ -118,8 +118,10 @@ class PlaylistDAO : public QObject, public virtual DAO { bool isTrackInPlaylist(TrackId trackId, const int playlistId) const; void getPlaylistsTrackIsIn(TrackId trackId, QSet* playlistSet) const; - QList createPlaylistSummary(QSet* playlistIds = nullptr); - QList createPlaylistSummaryForTracks(QList tracks); + QList createPlaylistSummary(QSet* playlistIds = nullptr, + HiddenType type = PLHT_NOT_HIDDEN); + QList createPlaylistSummaryForTracks(QList tracks, + HiddenType type = PLHT_NOT_HIDDEN); void setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor); diff --git a/src/library/library.cpp b/src/library/library.cpp index a1936ba3e1ae..41c02c9cac34 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -138,7 +138,8 @@ Library::Library( addFeature(browseFeature); addFeature(new RecordingFeature(this, m_pConfig, pRecordingManager)); - addFeature(new SetlogFeature(this, UserSettingsPointer(m_pConfig))); + m_pSetlogFeature = new SetlogFeature(this, UserSettingsPointer(m_pConfig)); + addFeature(m_pSetlogFeature); m_pAnalysisFeature = new AnalysisFeature(this, m_pConfig); connect(m_pPlaylistFeature, diff --git a/src/library/library.h b/src/library/library.h index 777a5a33e03b..3885afbdf2d9 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -27,6 +27,7 @@ class KeyboardEventFilter; class MixxxLibraryFeature; class PlayerManager; class PlaylistFeature; +class SetlogFeature; class RecordingManager; class SidebarModel; class TrackCollection; @@ -85,6 +86,15 @@ class Library: public QObject { } //static Library* buildDefaultLibrary(); + CrateFeature* getCreateFeature() { + return m_pCrateFeature; + }; + PlaylistFeature* getPlaylistFeature() { + return m_pPlaylistFeature; + }; + SetlogFeature* getSetlogFeature() { + return m_pSetlogFeature; + }; enum class RemovalType { KeepTracks, @@ -161,6 +171,7 @@ class Library: public QObject { const static QString m_sAutoDJViewName; MixxxLibraryFeature* m_pMixxxLibraryFeature; PlaylistFeature* m_pPlaylistFeature; + SetlogFeature* m_pSetlogFeature; CrateFeature* m_pCrateFeature; AnalysisFeature* m_pAnalysisFeature; QFont m_trackTableFont; diff --git a/src/library/trackset/crate/cratefeature.h b/src/library/trackset/crate/cratefeature.h index 2b1d77c5047e..c7219e06a2ec 100644 --- a/src/library/trackset/crate/cratefeature.h +++ b/src/library/trackset/crate/cratefeature.h @@ -42,6 +42,7 @@ class CrateFeature : public BaseTrackSetFeature { void bindSidebarWidget(WLibrarySidebar* pSidebarWidget) override; TreeItemModel* getChildModel() override; + bool activateCrate(CrateId crateId); public slots: void activateChild(const QModelIndex& index) override; @@ -80,8 +81,6 @@ class CrateFeature : public BaseTrackSetFeature { void connectLibrary(Library* pLibrary); void connectTrackCollection(); - bool activateCrate(CrateId crateId); - std::unique_ptr newTreeItemForCrateSummary( const CrateSummary& crateSummary); void updateTreeItemForCrateSummary( diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp index eb567da195e9..15fee6798df5 100644 --- a/src/skin/legacyskinparser.cpp +++ b/src/skin/legacyskinparser.cpp @@ -1320,39 +1320,39 @@ QWidget* LegacySkinParser::parseInfobar(const QDomElement& node) { return NULL; } - WInfoBar* p = new WInfoBar(group, m_pConfig, m_pLibrary, m_pParent); + WInfoBar* pInfobar = new WInfoBar(group, m_pConfig, m_pLibrary, m_pParent); - commonWidgetSetup(node, p); - p->setup(node, *m_pContext); + commonWidgetSetup(node, pInfobar); + pInfobar->setup(node, *m_pContext); if (pPlayer) { connect(pPlayer, SIGNAL(newTrackLoaded(TrackPointer)), - p, + pInfobar, SLOT(slotTrackLoaded(TrackPointer))); connect(pPlayer, SIGNAL(loadingTrack(TrackPointer, TrackPointer)), - p, + pInfobar, SLOT(slotTrackLoaded(TrackPointer))); // load if there is already a track in the deck TrackPointer pTrack = pPlayer->getLoadedTrack(); if (pTrack) { - p->slotTrackLoaded(pTrack); + pInfobar->slotTrackLoaded(pTrack); } } else { // hookup to library // FIXME(poelzi) signals connect(m_pLibrary, &Library::switchToView, - p, + pInfobar, &WInfoBar::slotClear); connect(m_pLibrary, &Library::trackSelection, - p, + pInfobar, &WInfoBar::slotTrackSelection); } - return p; + return pInfobar; } void LegacySkinParser::parseSingletonDefinition(const QDomElement& node) { diff --git a/src/widget/winfobar.cpp b/src/widget/winfobar.cpp index 8d391fcf815a..6cf4d0c402ce 100644 --- a/src/widget/winfobar.cpp +++ b/src/widget/winfobar.cpp @@ -1,6 +1,7 @@ #include "widget/winfobar.h" +#include #include #include #include @@ -9,11 +10,16 @@ #include #include #include +#include #include #include #include +#include #include "control/controlobject.h" +#include "library/trackset/crate/cratefeature.h" +#include "library/trackset/playlistfeature.h" +#include "library/trackset/setlogfeature.h" #include "util/dnd.h" // crates which are only occupied by some tracks @@ -26,14 +32,27 @@ WInfoBarItem::WInfoBarItem(const QString& text, QWidget* parent) } // crates in which all tracks are part of -WInfoBarCrateItem::WInfoBarCrateItem(const CrateSummary crate, QWidget* parent) - : WInfoBarItem(crate.getName(), parent) { - //setText(); +WInfoBarCrateItem::WInfoBarCrateItem(const CrateSummary crt, QWidget* parent) + : WInfoBarItem(crt.getName(), parent), + m_crate(crt) { + connect(this, + &QAbstractButton::clicked, + [this] { + emit(activateCrate(m_crate)); + }); } // crates which are only occupied by some tracks -WInfoBarCrateMixedItem::WInfoBarCrateMixedItem(const CrateSummary crate, QWidget* parent) - : WInfoBarCrateItem(crate, parent) { +WInfoBarPlaylistItem::WInfoBarPlaylistItem( + const PlaylistSummary playlist, bool isHistory, QWidget* parent) + : WInfoBarItem(playlist.name(), parent), + m_playlist(playlist), + m_isHistory(isHistory) { + connect(this, + &QAbstractButton::clicked, + [this] { + emit(activatePlaylist(m_playlist, m_isHistory)); + }); } WInfoBarWorker::WInfoBarWorker(QObject* parent, TrackCollectionManager* manager) @@ -43,6 +62,12 @@ WInfoBarWorker::WInfoBarWorker(QObject* parent, TrackCollectionManager* manager) } void WInfoBarWorker::query(int query, QList trackIds) { + queryCrates(query, trackIds); + queryPlaylists(query, trackIds); + queryHistory(query, trackIds); +} + +void WInfoBarWorker::queryCrates(int query, QList trackIds) { QString where = QString(" WHERE %1 > 0 ").arg("track_count"); QList rv = QList(); @@ -62,13 +87,146 @@ void WInfoBarWorker::query(int query, QList trackIds) { emit(crateResult(query, trackIds.length(), rv)); } +void WInfoBarWorker::queryPlaylists(int query, QList trackIds) { + //QString where = QString(" WHERE %1 > 0 ").arg("track_count"); + + QList rv = QList(); + rv.reserve(trackIds.length()); + + QList results = + m_pTrackCollectionManager->internalCollection() + ->getPlaylistDAO() + .createPlaylistSummaryForTracks(trackIds); + + emit(playlistResult(query, trackIds.length(), results)); +} + +void WInfoBarWorker::queryHistory(int query, QList trackIds) { + //QString where = QString(" WHERE %1 > 0 ").arg("track_count"); + + QList rv = QList(); + rv.reserve(trackIds.length()); + + QList results = + m_pTrackCollectionManager->internalCollection() + ->getPlaylistDAO() + .createPlaylistSummaryForTracks( + trackIds, PlaylistDAO::HiddenType::PLHT_SET_LOG); + qDebug() << "history result length" << results.length(); + + emit(historyResult(query, trackIds.length(), results)); +} + +WInfoBarButton::WInfoBarButton(QWidget* parent) + : QToolButton(parent) { + /* connect(this, + &QToolButton::clicked, + this, + &WInfoBarButton::slotTriggered); +*/ + setState(State::VISIBLE); +} + +void WInfoBarButton::setState(WInfoBarButton::State newState) { + m_state = newState; + qDebug() << "updated"; + style()->unpolish(this); + style()->polish(this); + emit(stateChanged(m_state)); +}; + +void WInfoBarButton::nextCheckState() { + //Q_UNUSED(action); + qDebug() << "triggered"; + switch (m_state) { + case WInfoBarButton::State::VISIBLE: + m_state = WInfoBarButton::State::EXPANDED; + break; + case WInfoBarButton::State::EXPANDED: + m_state = WInfoBarButton::State::HIDDEN; + break; + default: + m_state = WInfoBarButton::State::VISIBLE; + } + style()->unpolish(this); + style()->polish(this); + emit(stateChanged(m_state)); +} + +WInfoBarContainer::WInfoBarContainer(QString name, + QWidget* pParent) + : QFrame(pParent), + m_pButton(new WInfoBarButton(this)), + m_pContainer(nullptr), + m_pMainLayout(nullptr), + m_pMainContainer(nullptr) { + setObjectName(QString("%1Frame").arg(name)); + + m_pContainer = new QHBoxLayout(this); + m_pContainer->setSpacing(2); + m_pContainer->setContentsMargins(QMargins(2, 0, 2, 0)); + + m_pMainContainer = new QWidget(this); + m_pMainContainer->setObjectName(QString("%1Container").arg(name)); + m_pMainContainer->setLayout(m_pContainer); + + m_pMainLayout = new QHBoxLayout(this); + m_pMainLayout->setContentsMargins(QMargins(0, 0, 0, 0)); + m_pMainLayout->addWidget(m_pButton); + m_pMainLayout->addWidget(m_pMainContainer); + + m_pButton->setObjectName(QString("%1Button").arg(name)); + connect(m_pButton, + &WInfoBarButton::stateChanged, + this, + &WInfoBarContainer::slotStateChange); + + setLayout(m_pMainLayout); +} + +void WInfoBarContainer::slotStateChange(WInfoBarButton::State state) { + qDebug() << "stateChange" << static_cast(state); + if (state == WInfoBarButton::State::HIDDEN) { + m_pMainContainer->setVisible(false); + } else { + m_pMainContainer->setVisible(true); + } + if (state == WInfoBarButton::State::EXPANDED) { + m_pMainContainer->setSizePolicy(QSizePolicy(QSizePolicy::Policy::Expanding, + QSizePolicy::Policy::Minimum)); + m_pMainContainer->setMaximumSize(QSize(1000000, 20)); + } else { + m_pMainContainer->setSizePolicy(QSizePolicy(QSizePolicy::Policy::Minimum, + QSizePolicy::Policy::Minimum)); + } + emit(stateChanged(state)); +} + +void WInfoBarContainer::clear() { + QLayoutItem* child; + while ((child = m_pContainer->takeAt(0)) != nullptr) { + delete child->widget(); // delete the widget + delete child; // delete the layout item + } +} + +void WInfoBarContainer::addItem(WInfoBarItem* item) { + m_pContainer->addWidget(item); + m_pContainer->setAlignment(item, Qt::AlignLeft | Qt::AlignTop); +} + +void WInfoBarContainer::addStretch(int factor) { + m_pContainer->addStretch(factor); +} + +// WInfoBar implementation QThread* WInfoBar::s_worker_thread = nullptr; //QThread(); WInfoBar::WInfoBar(QString group, UserSettingsPointer pConfig, Library* pLibrary, QWidget* pParent) - : QScrollArea(pParent), + : QStatusBar(pParent), WBaseWidget(pParent), m_pGroup(group), m_pConfig(pConfig), @@ -76,10 +234,10 @@ WInfoBar::WInfoBar(QString group, // FIXME(poelzi): does it make sense to allow drops of certain stuff ??? setAcceptDrops(false); setMinimumSize(0, 0); - setWidgetResizable(true); + //setWidgetResizable(true); setFocusPolicy(Qt::NoFocus); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + //setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + //setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // initialize the shared worker thread if (s_worker_thread == nullptr) { @@ -92,14 +250,40 @@ WInfoBar::WInfoBar(QString group, m_pWorker = new WInfoBarWorker(this, pLibrary->trackCollections()); m_pWorker->moveToThread(s_worker_thread); + // we use queued connections because they connect to a different thread connect(m_pWorker, &WInfoBarWorker::crateResult, this, - &WInfoBar::receiveCrateResults); + &WInfoBar::receiveCrateResults, + Qt::QueuedConnection); + connect(m_pWorker, + &WInfoBarWorker::playlistResult, + this, + &WInfoBar::receivePlaylistResults, + Qt::QueuedConnection); + connect(m_pWorker, + &WInfoBarWorker::historyResult, + this, + &WInfoBar::receiveHistoryResults, + Qt::QueuedConnection); connect(this, &WInfoBar::query, m_pWorker, - &WInfoBarWorker::query); + &WInfoBarWorker::query, + Qt::QueuedConnection); + + // crate updates + connect(&m_pLibrary->trackCollection(), + &TrackCollection::crateTracksChanged, + this, + &WInfoBar::slotCrateTracksChanged); + // very seldom, so we build it eagerly + connect(&m_pLibrary->trackCollection(), + &TrackCollection::crateSummaryChanged, + [this](const QSet& crates) { + Q_UNUSED(crates); + queryCurrentTracks(); + }); } // generates unique id's for all worker requests @@ -109,25 +293,130 @@ int WInfoBar::generateId() { return ++s_last_id; } -void WInfoBar::receiveCrateResults(int query, uint total, QList crates) { - qDebug() << "WInfoBar::receiveCrateResults" << query << total; +void WInfoBar::slotCrateTracksChanged(CrateId crate, + const QList& tracksAdded, + const QList& tracksRemoved) { + Q_UNUSED(crate); + bool rebuild = false; + for (TrackPointer track : qAsConst(m_currentTracks)) { + const TrackId id = track->getId(); + if (tracksAdded.contains(id) || tracksRemoved.contains(id)) { + rebuild = true; + break; + } + } + if (rebuild) { + // A currently loaded track is affected, rebuild the bar + queryCurrentTracks(); + } +} + +void WInfoBar::receiveCrateResults(int queryId, int total, QList crates) { + qDebug() << "WInfoBar::receiveCrateResults" << queryId << total << crates.length(); // we are only interested in results we requested last - if (query != m_id) { + if (queryId != m_id) { return; } - + m_pCratesContainer->clear(); foreach (CrateSummary crate, crates) { - if (crate.getTrackCount() == total) { - auto item = new WInfoBarCrateItem(crate, this); - m_pCratesContainer->addWidget(item); - m_pCratesContainer->setAlignment(item, Qt::AlignLeft | Qt::AlignTop); - } else { - auto item = new WInfoBarCrateMixedItem(crate, this); - m_pCratesContainer->addWidget(item); - m_pCratesContainer->setAlignment(item, Qt::AlignLeft | Qt::AlignTop); + auto item = new WInfoBarCrateItem(crate, m_pCratesContainer); + item->setTotals(total); + + connect(item, + &WInfoBarCrateItem::activateCrate, + this, + &WInfoBar::slotActivateCrate); + + m_pCratesContainer->addItem(item); + } + m_pCratesContainer->addStretch(0); + //m_pCratesContainer-> + //updateVisibilty(); + //m_pCratesContainer->addStretch(); +} + +void WInfoBar::slotActivateCrate(CrateSummary crate) { + VERIFY_OR_DEBUG_ASSERT(m_pLibrary && m_pLibrary->getCreateFeature()) { + return; + } + m_pLibrary->getCreateFeature()->activate(); + m_pLibrary->getCreateFeature()->activateCrate(crate.getId()); +} + +void WInfoBar::slotActivatePlaylist(PlaylistSummary playlist, bool isHistory) { + VERIFY_OR_DEBUG_ASSERT(m_pLibrary) { + return; + } + if (isHistory) { + VERIFY_OR_DEBUG_ASSERT(m_pLibrary->getSetlogFeature()) { + return; + } + m_pLibrary->getSetlogFeature()->activate(); + m_pLibrary->getSetlogFeature()->activatePlaylist(playlist.id()); + } else { + VERIFY_OR_DEBUG_ASSERT(m_pLibrary->getPlaylistFeature()) { + return; + } + m_pLibrary->getPlaylistFeature()->activate(); + m_pLibrary->getPlaylistFeature()->activatePlaylist(playlist.id()); + } +} + +void WInfoBar::receivePlaylistResults(int queryId, int total, QList playlists) { + addPlaylistResults(false, queryId, total, playlists); +} + +void WInfoBar::receiveHistoryResults(int queryId, int total, QList playlists) { + addPlaylistResults(true, queryId, total, playlists); +} + +void WInfoBar::addPlaylistResults(bool isHistory, + int queryId, + int total, + QList playlists) { + qDebug() << "WInfoBar::receivePlaylistResults" << isHistory << queryId + << total << playlists.length(); + WInfoBarContainer* container; + if (isHistory) { + container = m_pHistoryContainer; + } else { + container = m_pPlaylistsContainer; + } + // we are only interested in results we requested last + if (queryId != m_id) { + return; + } + // clear the container in case this was a refresh request + container->clear(); + foreach (PlaylistSummary playlist, playlists) { + auto item = new WInfoBarPlaylistItem(playlist, isHistory, container); + item->setTotals(total); + + connect(item, + &WInfoBarPlaylistItem::activatePlaylist, + this, + &WInfoBar::slotActivatePlaylist); + + container->addItem(item); + } + container->addStretch(0); + + //updateVisibilty(); + //m_pCratesContainer->addStretch(); +} + +void WInfoBar::clearCurrentTracks() { + foreach (TrackPointer track, qAsConst(m_currentTracks)) { + VERIFY_OR_DEBUG_ASSERT(track) { + continue; } + disconnect(track.get(), + nullptr, + this, + nullptr); } - m_pCratesContainer->addStretch(); + + m_currentTracks.clear(); } void WInfoBar::slotTrackLoaded(TrackPointer track) { @@ -137,21 +426,29 @@ void WInfoBar::slotTrackLoaded(TrackPointer track) { } m_id = generateId(); - QList lst = QList(); - lst.append(track->getId()); - emit query(m_id, lst); + clearCurrentTracks(); + m_currentTracks.append(track); + + queryCurrentTracks(); } void WInfoBar::slotTrackSelection(QList tracks) { clear(); qDebug() << "WInfoBar::slotTrackSelection"; + clearCurrentTracks(); + m_currentTracks = tracks; + + queryCurrentTracks(); +} + +void WInfoBar::queryCurrentTracks() { m_id = generateId(); QList lst = QList(); - lst.reserve(tracks.size()); + lst.reserve(m_currentTracks.size()); - foreach (auto track, tracks) { + foreach (auto track, qAsConst(m_currentTracks)) { if (track != nullptr) { lst.append(track->getId()); } @@ -167,82 +464,134 @@ void WInfoBar::setup(const QDomNode& node, const SkinContext& context) { setupUI(); } +void WInfoBar::prepareFrame(QFrame* frame) { + frame->setMinimumSize(0, 0); + frame->setSizePolicy(QSizePolicy( + QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Minimum)); +} + void WInfoBar::setupUI() { - m_pContainerFrame = new QFrame(); - m_pContainerFrame->setObjectName(QString::fromUtf8("infobarFrame")); + /* + m_pContainerFrame = new QFrame(this); + m_pContainerFrame->setObjectName(QLatin1String("infobarFrame")); m_pContainerFrame->setMinimumSize(0, 0); m_pContainer = new QHBoxLayout(); m_pContainer->setSpacing(0); - m_pContainer->setObjectName(QString::fromUtf8("infobarContainer")); + m_pContainer->setObjectName(QLatin1String("infobarContainer")); + m_pContainer->setContentsMargins(QMargins(0, 0, 0, 0)); + m_pContainer->setSpacing(0); m_pContainerFrame->setLayout(m_pContainer); - m_pCratesFrame = new QFrame(); - m_pCratesFrame->setObjectName(QString::fromUtf8("infobarCrates")); - m_pCratesFrame->setMinimumSize(0, 0); - m_pCratesFrame->setSizePolicy(QSizePolicy( - QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Minimum)); + m_pCratesFrame = new QFrame(this); + m_pCratesFrame->setObjectName(QLatin1String("infobarCrates")); + prepareFrame(m_pCratesFrame); m_pCratesContainer = new QHBoxLayout(); - m_pCratesContainer->setObjectName(QString::fromUtf8("infobarCratesContainer")); + m_pCratesContainer->setObjectName(QLatin1String("infobarCratesContainer")); + m_pCratesContainer->setContentsMargins(QMargins(0, 0, 0, 0)); m_pCratesContainer->setSpacing(0); //m_pCratesContainer->setMinimumSize(0, 0); m_pCratesFrame->setLayout(m_pCratesContainer); - m_pPlaylistsFrame = new QFrame(); - m_pPlaylistsFrame->setObjectName(QString::fromUtf8("infobarPlaylists")); - m_pPlaylistsFrame->setMinimumSize(0, 0); - m_pPlaylistsFrame->setSizePolicy(QSizePolicy( - QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Minimum)); + m_pPlaylistsFrame = new QFrame(this); + m_pPlaylistsFrame->setObjectName(QLatin1String("infobarPlaylists")); + prepareFrame(m_pPlaylistsFrame); + m_pPlaylistsContainer = new QHBoxLayout(); - m_pPlaylistsContainer->setObjectName(QString::fromUtf8("infobarPlaylistsContainer")); + m_pPlaylistsContainer->setObjectName(QLatin1String("infobarPlaylistsContainer")); //m_pPlaylistsContainer->setMinimumSize(0, 0); + m_pPlaylistsContainer->setContentsMargins(QMargins(0, 0, 0, 0)); + m_pPlaylistsContainer->setSpacing(0); + m_pPlaylistsFrame->setLayout(m_pPlaylistsContainer); - m_pHistoryFrame = new QFrame(); - m_pHistoryFrame->setObjectName(QString::fromUtf8("infobarHistory")); - m_pHistoryFrame->setMinimumSize(0, 0); - m_pHistoryFrame->setSizePolicy(QSizePolicy( - QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Minimum)); + m_pHistoryFrame = new QFrame(this); + m_pHistoryFrame->setObjectName(QLatin1String("infobarHistory")); + prepareFrame(m_pHistoryFrame); m_pHistoryContainer = new QHBoxLayout(); - m_pHistoryContainer->setObjectName(QString::fromUtf8("infobarHistoryContainer")); + m_pHistoryContainer->setObjectName(QLatin1String("infobarHistoryContainer")); + m_pHistoryContainer->setContentsMargins(QMargins(0, 0, 0, 0)); + m_pHistoryContainer->setSpacing(0); + //m_pHistoryContainer->setMinimumSize(0, 0); m_pHistoryFrame->setLayout(m_pHistoryContainer); + */ + m_pCratesContainer = new WInfoBarContainer("InfobarCrates", this); + connect(m_pCratesContainer, + &WInfoBarContainer::stateChanged, + this, + &WInfoBar::slotRebuildWidgets); + + m_pPlaylistsContainer = new WInfoBarContainer("InfobarPlaylists", this); + connect(m_pPlaylistsContainer, + &WInfoBarContainer::stateChanged, + this, + &WInfoBar::slotRebuildWidgets); + + m_pHistoryContainer = new WInfoBarContainer("InfobarHistory", this); + connect(m_pHistoryContainer, + &WInfoBarContainer::stateChanged, + this, + &WInfoBar::slotRebuildWidgets); - m_pContainer->addWidget(m_pCratesFrame, 0); - m_pContainer->addWidget(m_pPlaylistsFrame, 0); - m_pContainer->addWidget(m_pHistoryFrame, 0); - m_pContainer->addStretch(); + //m_pContainer->addWidget(m_pCratesFrame, 0); + //m_pContainer->addWidget(m_pPlaylistsFrame, 0); + //m_pContainer->addWidget(m_pHistoryFrame, 0); + //m_pContainer->addStretch(); //m_pContainer->addSpacing(0); - m_pContainerFrame->setLayout(m_pContainer); - setWidget(m_pContainerFrame); + //m_pContainerFrame->setLayout(m_pContainer); + //setWidget(m_pContainerFrame); //setLayout(m_pContainer); + setSizeGripEnabled(false); + setMinimumWidth(0); + rebuildWidgets(); +} + +void WInfoBar::rebuildWidgets() { + removeWidget(m_pCratesContainer); + removeWidget(m_pPlaylistsContainer); + removeWidget(m_pHistoryContainer); + + insertWidget(0, + m_pCratesContainer, + m_pCratesContainer->state() == WInfoBarButton::State::EXPANDED ? 1 + : 0); + insertWidget(1, + m_pPlaylistsContainer, + m_pPlaylistsContainer->state() == WInfoBarButton::State::EXPANDED + ? 1 + : 0); + insertWidget(2, + m_pHistoryContainer, + m_pHistoryContainer->state() == WInfoBarButton::State::EXPANDED + ? 1 + : 0); + + m_pCratesContainer->show(); + m_pPlaylistsContainer->show(); + m_pHistoryContainer->show(); } void WInfoBar::clear() { - QLayoutItem* child; - while ((child = m_pCratesContainer->takeAt(0)) != nullptr) { - delete child->widget(); // delete the widget - delete child; // delete the layout item - } - while ((child = m_pPlaylistsContainer->takeAt(0)) != nullptr) { - delete child->widget(); // delete the widget - delete child; // delete the layout item - } - while ((child = m_pHistoryContainer->takeAt(0)) != nullptr) { - delete child->widget(); // delete the widget - delete child; // delete the layout item - } + m_pCratesContainer->clear(); + m_pPlaylistsContainer->clear(); + m_pHistoryContainer->clear(); } -void WInfoBar::mouseMoveEvent(QMouseEvent* event) { - if ((event->buttons() & Qt::LeftButton) && m_pCurrentTrack) { - DragAndDropHelper::dragTrack(m_pCurrentTrack, this, m_pGroup); - } +void WInfoBar::contextMenuEvent(QContextMenuEvent* event) { + Q_UNUSED(event); + qDebug() << "contextmen"; } +// void WInfoBar::mouseMoveEvent(QMouseEvent* event) { +// if ((event->buttons() & Qt::LeftButton) && m_pCurrentTrack) { +// DragAndDropHelper::dragTrack(m_pCurrentTrack, this, m_pGroup); +// } +// } + void WInfoBar::dragEnterEvent(QDragEnterEvent* event) { event->ignore(); } diff --git a/src/widget/winfobar.h b/src/widget/winfobar.h index 908b5e4d5f36..7c606f348b19 100644 --- a/src/widget/winfobar.h +++ b/src/widget/winfobar.h @@ -2,17 +2,22 @@ #include #include +#include #include #include #include #include #include +#include #include +#include +#include #include "library/library.h" #include "library/trackcollection.h" #include "library/trackcollectionmanager.h" #include "library/trackset/crate/cratestorage.h" +#include "library/trackset/playlistsummary.h" #include "preferences/usersettings.h" #include "skin/skincontext.h" #include "track/track.h" @@ -27,8 +32,14 @@ class WInfoBarWorker : public QObject { public slots: void query(int query, QList); + void queryCrates(int query, QList trackIds); + void queryPlaylists(int query, QList trackIds); + void queryHistory(int query, QList trackIds); + signals: - void crateResult(int query, uint total, QList); + void crateResult(int query, int total, QList); + void playlistResult(int query, int total, QList); + void historyResult(int query, int total, QList); private: // add your variables here @@ -36,28 +47,128 @@ class WInfoBarWorker : public QObject { }; class WInfoBarItem : public QPushButton { + Q_OBJECT public: WInfoBarItem(const QString& text, QWidget* parent = nullptr); + ~WInfoBarItem() = default; + void setTotals(int totals) { + m_totals = totals; + }; + int totals() { + return m_totals; + }; + void setMatches(int matches) { + m_matches = matches; + }; + int matches() { + return m_matches; + }; + + bool notAll() { + return matches() != totals(); + } + + Q_PROPERTY(int totals READ totals WRITE setTotals); + Q_PROPERTY(int matches READ matches WRITE setMatches); + Q_PROPERTY(bool notAll READ notAll); + + private: + int m_totals; + int m_matches; }; class WInfoBarCrateItem : public WInfoBarItem { + Q_OBJECT + public: WInfoBarCrateItem(const CrateSummary crate, QWidget* parent = nullptr); + + signals: + void activateCrate(CrateSummary crate); + + private: + const CrateSummary m_crate; }; -class WInfoBarCrateMixedItem : public WInfoBarCrateItem { +class WInfoBarPlaylistItem : public WInfoBarItem { + Q_OBJECT public: - WInfoBarCrateMixedItem(const CrateSummary crate, QWidget* parent = nullptr); + WInfoBarPlaylistItem(const PlaylistSummary playlist, bool isHistory, QWidget* parent = nullptr); + + Q_PROPERTY(bool isHistory MEMBER m_isHistory CONSTANT); + signals: + void activatePlaylist(PlaylistSummary playlist, bool isHistory); + + private: + const PlaylistSummary m_playlist; + const bool m_isHistory; }; -class QVBoxLayout; -class QHBoxLayout; -class QFrame; +//Q_DECLARE_METATYPE(WInfoBarButtonState); -class WInfoBar : public QScrollArea, public WBaseWidget { +class WInfoBarButton : public QToolButton { + Q_OBJECT + public: + enum State { + VISIBLE, + HIDDEN, + EXPANDED + }; + Q_ENUM(State); + WInfoBarButton(QWidget* pParent); + ~WInfoBarButton() = default; + void setState(State newState); + State state() { + return m_state; + }; + Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged); + void nextCheckState() override; + + signals: + void stateChanged(State newState); + + private slots: + //void slotTriggered(QAction* action); + + private: + State m_state; +}; + +//qRegisterMetaType("States"); + +class WInfoBarContainer : public QFrame { + Q_OBJECT + public: + WInfoBarContainer(QString name, QWidget* pParent); + ~WInfoBarContainer() = default; + + void addItem(WInfoBarItem* item); + void addStretch(int factor); + void clear(); + void setState(WInfoBarButton::State state); + WInfoBarButton::State state() { + VERIFY_OR_DEBUG_ASSERT(m_pButton) { + return WInfoBarButton::State::VISIBLE; + } + return m_pButton->state(); + } + signals: + void stateChanged(WInfoBarButton::State newState); + + private: + void slotStateChange(WInfoBarButton::State state); + + WInfoBarButton* m_pButton; + QHBoxLayout* m_pContainer; + QHBoxLayout* m_pMainLayout; + QWidget* m_pMainContainer; +}; + +class WInfoBar : public QStatusBar, public WBaseWidget { Q_OBJECT public: WInfoBar(QString group, UserSettingsPointer pConfig, Library* pLibrary, QWidget* pParent); + ~WInfoBar() = default; void setup(const QDomNode& node, const SkinContext& context); int generateId(); @@ -65,9 +176,14 @@ class WInfoBar : public QScrollArea, public WBaseWidget { QSize minimumSize() const { return QSize(0, 0); } - QSize minimumSizeHint() const { + QSize minimumSizeHint() const override { return QSize(0, 0); } + QSize sizeHint() const override { + QSize rv = QStatusBar::sizeHint(); + rv.setWidth(0); + return rv; + } //QSize const minimumSizeHint(); /* @@ -91,27 +207,59 @@ class WInfoBar : public QScrollArea, public WBaseWidget { //void slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack); private slots: - //void updateLabel(Track*); - void receiveCrateResults(int query, uint total, QList); + void receiveCrateResults(int queryId, int total, QList crates); + void receivePlaylistResults(int queryId, int total, QList playlists); + void receiveHistoryResults(int queryId, int total, QList playlists); + void slotActivateCrate(CrateSummary crate); + void slotActivatePlaylist(PlaylistSummary playlist, bool isHistory); + void slotRebuildWidgets(WInfoBarButton::State state) { + Q_UNUSED(state); + rebuildWidgets(); + }; + void slotCrateTracksChanged(CrateId crate, + const QList& tracksAdded, + const QList& tracksRemoved); private: + /* + void clearContainer(QHBoxLayout* layout); + void clearCrates() { clearContainer(m_pCratesContainer); } + void clearPlaylists() { clearContainer(m_pPlaylistsContainer); } + void clearHistory() { clearContainer(m_pHistoryContainer); } + */ + void addPlaylistResults(bool isHistory, + int queryId, + int total, + QList playlists); + //void updateVisibilty(); void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; + void contextMenuEvent(QContextMenuEvent* event) override; void setupUI(); + void prepareFrame(QFrame* frame); + void rebuildWidgets(); + void queryCurrentTracks(); + void clearCurrentTracks(); QFrame* m_pContainerFrame; QHBoxLayout* m_pContainer; + + /* QFrame* m_pCratesFrame; QHBoxLayout* m_pCratesContainer; QFrame* m_pPlaylistsFrame; QHBoxLayout* m_pPlaylistsContainer; QFrame* m_pHistoryFrame; QHBoxLayout* m_pHistoryContainer; + */ + WInfoBarContainer* m_pCratesContainer; + WInfoBarContainer* m_pPlaylistsContainer; + WInfoBarContainer* m_pHistoryContainer; QString m_pGroup; UserSettingsPointer m_pConfig; - TrackPointer m_pCurrentTrack; + QList m_currentTracks{}; + //QString m_property; //QString m_separator; //TrackCollectionManager* const m_pCollectionManager; diff --git a/src/widget/wmainmenubar.cpp b/src/widget/wmainmenubar.cpp index 2e14b9d2dddb..bdf0f683f308 100644 --- a/src/widget/wmainmenubar.cpp +++ b/src/widget/wmainmenubar.cpp @@ -270,19 +270,20 @@ void WMainMenuBar::initialize() { createVisibilityControl(pViewShowCoverArt, ConfigKey("[Library]", "show_coverart")); pViewMenu->addAction(pViewShowCoverArt); - QString showCratesTitle = tr("Show Crates List"); - QString showCratesText = tr("Show a list with crates the selection is in") + + QString showInfobarTitle = tr("Show Infobar"); + QString showInfobarText = tr("Show a infobar with crates/playlist " + "information about the selected track") + " " + mayNotBeSupported; - auto pViewShowCrates = new QAction(showCratesTitle, this); - pViewShowCrates->setCheckable(true); - pViewShowCrates->setShortcut( + auto pViewShowInfobar = new QAction(showInfobarTitle, this); + pViewShowInfobar->setCheckable(true); + pViewShowInfobar->setShortcut( QKeySequence(m_pKbdConfig->getValue( - ConfigKey("[KeyboardShortcuts]", "ViewMenu_ShowCrates"), - tr("Ctrl+7", "Menubar|View|Show Crates Section")))); - pViewShowCrates->setStatusTip(showCratesText); - pViewShowCrates->setWhatsThis(buildWhatsThis(showCratesTitle, showCratesText)); - createVisibilityControl(pViewShowCrates, ConfigKey("[Library]", "show_crates")); - pViewMenu->addAction(pViewShowCrates); + ConfigKey("[KeyboardShortcuts]", "ViewMenu_ShowInfobar"), + tr("Ctrl+7", "Menubar|View|Show Infobar")))); + pViewShowInfobar->setStatusTip(showInfobarText); + pViewShowInfobar->setWhatsThis(buildWhatsThis(showInfobarTitle, showInfobarText)); + createVisibilityControl(pViewShowInfobar, ConfigKey("[Library]", "show_infobar")); + pViewMenu->addAction(pViewShowInfobar); QString maximizeLibraryTitle = tr("Maximize Library"); QString maximizeLibraryText = tr("Maximize the track library to take up all the available screen space.") + From 2e2e6e0707b88b3cd0efc58e28ae8623e3344d4b Mon Sep 17 00:00:00 2001 From: Daniel Poelzleithner Date: Sun, 6 Dec 2020 01:21:17 +0100 Subject: [PATCH 6/6] remove duplicate entry --- src/controllers/controlpickermenu.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index d40084b77fee..16b9233cfc4a 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -1128,11 +1128,6 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Cover Art Show/Hide (Library)"), tr("Show/hide cover art in the library"), guiMenu); - addControl("[Library]", - "show_infobar", - tr("Crates List Show/Hide"), - tr("Show/hide infobar"), - guiMenu); addControl("[Master]", "maximize_library", tr("Library Maximize/Restore"),