Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 8 additions & 3 deletions src/library/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,12 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) {
m_pConfig->getValue(
kSidebarHoverExpandDelayConfigKey,
kSidebarHoverExpandDelayDefault);
pSidebarWidget->slotSetExpandOnHoverDelay(sidebarHoverExpandDelay);
const auto sidebarHoverCollapseDelay =
m_pConfig->getValue(
kSidebarHoverCollapseDelayConfigKey,
kSidebarHoverCollapseDelayDefault);
pSidebarWidget->slotSetExpandCollapseOnHoverDelay(
sidebarHoverExpandDelay, sidebarHoverCollapseDelay);

m_pLibraryControl->bindSidebarWidget(pSidebarWidget);

Expand Down Expand Up @@ -392,9 +397,9 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) {
&WLibrarySidebar::slotSetFont);

connect(this,
&Library::setSidebarHoverExpandDelay,
&Library::setSidebarHoverDelay,
pSidebarWidget,
&WLibrarySidebar::slotSetExpandOnHoverDelay);
&WLibrarySidebar::slotSetExpandCollapseOnHoverDelay);

for (const auto& feature : std::as_const(m_features)) {
feature->bindSidebarWidget(pSidebarWidget);
Expand Down
2 changes: 1 addition & 1 deletion src/library/library.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class Library: public QObject {
void setTrackTableRowHeight(int rowHeight);
void setSelectedClick(bool enable);

void setSidebarHoverExpandDelay(int delay);
void setSidebarHoverDelay(int expandDelay, int collapseDelay);

void onTrackAnalyzerProgress(TrackId trackId, AnalyzerProgress analyzerProgress);

Expand Down
5 changes: 5 additions & 0 deletions src/library/library_prefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,8 @@ const ConfigKey mixxx::library::prefs::kSidebarHoverExpandDelayConfigKey =
ConfigKey{
mixxx::library::prefs::kConfigGroup,
QStringLiteral("sidebar_hover_expand_delay")};

const ConfigKey mixxx::library::prefs::kSidebarHoverCollapseDelayConfigKey =
ConfigKey{
mixxx::library::prefs::kConfigGroup,
QStringLiteral("sidebar_hover_collapse_delay")};
4 changes: 4 additions & 0 deletions src/library/library_prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ const int kSidebarHoverExpandDelayDefault = 500; // ms

extern const ConfigKey kSidebarHoverExpandDelayConfigKey;

const int kSidebarHoverCollapseDelayDefault = 750; // ms

extern const ConfigKey kSidebarHoverCollapseDelayConfigKey;

} // namespace prefs

} // namespace library
Expand Down
104 changes: 104 additions & 0 deletions src/library/sidebarmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
#include "moc_sidebarmodel.cpp"
#include "util/assert.h"
#include "util/cmdlineargs.h"
#include "util/dnd.h"

namespace {

/// The MIME type supported for drag & drop
const QString kUriListMimeType = QStringLiteral("text/uri-list");

/// The time between selecting and activating (= clicking) a feature item
/// in the sidebar tree. This is essential to allow smooth scrolling through
/// a list of items with an encoder or the keyboard! A value of 300 ms has
Expand All @@ -27,6 +31,7 @@ SidebarModel::SidebarModel(
: QAbstractItemModel(parent),
m_iDefaultSelectedIndex(0),
m_pressedUntilClickedTimer(new QTimer(this)) {
m_mimeTypes << kUriListMimeType;
m_pressedUntilClickedTimer->setSingleShot(true);
connect(m_pressedUntilClickedTimer,
&QTimer::timeout,
Expand Down Expand Up @@ -314,6 +319,9 @@ QVariant SidebarModel::data(const QModelIndex& index, int role) const {
return pTreeItem->getData();
case SidebarModel::IconNameRole:
// TODO: Add support for icon names in tree items
return QVariant();
case SidebarModel::UrlRole:
return pTreeItem->getUrl();
default:
return QVariant();
}
Expand Down Expand Up @@ -437,6 +445,102 @@ void SidebarModel::deleteItem(const QModelIndex& index) {
}
}

QStringList SidebarModel::mimeTypes() const {
return m_mimeTypes;
}

QMimeData* SidebarModel::mimeData(const QModelIndexList& indexes) const {
if constexpr (kDebug) {
qDebug() << "SidebarModel::mimeData() indexes=" << indexes;
}
DEBUG_ASSERT(mimeTypes().size() == 1 && mimeTypes().at(0) == kUriListMimeType);
const auto urls = collectUrls(indexes);
if (urls.isEmpty()) {
return nullptr;
} else {
QMimeData* mimeData = new QMimeData();
mimeData->setUrls(urls);
return mimeData;
}
}

QList<QUrl> SidebarModel::collectUrls(const QModelIndexList& indexes) const {
QList<QUrl> urls;
urls.reserve(indexes.size());
// The list of indexes we're given may contain separate indices for each
// column, so even if only one row is selected, we might have columnCount()
// indices. We need to only count a single QModelIndex per unique row.
//
// TODO(cr7pt0gr4ph7): An alternative implementation would be to instead
// use a QSet<QUrl> to check if an URL has already been seen. Are there
// any cases where the behavior of these two implementations would differ?
QSet<QModelIndex> visitedRows;
for (const auto& index : indexes) {
if (!index.isValid()) {
continue;
}
auto uniqueRow = index.siblingAtColumn(0);
if (visitedRows.contains(uniqueRow)) {
continue;
}
visitedRows.insert(uniqueRow);
QUrl url = data(index, Roles::UrlRole).toUrl();
if (url.isValid()) {
urls.append(url);
}
}
return urls;
}

Qt::ItemFlags SidebarModel::flags(const QModelIndex& index) const {
Q_UNUSED(index);
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}

QModelIndex SidebarModel::resolveDropIndex(int row, int column, const QModelIndex& parent) const {
Q_UNUSED(row);
Q_UNUSED(column);
return parent;
}

bool SidebarModel::canDropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& parent) const {
Q_UNUSED(action);
const QModelIndex index = resolveDropIndex(row, column, parent);

if (data->hasUrls()) {
return dragMoveAccept(index, data->urls());
}

return false;
}

bool SidebarModel::dropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& parent) {
Q_UNUSED(action);
QModelIndex index = resolveDropIndex(row, column, parent);

if (data->hasUrls()) {
const QList<QUrl> urls = data->urls();

// m_sourceOfCurrentDragDropEvent will be NULL if
// something is dropped from a different application
return dropAccept(index, urls, m_sourceOfCurrentDragDropEvent);
}

return false;
}

void SidebarModel::setSourceOfCurrentDragDropEvent(QObject* source) {
m_sourceOfCurrentDragDropEvent = source;
}

bool SidebarModel::dropAccept(const QModelIndex& index, const QList<QUrl>& urls, QObject* pSource) {
if constexpr (kDebug) {
qDebug() << "SidebarModel::dropAccept() index=" << index << urls;
Expand Down
19 changes: 19 additions & 0 deletions src/library/sidebarmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SidebarModel : public QAbstractItemModel {
enum Roles {
IconNameRole = Qt::UserRole + 1,
DataRole,
UrlRole,
};
Q_ENUM(Roles);

Expand All @@ -38,6 +39,21 @@ class SidebarModel : public QAbstractItemModel {
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index,
int role = Qt::DisplayRole) const override;
QStringList mimeTypes() const override;
QMimeData* mimeData(const QModelIndexList& indexes) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
QModelIndex resolveDropIndex(int row, int column, const QModelIndex& index) const;
bool canDropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& index) const override;
bool dropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& index) override;
void setSourceOfCurrentDragDropEvent(QObject* source);
bool dropAccept(const QModelIndex& index, const QList<QUrl>& urls, QObject* pSource);
bool dragMoveAccept(const QModelIndex& index, const QList<QUrl>& urls) const;
bool hasChildren(const QModelIndex& parent = QModelIndex()) const override;
Expand Down Expand Up @@ -90,13 +106,16 @@ class SidebarModel : public QAbstractItemModel {
QList<LibraryFeature*> m_sFeatures;

private:
QList<QUrl> collectUrls(const QModelIndexList& indexes) const;
QModelIndex translateSourceIndex(const QModelIndex& parent);
QModelIndex translateIndex(const QModelIndex& index, const QAbstractItemModel* model);
void featureRenamed(LibraryFeature*);
unsigned int m_iDefaultSelectedIndex; /** Index of the item in the sidebar model to select at startup. */

QTimer* const m_pressedUntilClickedTimer;
QModelIndex m_pressedIndex;
QStringList m_mimeTypes;
QObject* m_sourceOfCurrentDragDropEvent;

void startPressedUntilClickedTimer(const QModelIndex& pressedIndex);
void stopPressedUntilClickedTimer();
Expand Down
9 changes: 9 additions & 0 deletions src/library/treeitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QIcon>
#include <QList>
#include <QString>
#include <QUrl>
#include <QVariant>
#include <memory>

Expand Down Expand Up @@ -112,6 +113,13 @@ class TreeItem final {
return m_data;
}

void setUrl(const QUrl& url) {
m_url = url;
}
const QUrl& getUrl() const {
return m_url;
}

void setIcon(const QIcon& icon) {
m_icon = icon;
}
Expand Down Expand Up @@ -145,6 +153,7 @@ class TreeItem final {

QString m_label;
QVariant m_data;
QUrl m_url;
QIcon m_icon;
bool m_bold;
};
2 changes: 2 additions & 0 deletions src/library/treeitemmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ QVariant TreeItemModel::data(const QModelIndex &index, int role) const {
return item->getData();
case kBoldRole:
return item->isBold();
case kUrlRole:
return item->getUrl();
default:
return QVariant();
}
Expand Down
5 changes: 3 additions & 2 deletions src/library/treeitemmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ class TreeItem;
class TreeItemModel : public QAbstractItemModel {
Q_OBJECT
public:
static const int kDataRole = Qt::UserRole;
static const int kBoldRole = Qt::UserRole + 1;
static constexpr int kDataRole = Qt::UserRole;
static constexpr int kBoldRole = Qt::UserRole + 1;
static constexpr int kUrlRole = Qt::UserRole + 2;

explicit TreeItemModel(QObject* parent = nullptr);
~TreeItemModel() override;
Expand Down
11 changes: 10 additions & 1 deletion src/preferences/dialog/dlgpreflibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ void DlgPrefLibrary::slotResetToDefaults() {
}

spinBox_sidebar_hover_expand_delay->setValue(kSidebarHoverExpandDelayDefault);
spinBox_sidebar_hover_collapse_delay->setValue(kSidebarHoverCollapseDelayDefault);

checkBox_show_rhythmbox->setChecked(true);
checkBox_show_banshee->setChecked(true);
Expand Down Expand Up @@ -464,6 +465,12 @@ void DlgPrefLibrary::slotUpdate() {
kSidebarHoverExpandDelayConfigKey,
kSidebarHoverExpandDelayDefault);
spinBox_sidebar_hover_expand_delay->setValue(sidebarHoverExpandDelay);

const auto sidebarHoverCollapseDelay =
m_pConfig->getValue(
kSidebarHoverCollapseDelayConfigKey,
kSidebarHoverCollapseDelayDefault);
spinBox_sidebar_hover_collapse_delay->setValue(sidebarHoverCollapseDelay);
}

void DlgPrefLibrary::slotCancel() {
Expand Down Expand Up @@ -684,8 +691,10 @@ void DlgPrefLibrary::slotApply() {
ConfigValue(checkbox_played_track_color->isChecked()));

int sidebarHoverExpandDelay = spinBox_sidebar_hover_expand_delay->value();
int sidebarHoverCollapseDelay = spinBox_sidebar_hover_collapse_delay->value();
m_pConfig->setValue(kSidebarHoverExpandDelayConfigKey, sidebarHoverExpandDelay);
emit m_pLibrary->setSidebarHoverExpandDelay(sidebarHoverExpandDelay);
m_pConfig->setValue(kSidebarHoverCollapseDelayConfigKey, sidebarHoverCollapseDelay);
emit m_pLibrary->setSidebarHoverDelay(sidebarHoverExpandDelay, sidebarHoverCollapseDelay);

// TODO(rryan): Don't save here.
m_pConfig->save();
Expand Down
35 changes: 34 additions & 1 deletion src/preferences/dialog/dlgpreflibrarydlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,40 @@
<string> ms</string>
</property>
<property name="toolTip">
<string>The delay until sidebar items are expanded or collapsed hovered during drag'n'drop. -1 disables auto-expand.</string>
<string>The delay until sidebar items are expanded hovered during drag'n'drop. -1 disables auto-expand.</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>50</number>
</property>
</widget>
</item>

<item row="1" column="0">
<widget class="QLabel" name="label_sidebar_hover_collapse_delay">
<property name="text">
<string>Hover collapse delay:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>spinBox_sidebar_hover_collapse_delay</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QSpinBox" name="spinBox_sidebar_hover_collapse_delay">
<property name="suffix">
<string> ms</string>
</property>
<property name="toolTip">
<string>The delay until sidebar items are collapsed hovered during drag'n'drop. -1 disables auto-expand.</string>
</property>
<property name="minimum">
<number>-1</number>
Expand Down
Loading
Loading