diff --git a/src/avatargallery.cpp b/src/avatargallery.cpp index 546c723..56c3d5f 100644 --- a/src/avatargallery.cpp +++ b/src/avatargallery.cpp @@ -1,74 +1,73 @@ /** * Copyright 2003 Braden MacDonald * Copyright 2003 Ravikiran Rajagopal * Copyright 2015 Kai Uwe Broulik * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * */ #include "avatargallery.h" #include #include #include -#include AvatarGallery::AvatarGallery(QWidget *parent) : QDialog(parent) { setWindowTitle(i18nc("@title:window", "Change your Face")); ui.setupUi(this); ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(ui.m_FacesWidget, &QListWidget::currentItemChanged, this, [this](QListWidgetItem *current, QListWidgetItem *previous) { Q_UNUSED(previous); ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!current->icon().isNull()); }); connect(ui.m_FacesWidget, &QListWidget::doubleClicked, this, &AvatarGallery::accept); const QStringList &locations = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("user-manager/avatars"), QStandardPaths::LocateDirectory); if (locations.isEmpty()) { return; } const QString &systemFacesPath = locations.last() + QLatin1Char('/'); QDir avatarsDir(systemFacesPath); foreach(const QString &avatarStyle, avatarsDir.entryList(QDir::Dirs | QDir::NoDotDot)) { QDir facesDir = (avatarsDir.filePath(avatarStyle)); const QStringList &avatarList = facesDir.entryList(QDir::Files); for (auto it = avatarList.constBegin(), end = avatarList.constEnd(); it != end; ++it) { const QString iconPath = (facesDir.absoluteFilePath(*it)); auto *item = new QListWidgetItem(QIcon(iconPath), it->section(QLatin1Char('.'), 0, 0), ui.m_FacesWidget); item->setData(Qt::UserRole, iconPath); } } resize(420, 400); // FIXME } QUrl AvatarGallery::url() const { return QUrl::fromLocalFile(ui.m_FacesWidget->currentItem()->data(Qt::UserRole).toString()); } diff --git a/src/createavatarjob.cpp b/src/createavatarjob.cpp index 58f3452..8ee873d 100644 --- a/src/createavatarjob.cpp +++ b/src/createavatarjob.cpp @@ -1,95 +1,94 @@ /************************************************************************************* * Copyright (C) 2013 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "createavatarjob.h" #include "user_manager_debug.h" #include #include #include -#include #include #include CreateAvatarJob::CreateAvatarJob(QObject* parent) : KJob(parent) { } void CreateAvatarJob::setUrl(const QUrl& url) { m_url = url; } QString CreateAvatarJob::avatarPath() const { return m_tmpFile; } void CreateAvatarJob::start() { QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection); } void CreateAvatarJob::doStart() { qCDebug(USER_MANAGER_LOG) << "Starting: " << m_url; QTemporaryFile file; file.open(); m_tmpFile = file.fileName(); file.remove(); qCDebug(USER_MANAGER_LOG) << "From: " << m_url << "to: " << m_tmpFile; KIO::CopyJob* job = KIO::copy(m_url, QUrl::fromLocalFile(m_tmpFile), KIO::HideProgressInfo); connect(job, &KJob::finished, this, &CreateAvatarJob::copyDone); job->setUiDelegate(nullptr); job->start(); } void CreateAvatarJob::copyDone(KJob* job) { if (job->error()) { qCDebug(USER_MANAGER_LOG) << "Error:" << job->errorString(); setError(job->error()); emitResult(); return; } QImage face = KPixmapRegionSelectorDialog::getSelectedImage(QPixmap(m_tmpFile), 192, 192); if (face.isNull()) { qCDebug(USER_MANAGER_LOG) << "Icon region selection aborted"; setError(UserDefinedError); emitResult(); return; } /* Accountmanager doesn't allow icon which are bigger than 1MB */ face = face.scaledToWidth(qMin(600, face.width())); /* Delete file, otherwise face.save() will fail */ QFile::remove(m_tmpFile); if (! face.save(m_tmpFile, "PNG", 10)) { qCDebug(USER_MANAGER_LOG) << "Saving icon failed"; setError(UserDefinedError); emitResult(); return; } emitResult(); } diff --git a/src/lib/modeltest.cpp b/src/lib/modeltest.cpp index a02e046..5b86c27 100644 --- a/src/lib/modeltest.cpp +++ b/src/lib/modeltest.cpp @@ -1,523 +1,522 @@ /**************************************************************************** * * ** Copyright (C) 2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Concurrent project on Trolltech Labs. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "modeltest.h" -#include #include - +#include /*! * Connect to all of the models signals. Whenever anything happens recheck everything. */ ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(parent), model(_model), fetchingMore(false) { Q_ASSERT(model); connect(model, &QAbstractItemModel::columnsAboutToBeInserted, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::columnsInserted, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::columnsRemoved, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::dataChanged, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::headerDataChanged, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::layoutChanged, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::modelReset, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::rowsAboutToBeInserted, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::rowsInserted, this, &ModelTest::runAllTests); connect(model, &QAbstractItemModel::rowsRemoved, this, &ModelTest::runAllTests); // Special checks for inserting/removing connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, &ModelTest::layoutAboutToBeChanged); connect(model, &QAbstractItemModel::layoutChanged, this, &ModelTest::layoutChanged); connect(model, &QAbstractItemModel::rowsAboutToBeInserted, this, &ModelTest::rowsAboutToBeInserted); connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ModelTest::rowsAboutToBeRemoved); connect(model, &QAbstractItemModel::rowsInserted, this, &ModelTest::rowsInserted); connect(model, &QAbstractItemModel::rowsRemoved, this, &ModelTest::rowsRemoved); runAllTests(); } void ModelTest::runAllTests() { if (fetchingMore) return; nonDestructiveBasicTest(); rowCount(); columnCount(); hasIndex(); index(); parent(); data(); } /*! * nonDestructiveBasicTest tries to call a number of the basic functions (not all) * to make sure the model doesn't outright segfault, testing the functions that makes sense. */ void ModelTest::nonDestructiveBasicTest() { Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex()); model->canFetchMore(QModelIndex()); Q_ASSERT(model->columnCount(QModelIndex()) >= 0); Q_ASSERT(model->data(QModelIndex()) == QVariant()); fetchingMore = true; model->fetchMore(QModelIndex()); fetchingMore = false; Qt::ItemFlags flags = model->flags(QModelIndex()); Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0); model->hasChildren(QModelIndex()); model->hasIndex(0, 0); model->headerData(0, Qt::Horizontal); model->index(0, 0); model->itemData(QModelIndex()); QVariant cache; model->match(QModelIndex(), -1, cache); model->mimeTypes(); Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); Q_ASSERT(model->rowCount() >= 0); QVariant variant; model->setData(QModelIndex(), variant, -1); model->setHeaderData(-1, Qt::Horizontal, QVariant()); model->setHeaderData(999999, Qt::Horizontal, QVariant()); QMap roles; model->sibling(0, 0, QModelIndex()); model->span(QModelIndex()); model->supportedDropActions(); } /*! * Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() * * Models that are dynamically populated are not as fully tested here. */ void ModelTest::rowCount() { // check top row QModelIndex topIndex = model->index(0, 0, QModelIndex()); int rows = model->rowCount(topIndex); Q_ASSERT(rows >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(topIndex) == true); QModelIndex secondLevelIndex = model->index(0, 0, topIndex); if (secondLevelIndex.isValid()) { // not the top level // check a row count where parent is valid rows = model->rowCount(secondLevelIndex); Q_ASSERT(rows >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(secondLevelIndex) == true); } // The models rowCount() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! * Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() */ void ModelTest::columnCount() { // check top row QModelIndex topIndex = model->index(0, 0, QModelIndex()); Q_ASSERT(model->columnCount(topIndex) >= 0); // check a column count where parent is valid QModelIndex childIndex = model->index(0, 0, topIndex); if (childIndex.isValid()) Q_ASSERT(model->columnCount(childIndex) >= 0); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! * Tests model's implementation of QAbstractItemModel::hasIndex() */ void ModelTest::hasIndex() { // Make sure that invalid values returns an invalid index Q_ASSERT(model->hasIndex(-2, -2) == false); Q_ASSERT(model->hasIndex(-2, 0) == false); Q_ASSERT(model->hasIndex(0, -2) == false); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds Q_ASSERT(model->hasIndex(rows, columns) == false); Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false); if (rows > 0) Q_ASSERT(model->hasIndex(0, 0) == true); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! * Tests model's implementation of QAbstractItemModel::index() */ void ModelTest::index() { // Make sure that invalid values returns an invalid index Q_ASSERT(model->index(-2, -2) == QModelIndex()); Q_ASSERT(model->index(-2, 0) == QModelIndex()); Q_ASSERT(model->index(0, -2) == QModelIndex()); int rows = model->rowCount(); int columns = model->columnCount(); if (rows == 0) return; // Catch off by one errors Q_ASSERT(model->index(rows, columns) == QModelIndex()); Q_ASSERT(model->index(0, 0).isValid() == true); // Make sure that the same index is *always* returned QModelIndex a = model->index(0, 0); QModelIndex b = model->index(0, 0); Q_ASSERT(a == b); // index() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! * Tests model's implementation of QAbstractItemModel::parent() */ void ModelTest::parent() { // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); if (model->rowCount() == 0) return; // Column 0 | Column 1 | // QModelIndex() | | // \- topIndex | topIndex1 | // \- childIndex | childIndex1 | // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. QModelIndex topIndex = model->index(0, 0, QModelIndex()); Q_ASSERT(model->parent(topIndex) == QModelIndex()); // Common error test #2, make sure that a second level index has a parent // that is the first level index. if (model->rowCount(topIndex) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); Q_ASSERT(model->parent(childIndex) == topIndex); } // Common error test #3, the second column should NOT have the same children // as the first column in a row. // Usually the second column shouldn't have children. QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); if (model->rowCount(topIndex1) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); QModelIndex childIndex1 = model->index(0, 0, topIndex1); Q_ASSERT(childIndex != childIndex1); } // Full test, walk n levels deep through the model making sure that all // parent's children correctly specify their parent. checkChildren(QModelIndex()); } /*! * Called from the parent() test. * * A model that returns an index of parent X should also return X when asking * for the parent of the index. * * This recursive function does pretty extensive testing on the whole model in an * effort to catch edge cases. * * This function assumes that rowCount(), columnCount() and index() already work. * If they have a bug it will point it out, but the above tests should have already * found the basic bugs because it is easier to figure out the problem in * those tests then this one. */ void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) { // First just try walking back up the tree. QModelIndex p = parent; while (p.isValid()) p = p.parent(); // For models that are dynamically populated if (model->canFetchMore(parent)) { fetchingMore = true; model->fetchMore(parent); fetchingMore = false; } int rows = model->rowCount(parent); int columns = model->columnCount(parent); if (rows > 0) Q_ASSERT(model->hasChildren(parent)); // Some further testing against rows(), columns(), and hasChildren() Q_ASSERT(rows >= 0); Q_ASSERT(columns >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(parent) == true); //qCDebug(USER_MANAGER_LOG) << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); Q_ASSERT(model->hasIndex(rows + 1, 0, parent) == false); for (int r = 0; r < rows; ++r) { if (model->canFetchMore(parent)) { fetchingMore = true; model->fetchMore(parent); fetchingMore = false; } Q_ASSERT(model->hasIndex(r, columns + 1, parent) == false); for (int c = 0; c < columns; ++c) { Q_ASSERT(model->hasIndex(r, c, parent) == true); QModelIndex index = model->index(r, c, parent); // rowCount() and columnCount() said that it existed... Q_ASSERT(index.isValid() == true); // index() should always return the same index when called twice in a row QModelIndex modifiedIndex = model->index(r, c, parent); Q_ASSERT(index == modifiedIndex); // Make sure we get the same index if we request it twice in a row QModelIndex a = model->index(r, c, parent); QModelIndex b = model->index(r, c, parent); Q_ASSERT(a == b); // Some basic checking on the index that is returned Q_ASSERT(index.model() == model); Q_ASSERT(index.row() == r); Q_ASSERT(index.column() == c); // While you can technically return a QVariant usually this is a sign // of an bug in data() Disable if this really is ok in your model. Q_ASSERT(model->data(index, Qt::DisplayRole).isValid() == true); // If the next test fails here is some somewhat useful debug you play with. /* * if (model->parent(index) != parent) { * qCDebug(USER_MANAGER_LOG) << r << c << currentDepth << model->data(index).toString() * << model->data(parent).toString(); * qCDebug(USER_MANAGER_LOG) << index << parent << model->parent(index); * // And a view that you can even use to show the model. * //QTreeView view; * //view.setModel(model); * //view.show(); }*/ // Check that we can get back our real parent. Q_ASSERT(model->parent(index) == parent); // recursively go down the children if (model->hasChildren(index) && currentDepth < 10 ) { //qCDebug(USER_MANAGER_LOG) << r << c << "has children" << model->rowCount(index); checkChildren(index, ++currentDepth); }/* else { if (currentDepth >= 10) qCDebug(USER_MANAGER_LOG) << "checked 10 deep"; };*/ // make sure that after testing the children that the index doesn't change. QModelIndex newerIndex = model->index(r, c, parent); Q_ASSERT(index == newerIndex); } } } /*! * Tests model's implementation of QAbstractItemModel::data() */ void ModelTest::data() { // Invalid index should return an invalid qvariant Q_ASSERT(!model->data(QModelIndex()).isValid()); if (model->rowCount() == 0) return; // A valid index should have a valid QVariant data Q_ASSERT(model->index(0, 0).isValid()); // shouldn't be able to set data on an invalid index Q_ASSERT(model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole) == false); // General Purpose roles that should return a QString QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QString)); } variant = model->data(model->index(0, 0), Qt::StatusTipRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QString)); } variant = model->data(model->index(0, 0), Qt::WhatsThisRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QString)); } // General Purpose roles that should return a QSize variant = model->data(model->index(0, 0), Qt::SizeHintRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QSize)); } // General Purpose roles that should return a QFont QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); if (fontVariant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QFont)); } // Check that the alignment is one we know about QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); if (textAlignmentVariant.isValid()) { int alignment = textAlignmentVariant.toInt(); Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); } // General Purpose roles that should return a QColor QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundRole); if (colorVariant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QColor)); } colorVariant = model->data(model->index(0, 0), Qt::ForegroundRole); if (colorVariant.isValid()) { Q_ASSERT(variant.canConvert(QMetaType::QColor)); } // Check that the "check state" is one we know about. QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); if (checkStateVariant.isValid()) { int state = checkStateVariant.toInt(); Q_ASSERT(state == Qt::Unchecked || state == Qt::PartiallyChecked || state == Qt::Checked); } } /*! * Store what is about to be inserted to make sure it actually happens * * \sa rowsInserted() */ void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) { Q_UNUSED(end); Changing c; c.parent = parent; c.oldSize = model->rowCount(parent); c.last = model->data(model->index(start - 1, 0, parent)); c.next = model->data(model->index(start, 0, parent)); insert.push(c); } /*! * Confirm that what was said was going to happen actually did * * \sa rowsAboutToBeInserted() */ void ModelTest::rowsInserted(const QModelIndex & parent, int start, int end) { Changing c = insert.pop(); Q_ASSERT(c.parent == parent); Q_ASSERT(c.oldSize + (end - start + 1) == model->rowCount(parent)); Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); /* * if (c.next != model->data(model->index(end + 1, 0, c.parent))) { * qCDebug(USER_MANAGER_LOG) << start << end; * for (int i=0; i < model->rowCount(); ++i) * qCDebug(USER_MANAGER_LOG) << model->index(i, 0).data().toString(); * qCDebug(USER_MANAGER_LOG) << c.next << model->data(model->index(end + 1, 0, c.parent)); } */ Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent))); } void ModelTest::layoutAboutToBeChanged() { for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) changing.append(QPersistentModelIndex(model->index(i, 0))); } void ModelTest::layoutChanged() { for (int i = 0; i < changing.count(); ++i) { QPersistentModelIndex p = changing[i]; Q_ASSERT(p == model->index(p.row(), p.column(), p.parent())); } changing.clear(); } /*! * Store what is about to be inserted to make sure it actually happens * * \sa rowsRemoved() */ void ModelTest::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { Changing c; c.parent = parent; c.oldSize = model->rowCount(parent); c.last = model->data(model->index(start - 1, 0, parent)); c.next = model->data(model->index(end + 1, 0, parent)); remove.push(c); } /*! * Confirm that what was said was going to happen actually did * * \sa rowsAboutToBeRemoved() */ void ModelTest::rowsRemoved(const QModelIndex & parent, int start, int end) { Changing c = remove.pop(); Q_ASSERT(c.parent == parent); Q_ASSERT(c.oldSize - (end - start + 1) == model->rowCount(parent)); Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent))); } diff --git a/src/lib/usersessions.h b/src/lib/usersessions.h index 6eef7bf..93de710 100644 --- a/src/lib/usersessions.h +++ b/src/lib/usersessions.h @@ -1,58 +1,57 @@ /************************************************************************************* * Copyright (C) 2013 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #ifndef USER_SESSION_H #define USER_SESSION_H #include #include -#include struct UserInfo { uint id; QString name; QDBusObjectPath path; }; Q_DECLARE_METATYPE(UserInfo) typedef QList UserInfoList; Q_DECLARE_METATYPE(UserInfoList) class QDBusPendingCallWatcher; class OrgFreedesktopLogin1ManagerInterface; class UserSession : public QObject { Q_OBJECT public: explicit UserSession(QObject* parent = nullptr); virtual ~UserSession(); public Q_SLOTS: void UserNew(uint id); void UserRemoved(uint id); void listUsersSlot(QDBusPendingCallWatcher *watcher); Q_SIGNALS: void userLogged(uint id, bool logged); private: OrgFreedesktopLogin1ManagerInterface* m_manager; }; #endif //USER_SESSION_H diff --git a/src/usermanager.cpp b/src/usermanager.cpp index c095176..2811812 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -1,141 +1,139 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "usermanager.h" #include "ui_kcm.h" #include "ui_account.h" #include "accountinfo.h" #include "lib/accountmodel.h" #include "lib/modeltest.h" #include -#include -#include #include #include #include #include #include K_PLUGIN_FACTORY(UserManagerFactory, registerPlugin();) UserManager::UserManager(QWidget* parent, const QVariantList& args) : KCModule(parent, args) , m_saveNeeded(false) , m_model(new AccountModel(this)) , m_widget(new AccountInfo(m_model, this)) , m_ui(new Ui::KCMUserManager) { Q_UNUSED(args); QVBoxLayout *layout = new QVBoxLayout(); m_ui->setupUi(this); m_ui->accountInfo->setLayout(layout); layout->addWidget(m_widget); m_selectionModel = new QItemSelectionModel(m_model); connect(m_selectionModel, &QItemSelectionModel::currentChanged, this, &UserManager::currentChanged); m_selectionModel->setCurrentIndex(m_model->index(0), QItemSelectionModel::SelectCurrent); m_ui->userList->setModel(m_model); m_ui->userList->setSelectionModel(m_selectionModel); m_ui->userList->setIconSize(QSize(IconSize(KIconLoader::Dialog), IconSize(KIconLoader::Dialog))); ModelTest* test = new ModelTest(m_model, nullptr); Q_UNUSED(test) connect(m_ui->addBtn, &QAbstractButton::clicked, this, &UserManager::addNewUser); connect(m_ui->removeBtn, &QAbstractButton::clicked, this, &UserManager::removeUser); connect(m_widget, SIGNAL(changed(bool)), SIGNAL(changed(bool))); connect(m_model, &QAbstractItemModel::dataChanged, this, &UserManager::dataChanged); } UserManager::~UserManager() { delete m_model; } void UserManager::load() { m_widget->loadFromModel(); } void UserManager::save() { m_widget->save(); } void UserManager::currentChanged(const QModelIndex& selected, const QModelIndex& previous) { Q_UNUSED(previous); m_widget->setModelIndex(selected); bool enabled = false; //If it is not last and not first if (selected.row() < m_model->rowCount() - 1 && selected.row() > 0) { enabled = true; } m_ui->removeBtn->setEnabled(enabled); m_selectionModel->setCurrentIndex(selected, QItemSelectionModel::SelectCurrent); } void UserManager::dataChanged(const QModelIndex& topLeft, const QModelIndex& topRight) { Q_UNUSED(topRight); if (m_selectionModel->currentIndex() != topLeft) { return; } currentChanged(topLeft, topLeft); } void UserManager::addNewUser() { m_selectionModel->setCurrentIndex(m_model->index(m_model->rowCount()-1), QItemSelectionModel::SelectCurrent); } void UserManager::removeUser() { QModelIndex index = m_selectionModel->currentIndex(); KGuiItem keep; keep.setText(i18n("Keep files")); KGuiItem deletefiles; deletefiles.setText(i18n("Delete files")); QString warning = i18n("What do you want to do after deleting %1 ?", m_model->data(index, AccountModel::FriendlyName).toString()); if (!m_model->data(index, AccountModel::Logged).toBool()) { warning.append(QStringLiteral("\n\n")); warning.append(i18n("This user is using the system right now, removing it will cause problems")); } int result = KMessageBox::questionYesNoCancel(this, warning, i18n("Delete User"), keep, deletefiles); if (result == KMessageBox::Cancel) { return; } bool deleteFiles = result == KMessageBox::Yes ? false : true; m_model->removeAccountKeepingFiles(index.row(), deleteFiles); Q_EMIT changed(false); } #include "usermanager.moc"