]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - liblightdm-qt/usersmodel.cpp
Revert the bogus .deps file changes and fix the clean rules
[sojka/lightdm.git] / liblightdm-qt / usersmodel.cpp
index 3fcc73dbda6cca286aa7d8831bdc9d4d13cde4f2..14d8df1f4484dc0e7c053cd9e4ecd1a1b7bd9ef5 100644 (file)
@@ -4,24 +4,17 @@
  *
  * This library is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option) any
- * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
- * license.
+ * Software Foundation; either version 2 or version 3 of the License.
+ * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
  */
 
 #include "QLightDM/usersmodel.h"
 
-#include <pwd.h>
-#include <errno.h>
-
-#include <QtCore/QSharedData>
 #include <QtCore/QString>
-#include <QtCore/QFileSystemWatcher>
-#include <QtCore/QFile>
-#include <QtCore/QDir>
-#include <QtCore/QSettings>
 #include <QtCore/QDebug>
-#include <QtGui/QPixmap>
+#include <QtGui/QIcon>
+
+#include <lightdm.h>
 
 using namespace QLightDM;
 
@@ -32,7 +25,11 @@ public:
     QString realName;
     QString homeDirectory;
     QString image;
+    QString background;
+    QString session;
     bool isLoggedIn;
+    bool hasMessages;
+    quint64 uid;
     QString displayName() const;
 };
 
@@ -45,189 +42,217 @@ QString UserItem::displayName() const {
     }
 }
 
-
+namespace QLightDM {
 class UsersModelPrivate {
 public:
+    UsersModelPrivate(UsersModel *parent);
+    virtual ~UsersModelPrivate();
     QList<UserItem> users;
-};
 
-UsersModel::UsersModel(QObject *parent) :
-    QAbstractListModel(parent),
-    d (new UsersModelPrivate())
-{
-    //load users on startup and if the password file changes.
-    QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
-    watcher->addPath("/etc/passwd"); //FIXME harcoded path
-    connect(watcher, SIGNAL(fileChanged(QString)), SLOT(loadUsers()));
+    protected:
+        UsersModel * const q_ptr;
+
+        void loadUsers();
 
-    loadUsers();
+        static void cb_userAdded(LightDMUserList *user_list, LightDMUser *user, gpointer data);
+        static void cb_userChanged(LightDMUserList *user_list, LightDMUser *user, gpointer data);
+        static void cb_userRemoved(LightDMUserList *user_list, LightDMUser *user, gpointer data);
+    private:
+        Q_DECLARE_PUBLIC(UsersModel)
+};
 }
 
-UsersModel::~UsersModel()
+UsersModelPrivate::UsersModelPrivate(UsersModel* parent) :
+    q_ptr(parent)
 {
-    delete d;
+#if !defined(GLIB_VERSION_2_36)
+    g_type_init();
+#endif
 }
 
-
-int UsersModel::rowCount(const QModelIndex &parent) const
+UsersModelPrivate::~UsersModelPrivate()
 {
-    return d->users.count();
+    g_signal_handlers_disconnect_by_data(lightdm_user_list_get_instance(), this);
 }
 
-QVariant UsersModel::data(const QModelIndex &index, int role) const
+void UsersModelPrivate::loadUsers()
 {
-    if (!index.isValid()) {
-        return QVariant();
-    }
+    Q_Q(UsersModel);
+
+    int rowCount = lightdm_user_list_get_length(lightdm_user_list_get_instance());
+
+    if (rowCount == 0) {
+        return;
+    } else {
+        q->beginInsertRows(QModelIndex(), 0, rowCount-1);
+
+        const GList *items, *item;
+        items = lightdm_user_list_get_users(lightdm_user_list_get_instance());
+        for (item = items; item; item = item->next) {
+            LightDMUser *ldmUser = static_cast<LightDMUser*>(item->data);
+
+            UserItem user;
+            user.name = QString::fromUtf8(lightdm_user_get_name(ldmUser));
+            user.homeDirectory = QString::fromUtf8(lightdm_user_get_home_directory(ldmUser));
+            user.realName = QString::fromUtf8(lightdm_user_get_real_name(ldmUser));
+            user.image = QString::fromUtf8(lightdm_user_get_image(ldmUser));
+            user.background = QString::fromUtf8(lightdm_user_get_background(ldmUser));
+            user.session = QString::fromUtf8(lightdm_user_get_session(ldmUser));
+            user.isLoggedIn = lightdm_user_get_logged_in(ldmUser);
+            user.hasMessages = lightdm_user_get_has_messages(ldmUser);
+            user.uid = (quint64)lightdm_user_get_uid(ldmUser);
+            users.append(user);
+        }
 
-    int row = index.row();
-    switch (role) {
-    case Qt::DisplayRole:
-        return d->users[row].displayName();
-    case Qt::DecorationRole:
-        return QPixmap(d->users[row].image);
-    case UsersModel::NameRole:
-        return d->users[row].name;
-    case UsersModel::RealNameRole:
-        return d->users[row].realName;
-    case UsersModel::LoggedInRole:
-        return d->users[row].isLoggedIn;
+        q->endInsertRows();
     }
-
-    return QVariant();
+    g_signal_connect(lightdm_user_list_get_instance(), LIGHTDM_USER_LIST_SIGNAL_USER_ADDED, G_CALLBACK (cb_userAdded), this);
+    g_signal_connect(lightdm_user_list_get_instance(), LIGHTDM_USER_LIST_SIGNAL_USER_CHANGED, G_CALLBACK (cb_userChanged), this);
+    g_signal_connect(lightdm_user_list_get_instance(), LIGHTDM_USER_LIST_SIGNAL_USER_REMOVED, G_CALLBACK (cb_userRemoved), this);
 }
 
-
-QList<UserItem> UsersModel::getUsers() const
+void UsersModelPrivate::cb_userAdded(LightDMUserList *user_list, LightDMUser *ldmUser, gpointer data)
 {
-    QString file = "/etc/lightdm/users.conf"; //FIXME hardcoded path!!
+    Q_UNUSED(user_list)
+    UsersModelPrivate *that = static_cast<UsersModelPrivate*>(data);
 
-    qDebug() << "Loading user configuration from " << file;
-    QSettings settings(file, QSettings::IniFormat);
+    that->q_func()->beginInsertRows(QModelIndex(), that->users.size(), that->users.size());
 
-    int minimumUid = settings.value("UserAccounts/minimum-uid", QVariant(500)).toInt();
-    QStringList hiddenShells;
-    if (settings.contains("UserAccounts/hidden-shells")) {
-        hiddenShells = settings.value("UserAccounts/hidden-shells").toString().split(" ");
-    }
-    else {
-        hiddenShells = QStringList() << "/bin/false" << "/usr/sbin/nologin";
-    }
-    QStringList hiddenUsers;
-    if (settings.contains("UserAccounts/hidden-users")) {
-        hiddenUsers = settings.value("UserAccounts/hidden-users").toString().split(" ");
-    }
-    else {
-        hiddenUsers = QStringList() << "nobody" << "nobody4" << "noaccess";
-    }
-    QList<UserItem> users;
+    UserItem user;
+    user.name = QString::fromUtf8(lightdm_user_get_name(ldmUser));
+    user.homeDirectory = QString::fromUtf8(lightdm_user_get_home_directory(ldmUser));
+    user.realName = QString::fromUtf8(lightdm_user_get_real_name(ldmUser));
+    user.image = QString::fromUtf8(lightdm_user_get_image(ldmUser));
+    user.background = QString::fromUtf8(lightdm_user_get_background(ldmUser));
+    user.isLoggedIn = lightdm_user_get_logged_in(ldmUser);
+    user.hasMessages = lightdm_user_get_has_messages(ldmUser);
+    user.uid = (quint64)lightdm_user_get_uid(ldmUser);
+    that->users.append(user);
 
-    setpwent();
-    Q_FOREVER {
-        errno = 0;
-        struct passwd *entry = getpwent();
-        if(!entry) {
-            break;
-        }
+    that->q_func()->endInsertRows();
 
-        /* Ignore system users */
-        if(entry->pw_uid < minimumUid) {
-            continue;
-        }
+}
 
-        /* Ignore users disabled by shell */
-        if(entry->pw_shell) {
-            if (hiddenShells.contains(entry->pw_shell)) {
-                continue;
-            }
-        }
+void UsersModelPrivate::cb_userChanged(LightDMUserList *user_list, LightDMUser *ldmUser, gpointer data)
+{
+    Q_UNUSED(user_list)
+    UsersModelPrivate *that = static_cast<UsersModelPrivate*>(data);
 
-        if (hiddenUsers.contains(entry->pw_name)) {
-            continue;
-        }
+    QString userToChange = QString::fromUtf8(lightdm_user_get_name(ldmUser));
 
-        QStringList tokens = QString(entry->pw_gecos).split(",");
-        QString realName;
-        if(tokens.size() > 0 && tokens.at(0) != "") {
-            realName = tokens.at(0);
-        }
+    for (int i=0;i<that->users.size();i++) {
+        if (that->users[i].name == userToChange) {
 
-        QDir homeDir(entry->pw_dir);
-        QString image = homeDir.filePath(".face");
-        if(!QFile::exists (image)) {
-            image = homeDir.filePath(".face.icon");
-            if(!QFile::exists (image)) {
-                image = "";
-            }
-        }
+            that->users[i].homeDirectory = QString::fromUtf8(lightdm_user_get_home_directory(ldmUser));
+            that->users[i].realName = QString::fromUtf8(lightdm_user_get_real_name(ldmUser));
+            that->users[i].image = QString::fromUtf8(lightdm_user_get_image(ldmUser));
+            that->users[i].background = QString::fromUtf8(lightdm_user_get_background(ldmUser));
+            that->users[i].isLoggedIn = lightdm_user_get_logged_in(ldmUser);
+            that->users[i].hasMessages = lightdm_user_get_has_messages(ldmUser);
+            that->users[i].uid = (quint64)lightdm_user_get_uid(ldmUser);
 
-        UserItem user;
-        user.name = entry->pw_name;
-        user.realName = realName;
-        user.homeDirectory = entry->pw_dir;
-        user.image = image;
-        user.isLoggedIn = false;
-        users.append(user);
+            QModelIndex index = that->q_ptr->createIndex(i, 0);
+            that->q_ptr->dataChanged(index, index);
+            break;
+        }
     }
+}
 
-    if(errno != 0) {
-        qDebug() << "Failed to read password database: " << strerror(errno);
+
+void UsersModelPrivate::cb_userRemoved(LightDMUserList *user_list, LightDMUser *ldmUser, gpointer data)
+{
+    Q_UNUSED(user_list)
+
+    UsersModelPrivate *that = static_cast<UsersModelPrivate*>(data);
+    QString userToRemove = QString::fromUtf8(lightdm_user_get_name(ldmUser));
+
+    for (int i=0;i<that->users.size();i++) {
+        if (that->users[i].name == userToRemove) {
+            that->q_ptr->beginRemoveRows(QModelIndex(), i, i);
+            that->users.removeAt(i);
+            that->q_ptr->endRemoveRows();
+            break;
+        }
     }
-    endpwent();
+}
 
+UsersModel::UsersModel(QObject *parent) :
+    QAbstractListModel(parent),
+    d_ptr(new UsersModelPrivate(this))
+{
+    Q_D(UsersModel);
+    // Extend roleNames (we want to keep the "display" role)
+    QHash<int, QByteArray> roles = roleNames();
+    roles[NameRole] = "name";
+    roles[RealNameRole] = "realName";
+    roles[LoggedInRole] = "loggedIn";
+    roles[BackgroundRole] = "background";
+    roles[BackgroundPathRole] = "backgroundPath";
+    roles[SessionRole] = "session";
+    roles[HasMessagesRole] = "hasMessages";
+    roles[ImagePathRole] = "imagePath";
+    roles[UidRole] = "uid";
+    setRoleNames(roles);
+    d->loadUsers();
 
-    return users;
 }
 
-void UsersModel::loadUsers()
+UsersModel::~UsersModel()
 {
-    QList<UserItem> usersToAdd;
-
-    //might get rid of "User" object, keep as private object (like sessionsmodel) - or make it copyable.
-
-    //loop through all the new list of users, if it's in the list already update it (or do nothing) otherwise append to list of new users
-    QList<UserItem> newUserList = getUsers();
-
-    Q_FOREACH(const UserItem &user, newUserList) {
-        bool alreadyInList = false;
-        for(int i=0; i < d->users.size(); i++) {
-            if (user.name == d->users[i].name) {
-                alreadyInList = true;
-//                d->users[i].update(user.name(), user.homeDirectory(), user.image(), user.isLoggedIn());
-                QModelIndex index = createIndex(i,0);
-                dataChanged(index, index);
-            }
-        }
+    delete d_ptr;
+}
 
-        if (!alreadyInList) {
-            usersToAdd.append(user);
-        }
+
+int UsersModel::rowCount(const QModelIndex &parent) const
+{
+    Q_D(const UsersModel);
+    if (parent == QModelIndex()) {
+        return d->users.size();
     }
 
-    //loop through all the existing users, if they're not in the newly gathered list, remove them.
+    return 0;
+}
 
-    //FIXME this isn't perfect, looping like this in a mutating list - use mutable iterator.
-    for (int i=0; i < d->users.size() ; i++) {
-        bool found = false;
-        foreach(const UserItem &user, newUserList) {
-            if (d->users[i].name == user.name) {
-                found = true;
-            }
-        }
+QVariant UsersModel::data(const QModelIndex &index, int role) const
+{
+    Q_D(const UsersModel);
 
-        if (!found) {
-            beginRemoveRows(QModelIndex(), i, i);
-            d->users.removeAt(i);
-            endRemoveRows();
-        }
+    if (!index.isValid()) {
+        return QVariant();
     }
 
-    //append new users
-    if (usersToAdd.size() > 0) {
-        beginInsertRows(QModelIndex(), d->users.size(), d->users.size() + usersToAdd.size() -1);
-        d->users.append(usersToAdd);
-        endInsertRows();
+    int row = index.row();
+    switch (role) {
+    case Qt::DisplayRole:
+        return d->users[row].displayName();
+    case Qt::DecorationRole:
+        return QIcon(d->users[row].image);
+    case UsersModel::NameRole:
+        return d->users[row].name;
+    case UsersModel::RealNameRole:
+        return d->users[row].realName;
+    case UsersModel::SessionRole:
+        return d->users[row].session;
+    case UsersModel::LoggedInRole:
+        return d->users[row].isLoggedIn;
+    case UsersModel::BackgroundRole:
+        return QPixmap(d->users[row].background);
+    case UsersModel::BackgroundPathRole:
+        return d->users[row].background;
+    case UsersModel::HasMessagesRole:
+        return d->users[row].hasMessages;
+    case UsersModel::ImagePathRole:
+        return d->users[row].image;
+    case UsersModel::UidRole:
+        return d->users[row].uid;
     }
+
+    return QVariant();
 }
 
-#include "usersmodel_moc.cpp"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+#include "usersmodel_moc5.cpp"
+#else
+#include "usersmodel_moc4.cpp"
+#endif