Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eb5cf7e
Highlight Crates a Track is in. Still some work to do
May 28, 2015
3832e41
Rename delegate according to his function
May 28, 2015
dccb519
Highlighting crates the selected track is in works now
May 29, 2015
c48d33a
Some minor code-style fixes
May 29, 2015
a096fb6
Added comment to CrateHighlightDelegate::initStyleOption
May 29, 2015
ca3f011
Added highlighting of playlists
May 29, 2015
34ce420
Another aproach for Repainting preventing the selection to move
May 29, 2015
5d09cfa
Ignore QModelIndex's that don't have TreeItem internal pointers in Cr…
rryan May 29, 2015
915c682
Fix SidebarModel handling of child models' dataChanged signals.
rryan May 29, 2015
f2fb6bf
Merge pull request #1 from rryan/sidebar-highlight
MK-42 May 29, 2015
8f27dc3
Holding Track-Crate relation in memory for faster highlighting
May 29, 2015
4dbc7ac
Holding Track-Playlist relation in memory for faster highlighting
May 29, 2015
d9c3db3
Clean up used memory
May 29, 2015
29cd09a
fix missing signals
May 29, 2015
dc1f573
Clear selected Playlists/Crates on viewChange
May 29, 2015
dbb60d8
Remove CrateHighlightDelegate.
rryan May 30, 2015
6552667
Add bold attribute to TreeItem.
rryan May 30, 2015
d6692f0
Restore LibraryFeature::trackSelected signal.
rryan May 30, 2015
89e3ad3
Respond to Qt::FontRole in SidebarModel.
rryan May 30, 2015
986013d
Populate playlist and crate TreeItems with bold attribute when track …
rryan May 30, 2015
939428f
Populate TreeItem state when re-building the child model.
rryan May 30, 2015
4a75b85
Merge pull request #2 from rryan/sidebar-highlight
MK-42 May 31, 2015
55381bf
Swap key/value pairing of crate/playlist membership cache in CrateDAO…
rryan Jun 2, 2015
1176128
Fetch playlist / crate membership set on track selection.
rryan Jun 3, 2015
41c5fa5
Fix crate/playlist membership fetchers.
rryan Jun 10, 2015
de3e581
Don't call TreeItemModel::setData in a loop.
rryan Jun 10, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/library/baseplaylistfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QFileInfo>
#include <QDesktopServices>

#include "library/library.h"
#include "library/parser.h"
#include "library/parserm3u.h"
#include "library/parserpls.h"
Expand Down Expand Up @@ -82,6 +83,12 @@ BasePlaylistFeature::BasePlaylistFeature(QObject* parent,

connect(&m_playlistDao, SIGNAL(lockChanged(int)),
this, SLOT(slotPlaylistTableChanged(int)));

Library* pLibrary = static_cast<Library*>(parent);
connect(pLibrary, SIGNAL(trackSelected(TrackPointer)),
this, SLOT(slotTrackSelected(TrackPointer)));
connect(pLibrary, SIGNAL(switchToView(const QString&)),
this, SLOT(slotResetSelectedTrack()));
}

BasePlaylistFeature::~BasePlaylistFeature() {
Expand Down Expand Up @@ -553,6 +560,8 @@ QModelIndex BasePlaylistFeature::constructChildModel(int selected_id) {

// 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));

decorateChild(item, playlist_id);
data_list.append(item);
}
Expand Down Expand Up @@ -585,3 +594,36 @@ QModelIndex BasePlaylistFeature::indexFromPlaylistId(int playlistId) {
}
return QModelIndex();
}

void BasePlaylistFeature::slotTrackSelected(TrackPointer pTrack) {
m_pSelectedTrack = pTrack;
int trackId = pTrack.isNull() ? -1 : pTrack->getId();
m_playlistDao.getPlaylistsTrackIsIn(trackId, &m_playlistsSelectedTrackIsIn);

TreeItem* rootItem = m_childModel.getItem(QModelIndex());
if (rootItem == nullptr) {
return;
}

// Set all playlists the track is in bold (or if there is no track selected,
// clear all the bolding).
int row = 0;
for (QList<QPair<int, QString> >::const_iterator it = m_playlistList.begin();
it != m_playlistList.end(); ++it, ++row) {
TreeItem* playlist = rootItem->child(row);
if (playlist == nullptr) {
continue;
}

int playlistId = it->first;
bool shouldBold = m_playlistsSelectedTrackIsIn.contains(playlistId);
playlist->setBold(shouldBold);
}

m_childModel.triggerRepaint();
}


void BasePlaylistFeature::slotResetSelectedTrack() {
slotTrackSelected(TrackPointer());
}
8 changes: 8 additions & 0 deletions src/library/baseplaylistfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
#include <QAction>
#include <QList>
#include <QPair>
#include <QSet>
#include <QString>

#include "library/libraryfeature.h"
#include "library/dao/playlistdao.h"
#include "library/dao/trackdao.h"
#include "trackinfoobject.h"

class WLibrary;
class MixxxKeyboard;
Expand Down Expand Up @@ -89,10 +91,16 @@ class BasePlaylistFeature : public LibraryFeature {
QList<QPair<int, QString> > m_playlistList;
QModelIndex m_lastRightClickedIndex;
TreeItemModel m_childModel;
TrackPointer m_pSelectedTrack;

private slots:
void slotTrackSelected(TrackPointer pTrack);
void slotResetSelectedTrack();

private:
virtual QString getRootViewHtml() const = 0;

QSet<int> m_playlistsSelectedTrackIsIn;
QString m_rootViewName;
};

Expand Down
40 changes: 38 additions & 2 deletions src/library/cratefeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
#include "util/dnd.h"
#include "util/time.h"

CrateFeature::CrateFeature(QObject* parent,
CrateFeature::CrateFeature(Library* pLibrary,
TrackCollection* pTrackCollection,
ConfigObject<ConfigValue>* pConfig)
: m_pTrackCollection(pTrackCollection),
m_crateDao(pTrackCollection->getCrateDAO()),
m_crateTableModel(this, pTrackCollection),
m_pConfig(pConfig) {
Q_UNUSED(parent);
m_pCreateCrateAction = new QAction(tr("Create New Crate"),this);
connect(m_pCreateCrateAction, SIGNAL(triggered()),
this, SLOT(slotCreateCrate()));
Expand Down Expand Up @@ -92,6 +91,11 @@ CrateFeature::CrateFeature(QObject* parent,
TreeItem *rootItem = new TreeItem();
m_childModel.setRootItem(rootItem);
constructChildModel(-1);

connect(pLibrary, SIGNAL(trackSelected(TrackPointer)),
this, SLOT(slotTrackSelected(TrackPointer)));
connect(pLibrary, SIGNAL(switchToView(const QString&)),
this, SLOT(slotResetSelectedTrack()));
}

CrateFeature::~CrateFeature() {
Expand Down Expand Up @@ -511,6 +515,7 @@ QModelIndex CrateFeature::constructChildModel(int selected_id) {
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);
}

Expand Down Expand Up @@ -705,3 +710,34 @@ QString CrateFeature::getRootViewHtml() const {
html.append("</td></tr></table>");
return html;
}

void CrateFeature::slotTrackSelected(TrackPointer pTrack) {
m_pSelectedTrack = pTrack;
int trackId = pTrack.isNull() ? -1 : 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<QPair<int, QString> >::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());
}
11 changes: 10 additions & 1 deletion src/library/cratefeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@
#include <QUrl>
#include <QIcon>
#include <QPoint>
#include <QSet>

#include "library/libraryfeature.h"
#include "library/cratetablemodel.h"
#include "library/library.h"

#include "treeitemmodel.h"
#include "configobject.h"
#include "trackinfoobject.h"

class TrackCollection;

class CrateFeature : public LibraryFeature {
Q_OBJECT
public:
CrateFeature(QObject* parent,
CrateFeature(Library* pLibrary,
TrackCollection* pTrackCollection,
ConfigObject<ConfigValue>* pConfig);
virtual ~CrateFeature();
Expand Down Expand Up @@ -60,6 +63,10 @@ class CrateFeature : public LibraryFeature {
void slotCrateTableRenamed(int playlistId, QString a_strName);
void htmlLinkClicked(const QUrl& link);

private slots:
void slotTrackSelected(TrackPointer pTrack);
void slotResetSelectedTrack();

private:
QString getRootViewHtml() const;
QModelIndex constructChildModel(int selected_id);
Expand All @@ -85,6 +92,8 @@ class CrateFeature : public LibraryFeature {
QModelIndex m_lastRightClickedIndex;
TreeItemModel m_childModel;
ConfigObject<ConfigValue>* m_pConfig;
TrackPointer m_pSelectedTrack;
QSet<int> m_cratesSelectedTrackIsIn;
};

#endif /* CRATEFEATURE_H */
63 changes: 63 additions & 0 deletions src/library/dao/cratedao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,36 @@ CrateDAO::~CrateDAO() {

void CrateDAO::initialize() {
qDebug() << "CrateDAO::initialize()";

populateCrateMembershipCache();
}

void CrateDAO::populateCrateMembershipCache() {
// get the count to allocate HashMap
int tracksInCratesCount = 0;
QSqlQuery query(m_database);
query.prepare("SELECT COUNT(*) from " CRATE_TRACKS_TABLE);

if (!query.exec()) {
LOG_FAILED_QUERY(query);
}

tracksInCratesCount = query.value(0).toInt();

m_cratesTrackIsIn.reserve(tracksInCratesCount);

// now fetch all Tracks from all crates and insert them into the hashmap
query.prepare("SELECT track_id, crate_id from " CRATE_TRACKS_TABLE);
if (!query.exec()) {
LOG_FAILED_QUERY(query);
}

const int trackIdColumn = query.record().indexOf("track_id");
const int crateIdColumn = query.record().indexOf("crate_id");
while (query.next()) {
m_cratesTrackIsIn.insert(query.value(trackIdColumn).toInt(),
query.value(crateIdColumn).toInt());
}
}

unsigned int CrateDAO::crateCount() {
Expand Down Expand Up @@ -236,6 +266,17 @@ bool CrateDAO::deleteCrate(const int crateId) {
transaction.commit();

emit(deleted(crateId));

// Update in-memory map
for (QMultiHash<int, int>::iterator it = m_cratesTrackIsIn.begin();
it != m_cratesTrackIsIn.end();) {
if (it.value() == crateId) {
it = m_cratesTrackIsIn.erase(it);
} else {
it++;
}
}

return true;
}

Expand Down Expand Up @@ -332,6 +373,7 @@ bool CrateDAO::addTrackToCrate(const int trackId, const int crateId) {
return false;
}

m_cratesTrackIsIn.insert(trackId, crateId);
emit(trackAdded(crateId, trackId));
emit(changed(crateId));
return true;
Expand All @@ -358,6 +400,7 @@ int CrateDAO::addTracksToCrate(const int crateId, QList<int>* trackIdList) {

// Emitting the trackAdded signals for each trackID outside the transaction
foreach(int trackId, *trackIdList) {
m_cratesTrackIsIn.insert(trackId, crateId);
emit(trackAdded(crateId, trackId));
}

Expand All @@ -379,6 +422,7 @@ bool CrateDAO::removeTrackFromCrate(const int trackId, const int crateId) {
return false;
}

m_cratesTrackIsIn.remove(trackId, crateId);
emit(trackRemoved(crateId, trackId));
emit(changed(crateId));
return true;
Expand All @@ -400,6 +444,7 @@ bool CrateDAO::removeTracksFromCrate(const QList<int>& ids, const int crateId) {
return false;
}
foreach (int trackId, ids) {
m_cratesTrackIsIn.remove(trackId, crateId);
emit(trackRemoved(crateId, trackId));
}
emit(changed(crateId));
Expand All @@ -418,7 +463,25 @@ void CrateDAO::removeTracksFromCrates(const QList<int>& ids) {
LOG_FAILED_QUERY(query);
}

// remove those tracks from memory-map
foreach (int trackId, ids) {
m_cratesTrackIsIn.remove(trackId);
}

// TODO(XXX) should we emit this for all crates?
// emit(trackRemoved(crateId, trackId));
// emit(changed(crateId));
}

bool CrateDAO::isTrackInCrate(const int trackId, const int crateId) {
return m_cratesTrackIsIn.contains(trackId, crateId);
}

void CrateDAO::getCratesTrackIsIn(const int trackId,
QSet<int>* crateSet) const {
crateSet->clear();
for (QHash<int, int>::const_iterator it = m_cratesTrackIsIn.find(trackId);
it != m_cratesTrackIsIn.end() && it.key() == trackId; ++it) {
crateSet->insert(it.value());
}
}
7 changes: 7 additions & 0 deletions src/library/dao/cratedao.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include <QObject>
#include <QMap>
#include <QMultiHash>
#include <QSqlDatabase>
#include <QSet>

#include "library/dao/dao.h"
#include "util.h"
Expand Down Expand Up @@ -61,6 +63,8 @@ class CrateDAO : public QObject, public virtual DAO {
bool removeTracksFromCrate(const QList<int>& ids, const int crateId);
// remove tracks from all crates
void removeTracksFromCrates(const QList<int>& ids);
bool isTrackInCrate(const int trackId, const int crateId);
void getCratesTrackIsIn(const int trackId, QSet<int>* crateSet) const;

signals:
void added(int crateId);
Expand All @@ -73,7 +77,10 @@ class CrateDAO : public QObject, public virtual DAO {
void autoDjChanged(int a_iCrateId, bool a_bIn);

private:
void populateCrateMembershipCache();

QSqlDatabase& m_database;
QMultiHash<int,int> m_cratesTrackIsIn;
DISALLOW_COPY_AND_ASSIGN(CrateDAO);
};

Expand Down
Loading