File indexing completed on 2024-04-21 05:36:33
0001 /* 0002 * SPDX-FileCopyrightText: 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com> 0003 * SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 #include "sessionmodel.h" 0006 #include "config.h" 0007 0008 #include <memory> 0009 0010 #include <QDir> 0011 #include <QFile> 0012 #include <QList> 0013 #include <QTextStream> 0014 0015 #include <KLocalizedString> 0016 0017 class Session 0018 { 0019 public: 0020 QString file; 0021 QString name; 0022 QString exec; 0023 QString comment; 0024 }; 0025 0026 typedef std::shared_ptr<Session> SessionPtr; 0027 0028 class SessionModelPrivate 0029 { 0030 public: 0031 int lastIndex{0}; 0032 QList<SessionPtr> sessions; 0033 }; 0034 0035 SessionModel::SessionModel(QObject *parent) 0036 : QAbstractListModel(parent) 0037 , d(new SessionModelPrivate()) 0038 { 0039 loadDir(QStringLiteral(XSESSIONS_DIR), SessionTypeX); 0040 loadDir(QStringLiteral(WAYLAND_SESSIONS_DIR), SessionTypeWayland); 0041 } 0042 0043 SessionModel::~SessionModel() 0044 { 0045 delete d; 0046 } 0047 0048 void SessionModel::loadDir(const QString &path, SessionType type) 0049 { 0050 QDir dir(path); 0051 dir.setNameFilters(QStringList() << QStringLiteral("*.desktop")); 0052 dir.setFilter(QDir::Files); 0053 // read session 0054 foreach (const QString &session, dir.entryList()) { 0055 QFile inputFile(dir.absoluteFilePath(session)); 0056 if (!inputFile.open(QIODevice::ReadOnly)) { 0057 continue; 0058 } 0059 SessionPtr si{new Session{session.chopped(strlen(".desktop")), QString(), QString(), QString()}}; 0060 bool isHidden = false; 0061 QString current_section; 0062 QTextStream in(&inputFile); 0063 while (!in.atEnd()) { 0064 QString line = in.readLine(); 0065 0066 if (line.startsWith(QLatin1String("["))) { 0067 // The section name ends before the last ] before the start of a comment 0068 int end = line.lastIndexOf(QLatin1Char(']'), line.indexOf(QLatin1Char('#'))); 0069 if (end != -1) { 0070 current_section = line.mid(1, end - 1); 0071 } 0072 } 0073 0074 if (current_section != QLatin1String("Desktop Entry")) { 0075 continue; // We are only interested in the "Desktop Entry" section 0076 } 0077 0078 if (line.startsWith(QLatin1String("Name="))) { 0079 si->name = line.mid(5); 0080 if (type == SessionTypeWayland) { 0081 // we want to exactly match the SDDM prompt which is formatted in this way 0082 // with the exact same check 0083 if (!si->name.endsWith(QLatin1String(" (Wayland)"))) { 0084 si->name = i18nc("%1 is the name of a session", "%1 (Wayland)", si->name); 0085 } 0086 } 0087 } 0088 if (line.startsWith(QLatin1String("Exec="))) { 0089 si->exec = line.mid(5); 0090 } 0091 if (line.startsWith(QLatin1String("Comment="))) { 0092 si->comment = line.mid(8); 0093 } 0094 if (line.startsWith(QLatin1String("Hidden="))) { 0095 isHidden = line.mid(7).toLower() == QLatin1String("true"); 0096 } 0097 } 0098 if (!isHidden) { 0099 // add to sessions list 0100 d->sessions.push_back(si); 0101 } 0102 0103 // close file 0104 inputFile.close(); 0105 } 0106 } 0107 0108 QHash<int, QByteArray> SessionModel::roleNames() const 0109 { 0110 // set role names 0111 QHash<int, QByteArray> roleNames; 0112 roleNames[FileRole] = "file"; 0113 roleNames[NameRole] = "name"; 0114 roleNames[ExecRole] = "exec"; 0115 roleNames[CommentRole] = "comment"; 0116 0117 return roleNames; 0118 } 0119 0120 int SessionModel::rowCount(const QModelIndex &parent) const 0121 { 0122 Q_UNUSED(parent); 0123 return d->sessions.length(); 0124 } 0125 0126 QVariant SessionModel::data(const QModelIndex &index, int role) const 0127 { 0128 if (index.row() < 0 || index.row() >= d->sessions.count()) { 0129 return QVariant(); 0130 } 0131 0132 // get session 0133 SessionPtr session = d->sessions[index.row()]; 0134 0135 // return correct value 0136 if (role == FileRole) { 0137 return session->file; 0138 } else if (role == NameRole) { 0139 return session->name; 0140 } else if (role == ExecRole) { 0141 return session->exec; 0142 } else if (role == CommentRole) { 0143 return session->comment; 0144 } 0145 0146 // return empty value 0147 return QVariant(); 0148 } 0149 0150 int SessionModel::indexOf(const QString &sessionId) const 0151 { 0152 for (int i = 0; i < d->sessions.length(); i++) { 0153 if (d->sessions[i]->file == sessionId) { 0154 return i; 0155 } 0156 } 0157 return 0; 0158 }