@@ -39,54 +39,54 @@ public:
3939 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
4040
4141private:
42− int manualRow() const;
43− int guestRow() const;
42+ struct CustomRow {
43+ QString name;
44+ QString realName;
45+ };
4446
45− void updateShowManual();
47+ void addCustomRow(const CustomRow &newRow);
48+ void removeCustomRow(const QString &rowName);
49+ void updateGuestRow();
50+ void updateManualRow();
4651
47− bool m_showManual;
52+ QList<CustomRow> m_customRows;
4853};
4954
5055MangleModel::MangleModel(QObject* parent)
5156 : QIdentityProxyModel(parent)
52− , m_showManual(false)
5357{
5458 if (!Greeter::instance()->hideUsersHint()) {
5559 setSourceModel(new QLightDM::UsersModel(this));
5660 }
5761
58− updateShowManual();
62+ updateGuestRow();
63+ updateManualRow();
5964
65+ // Would be nice if there were a rowCountChanged signal in the base class
6066 connect(this, &QIdentityProxyModel::modelReset,
61− this, &MangleModel::updateShowManual);
67+ this, &MangleModel::updateManualRow);
6268 connect(this, &QIdentityProxyModel::rowsInserted,
63− this, &MangleModel::updateShowManual);
69+ this, &MangleModel::updateManualRow);
6470 connect(this, &QIdentityProxyModel::rowsRemoved,
65− this, &MangleModel::updateShowManual);
71+ this, &MangleModel::updateManualRow);
6672}
6773
6874QVariant MangleModel::data(const QModelIndex &index, int role) const
6975{
7076 QVariant variantData;
7177
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;
78+ bool isCustomRow = index.row() >= sourceModel()->rowCount() &&
79+ index.row() < rowCount();
80+ if (isCustomRow && index.column() == 0) {
81+ int customIndex = index.row() - sourceModel()->rowCount();
82+ if (role == QLightDM::UsersModel::NameRole) {
83+ variantData = m_customRows[customIndex].name;
84+ } else if (role == QLightDM::UsersModel::RealNameRole) {
85+ variantData = m_customRows[customIndex].realName;
86+ } else if (role == QLightDM::UsersModel::LoggedInRole) {
87+ variantData = false;
88+ } else if (role == QLightDM::UsersModel::SessionRole) {
89+ variantData = Greeter::instance()->defaultSessionHint();
9090 }
9191 } else {
9292 variantData = QIdentityProxyModel::data(index, role);
@@ -94,7 +94,7 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
9494
9595 // If user's real name is empty, switch to unix name
9696 if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
97− variantData = QIdentityProxyModel::data(index, QLightDM::UsersModel::NameRole);
97+ variantData = data(index, QLightDM::UsersModel::NameRole);
9898 } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
9999 const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
100100 variantData = stringData;
@@ -103,64 +103,67 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
103103 return variantData;
104104}
105105
106−void MangleModel::updateShowManual()
106+void MangleModel::addCustomRow(const CustomRow &newRow)
107107{
108− // Show manual login if we are asked to OR if no other entry exists
109− bool showManual = Greeter::instance()->showManualLoginHint() ||
110− (QIdentityProxyModel::rowCount() == 0 &&
111− !Greeter::instance()->hasGuestAccount());
112−
113− if (m_showManual != showManual) {
114− int row = QIdentityProxyModel::rowCount();
115− if (showManual)
116− beginInsertRows(QModelIndex(), row, row);
117− else
118− beginRemoveRows(QModelIndex(), row, row);
119−
120− m_showManual = showManual;
121−
122− if (showManual)
123− endInsertRows();
124− else
125− endRemoveRows();
108+ for (int i = 0; i < m_customRows.size(); i++) {
109+ if (m_customRows[i].name == newRow.name) {
110+ return; // we don't have custom rows that change content yet
111+ }
126112 }
113+
114+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
115+ m_customRows << newRow;
116+ endInsertRows();
127117}
128118
129−int MangleModel::manualRow() const
119+void MangleModel::removeCustomRow(const QString &rowName)
130120{
131− if (!m_showManual)
132− return -1;
133−
134− return QIdentityProxyModel::rowCount();
121+ for (int i = 0; i < m_customRows.size(); i++) {
122+ if (m_customRows[i].name == rowName) {
123+ int rowNum = sourceModel()->rowCount() + i;
124+ beginRemoveRows(QModelIndex(), rowNum, rowNum);
125+ m_customRows.removeAt(i);
126+ endRemoveRows();
127+ break;
128+ }
129+ }
135130}
136131
137−int MangleModel::guestRow() const
132+void MangleModel::updateManualRow()
138133{
139− if (!Greeter::instance()->hasGuestAccount())
140− return -1;
134+ bool hasAnotherEntry = sourceModel()->rowCount() > 0;
135+ for (int i = 0; !hasAnotherEntry && i < m_customRows.size(); i++) {
136+ if (m_customRows[i].name != QStringLiteral("*other")) {
137+ hasAnotherEntry = true;
138+ }
139+ }
141140
142− int row = QIdentityProxyModel::rowCount();
143− if (m_showManual)
144− row++;
141+ // Show manual login if we are asked to OR if no other entry exists
142+ if (Greeter::instance()->showManualLoginHint() || !hasAnotherEntry)
143+ addCustomRow({QStringLiteral("*other"), gettext("Login")});
144+ else
145+ removeCustomRow(QStringLiteral("*other"));
146+}
145147
146− return row;
148+void MangleModel::updateGuestRow()
149+{
150+ if (Greeter::instance()->hasGuestAccount())
151+ addCustomRow({QStringLiteral("*guest"), gettext("Guest Session")});
152+ else
153+ removeCustomRow(QStringLiteral("*guest"));
147154}
148155
149156int MangleModel::rowCount(const QModelIndex &parent) const
150157{
151− auto count = QIdentityProxyModel::rowCount(parent);
152−
153− if (m_showManual && !parent.isValid())
154− count++;
155− if (Greeter::instance()->hasGuestAccount() && !parent.isValid())
156− count++;
157−
158− return count;
158+ return QIdentityProxyModel::rowCount(parent) +
159+ (parent.isValid() ? 0 : m_customRows.size());
159160}
160161
161162QModelIndex MangleModel::index(int row, int column, const QModelIndex &parent) const
162163{
163− if ((row == manualRow() || row == guestRow()) && !parent.isValid()) {
164+ bool isCustomRow = row >= sourceModel()->rowCount() &&
165+ row < rowCount();
166+ if (isCustomRow && !parent.isValid()) {
164167 return createIndex(row, column);
165168 } else {
166169 return QIdentityProxyModel::index(row, column, parent);
@@ -188,6 +191,10 @@ bool UsersModel::lessThan(const QModelIndex &source_left, const QModelIndex &sou
188191 return false;
189192 if (rightName == QStringLiteral("*guest"))
190193 return true;
194+ if (leftName == QStringLiteral("*other"))
195+ return false;
196+ if (rightName == QStringLiteral("*other"))
197+ return true;
191198
192199 return UnitySortFilterProxyModelQML::lessThan(source_left, source_right);
193200}