mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
Refactor sorting and filtering compatibility code (GTK client) (#4558)
* Refactor sorting and filtering compatibility code Factor out parts of `TorrentFilter` and `TorrentSorter` classes into reusable `FilterBase<>` and `SorterBase<>` templates. Factor out filter and sort models setup from `FilterBar` and `Session` classes into reusable `FilterListModel<>` and `SortListModel<>` templates. * Remove unused lambda capture (Clang build failure)
This commit is contained in:
@@ -18,6 +18,10 @@ target_sources(${TR_NAME}-gtk
|
|||||||
FileList.h
|
FileList.h
|
||||||
FilterBar.cc
|
FilterBar.cc
|
||||||
FilterBar.h
|
FilterBar.h
|
||||||
|
FilterBase.h
|
||||||
|
FilterBase.hh
|
||||||
|
FilterListModel.h
|
||||||
|
FilterListModel.hh
|
||||||
Flags.h
|
Flags.h
|
||||||
FreeSpaceLabel.cc
|
FreeSpaceLabel.cc
|
||||||
FreeSpaceLabel.h
|
FreeSpaceLabel.h
|
||||||
@@ -48,6 +52,10 @@ target_sources(${TR_NAME}-gtk
|
|||||||
RelocateDialog.h
|
RelocateDialog.h
|
||||||
Session.cc
|
Session.cc
|
||||||
Session.h
|
Session.h
|
||||||
|
SorterBase.h
|
||||||
|
SorterBase.hh
|
||||||
|
SortListModel.h
|
||||||
|
SortListModel.hh
|
||||||
StatsDialog.cc
|
StatsDialog.cc
|
||||||
StatsDialog.h
|
StatsDialog.h
|
||||||
SystemTrayIcon.cc
|
SystemTrayIcon.cc
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// This file Copyright © 2012-2022 Mnemosyne LLC.
|
// This file Copyright © 2012-2023 Mnemosyne LLC.
|
||||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
// or any future license endorsed by Mnemosyne LLC.
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
// License text can be found in the licenses/ folder.
|
// License text can be found in the licenses/ folder.
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "FilterBar.h"
|
#include "FilterBar.h"
|
||||||
|
|
||||||
#include "FaviconCache.h" // gtr_get_favicon()
|
#include "FaviconCache.h" // gtr_get_favicon()
|
||||||
|
#include "FilterListModel.hh"
|
||||||
#include "HigWorkarea.h" // GUI_PAD
|
#include "HigWorkarea.h" // GUI_PAD
|
||||||
#include "ListModelAdapter.h"
|
#include "ListModelAdapter.h"
|
||||||
#include "Session.h" // torrent_cols
|
#include "Session.h" // torrent_cols
|
||||||
@@ -110,11 +111,9 @@ private:
|
|||||||
Gtk::Entry* entry_ = nullptr;
|
Gtk::Entry* entry_ = nullptr;
|
||||||
Gtk::Label* show_lb_ = nullptr;
|
Gtk::Label* show_lb_ = nullptr;
|
||||||
Glib::RefPtr<TorrentFilter> filter_ = TorrentFilter::create();
|
Glib::RefPtr<TorrentFilter> filter_ = TorrentFilter::create();
|
||||||
Glib::RefPtr<FilterModel> filter_model_;
|
Glib::RefPtr<FilterListModel<Torrent>> filter_model_;
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
sigc::connection filter_model_items_changed_tag_;
|
sigc::connection filter_model_items_changed_tag_;
|
||||||
#endif
|
|
||||||
sigc::connection update_count_label_tag_;
|
sigc::connection update_count_label_tag_;
|
||||||
sigc::connection update_filter_models_tag_;
|
sigc::connection update_filter_models_tag_;
|
||||||
sigc::connection update_filter_models_on_add_remove_tag_;
|
sigc::connection update_filter_models_on_add_remove_tag_;
|
||||||
@@ -567,7 +566,7 @@ void FilterBar::Impl::update_filter_tracker()
|
|||||||
bool FilterBar::Impl::update_count_label()
|
bool FilterBar::Impl::update_count_label()
|
||||||
{
|
{
|
||||||
/* get the visible count */
|
/* get the visible count */
|
||||||
auto const visibleCount = static_cast<int>(filter_model_->IF_GTKMM4(get_n_items(), children().size()));
|
auto const visibleCount = static_cast<int>(filter_model_->get_n_items());
|
||||||
|
|
||||||
/* get the tracker count */
|
/* get the tracker count */
|
||||||
int trackerCount = 0;
|
int trackerCount = 0;
|
||||||
@@ -701,22 +700,9 @@ FilterBar::Impl::Impl(FilterBar& widget, Glib::RefPtr<Session> const& core)
|
|||||||
activity_combo_box_init(*activity_);
|
activity_combo_box_init(*activity_);
|
||||||
tracker_combo_box_init(*tracker_);
|
tracker_combo_box_init(*tracker_);
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
filter_model_ = FilterListModel<Torrent>::create(core_->get_sorted_model(), filter_);
|
||||||
filter_model_ = Gtk::FilterListModel::create(core_->get_sorted_model(), filter_);
|
|
||||||
filter_model_items_changed_tag_ = filter_model_->signal_items_changed().connect(
|
filter_model_items_changed_tag_ = filter_model_->signal_items_changed().connect(
|
||||||
[this](guint /*position*/, guint /*removed*/, guint /*added*/) { update_count_label_idle(); });
|
[this](guint /*position*/, guint /*removed*/, guint /*added*/) { update_count_label_idle(); });
|
||||||
#else
|
|
||||||
static auto const& self_col = Torrent::get_columns().self;
|
|
||||||
|
|
||||||
auto const filter_func = [this](FilterModel::const_iterator const& iter)
|
|
||||||
{
|
|
||||||
return filter_->match(*iter->get_value(self_col));
|
|
||||||
};
|
|
||||||
|
|
||||||
filter_model_ = Gtk::TreeModelFilter::create(core_->get_sorted_model());
|
|
||||||
filter_model_->set_visible_func(filter_func);
|
|
||||||
filter_->signal_changed().connect([this]() { filter_model_->refilter(); });
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tracker_->signal_changed().connect(sigc::mem_fun(*this, &Impl::update_filter_tracker));
|
tracker_->signal_changed().connect(sigc::mem_fun(*this, &Impl::update_filter_tracker));
|
||||||
activity_->signal_changed().connect(sigc::mem_fun(*this, &Impl::update_filter_activity));
|
activity_->signal_changed().connect(sigc::mem_fun(*this, &Impl::update_filter_activity));
|
||||||
@@ -735,9 +721,7 @@ FilterBar::Impl::~Impl()
|
|||||||
update_filter_models_on_add_remove_tag_.disconnect();
|
update_filter_models_on_add_remove_tag_.disconnect();
|
||||||
update_filter_models_tag_.disconnect();
|
update_filter_models_tag_.disconnect();
|
||||||
update_count_label_tag_.disconnect();
|
update_count_label_tag_.disconnect();
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
filter_model_items_changed_tag_.disconnect();
|
filter_model_items_changed_tag_.disconnect();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::RefPtr<FilterBar::Model> FilterBar::get_filter_model() const
|
Glib::RefPtr<FilterBar::Model> FilterBar::get_filter_model() const
|
||||||
|
|||||||
53
gtk/FilterBase.h
Normal file
53
gtk/FilterBase.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GtkCompat.h"
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include <gtkmm/filter.h>
|
||||||
|
#else
|
||||||
|
#include <glibmm/object.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class FilterBase : public IF_GTKMM4(Gtk::Filter, Glib::Object)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
enum class Change{
|
||||||
|
DIFFERENT,
|
||||||
|
LESS_STRICT,
|
||||||
|
MORE_STRICT,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
~FilterBase() override = default;
|
||||||
|
|
||||||
|
virtual bool match(T const& item) const = 0;
|
||||||
|
|
||||||
|
virtual bool matches_all() const;
|
||||||
|
virtual bool matches_none() const;
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
sigc::signal<void(Change)>& signal_changed();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
// Gtk::Filter
|
||||||
|
bool match_vfunc(Glib::RefPtr<Glib::ObjectBase> const& object) override;
|
||||||
|
Match get_strictness_vfunc() override;
|
||||||
|
#else
|
||||||
|
void changed(Change change);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
sigc::signal<void(Change)> signal_changed_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
67
gtk/FilterBase.hh
Normal file
67
gtk/FilterBase.hh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FilterBase.h"
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include "Utils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool FilterBase<T>::matches_all() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool FilterBase<T>::matches_none() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool FilterBase<T>::match_vfunc(Glib::RefPtr<Glib::ObjectBase> const& object)
|
||||||
|
{
|
||||||
|
auto const concrete_object = gtr_ptr_dynamic_cast<T>(object);
|
||||||
|
g_return_val_if_fail(concrete_object != nullptr, false);
|
||||||
|
|
||||||
|
return match(*concrete_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename FilterBase<T>::Match FilterBase<T>::get_strictness_vfunc()
|
||||||
|
{
|
||||||
|
if (matches_all())
|
||||||
|
{
|
||||||
|
return Match::ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches_none())
|
||||||
|
{
|
||||||
|
return Match::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Match::SOME;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
sigc::signal<void(typename FilterBase<T>::Change)>& FilterBase<T>::signal_changed()
|
||||||
|
{
|
||||||
|
return signal_changed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void FilterBase<T>::changed(Change change)
|
||||||
|
{
|
||||||
|
signal_changed_.emit(change);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
54
gtk/FilterListModel.h
Normal file
54
gtk/FilterListModel.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// This file Copyright © 2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GtkCompat.h"
|
||||||
|
|
||||||
|
#include <giomm/listmodel.h>
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include <gtkmm/filterlistmodel.h>
|
||||||
|
#else
|
||||||
|
#include <gtkmm/treemodel.h>
|
||||||
|
#include <gtkmm/treemodelfilter.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
class FilterBase;
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
class FilterListModel : public IF_GTKMM4(Gtk::FilterListModel, Gtk::TreeModelFilter)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using FilterType = FilterBase<ItemT>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FilterListModel(Glib::RefPtr<Gio::ListModel> const& model, Glib::RefPtr<FilterType> const& filter);
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
FilterListModel(Glib::RefPtr<Gtk::TreeModel> const& model, Glib::RefPtr<FilterType> const& filter);
|
||||||
|
~FilterListModel() override;
|
||||||
|
|
||||||
|
guint get_n_items() const;
|
||||||
|
|
||||||
|
sigc::signal<void(guint, guint, guint)>& signal_items_changed();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ModelT>
|
||||||
|
static Glib::RefPtr<FilterListModel<ItemT>> create(
|
||||||
|
Glib::RefPtr<ModelT> const& model,
|
||||||
|
Glib::RefPtr<FilterType> const& filter);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
bool matches_all_ = false;
|
||||||
|
bool matches_none_ = false;
|
||||||
|
|
||||||
|
sigc::signal<void(guint, guint, guint)> signal_items_changed_;
|
||||||
|
|
||||||
|
sigc::connection signal_changed_tag_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
96
gtk/FilterListModel.hh
Normal file
96
gtk/FilterListModel.hh
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
// This file Copyright © 2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FilterBase.hh"
|
||||||
|
#include "FilterListModel.h"
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include "ListModelAdapter.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
FilterListModel<ItemT>::FilterListModel(Glib::RefPtr<Gio::ListModel> const& model, Glib::RefPtr<FilterType> const& filter)
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
: Gtk::FilterListModel(model, filter)
|
||||||
|
#else
|
||||||
|
: FilterListModel(gtr_ptr_static_cast<Gtk::TreeModel>(ListModelAdapter::create<ItemT>(model)), filter)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
FilterListModel<ItemT>::FilterListModel(Glib::RefPtr<Gtk::TreeModel> const& model, Glib::RefPtr<FilterType> const& filter)
|
||||||
|
: Gtk::TreeModelFilter(model)
|
||||||
|
, matches_all_(filter->matches_all())
|
||||||
|
, matches_none_(filter->matches_none())
|
||||||
|
{
|
||||||
|
static auto const& self_col = ItemT::get_columns().self;
|
||||||
|
|
||||||
|
auto const filter_func = [this, filter](const_iterator const& iter)
|
||||||
|
{
|
||||||
|
if (matches_all_)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches_none_)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const* const self = iter->get_value(self_col);
|
||||||
|
g_return_val_if_fail(self != nullptr, false);
|
||||||
|
|
||||||
|
return filter->match(*self);
|
||||||
|
};
|
||||||
|
|
||||||
|
set_visible_func(filter_func);
|
||||||
|
|
||||||
|
signal_changed_tag_ = filter->signal_changed().connect(
|
||||||
|
[this, filter](auto /*changes*/)
|
||||||
|
{
|
||||||
|
matches_all_ = filter->matches_all();
|
||||||
|
matches_none_ = filter->matches_none();
|
||||||
|
refilter();
|
||||||
|
});
|
||||||
|
|
||||||
|
signal_row_inserted().connect([this](auto const& path, auto const& /*iter*/)
|
||||||
|
{ signal_items_changed_.emit(path.front(), 0, 1); });
|
||||||
|
signal_row_deleted().connect([this](auto const& path) { signal_items_changed_.emit(path.front(), 1, 0); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
FilterListModel<ItemT>::~FilterListModel()
|
||||||
|
{
|
||||||
|
signal_changed_tag_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
guint FilterListModel<ItemT>::get_n_items() const
|
||||||
|
{
|
||||||
|
return children().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
sigc::signal<void(guint, guint, guint)>& FilterListModel<ItemT>::signal_items_changed()
|
||||||
|
{
|
||||||
|
return signal_items_changed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
template<typename ModelT>
|
||||||
|
Glib::RefPtr<FilterListModel<ItemT>> FilterListModel<ItemT>::create(
|
||||||
|
Glib::RefPtr<ModelT> const& model,
|
||||||
|
Glib::RefPtr<FilterType> const& filter)
|
||||||
|
{
|
||||||
|
return Glib::make_refptr_for_instance(new FilterListModel(model, filter));
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Notify.h"
|
#include "Notify.h"
|
||||||
#include "Prefs.h"
|
#include "Prefs.h"
|
||||||
#include "PrefsDialog.h"
|
#include "PrefsDialog.h"
|
||||||
|
#include "SortListModel.hh"
|
||||||
#include "Torrent.h"
|
#include "Torrent.h"
|
||||||
#include "TorrentSorter.h"
|
#include "TorrentSorter.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
@@ -83,8 +84,6 @@ TrVariantPtr create_variant(tr_variant& other)
|
|||||||
|
|
||||||
class Session::Impl
|
class Session::Impl
|
||||||
{
|
{
|
||||||
using SortModel = IF_GTKMM4(Gtk::SortListModel, Gtk::TreeModelSort);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Impl(Session& core, tr_session* session);
|
Impl(Session& core, tr_session* session);
|
||||||
~Impl();
|
~Impl();
|
||||||
@@ -94,7 +93,7 @@ public:
|
|||||||
tr_session* close();
|
tr_session* close();
|
||||||
|
|
||||||
Glib::RefPtr<Gio::ListStore<Torrent>> get_raw_model() const;
|
Glib::RefPtr<Gio::ListStore<Torrent>> get_raw_model() const;
|
||||||
Glib::RefPtr<SortModel> get_model();
|
Glib::RefPtr<SortListModel<Torrent>> get_model();
|
||||||
tr_session* get_session() const;
|
tr_session* get_session() const;
|
||||||
|
|
||||||
std::pair<Glib::RefPtr<Torrent>, guint> find_torrent_by_id(tr_torrent_id_t torrent_id) const;
|
std::pair<Glib::RefPtr<Torrent>, guint> find_torrent_by_id(tr_torrent_id_t torrent_id) const;
|
||||||
@@ -207,7 +206,7 @@ private:
|
|||||||
guint inhibit_cookie_ = 0;
|
guint inhibit_cookie_ = 0;
|
||||||
gint busy_count_ = 0;
|
gint busy_count_ = 0;
|
||||||
Glib::RefPtr<Gio::ListStore<Torrent>> raw_model_;
|
Glib::RefPtr<Gio::ListStore<Torrent>> raw_model_;
|
||||||
Glib::RefPtr<SortModel> sorted_model_;
|
Glib::RefPtr<SortListModel<Torrent>> sorted_model_;
|
||||||
Glib::RefPtr<TorrentSorter> sorter_ = TorrentSorter::create();
|
Glib::RefPtr<TorrentSorter> sorter_ = TorrentSorter::create();
|
||||||
tr_session* session_ = nullptr;
|
tr_session* session_ = nullptr;
|
||||||
};
|
};
|
||||||
@@ -237,7 +236,7 @@ Glib::RefPtr<Session::Model> Session::get_sorted_model() const
|
|||||||
return impl_->get_model();
|
return impl_->get_model();
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::RefPtr<Session::Impl::SortModel> Session::Impl::get_model()
|
Glib::RefPtr<SortListModel<Torrent>> Session::Impl::get_model()
|
||||||
{
|
{
|
||||||
return sorted_model_;
|
return sorted_model_;
|
||||||
}
|
}
|
||||||
@@ -537,20 +536,7 @@ Session::Impl::Impl(Session& core, tr_session* session)
|
|||||||
{
|
{
|
||||||
raw_model_ = Gio::ListStore<Torrent>::create();
|
raw_model_ = Gio::ListStore<Torrent>::create();
|
||||||
signal_torrents_changed_.connect(sigc::hide<0>(sigc::mem_fun(*sorter_.get(), &TorrentSorter::update)));
|
signal_torrents_changed_.connect(sigc::hide<0>(sigc::mem_fun(*sorter_.get(), &TorrentSorter::update)));
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
sorted_model_ = SortListModel<Torrent>::create(gtr_ptr_static_cast<Gio::ListModel>(raw_model_), sorter_);
|
||||||
sorted_model_ = Gtk::SortListModel::create(raw_model_, sorter_);
|
|
||||||
#else
|
|
||||||
static auto const& self_col = Torrent::get_columns().self;
|
|
||||||
|
|
||||||
auto const sort_func = [this](SortModel::const_iterator const& lhs, SortModel::const_iterator const& rhs)
|
|
||||||
{
|
|
||||||
return sorter_->compare(*lhs->get_value(self_col), *rhs->get_value(self_col));
|
|
||||||
};
|
|
||||||
|
|
||||||
sorted_model_ = Gtk::TreeModelSort::create(ListModelAdapter::create<Torrent>(raw_model_));
|
|
||||||
sorted_model_->set_default_sort_func(sort_func);
|
|
||||||
sorter_->signal_changed().connect([this, sort_func]() { sorted_model_->set_default_sort_func(sort_func); });
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* init from prefs & listen to pref changes */
|
/* init from prefs & listen to pref changes */
|
||||||
on_pref_changed(TR_KEY_sort_mode);
|
on_pref_changed(TR_KEY_sort_mode);
|
||||||
|
|||||||
43
gtk/SortListModel.h
Normal file
43
gtk/SortListModel.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
// This file Copyright © 2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GtkCompat.h"
|
||||||
|
|
||||||
|
#include <giomm/listmodel.h>
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include <gtkmm/sortlistmodel.h>
|
||||||
|
#else
|
||||||
|
#include <gtkmm/treemodel.h>
|
||||||
|
#include <gtkmm/treemodelsort.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
class SorterBase;
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
class SortListModel : public IF_GTKMM4(Gtk::SortListModel, Gtk::TreeModelSort)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using SorterType = SorterBase<ItemT>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SortListModel(Glib::RefPtr<Gio::ListModel> const& model, Glib::RefPtr<SorterType> const& sorter);
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
SortListModel(Glib::RefPtr<Gtk::TreeModel> const& model, Glib::RefPtr<SorterType> const& sorter);
|
||||||
|
~SortListModel() override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ModelT>
|
||||||
|
static Glib::RefPtr<SortListModel<ItemT>> create(Glib::RefPtr<ModelT> const& model, Glib::RefPtr<SorterType> const& sorter);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
sigc::connection signal_changed_tag_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
71
gtk/SortListModel.hh
Normal file
71
gtk/SortListModel.hh
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// This file Copyright © 2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SorterBase.hh"
|
||||||
|
#include "SortListModel.h"
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include "ListModelAdapter.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
SortListModel<ItemT>::SortListModel(Glib::RefPtr<Gio::ListModel> const& model, Glib::RefPtr<SorterType> const& sorter)
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
: Gtk::SortListModel(model, sorter)
|
||||||
|
#else
|
||||||
|
: SortListModel(gtr_ptr_static_cast<Gtk::TreeModel>(ListModelAdapter::create<ItemT>(model)), sorter)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
SortListModel<ItemT>::SortListModel(Glib::RefPtr<Gtk::TreeModel> const& model, Glib::RefPtr<SorterType> const& sorter)
|
||||||
|
: Gtk::TreeModelSort(model)
|
||||||
|
{
|
||||||
|
static auto const& self_col = ItemT::get_columns().self;
|
||||||
|
|
||||||
|
auto const sort_func = [sorter](const_iterator const& lhs, const_iterator const& rhs)
|
||||||
|
{
|
||||||
|
auto const* const lhs_self = lhs->get_value(self_col);
|
||||||
|
auto const* const rhs_self = rhs->get_value(self_col);
|
||||||
|
|
||||||
|
if (lhs_self == nullptr && rhs_self == nullptr)
|
||||||
|
{
|
||||||
|
g_return_val_if_reached(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_return_val_if_fail(lhs_self != nullptr, -1);
|
||||||
|
g_return_val_if_fail(rhs_self != nullptr, 1);
|
||||||
|
|
||||||
|
return sorter->compare(*lhs_self, *rhs_self);
|
||||||
|
};
|
||||||
|
|
||||||
|
set_default_sort_func(sort_func);
|
||||||
|
|
||||||
|
signal_changed_tag_ = sorter->signal_changed().connect([this, sort_func](auto /*changes*/)
|
||||||
|
{ set_default_sort_func(sort_func); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
SortListModel<ItemT>::~SortListModel()
|
||||||
|
{
|
||||||
|
signal_changed_tag_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename ItemT>
|
||||||
|
template<typename ModelT>
|
||||||
|
Glib::RefPtr<SortListModel<ItemT>> SortListModel<ItemT>::create(
|
||||||
|
Glib::RefPtr<ModelT> const& model,
|
||||||
|
Glib::RefPtr<SorterType> const& sorter)
|
||||||
|
{
|
||||||
|
return Glib::make_refptr_for_instance(new SortListModel(model, sorter));
|
||||||
|
}
|
||||||
51
gtk/SorterBase.h
Normal file
51
gtk/SorterBase.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GtkCompat.h"
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
#include <gtkmm/sorter.h>
|
||||||
|
#else
|
||||||
|
#include <glibmm/object.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SorterBase : public IF_GTKMM4(Gtk::Sorter, Glib::Object)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
enum class Change{
|
||||||
|
DIFFERENT,
|
||||||
|
INVERTED,
|
||||||
|
LESS_STRICT,
|
||||||
|
MORE_STRICT,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
~SorterBase() override = default;
|
||||||
|
|
||||||
|
virtual int compare(T const& lhs, T const& rhs) const = 0;
|
||||||
|
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
sigc::signal<void(Change)>& signal_changed();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
// Gtk::Sorter
|
||||||
|
Gtk::Ordering compare_vfunc(gpointer lhs, gpointer rhs) override;
|
||||||
|
Order get_order_vfunc() override;
|
||||||
|
#else
|
||||||
|
void changed(Change change);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
sigc::signal<void(Change)> signal_changed_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
49
gtk/SorterBase.hh
Normal file
49
gtk/SorterBase.hh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SorterBase.h"
|
||||||
|
|
||||||
|
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Gtk::Ordering SorterBase<T>::compare_vfunc(gpointer lhs, gpointer rhs)
|
||||||
|
{
|
||||||
|
auto const* const concrete_lhs = dynamic_cast<T const*>(Glib::wrap_auto(static_cast<GObject*>(lhs)));
|
||||||
|
auto const* const concrete_rhs = dynamic_cast<T const*>(Glib::wrap_auto(static_cast<GObject*>(rhs)));
|
||||||
|
|
||||||
|
if (concrete_lhs == nullptr && concrete_lhs == nullptr)
|
||||||
|
{
|
||||||
|
g_return_val_if_reached(Gtk::Ordering::EQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_return_val_if_fail(concrete_lhs != nullptr, Gtk::Ordering::SMALLER);
|
||||||
|
g_return_val_if_fail(concrete_rhs != nullptr, Gtk::Ordering::LARGER);
|
||||||
|
|
||||||
|
return Gtk::Ordering{ compare(*concrete_lhs, *concrete_rhs) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Gtk::Sorter::Order SorterBase<T>::get_order_vfunc()
|
||||||
|
{
|
||||||
|
return Gtk::Sorter::Order::PARTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
sigc::signal<void(typename SorterBase<T>::Change)>& SorterBase<T>::signal_changed()
|
||||||
|
{
|
||||||
|
return signal_changed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SorterBase<T>::changed(Change change)
|
||||||
|
{
|
||||||
|
signal_changed_.emit(change);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,20 @@
|
|||||||
// This file Copyright © 2022 Mnemosyne LLC.
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
// or any future license endorsed by Mnemosyne LLC.
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
// License text can be found in the licenses/ folder.
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
#include "TorrentFilter.h"
|
#include "TorrentFilter.h"
|
||||||
|
|
||||||
|
#include "FilterBase.hh"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <libtransmission/transmission.h>
|
#include <libtransmission/transmission.h>
|
||||||
|
|
||||||
|
TorrentFilter::TorrentFilter()
|
||||||
|
: Glib::ObjectBase(typeid(TorrentFilter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentFilter::set_activity(Activity type)
|
void TorrentFilter::set_activity(Activity type)
|
||||||
{
|
{
|
||||||
if (activity_type_ == type)
|
if (activity_type_ == type)
|
||||||
@@ -108,6 +114,11 @@ bool TorrentFilter::match(Torrent const& torrent) const
|
|||||||
return match_activity(torrent) && match_tracker(torrent) && match_text(torrent);
|
return match_activity(torrent) && match_tracker(torrent) && match_text(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TorrentFilter::matches_all() const
|
||||||
|
{
|
||||||
|
return activity_type_ == Activity::ALL && tracker_type_ == Tracker::ALL && text_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentFilter::update(Torrent::ChangeFlags changes)
|
void TorrentFilter::update(Torrent::ChangeFlags changes)
|
||||||
{
|
{
|
||||||
using Flag = Torrent::ChangeFlag;
|
using Flag = Torrent::ChangeFlag;
|
||||||
@@ -146,15 +157,6 @@ void TorrentFilter::update(Torrent::ChangeFlags changes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
|
|
||||||
sigc::signal<void()>& TorrentFilter::signal_changed()
|
|
||||||
{
|
|
||||||
return signal_changed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Glib::RefPtr<TorrentFilter> TorrentFilter::create()
|
Glib::RefPtr<TorrentFilter> TorrentFilter::create()
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||||
@@ -246,32 +248,3 @@ bool TorrentFilter::match_text(Torrent const& torrent, Glib::ustring const& text
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
|
|
||||||
bool TorrentFilter::match_vfunc(Glib::RefPtr<Glib::ObjectBase> const& item)
|
|
||||||
{
|
|
||||||
auto const torrent = gtr_ptr_dynamic_cast<Torrent>(item);
|
|
||||||
g_return_val_if_fail(torrent != nullptr, false);
|
|
||||||
|
|
||||||
return match(*torrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
TorrentFilter::Match TorrentFilter::get_strictness_vfunc()
|
|
||||||
{
|
|
||||||
return activity_type_ == Activity::ALL && tracker_type_ == Tracker::ALL && text_.empty() ? Match::ALL : Match::SOME;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void TorrentFilter::changed(Change /*change*/)
|
|
||||||
{
|
|
||||||
signal_changed_.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter()
|
|
||||||
: Glib::ObjectBase(typeid(TorrentFilter))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,32 +1,18 @@
|
|||||||
// This file Copyright © 2022 Mnemosyne LLC.
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
// or any future license endorsed by Mnemosyne LLC.
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
// License text can be found in the licenses/ folder.
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GtkCompat.h"
|
#include "FilterBase.h"
|
||||||
#include "Torrent.h"
|
#include "Torrent.h"
|
||||||
|
|
||||||
#include <glibmm/refptr.h>
|
#include <glibmm/refptr.h>
|
||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
class TorrentFilter : public FilterBase<Torrent>
|
||||||
#include <gtkmm/filter.h>
|
|
||||||
#else
|
|
||||||
#include <glibmm/object.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class TorrentFilter : public IF_GTKMM4(Gtk::Filter, Glib::Object)
|
|
||||||
{
|
{
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
enum class Change{
|
|
||||||
DIFFERENT,
|
|
||||||
LESS_STRICT,
|
|
||||||
MORE_STRICT,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Activity
|
enum class Activity
|
||||||
{
|
{
|
||||||
@@ -55,28 +41,18 @@ public:
|
|||||||
bool match_tracker(Torrent const& torrent) const;
|
bool match_tracker(Torrent const& torrent) const;
|
||||||
bool match_text(Torrent const& torrent) const;
|
bool match_text(Torrent const& torrent) const;
|
||||||
|
|
||||||
bool match(Torrent const& torrent) const;
|
// FilterBase<Torrent>
|
||||||
|
bool match(Torrent const& torrent) const override;
|
||||||
|
bool matches_all() const override;
|
||||||
|
|
||||||
void update(Torrent::ChangeFlags changes);
|
void update(Torrent::ChangeFlags changes);
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
sigc::signal<void()>& signal_changed();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static Glib::RefPtr<TorrentFilter> create();
|
static Glib::RefPtr<TorrentFilter> create();
|
||||||
|
|
||||||
static bool match_activity(Torrent const& torrent, Activity type);
|
static bool match_activity(Torrent const& torrent, Activity type);
|
||||||
static bool match_tracker(Torrent const& torrent, Tracker type, Glib::ustring const& host);
|
static bool match_tracker(Torrent const& torrent, Tracker type, Glib::ustring const& host);
|
||||||
static bool match_text(Torrent const& torrent, Glib::ustring const& text);
|
static bool match_text(Torrent const& torrent, Glib::ustring const& text);
|
||||||
|
|
||||||
protected:
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
bool match_vfunc(Glib::RefPtr<Glib::ObjectBase> const& item) override;
|
|
||||||
Match get_strictness_vfunc() override;
|
|
||||||
#else
|
|
||||||
void changed(Change change);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TorrentFilter();
|
TorrentFilter();
|
||||||
|
|
||||||
@@ -85,8 +61,4 @@ private:
|
|||||||
Tracker tracker_type_ = Tracker::ALL;
|
Tracker tracker_type_ = Tracker::ALL;
|
||||||
Glib::ustring tracker_host_;
|
Glib::ustring tracker_host_;
|
||||||
Glib::ustring text_;
|
Glib::ustring text_;
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
sigc::signal<void()> signal_changed_;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// This file Copyright © 2022 Mnemosyne LLC.
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
// or any future license endorsed by Mnemosyne LLC.
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
// License text can be found in the licenses/ folder.
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
#include "TorrentSorter.h"
|
#include "TorrentSorter.h"
|
||||||
|
|
||||||
|
#include "SorterBase.hh"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <libtransmission/transmission.h>
|
#include <libtransmission/transmission.h>
|
||||||
@@ -185,6 +186,11 @@ int compare_by_state(Torrent const& lhs, Torrent const& rhs)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
TorrentSorter::TorrentSorter()
|
||||||
|
: Glib::ObjectBase(typeid(TorrentSorter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentSorter::set_mode(std::string_view mode)
|
void TorrentSorter::set_mode(std::string_view mode)
|
||||||
{
|
{
|
||||||
static auto const compare_funcs = std::map<std::string_view, CompareFunc>({
|
static auto const compare_funcs = std::map<std::string_view, CompareFunc>({
|
||||||
@@ -253,49 +259,8 @@ void TorrentSorter::update(Torrent::ChangeFlags changes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
|
|
||||||
sigc::signal<void()>& TorrentSorter::signal_changed()
|
|
||||||
{
|
|
||||||
return signal_changed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Glib::RefPtr<TorrentSorter> TorrentSorter::create()
|
Glib::RefPtr<TorrentSorter> TorrentSorter::create()
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||||
return Glib::make_refptr_for_instance(new TorrentSorter());
|
return Glib::make_refptr_for_instance(new TorrentSorter());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
|
|
||||||
Gtk::Ordering TorrentSorter::compare_vfunc(gpointer lhs, gpointer rhs)
|
|
||||||
{
|
|
||||||
auto const* const lhs_torrent = dynamic_cast<Torrent const*>(Glib::wrap_auto(static_cast<GObject*>(lhs)));
|
|
||||||
g_return_val_if_fail(lhs_torrent != nullptr, Gtk::Ordering::SMALLER);
|
|
||||||
|
|
||||||
auto const* const rhs_torrent = dynamic_cast<Torrent const*>(Glib::wrap_auto(static_cast<GObject*>(rhs)));
|
|
||||||
g_return_val_if_fail(rhs_torrent != nullptr, Gtk::Ordering::LARGER);
|
|
||||||
|
|
||||||
return Gtk::Ordering{ compare(*lhs_torrent, *rhs_torrent) };
|
|
||||||
}
|
|
||||||
|
|
||||||
Gtk::Sorter::Order TorrentSorter::get_order_vfunc()
|
|
||||||
{
|
|
||||||
return Gtk::Sorter::Order::PARTIAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void TorrentSorter::changed(Change /*change*/)
|
|
||||||
{
|
|
||||||
signal_changed_.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TorrentSorter::TorrentSorter()
|
|
||||||
: Glib::ObjectBase(typeid(TorrentSorter))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,64 +1,34 @@
|
|||||||
// This file Copyright © 2022 Mnemosyne LLC.
|
// This file Copyright © 2022-2023 Mnemosyne LLC.
|
||||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||||
// or any future license endorsed by Mnemosyne LLC.
|
// or any future license endorsed by Mnemosyne LLC.
|
||||||
// License text can be found in the licenses/ folder.
|
// License text can be found in the licenses/ folder.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GtkCompat.h"
|
#include "SorterBase.h"
|
||||||
#include "Torrent.h"
|
#include "Torrent.h"
|
||||||
|
|
||||||
#include <glibmm/refptr.h>
|
#include <glibmm/refptr.h>
|
||||||
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
class TorrentSorter : public SorterBase<Torrent>
|
||||||
#include <gtkmm/sorter.h>
|
|
||||||
#else
|
|
||||||
#include <glibmm/object.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class TorrentSorter : public IF_GTKMM4(Gtk::Sorter, Glib::Object)
|
|
||||||
{
|
{
|
||||||
using CompareFunc = int (*)(Torrent const&, Torrent const&);
|
using CompareFunc = int (*)(Torrent const&, Torrent const&);
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
enum class Change{
|
|
||||||
DIFFERENT,
|
|
||||||
INVERTED,
|
|
||||||
LESS_STRICT,
|
|
||||||
MORE_STRICT,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_mode(std::string_view mode);
|
void set_mode(std::string_view mode);
|
||||||
void set_reversed(bool is_reversed);
|
void set_reversed(bool is_reversed);
|
||||||
|
|
||||||
int compare(Torrent const& lhs, Torrent const& rhs) const;
|
// SorterBase<Torrent>
|
||||||
|
int compare(Torrent const& lhs, Torrent const& rhs) const override;
|
||||||
|
|
||||||
void update(Torrent::ChangeFlags changes);
|
void update(Torrent::ChangeFlags changes);
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
sigc::signal<void()>& signal_changed();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static Glib::RefPtr<TorrentSorter> create();
|
static Glib::RefPtr<TorrentSorter> create();
|
||||||
|
|
||||||
protected:
|
|
||||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
Gtk::Ordering compare_vfunc(gpointer lhs, gpointer rhs) override;
|
|
||||||
Order get_order_vfunc() override;
|
|
||||||
#else
|
|
||||||
void changed(Change change);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TorrentSorter();
|
TorrentSorter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CompareFunc compare_func_ = nullptr;
|
CompareFunc compare_func_ = nullptr;
|
||||||
bool is_reversed_ = false;
|
bool is_reversed_ = false;
|
||||||
|
|
||||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
|
||||||
sigc::signal<void()> signal_changed_;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user