@@ -12,23 +12,22 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Michael Terry <michael.terry@canonical.com>
1715 */
1816
1917#include "Greeter.h"
2018#include "UsersModel.h"
19+#include <QIdentityProxyModel>
2120#include <QLightDM/UsersModel>
22−#include <QtCore/QSortFilterProxyModel>
2321
2422#include <libintl.h>
2523
2624// First, we define an internal class that wraps LightDM's UsersModel. This
2725// class will modify some of the data coming from LightDM. For example, we
28−// modify any empty Real Names into just normal Names.
26+// modify any empty Real Names into just normal Names. We also add optional
27+// rows, depending on configuration.
2928// (We can't modify the data directly in UsersModel below because it won't sort
3029// using the modified data.)
31−class MangleModel : public QSortFilterProxyModel
30+class MangleModel : public QIdentityProxyModel
3231{
3332 Q_OBJECT
3433
@@ -36,21 +35,66 @@ public:
3635 explicit MangleModel(QObject* parent=0);
3736
3837 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
39+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
40+
41+private:
42+ int manualRow() const;
43+ int guestRow() const;
44+
45+ void updateShowManual();
46+
47+ bool m_showManual;
3948};
4049
4150MangleModel::MangleModel(QObject* parent)
42− : QSortFilterProxyModel(parent)
51+ : QIdentityProxyModel(parent)
52+ , m_showManual(false)
4353{
44− setSourceModel(new QLightDM::UsersModel(this));
54+ if (!Greeter::instance()->hideUsersHint()) {
55+ setSourceModel(new QLightDM::UsersModel(this));
56+ }
57+
58+ updateShowManual();
59+
60+ connect(this, &QIdentityProxyModel::modelReset,
61+ this, &MangleModel::updateShowManual);
62+ connect(this, &QIdentityProxyModel::rowsInserted,
63+ this, &MangleModel::updateShowManual);
64+ connect(this, &QIdentityProxyModel::rowsRemoved,
65+ this, &MangleModel::updateShowManual);
4566}
4667
4768QVariant MangleModel::data(const QModelIndex &index, int role) const
4869{
49− QVariant variantData = QSortFilterProxyModel::data(index, role);
70+ QVariant variantData;
71+
72+ if (index.row() == manualRow() && index.column() == 0) {
73+ switch (role) {
74+ case QLightDM::UsersModel::NameRole: return QStringLiteral("*other");
75+ case QLightDM::UsersModel::RealNameRole: return gettext("Login");
76+ case QLightDM::UsersModel::LoggedInRole: return false;
77+ case QLightDM::UsersModel::SessionRole: return Greeter::instance()->defaultSessionHint();
78+ default: return QVariant();
79+ }
80+ } else if (index.row() == guestRow() && index.column() == 0) {
81+ switch (role) {
82+ case QLightDM::UsersModel::NameRole:
83+ variantData = QStringLiteral("*guest"); break;
84+ case QLightDM::UsersModel::RealNameRole:
85+ variantData = gettext("Guest Session"); break;
86+ case QLightDM::UsersModel::LoggedInRole:
87+ variantData = false; break;
88+ case QLightDM::UsersModel::SessionRole:
89+ variantData = Greeter::instance()->defaultSessionHint(); break;
90+ }
91+ } else {
92+ variantData = QIdentityProxyModel::data(index, role);
93+ }
5094
5195 // If user's real name is empty, switch to unix name
5296 if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
53− variantData = QSortFilterProxyModel::data(index, QLightDM::UsersModel::NameRole);
97+ variantData = QIdentityProxyModel::data(index, QLightDM::UsersModel::NameRole);
5498 } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
5599 const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
56100 variantData = stringData;
@@ -59,34 +103,15 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
59103 return variantData;
60104}
61105
62−// **** Now we continue with actual UsersModel class ****
63−
64−UsersModel::UsersModel(QObject* parent)
65− : UnitySortFilterProxyModelQML(parent)
66− , m_showManual(false)
67−{
68− if (!Greeter::instance()->hideUsersHint()) {
69− setModel(new MangleModel(this));
70− }
71− setSortCaseSensitivity(Qt::CaseInsensitive);
72− setSortLocaleAware(true);
73− setSortRole(QLightDM::UsersModel::RealNameRole);
74− sort(0);
75−
76− connect(this, &UnitySortFilterProxyModelQML::countChanged,
77− this, &UsersModel::updateShowManual);
78− updateShowManual();
79−}
80−
81−void UsersModel::updateShowManual()
106+void MangleModel::updateShowManual()
82107{
83108 // Show manual login if we are asked to OR if no other entry exists
84109 bool showManual = Greeter::instance()->showManualLoginHint() ||
85− (QSortFilterProxyModel::rowCount() == 0 &&
110+ (QIdentityProxyModel::rowCount() == 0 &&
86111 !Greeter::instance()->hasGuestAccount());
87112
88113 if (m_showManual != showManual) {
89− int row = QSortFilterProxyModel::rowCount();
114+ int row = QIdentityProxyModel::rowCount();
90115 if (showManual)
91116 beginInsertRows(QModelIndex(), row, row);
92117 else
@@ -101,29 +126,29 @@ void UsersModel::updateShowManual()
101126 }
102127}
103128
104−int UsersModel::manualRow() const
129+int MangleModel::manualRow() const
105130{
106131 if (!m_showManual)
107132 return -1;
108133
109− return QSortFilterProxyModel::rowCount();
134+ return QIdentityProxyModel::rowCount();
110135}
111136
112−int UsersModel::guestRow() const
137+int MangleModel::guestRow() const
113138{
114139 if (!Greeter::instance()->hasGuestAccount())
115140 return -1;
116141
117− int row = QSortFilterProxyModel::rowCount();
142+ int row = QIdentityProxyModel::rowCount();
118143 if (m_showManual)
119144 row++;
120145
121146 return row;
122147}
123148
124−int UsersModel::rowCount(const QModelIndex &parent) const
149+int MangleModel::rowCount(const QModelIndex &parent) const
125150{
126− auto count = UnitySortFilterProxyModelQML::rowCount(parent);
151+ auto count = QIdentityProxyModel::rowCount(parent);
127152
128153 if (m_showManual && !parent.isValid())
129154 count++;
@@ -133,36 +158,38 @@ int UsersModel::rowCount(const QModelIndex &parent) const
133158 return count;
134159}
135160
136−QModelIndex UsersModel::index(int row, int column, const QModelIndex &parent) const
161+QModelIndex MangleModel::index(int row, int column, const QModelIndex &parent) const
137162{
138163 if ((row == manualRow() || row == guestRow()) && !parent.isValid()) {
139164 return createIndex(row, column);
140165 } else {
141− return UnitySortFilterProxyModelQML::index(row, column, parent);
166+ return QIdentityProxyModel::index(row, column, parent);
142167 }
143168}
144169
145−QVariant UsersModel::data(const QModelIndex &index, int role) const
170+// **** Now we continue with actual UsersModel class ****
171+
172+UsersModel::UsersModel(QObject* parent)
173+ : UnitySortFilterProxyModelQML(parent)
146174{
147− if (index.row() == manualRow() && index.column() == 0) {
148− switch (role) {
149− case QLightDM::UsersModel::NameRole: return QStringLiteral("*other");
150− case QLightDM::UsersModel::RealNameRole: return gettext("Login");
151− case QLightDM::UsersModel::LoggedInRole: return false;
152− case QLightDM::UsersModel::SessionRole: return Greeter::instance()->defaultSessionHint();
153− default: return QVariant();
154− }
155− } else if (index.row() == guestRow() && index.column() == 0) {
156− switch (role) {
157− case QLightDM::UsersModel::NameRole: return QStringLiteral("*guest");
158− case QLightDM::UsersModel::RealNameRole: return gettext("Guest Session");
159− case QLightDM::UsersModel::LoggedInRole: return false;
160− case QLightDM::UsersModel::SessionRole: return Greeter::instance()->defaultSessionHint();
161− default: return QVariant();
162− }
163− }
175+ setModel(new MangleModel(this));
176+ setSortCaseSensitivity(Qt::CaseInsensitive);
177+ setSortLocaleAware(true);
178+ setSortRole(QLightDM::UsersModel::RealNameRole);
179+ sort(0);
180+}
181+
182+bool UsersModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
183+{
184+ auto leftName = source_left.data(QLightDM::UsersModel::NameRole);
185+ auto rightName = source_right.data(QLightDM::UsersModel::NameRole);
186+
187+ if (leftName == QStringLiteral("*guest"))
188+ return false;
189+ if (rightName == QStringLiteral("*guest"))
190+ return true;
164191
165− return QSortFilterProxyModel::data(index, role);
192+ return UnitySortFilterProxyModelQML::lessThan(source_left, source_right);
166193}
167194
168195#include "UsersModel.moc"