Skip to content

Commit

Permalink
Enable natural sort in the nations view
Browse files Browse the repository at this point in the history
Closes #2050.
  • Loading branch information
lmoureaux committed Dec 24, 2023
1 parent 26febb5 commit fd8e41d
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 4 deletions.
1 change: 1 addition & 0 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ target_sources(
tileset/layer.cpp
tileset/sprite.cpp
tileset/tilespec.cpp
utils/collated_sort_proxy.cpp
utils/colorizer.cpp
utils/improvement_seller.cpp
utils/unit_quick_menu.cpp
Expand Down
60 changes: 60 additions & 0 deletions client/utils/collated_sort_proxy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SPDX-License-Identifier: GPLv3-or-later
* SPDX-FileCopyrightText: Louis Moureaux <[email protected]>
*/

#include "collated_sort_proxy.h"

namespace freeciv {

/**
* \class collated_sort_filter_proxy_model
* \brief A sort and filter proxy model supporting string collation.
*
* This model can be used when strings in a model should use a "natural" sort
* order.
*/

/**
* \brief Constructor.
*/
collated_sort_filter_proxy_model::collated_sort_filter_proxy_model(
QObject *parent)
: QSortFilterProxyModel(parent)
{
}

/**
* \brief Changes the collator currently in use.
*/
void collated_sort_filter_proxy_model::set_collator(const QCollator &coll)
{
m_collator = coll;
invalidate();
}

/**
* \brief Reimplemented protected function.
*
* This overrides @c QSortFilterProxyModel::lessThan to use the collator when
* comparing strings.
*/
bool collated_sort_filter_proxy_model::lessThan(
const QModelIndex &source_left, const QModelIndex &source_right) const
{
// Copied from QSortFilterProxyModel
QVariant l = (source_left.model()
? source_left.model()->data(source_left, sortRole())
: QVariant());
QVariant r = (source_right.model()
? source_right.model()->data(source_right, sortRole())
: QVariant());

if (l.type() == QVariant::String && r.type() == QVariant::String) {
return m_collator(l.toString(), r.toString());
}

return QSortFilterProxyModel::lessThan(source_left, source_right);
}

} // namespace freeciv
28 changes: 28 additions & 0 deletions client/utils/collated_sort_proxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-License-Identifier: GPLv3-or-later
* SPDX-FileCopyrightText: Louis Moureaux <[email protected]>
*/

#pragma once

#include <QCollator>
#include <QSortFilterProxyModel>

namespace freeciv {

class collated_sort_filter_proxy_model : public QSortFilterProxyModel {
QCollator m_collator;

public:
collated_sort_filter_proxy_model(QObject *parent = nullptr);

/// Retrieves the string collator currently in use.
QCollator collator() const { return m_collator; }
void set_collator(const QCollator &coll);

protected:
bool lessThan(const QModelIndex &source_left,
const QModelIndex &source_right) const override;
};

} // namespace freeciv
11 changes: 10 additions & 1 deletion client/views/view_nations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <QMouseEvent>
#include <QPainter>
#include <QSortFilterProxyModel>
#include <qnamespace.h>
// utility
#include "astring.h"
#include "fcintl.h"
Expand All @@ -30,6 +31,7 @@
#include "improvement.h"
#include "nation.h"
#include "research.h"
#include "utils/collated_sort_proxy.h"
#include "views/view_nations_data.h"
// client
#include "chatline_common.h"
Expand Down Expand Up @@ -315,11 +317,18 @@ plr_widget::plr_widget(QWidget *widget) : QTableView(widget)
pid = new plr_item_delegate(this);
setItemDelegate(pid);
list_model = new plr_model(this);
filter_model = new QSortFilterProxyModel();

filter_model = new freeciv::collated_sort_filter_proxy_model;
filter_model->setDynamicSortFilter(true);
filter_model->setSourceModel(list_model);
filter_model->setFilterRole(Qt::DisplayRole);
QCollator coll;
coll.setCaseSensitivity(Qt::CaseInsensitive);
coll.setLocale(locale());
coll.setNumericMode(true);
filter_model->set_collator(coll);
setModel(filter_model);

setSortingEnabled(true);
setSelectionMode(QAbstractItemView::SingleSelection);
setAutoScroll(true);
Expand Down
8 changes: 5 additions & 3 deletions client/views/view_nations.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
**************************************************************************/
#pragma once

// client
#include "utils/collated_sort_proxy.h"
#include "views/view_nations_data.h"

// Qt
#include <QAbstractListModel>
#include <QItemDelegate>
#include <QTableView>
#include <QWidget>
// client
#include "views/view_nations_data.h"

class QHBoxLayout;
class QItemSelection;
Expand Down Expand Up @@ -102,7 +104,7 @@ private slots:
class plr_widget : public QTableView {
Q_OBJECT
plr_model *list_model;
QSortFilterProxyModel *filter_model;
freeciv::collated_sort_filter_proxy_model *filter_model;
plr_item_delegate *pid;
plr_report *plr;
QString techs_known;
Expand Down

0 comments on commit fd8e41d

Please sign in to comment.