Hide use of boost multi-index behind pimpl.
This commit is contained in:
parent
71893e4847
commit
8d1f4612db
@ -22,14 +22,61 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
// boost::multi_index still relies on these being in the global namespace.
|
||||||
|
using std::placeholders::_1;
|
||||||
|
using std::placeholders::_2;
|
||||||
|
|
||||||
|
#include <boost/multi_index_container.hpp>
|
||||||
|
#include <boost/multi_index/member.hpp>
|
||||||
|
#include <boost/multi_index/hashed_index.hpp>
|
||||||
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
|
|
||||||
|
using boost::multi_index::hashed_unique;
|
||||||
|
using boost::multi_index::identity;
|
||||||
|
using boost::multi_index::indexed_by;
|
||||||
|
using boost::multi_index::member;
|
||||||
|
using boost::multi_index::multi_index_container;
|
||||||
|
using boost::multi_index::ordered_unique;
|
||||||
|
using boost::multi_index::tag;
|
||||||
|
|
||||||
std::size_t hash_value(const QModelIndex& index) {
|
std::size_t hash_value(const QModelIndex& index) {
|
||||||
return qHash(index);
|
return qHash(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Mapping {
|
||||||
|
Mapping(const QModelIndex& _source_index)
|
||||||
|
: source_index(_source_index) {}
|
||||||
|
|
||||||
|
QModelIndex source_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tag_by_source {};
|
||||||
|
struct tag_by_pointer {};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class MergedProxyModelPrivate {
|
||||||
|
private:
|
||||||
|
typedef multi_index_container<
|
||||||
|
Mapping*,
|
||||||
|
indexed_by<
|
||||||
|
hashed_unique<tag<tag_by_source>,
|
||||||
|
member<Mapping, QModelIndex, &Mapping::source_index> >,
|
||||||
|
ordered_unique<tag<tag_by_pointer>,
|
||||||
|
identity<Mapping*> >
|
||||||
|
>
|
||||||
|
> MappingContainer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MappingContainer mappings_;
|
||||||
|
};
|
||||||
|
|
||||||
MergedProxyModel::MergedProxyModel(QObject* parent)
|
MergedProxyModel::MergedProxyModel(QObject* parent)
|
||||||
: QAbstractProxyModel(parent),
|
: QAbstractProxyModel(parent),
|
||||||
resetting_model_(nullptr)
|
resetting_model_(nullptr),
|
||||||
{
|
p_(new MergedProxyModelPrivate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MergedProxyModel::~MergedProxyModel() {
|
MergedProxyModel::~MergedProxyModel() {
|
||||||
@ -37,10 +84,8 @@ MergedProxyModel::~MergedProxyModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MergedProxyModel::DeleteAllMappings() {
|
void MergedProxyModel::DeleteAllMappings() {
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator begin =
|
const auto& begin = p_->mappings_.get<tag_by_pointer>().begin();
|
||||||
mappings_.get<tag_by_pointer>().begin();
|
const auto& end = p_->mappings_.get<tag_by_pointer>().end();
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator end =
|
|
||||||
mappings_.get<tag_by_pointer>().end();
|
|
||||||
qDeleteAll(begin, end);
|
qDeleteAll(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,14 +133,12 @@ void MergedProxyModel::RemoveSubModel(const QModelIndex &source_parent) {
|
|||||||
resetting_model_ = nullptr;
|
resetting_model_ = nullptr;
|
||||||
|
|
||||||
// Delete all the mappings that reference the submodel
|
// Delete all the mappings that reference the submodel
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator it =
|
auto it = p_->mappings_.get<tag_by_pointer>().begin();
|
||||||
mappings_.get<tag_by_pointer>().begin();
|
auto end = p_->mappings_.get<tag_by_pointer>().end();
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator end =
|
|
||||||
mappings_.get<tag_by_pointer>().end();
|
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
if ((*it)->source_index.model() == submodel) {
|
if ((*it)->source_index.model() == submodel) {
|
||||||
delete *it;
|
delete *it;
|
||||||
it = mappings_.get<tag_by_pointer>().erase(it);
|
it = p_->mappings_.get<tag_by_pointer>().erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
@ -145,7 +188,7 @@ void MergedProxyModel::SourceModelReset() {
|
|||||||
DeleteAllMappings();
|
DeleteAllMappings();
|
||||||
|
|
||||||
// Clear the containers
|
// Clear the containers
|
||||||
mappings_.clear();
|
p_->mappings_.clear();
|
||||||
merge_points_.clear();
|
merge_points_.clear();
|
||||||
|
|
||||||
// Reset the proxy
|
// Reset the proxy
|
||||||
@ -170,14 +213,12 @@ void MergedProxyModel::SubModelReset() {
|
|||||||
resetting_model_ = nullptr;
|
resetting_model_ = nullptr;
|
||||||
|
|
||||||
// Delete all the mappings that reference the submodel
|
// Delete all the mappings that reference the submodel
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator it =
|
auto it = p_->mappings_.get<tag_by_pointer>().begin();
|
||||||
mappings_.get<tag_by_pointer>().begin();
|
auto end = p_->mappings_.get<tag_by_pointer>().end();
|
||||||
MappingContainer::index<tag_by_pointer>::type::iterator end =
|
|
||||||
mappings_.get<tag_by_pointer>().end();
|
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
if ((*it)->source_index.model() == submodel) {
|
if ((*it)->source_index.model() == submodel) {
|
||||||
delete *it;
|
delete *it;
|
||||||
it = mappings_.get<tag_by_pointer>().erase(it);
|
it = p_->mappings_.get<tag_by_pointer>().erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
@ -227,8 +268,8 @@ QModelIndex MergedProxyModel::mapToSource(const QModelIndex& proxy_index) const
|
|||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
Mapping* mapping = static_cast<Mapping*>(proxy_index.internalPointer());
|
Mapping* mapping = static_cast<Mapping*>(proxy_index.internalPointer());
|
||||||
if (mappings_.get<tag_by_pointer>().find(mapping) ==
|
if (p_->mappings_.get<tag_by_pointer>().find(mapping) ==
|
||||||
mappings_.get<tag_by_pointer>().end())
|
p_->mappings_.get<tag_by_pointer>().end())
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
if (mapping->source_index.model() == resetting_model_)
|
if (mapping->source_index.model() == resetting_model_)
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
@ -243,14 +284,14 @@ QModelIndex MergedProxyModel::mapFromSource(const QModelIndex& source_index) con
|
|||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
// Add a mapping if we don't have one already
|
// Add a mapping if we don't have one already
|
||||||
MappingContainer::index<tag_by_source>::type::iterator it =
|
const auto& it =
|
||||||
mappings_.get<tag_by_source>().find(source_index);
|
p_->mappings_.get<tag_by_source>().find(source_index);
|
||||||
Mapping* mapping;
|
Mapping* mapping;
|
||||||
if (it != mappings_.get<tag_by_source>().end()) {
|
if (it != p_->mappings_.get<tag_by_source>().end()) {
|
||||||
mapping = *it;
|
mapping = *it;
|
||||||
} else {
|
} else {
|
||||||
mapping = new Mapping(source_index);
|
mapping = new Mapping(source_index);
|
||||||
const_cast<MergedProxyModel*>(this)->mappings_.insert(mapping);
|
const_cast<MergedProxyModel*>(this)->p_->mappings_.insert(mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
return createIndex(source_index.row(), source_index.column(), mapping);
|
return createIndex(source_index.row(), source_index.column(), mapping);
|
||||||
|
@ -18,26 +18,14 @@
|
|||||||
#ifndef MERGEDPROXYMODEL_H
|
#ifndef MERGEDPROXYMODEL_H
|
||||||
#define MERGEDPROXYMODEL_H
|
#define MERGEDPROXYMODEL_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QAbstractProxyModel>
|
#include <QAbstractProxyModel>
|
||||||
|
|
||||||
using std::placeholders::_1;
|
|
||||||
using std::placeholders::_2;
|
|
||||||
|
|
||||||
#include <boost/multi_index_container.hpp>
|
|
||||||
#include <boost/multi_index/member.hpp>
|
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
|
||||||
#include <boost/multi_index/hashed_index.hpp>
|
|
||||||
|
|
||||||
using boost::multi_index::multi_index_container;
|
|
||||||
using boost::multi_index::indexed_by;
|
|
||||||
using boost::multi_index::hashed_unique;
|
|
||||||
using boost::multi_index::ordered_unique;
|
|
||||||
using boost::multi_index::tag;
|
|
||||||
using boost::multi_index::member;
|
|
||||||
using boost::multi_index::identity;
|
|
||||||
|
|
||||||
std::size_t hash_value(const QModelIndex& index);
|
std::size_t hash_value(const QModelIndex& index);
|
||||||
|
|
||||||
|
class MergedProxyModelPrivate;
|
||||||
|
|
||||||
class MergedProxyModel : public QAbstractProxyModel {
|
class MergedProxyModel : public QAbstractProxyModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -105,30 +93,13 @@ class MergedProxyModel : public QAbstractProxyModel {
|
|||||||
void DeleteAllMappings();
|
void DeleteAllMappings();
|
||||||
bool IsKnownModel(const QAbstractItemModel* model) const;
|
bool IsKnownModel(const QAbstractItemModel* model) const;
|
||||||
|
|
||||||
struct Mapping {
|
|
||||||
Mapping(const QModelIndex& _source_index)
|
|
||||||
: source_index(_source_index) {}
|
|
||||||
|
|
||||||
QModelIndex source_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tag_by_source {};
|
|
||||||
struct tag_by_pointer {};
|
|
||||||
typedef multi_index_container<
|
|
||||||
Mapping*,
|
|
||||||
indexed_by<
|
|
||||||
hashed_unique<tag<tag_by_source>,
|
|
||||||
member<Mapping, QModelIndex, &Mapping::source_index> >,
|
|
||||||
ordered_unique<tag<tag_by_pointer>,
|
|
||||||
identity<Mapping*> >
|
|
||||||
>
|
|
||||||
> MappingContainer;
|
|
||||||
|
|
||||||
MappingContainer mappings_;
|
|
||||||
QMap<QAbstractItemModel*, QPersistentModelIndex> merge_points_;
|
QMap<QAbstractItemModel*, QPersistentModelIndex> merge_points_;
|
||||||
QAbstractItemModel* resetting_model_;
|
QAbstractItemModel* resetting_model_;
|
||||||
|
|
||||||
QMap<QAbstractItemModel*, QModelIndex> old_merge_points_;
|
QMap<QAbstractItemModel*, QModelIndex> old_merge_points_;
|
||||||
|
|
||||||
|
std::unique_ptr<MergedProxyModelPrivate> p_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MERGEDPROXYMODEL_H
|
#endif // MERGEDPROXYMODEL_H
|
||||||
|
@ -20,25 +20,69 @@
|
|||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
// boost::multi_index still relies on these being in the global namespace.
|
||||||
|
using std::placeholders::_1;
|
||||||
|
using std::placeholders::_2;
|
||||||
|
|
||||||
|
#include <boost/multi_index_container.hpp>
|
||||||
|
#include <boost/multi_index/member.hpp>
|
||||||
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
|
|
||||||
|
using boost::multi_index_container;
|
||||||
|
using boost::multi_index::indexed_by;
|
||||||
|
using boost::multi_index::ordered_unique;
|
||||||
|
using boost::multi_index::tag;
|
||||||
|
using boost::multi_index::member;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Mapping {
|
||||||
|
Mapping(LibraryModel::GroupBy g, int i) : group_by(g), combo_box_index(i) {}
|
||||||
|
|
||||||
|
LibraryModel::GroupBy group_by;
|
||||||
|
int combo_box_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tag_index {};
|
||||||
|
struct tag_group_by {};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class GroupByDialogPrivate {
|
||||||
|
private:
|
||||||
|
typedef multi_index_container<
|
||||||
|
Mapping,
|
||||||
|
indexed_by<
|
||||||
|
ordered_unique<tag<tag_index>,
|
||||||
|
member<Mapping, int, &Mapping::combo_box_index> >,
|
||||||
|
ordered_unique<tag<tag_group_by>,
|
||||||
|
member<Mapping, LibraryModel::GroupBy, &Mapping::group_by> >
|
||||||
|
>
|
||||||
|
> MappingContainer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MappingContainer mapping_;
|
||||||
|
};
|
||||||
|
|
||||||
GroupByDialog::GroupByDialog(QWidget *parent)
|
GroupByDialog::GroupByDialog(QWidget *parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
ui_(new Ui_GroupByDialog)
|
ui_(new Ui_GroupByDialog),
|
||||||
{
|
p_(new GroupByDialogPrivate) {
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_None, 0));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_None, 0));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Album, 1));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Album, 1));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Artist, 2));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Artist, 2));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_AlbumArtist, 3));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_AlbumArtist, 3));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Composer, 4));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Composer, 4));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_FileType, 5));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_FileType, 5));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Genre, 6));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Genre, 6));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Year, 7));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Year, 7));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_YearAlbum, 8));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_YearAlbum, 8));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Bitrate, 9));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Bitrate, 9));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 10));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 10));
|
||||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 11));
|
p_->mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 11));
|
||||||
|
|
||||||
connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()),
|
connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()),
|
||||||
SLOT(Reset()));
|
SLOT(Reset()));
|
||||||
@ -46,9 +90,7 @@ GroupByDialog::GroupByDialog(QWidget *parent)
|
|||||||
resize(sizeHint());
|
resize(sizeHint());
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupByDialog::~GroupByDialog() {
|
GroupByDialog::~GroupByDialog() {}
|
||||||
delete ui_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupByDialog::Reset() {
|
void GroupByDialog::Reset() {
|
||||||
ui_->first->setCurrentIndex(2); // Artist
|
ui_->first->setCurrentIndex(2); // Artist
|
||||||
@ -58,14 +100,14 @@ void GroupByDialog::Reset() {
|
|||||||
|
|
||||||
void GroupByDialog::accept() {
|
void GroupByDialog::accept() {
|
||||||
emit Accepted(LibraryModel::Grouping(
|
emit Accepted(LibraryModel::Grouping(
|
||||||
mapping_.get<tag_index>().find(ui_->first->currentIndex())->group_by,
|
p_->mapping_.get<tag_index>().find(ui_->first->currentIndex())->group_by,
|
||||||
mapping_.get<tag_index>().find(ui_->second->currentIndex())->group_by,
|
p_->mapping_.get<tag_index>().find(ui_->second->currentIndex())->group_by,
|
||||||
mapping_.get<tag_index>().find(ui_->third->currentIndex())->group_by));
|
p_->mapping_.get<tag_index>().find(ui_->third->currentIndex())->group_by));
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupByDialog::LibraryGroupingChanged(const LibraryModel::Grouping& g) {
|
void GroupByDialog::LibraryGroupingChanged(const LibraryModel::Grouping& g) {
|
||||||
ui_->first->setCurrentIndex(mapping_.get<tag_group_by>().find(g[0])->combo_box_index);
|
ui_->first->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[0])->combo_box_index);
|
||||||
ui_->second->setCurrentIndex(mapping_.get<tag_group_by>().find(g[1])->combo_box_index);
|
ui_->second->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[1])->combo_box_index);
|
||||||
ui_->third->setCurrentIndex(mapping_.get<tag_group_by>().find(g[2])->combo_box_index);
|
ui_->third->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[2])->combo_box_index);
|
||||||
}
|
}
|
||||||
|
@ -22,28 +22,16 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using std::placeholders::_1;
|
|
||||||
using std::placeholders::_2;
|
|
||||||
|
|
||||||
#include <boost/multi_index_container.hpp>
|
|
||||||
#include <boost/multi_index/member.hpp>
|
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
|
||||||
|
|
||||||
#include "librarymodel.h"
|
#include "librarymodel.h"
|
||||||
|
|
||||||
|
class GroupByDialogPrivate;
|
||||||
class Ui_GroupByDialog;
|
class Ui_GroupByDialog;
|
||||||
|
|
||||||
using boost::multi_index_container;
|
|
||||||
using boost::multi_index::indexed_by;
|
|
||||||
using boost::multi_index::ordered_unique;
|
|
||||||
using boost::multi_index::tag;
|
|
||||||
using boost::multi_index::member;
|
|
||||||
|
|
||||||
class GroupByDialog : public QDialog {
|
class GroupByDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GroupByDialog(QWidget *parent = 0);
|
GroupByDialog(QWidget* parent = nullptr);
|
||||||
~GroupByDialog();
|
~GroupByDialog();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -57,27 +45,8 @@ class GroupByDialog : public QDialog {
|
|||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Mapping {
|
std::unique_ptr<Ui_GroupByDialog> ui_;
|
||||||
Mapping(LibraryModel::GroupBy g, int i) : group_by(g), combo_box_index(i) {}
|
std::unique_ptr<GroupByDialogPrivate> p_;
|
||||||
|
|
||||||
LibraryModel::GroupBy group_by;
|
|
||||||
int combo_box_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tag_index {};
|
|
||||||
struct tag_group_by {};
|
|
||||||
typedef multi_index_container<
|
|
||||||
Mapping,
|
|
||||||
indexed_by<
|
|
||||||
ordered_unique<tag<tag_index>,
|
|
||||||
member<Mapping, int, &Mapping::combo_box_index> >,
|
|
||||||
ordered_unique<tag<tag_group_by>,
|
|
||||||
member<Mapping, LibraryModel::GroupBy, &Mapping::group_by> >
|
|
||||||
>
|
|
||||||
> MappingContainer;
|
|
||||||
|
|
||||||
MappingContainer mapping_;
|
|
||||||
Ui_GroupByDialog* ui_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GROUPBYDIALOG_H
|
#endif // GROUPBYDIALOG_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user