@@ -39,54 +39,54 @@ public:
39 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
39 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
42− int manualRow() const;
42+ struct CustomRow {
43− int guestRow() const;
43+ QString name;
45− void updateShowManual();
47+ void addCustomRow(const CustomRow &newRow);
48+ void removeCustomRow(const QString &rowName);
49+ void updateGuestRow();
50+ void updateManualRow();
47− bool m_showManual;
52+ QList<CustomRow> m_customRows;
50MangleModel::MangleModel(QObject* parent)
55MangleModel::MangleModel(QObject* parent)
51 : QIdentityProxyModel(parent)
56 : QIdentityProxyModel(parent)
52− , m_showManual(false)
54 if (!Greeter::instance()->hideUsersHint()) {
58 if (!Greeter::instance()->hideUsersHint()) {
55 setSourceModel(new QLightDM::UsersModel(this));
59 setSourceModel(new QLightDM::UsersModel(this));
58− updateShowManual();
62+ updateGuestRow();
65+ // Would be nice if there were a rowCountChanged signal in the base class
60 connect(this, &QIdentityProxyModel::modelReset,
66 connect(this, &QIdentityProxyModel::modelReset,
61− this, &MangleModel::updateShowManual);
67+ this, &MangleModel::updateManualRow);
62 connect(this, &QIdentityProxyModel::rowsInserted,
68 connect(this, &QIdentityProxyModel::rowsInserted,
63− this, &MangleModel::updateShowManual);
69+ this, &MangleModel::updateManualRow);
64 connect(this, &QIdentityProxyModel::rowsRemoved,
70 connect(this, &QIdentityProxyModel::rowsRemoved,
65− this, &MangleModel::updateShowManual);
71+ this, &MangleModel::updateManualRow);
68QVariant MangleModel::data(const QModelIndex &index, int role) const
74QVariant MangleModel::data(const QModelIndex &index, int role) const
70 QVariant variantData;
76 QVariant variantData;
72− if (index.row() == manualRow() && index.column() == 0) {
78+ bool isCustomRow = index.row() >= sourceModel()->rowCount() &&
73− switch (role) {
79+ index.row() < rowCount();
74− case QLightDM::UsersModel::NameRole: return QStringLiteral("*other");
80+ if (isCustomRow && index.column() == 0) {
75− case QLightDM::UsersModel::RealNameRole: return gettext("Login");
81+ int customIndex = index.row() - sourceModel()->rowCount();
76− case QLightDM::UsersModel::LoggedInRole: return false;
77− case QLightDM::UsersModel::SessionRole: return Greeter::instance()->defaultSessionHint();
78− default: return QVariant();
80− } else if (index.row() == guestRow() && index.column() == 0) {
82− case QLightDM::UsersModel::NameRole:
82+ if (role == QLightDM::UsersModel::NameRole) {
83− variantData = QStringLiteral("*guest"); break;
83+ variantData = m_customRows[customIndex].name;
84− case QLightDM::UsersModel::RealNameRole:
84+ } else if (role == QLightDM::UsersModel::RealNameRole) {
85− variantData = gettext("Guest Session"); break;
85+ variantData = m_customRows[customIndex].realName;
86− case QLightDM::UsersModel::LoggedInRole:
86+ } else if (role == QLightDM::UsersModel::LoggedInRole) {
87− variantData = false; break;
87+ variantData = false;
88− case QLightDM::UsersModel::SessionRole:
88+ } else if (role == QLightDM::UsersModel::SessionRole) {
89− variantData = Greeter::instance()->defaultSessionHint(); break;
89+ variantData = Greeter::instance()->defaultSessionHint();
92 variantData = QIdentityProxyModel::data(index, role);
92 variantData = QIdentityProxyModel::data(index, role);
@@ -94,7 +94,7 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
95 // If user's real name is empty, switch to unix name
95 // If user's real name is empty, switch to unix name
96 if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
96 if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
97− variantData = QIdentityProxyModel::data(index, QLightDM::UsersModel::NameRole);
97+ variantData = data(index, QLightDM::UsersModel::NameRole);
98 } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
98 } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
99 const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
99 const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
100 variantData = stringData;
100 variantData = stringData;
@@ -103,64 +103,67 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
103 return variantData;
103 return variantData;
106−void MangleModel::updateShowManual()
106+void MangleModel::addCustomRow(const CustomRow &newRow)
108− // Show manual login if we are asked to OR if no other entry exists
108+ for (int i = 0; i < m_customRows.size(); i++) {
109− bool showManual = Greeter::instance()->showManualLoginHint() ||
109+ if (m_customRows[i].name == newRow.name) {
110− (QIdentityProxyModel::rowCount() == 0 &&
110+ return; // we don't have custom rows that change content yet
111− !Greeter::instance()->hasGuestAccount());
111+ }
113− if (m_showManual != showManual) {
114− int row = QIdentityProxyModel::rowCount();
116− beginInsertRows(QModelIndex(), row, row);
118− beginRemoveRows(QModelIndex(), row, row);
120− m_showManual = showManual;
114+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
115+ m_customRows << newRow;
129−int MangleModel::manualRow() const
119+void MangleModel::removeCustomRow(const QString &rowName)
131− if (!m_showManual)
121+ for (int i = 0; i < m_customRows.size(); i++) {
132− return -1;
122+ if (m_customRows[i].name == rowName) {
133−
123+ int rowNum = sourceModel()->rowCount() + i;
134− return QIdentityProxyModel::rowCount();
124+ beginRemoveRows(QModelIndex(), rowNum, rowNum);
125+ m_customRows.removeAt(i);
137−int MangleModel::guestRow() const
132+void MangleModel::updateManualRow()
139− if (!Greeter::instance()->hasGuestAccount())
134+ bool hasAnotherEntry = sourceModel()->rowCount() > 0;
140− return -1;
135+ for (int i = 0; !hasAnotherEntry && i < m_customRows.size(); i++) {
136+ if (m_customRows[i].name != QStringLiteral("*other")) {
137+ hasAnotherEntry = true;
142− int row = QIdentityProxyModel::rowCount();
141+ // Show manual login if we are asked to OR if no other entry exists
143− if (m_showManual)
142+ if (Greeter::instance()->showManualLoginHint() || !hasAnotherEntry)
144− row++;
143+ addCustomRow({QStringLiteral("*other"), gettext("Login")});
145+ removeCustomRow(QStringLiteral("*other"));
146− return row;
148+void MangleModel::updateGuestRow()
150+ if (Greeter::instance()->hasGuestAccount())
151+ addCustomRow({QStringLiteral("*guest"), gettext("Guest Session")});
153+ removeCustomRow(QStringLiteral("*guest"));
149int MangleModel::rowCount(const QModelIndex &parent) const
156int MangleModel::rowCount(const QModelIndex &parent) const
151− auto count = QIdentityProxyModel::rowCount(parent);
158+ return QIdentityProxyModel::rowCount(parent) +
153− if (m_showManual && !parent.isValid())
159+ (parent.isValid() ? 0 : m_customRows.size());
155− if (Greeter::instance()->hasGuestAccount() && !parent.isValid())
161QModelIndex MangleModel::index(int row, int column, const QModelIndex &parent) const
162QModelIndex MangleModel::index(int row, int column, const QModelIndex &parent) const
164+ bool isCustomRow = row >= sourceModel()->rowCount() &&
163− if ((row == manualRow() || row == guestRow()) && !parent.isValid()) {
166+ if (isCustomRow && !parent.isValid()) {
164 return createIndex(row, column);
167 return createIndex(row, column);
166 return QIdentityProxyModel::index(row, column, parent);
169 return QIdentityProxyModel::index(row, column, parent);
@@ -188,6 +191,10 @@ bool UsersModel::lessThan(const QModelIndex &source_left, const QModelIndex &sou
188 return false;
191 return false;
189 if (rightName == QStringLiteral("*guest"))
192 if (rightName == QStringLiteral("*guest"))
190 return true;
193 return true;
194+ if (leftName == QStringLiteral("*other"))
196+ if (rightName == QStringLiteral("*other"))
192 return UnitySortFilterProxyModelQML::lessThan(source_left, source_right);
199 return UnitySortFilterProxyModelQML::lessThan(source_left, source_right);