From ee3f7eafae9e2e570c95e1afa9bea156ba3bf736 Mon Sep 17 00:00:00 2001 From: Jan Darmochwal Date: Sun, 3 Oct 2010 18:39:42 +0200 Subject: TreeView for sessions (replaces ListView) TreeView with SessionTreeModel replaces the old List View Other changes: * fixed bad copy and paste in CMakeLists.txt * added make clean to build.sh * removed moc_ and ui_ files from src --- src/dialog.cpp | 40 ++++++----- src/dialog.h | 5 +- src/moc_dialog.cpp | 85 ------------------------ src/moc_model.cpp | 69 ------------------- src/model.cpp | 47 ------------- src/model.h | 28 -------- src/session.h | 2 +- src/sessiontreeitem.cpp | 60 +++++++++++++++++ src/sessiontreeitem.h | 35 ++++++++++ src/sessiontreemodel.cpp | 169 +++++++++++++++++++++++++++++++++++++++++++++++ src/sessiontreemodel.h | 36 ++++++++++ src/ui/dialog.ui | 4 +- src/ui_dialog.h | 95 -------------------------- src/vsession.cpp | 2 +- src/vsession.h | 2 +- src/xsession.cpp | 2 +- src/xsession.h | 2 +- 17 files changed, 335 insertions(+), 348 deletions(-) delete mode 100644 src/moc_dialog.cpp delete mode 100644 src/moc_model.cpp delete mode 100644 src/model.cpp delete mode 100644 src/model.h create mode 100644 src/sessiontreeitem.cpp create mode 100644 src/sessiontreeitem.h create mode 100644 src/sessiontreemodel.cpp create mode 100644 src/sessiontreemodel.h delete mode 100644 src/ui_dialog.h (limited to 'src') diff --git a/src/dialog.cpp b/src/dialog.cpp index a1ab266..a7b3a5e 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -1,19 +1,20 @@ #include "dialog.h" #include "ui_dialog.h" -#include "model.h" -#include "session.h" #include "save_restore_session.h" +#include "sessiontreeitem.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { + model_ = new SessionTreeModel(parent); ui->setupUi(this); } Dialog::~Dialog() { delete ui; + delete model_; } void Dialog::changeEvent(QEvent *e) @@ -28,13 +29,20 @@ void Dialog::changeEvent(QEvent *e) } } -void Dialog::on_listView_activated(QModelIndex index) +void Dialog::on_treeView_activated(QModelIndex index) { //TODO handle failures - printf ("Item %d has been activated\n", index.row()); + //printf ("Item %d has been activated\n", index.row()); //TODO get rid of this->entries, storing them in the model should be enough // alternatively use references instead of copies? - Session* s(this->entries_.at(index.row())); + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + const Session* s(item->session()); + if (!s) { + return; + } if (s->run()) { writeSessionName(s->shortDescription()); close(); @@ -48,15 +56,17 @@ void Dialog::addItems(const QList& entries, const QString& section) { // TODO: section // TODO: this is not the right way to do this // we probably do not need a copy of the entries vector in Dialog and Model - printf("Dialog::addItems()\n"); - printf(" before: %d items\n", this->entries_.size()); - printf(" %d new items\n", entries.size()); - this->entries_.append(entries); - printf(" after: %d items\n", this->entries_.size()); - QAbstractListModel *data = new Model(this->entries_, ui->listView); - QItemSelectionModel *m = ui->listView->selectionModel(); - ui->listView->setModel(data); - delete m; + //printf("Dialog::addItems()\n"); + //printf(" before: %d items\n", this->entries_.size()); + //printf(" %d new items\n", entries.size()); + //this->entries_.append(entries); + //printf(" after: %d items\n", this->entries_.size()); + + this->model_->addItems(entries, section); + + // TODO: do this only once? + ui->treeView->setModel(model_); + ui->treeView->expandAll(); } void Dialog::on_pushButtonAbort_clicked() @@ -67,5 +77,5 @@ void Dialog::on_pushButtonAbort_clicked() void Dialog::on_pushButtonStart_clicked() { // TODO: check if a model is selected - this->on_listView_activated(ui->listView->selectionModel()->currentIndex()); + this->on_treeView_activated(ui->treeView->selectionModel()->currentIndex()); } diff --git a/src/dialog.h b/src/dialog.h index 9f9ac5a..f452c61 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -5,6 +5,7 @@ #include #include #include "session.h" +#include "sessiontreemodel.h" namespace Ui { class Dialog; @@ -22,12 +23,12 @@ protected: private: Ui::Dialog *ui; - QList entries_; + SessionTreeModel *model_; private slots: void on_pushButtonStart_clicked(); void on_pushButtonAbort_clicked(); - void on_listView_activated(QModelIndex index); + void on_treeView_activated(QModelIndex index); }; #endif // DIALOG_H diff --git a/src/moc_dialog.cpp b/src/moc_dialog.cpp deleted file mode 100644 index d7dc097..0000000 --- a/src/moc_dialog.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** Meta object code from reading C++ file 'dialog.h' -** -** Created: Sat Jul 10 14:28:06 2010 -** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2) -** -** WARNING! All changes made in this file will be lost! -*****************************************************************************/ - -#include "dialog.h" -#if !defined(Q_MOC_OUTPUT_REVISION) -#error "The header file 'dialog.h' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 62 -#error "This file was generated using the moc from 4.6.2. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -QT_BEGIN_MOC_NAMESPACE -static const uint qt_meta_data_Dialog[] = { - - // content: - 4, // revision - 0, // classname - 0, 0, // classinfo - 3, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 8, 7, 7, 7, 0x08, - 37, 7, 7, 7, 0x08, - 72, 66, 7, 7, 0x08, - - 0 // eod -}; - -static const char qt_meta_stringdata_Dialog[] = { - "Dialog\0\0on_pushButtonStart_clicked()\0" - "on_pushButtonAbort_clicked()\0index\0" - "on_listView_activated(QModelIndex)\0" -}; - -const QMetaObject Dialog::staticMetaObject = { - { &QDialog::staticMetaObject, qt_meta_stringdata_Dialog, - qt_meta_data_Dialog, 0 } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &Dialog::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *Dialog::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *Dialog::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_Dialog)) - return static_cast(const_cast< Dialog*>(this)); - return QDialog::qt_metacast(_clname); -} - -int Dialog::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QDialog::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - switch (_id) { - case 0: on_pushButtonStart_clicked(); break; - case 1: on_pushButtonAbort_clicked(); break; - case 2: on_listView_activated((*reinterpret_cast< QModelIndex(*)>(_a[1]))); break; - default: ; - } - _id -= 3; - } - return _id; -} -QT_END_MOC_NAMESPACE diff --git a/src/moc_model.cpp b/src/moc_model.cpp deleted file mode 100644 index 7607fc9..0000000 --- a/src/moc_model.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** Meta object code from reading C++ file 'model.h' -** -** Created: Sat Jul 10 19:12:36 2010 -** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2) -** -** WARNING! All changes made in this file will be lost! -*****************************************************************************/ - -#include "model.h" -#if !defined(Q_MOC_OUTPUT_REVISION) -#error "The header file 'model.h' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 62 -#error "This file was generated using the moc from 4.6.2. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -QT_BEGIN_MOC_NAMESPACE -static const uint qt_meta_data_Model[] = { - - // content: - 4, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - 0 // eod -}; - -static const char qt_meta_stringdata_Model[] = { - "Model\0" -}; - -const QMetaObject Model::staticMetaObject = { - { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Model, - qt_meta_data_Model, 0 } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &Model::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *Model::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *Model::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_Model)) - return static_cast(const_cast< Model*>(this)); - return QAbstractListModel::qt_metacast(_clname); -} - -int Model::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QAbstractListModel::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} -QT_END_MOC_NAMESPACE diff --git a/src/model.cpp b/src/model.cpp deleted file mode 100644 index 672f91e..0000000 --- a/src/model.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "model.h" -#include -#include - -Model::Model(QList e, QObject *parent) - : QAbstractListModel(parent), - rowCount_(e.size()), entries_(e) -{ - printf("model with %d entries created\n", this->entries_.size()); -} - -Model::~Model() -{ -} - -int Model::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() && parent.column() != 0) ? 0 : rowCount_; -} - -QVariant Model::data(const QModelIndex &index, int role) const -{ - printf("request for model row %d role %d\n", index.row(), role); - if (!index.isValid()) - return QVariant(); - if (role == Qt::DisplayRole) - return this->entries_.at(index.row())->shortDescription(); - if (role == Qt::ToolTipRole) - return this->entries_.at(index.row())->description(); - if (role == Qt::DecorationRole) { - // TODO: use cache for icons - if (index.column() == 0) { - const Session* e(this->entries_.at(index.row())); - - QString icon(e->icon()); - - if (QFileInfo(icon).isAbsolute()) { - // try to load icon from file - return QIcon(icon); - } else { - // try to load icon from QResource - return QIcon(":" + icon.toLower()); - } - } - } - return QVariant(); -} diff --git a/src/model.h b/src/model.h deleted file mode 100644 index a03f015..0000000 --- a/src/model.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MODEL_H -#define MODEL_H - -#include -#include -#include -#include "session.h" - -class Model : public QAbstractListModel -{ - Q_OBJECT - -public: - Model(QList, QObject *parent = 0); - ~Model(); - - int rowCount(const QModelIndex &parent) const; - - QVariant data(const QModelIndex &index, int role) const; - -private: - - int rowCount_; - QList entries_; - QFileIconProvider iconProvider; //TODO -}; - -#endif // MODEL_H diff --git a/src/session.h b/src/session.h index ce8ce43..a61f286 100644 --- a/src/session.h +++ b/src/session.h @@ -13,7 +13,7 @@ public: virtual QString shortDescription() const = 0; virtual QString description() const = 0; virtual QString icon() const = 0; - virtual bool run() = 0; + virtual bool run() const = 0; virtual bool operator<(const Session& s) const = 0; }; diff --git a/src/sessiontreeitem.cpp b/src/sessiontreeitem.cpp new file mode 100644 index 0000000..5e07ad4 --- /dev/null +++ b/src/sessiontreeitem.cpp @@ -0,0 +1,60 @@ +#include "sessiontreeitem.h" + +SessionTreeItem::SessionTreeItem(const Session* session, SessionTreeItem *parent) : + parent_(parent), session_(session) +{ +} + +SessionTreeItem::SessionTreeItem(const QString& text, SessionTreeItem *parent) : + parent_(parent), session_(NULL), text_(text) +{ +} + +SessionTreeItem::~SessionTreeItem() +{ + qDeleteAll(children_); +} + +void SessionTreeItem::appendChild(SessionTreeItem *item) +{ + children_.append(item); +} + +SessionTreeItem *SessionTreeItem::child(int row) +{ + return children_.value(row); +} + +int SessionTreeItem::childCount() const +{ + return children_.count(); +} + +int SessionTreeItem::columnCount() const +{ + return 1; +} + +SessionTreeItem *SessionTreeItem::parent() +{ + return parent_; +} + +int SessionTreeItem::row() const +{ + if (parent_) { + return parent_->children_.indexOf(const_cast(this)); + } + + return 0; +} + +const Session* SessionTreeItem::session() const +{ + return session_; +} + +const QString SessionTreeItem::text() const +{ + return text_; +} diff --git a/src/sessiontreeitem.h b/src/sessiontreeitem.h new file mode 100644 index 0000000..ee587ae --- /dev/null +++ b/src/sessiontreeitem.h @@ -0,0 +1,35 @@ +#ifndef SESSIONTREEITEM_H +#define SESSIONTREEITEM_H + +#include +#include + +// class ... instead of include? +#include "session.h" +#include + +class SessionTreeItem +{ +public: + SessionTreeItem(const Session* session, SessionTreeItem *parent = 0); + SessionTreeItem(const QString& text, SessionTreeItem *parent = 0); + ~SessionTreeItem(); + + void appendChild(SessionTreeItem *child); + + SessionTreeItem *child(int row); + int childCount() const; + int columnCount() const; + int row() const; + SessionTreeItem *parent(); + const Session* session() const; + const QString text() const; + +private: + QList children_; + SessionTreeItem *parent_; + const Session *session_; + const QString text_; +}; + +#endif // SESSIONTREEITEM_H diff --git a/src/sessiontreemodel.cpp b/src/sessiontreemodel.cpp new file mode 100644 index 0000000..d3cd7ac --- /dev/null +++ b/src/sessiontreemodel.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include "sessiontreemodel.h" +#include "sessiontreeitem.h" + +SessionTreeModel::SessionTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + printf("new SessionTreeModel created\n"); + root_ = new SessionTreeItem("dummy"); +} + +SessionTreeModel::~SessionTreeModel() +{ + delete root_; +} + +int SessionTreeModel::columnCount(const QModelIndex &parent) const + { + //TODO: check if this is right for invalid parent of root_ + return 1; + } + +int SessionTreeModel::rowCount(const QModelIndex &parent) const +{ + SessionTreeItem* parentItem; + if (parent.column() > 0) + { + return 0; + } + + if (!parent.isValid()) + { + parentItem = root_; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +QVariant SessionTreeModel::data(const QModelIndex &index, int role) const +{ + printf("request for model row %d role %d\n", index.row(), role); + + if (!index.isValid()) { + return QVariant(); + } + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + const Session* s = item->session(); + if (s) { + if (role == Qt::DisplayRole) + return s->shortDescription(); + if (role == Qt::ToolTipRole) + return s->description(); + if (role == Qt::DecorationRole) { + // TODO: use cache for icons + if (index.column() == 0) { // TODO: is this line needed? + QString icon(s->icon()); + + if (QFileInfo(icon).isAbsolute()) { + // try to load icon from file + return QIcon(icon); + } else { + // try to load icon from QResource + return QIcon(":" + icon.toLower()); + } + } + } + } else if (role == Qt::DisplayRole) { + // this is a section item (X Sessions / Virtual Sessions) + return item->text(); + } + + return QVariant(); +} + +Qt::ItemFlags SessionTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) { + return 0; + } + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + if (item->session()) { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return Qt::ItemIsEnabled; + } +} + +QVariant SessionTreeModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + return QVariant(); +} + +QModelIndex SessionTreeModel::index(int row, int column, + const QModelIndex &parent) +const +{ + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + + SessionTreeItem *parentItem; + + if (!parent.isValid()) { + parentItem = root_; + } else { + parentItem = static_cast(parent.internalPointer()); + } + + SessionTreeItem *childItem = parentItem->child(row); + if (childItem) { + return createIndex(row, column, childItem); + } else { + return QModelIndex(); + } +} + +QModelIndex SessionTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + + SessionTreeItem *childItem = static_cast(index.internalPointer()); + SessionTreeItem *parentItem = childItem->parent(); + + if (parentItem == root_) { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +void SessionTreeModel::addItems(const QList& sessions, const QString& section) +{ + SessionTreeItem* parentItem; + + bool sectionExists = false; + + for (int i = 0; i < root_->childCount(); ++i) { + SessionTreeItem* item = root_->child(i); + if (item->text() == section) { + parentItem = item; + sectionExists = true; + break; + } + } + + if (!sectionExists) { + parentItem = new SessionTreeItem(section, root_); + root_->appendChild(parentItem); + } + + foreach (Session* s, sessions) { + parentItem->appendChild(new SessionTreeItem(s, parentItem)); + } +} diff --git a/src/sessiontreemodel.h b/src/sessiontreemodel.h new file mode 100644 index 0000000..31611cb --- /dev/null +++ b/src/sessiontreemodel.h @@ -0,0 +1,36 @@ +#ifndef VMCHOOSER_SESSIONTREEMODEL_H +#define VMCHOOSER_SESSIONTREEMODEL_H + +#include +#include +#include + +class SessionTreeItem; +class Session; + +class SessionTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + SessionTreeModel(QObject *parent = 0); + ~SessionTreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + void addItems(const QList& sessions, const QString& section); + + +private: + SessionTreeItem* root_; +}; + +#endif // VMCHOOSER_SESSIONTREEMODEL_H diff --git a/src/ui/dialog.ui b/src/ui/dialog.ui index 4c2853b..522ae55 100644 --- a/src/ui/dialog.ui +++ b/src/ui/dialog.ui @@ -15,14 +15,14 @@ - + 32 32 - + true diff --git a/src/ui_dialog.h b/src/ui_dialog.h deleted file mode 100644 index 6673f39..0000000 --- a/src/ui_dialog.h +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************** -** Form generated from reading UI file 'dialog.ui' -** -** Created: Mon Jul 12 08:20:43 2010 -** by: Qt User Interface Compiler version 4.6.2 -** -** WARNING! All changes made in this file will be lost when recompiling UI file! -********************************************************************************/ - -#ifndef UI_DIALOG_H -#define UI_DIALOG_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Ui_Dialog -{ -public: - QVBoxLayout *verticalLayout; - QListView *listView; - QHBoxLayout *horizontalLayout; - QSpacerItem *horizontalSpacer; - QPushButton *pushButtonAbort; - QPushButton *pushButtonStart; - - void setupUi(QDialog *Dialog) - { - if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); - Dialog->resize(600, 400); - verticalLayout = new QVBoxLayout(Dialog); - verticalLayout->setSpacing(6); - verticalLayout->setContentsMargins(11, 11, 11, 11); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); - listView = new QListView(Dialog); - listView->setObjectName(QString::fromUtf8("listView")); - listView->setIconSize(QSize(32, 32)); - listView->setUniformItemSizes(true); - - verticalLayout->addWidget(listView); - - horizontalLayout = new QHBoxLayout(); - horizontalLayout->setSpacing(6); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); - horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - - horizontalLayout->addItem(horizontalSpacer); - - pushButtonAbort = new QPushButton(Dialog); - pushButtonAbort->setObjectName(QString::fromUtf8("pushButtonAbort")); - - horizontalLayout->addWidget(pushButtonAbort); - - pushButtonStart = new QPushButton(Dialog); - pushButtonStart->setObjectName(QString::fromUtf8("pushButtonStart")); - pushButtonStart->setDefault(true); - - horizontalLayout->addWidget(pushButtonStart); - - - verticalLayout->addLayout(horizontalLayout); - - - retranslateUi(Dialog); - - QMetaObject::connectSlotsByName(Dialog); - } // setupUi - - void retranslateUi(QDialog *Dialog) - { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", 0, QApplication::UnicodeUTF8)); - pushButtonAbort->setText(QApplication::translate("Dialog", "Abbrechen", 0, QApplication::UnicodeUTF8)); - pushButtonStart->setText(QApplication::translate("Dialog", "Start", 0, QApplication::UnicodeUTF8)); - } // retranslateUi - -}; - -namespace Ui { - class Dialog: public Ui_Dialog {}; -} // namespace Ui - -QT_END_NAMESPACE - -#endif // UI_DIALOG_H diff --git a/src/vsession.cpp b/src/vsession.cpp index 3fa385f..f51fa3a 100644 --- a/src/vsession.cpp +++ b/src/vsession.cpp @@ -165,7 +165,7 @@ void VSession::addUserAndHostname() { this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); } -bool VSession::run() { +bool VSession::run() const { printf("VSession::run()\n"); QString command = getAttribute("command"); diff --git a/src/vsession.h b/src/vsession.h index bb29f64..da3a5a4 100644 --- a/src/vsession.h +++ b/src/vsession.h @@ -66,7 +66,7 @@ public: QString toXml() const; - bool run(); + bool run() const; bool operator<(const Session& other) const; diff --git a/src/xsession.cpp b/src/xsession.cpp index 2c1ed57..fb274b4 100644 --- a/src/xsession.cpp +++ b/src/xsession.cpp @@ -46,7 +46,7 @@ QString XSession::icon() const { return icon; } -bool XSession::run() { +bool XSession::run() const { return QProcess::startDetached(this->exec_); } diff --git a/src/xsession.h b/src/xsession.h index f5b5049..aac80fd 100644 --- a/src/xsession.h +++ b/src/xsession.h @@ -29,7 +29,7 @@ public: QString icon() const; - bool run(); + bool run() const; bool operator<(const Session& other) const; -- cgit v1.2.3-55-g7522