diff --git a/kate/CMakeLists.txt b/kate/CMakeLists.txt --- a/kate/CMakeLists.txt +++ b/kate/CMakeLists.txt @@ -32,11 +32,9 @@ katetabbar.cpp # session - session/katesessionchooser.cpp session/katesessionsaction.cpp session/katesessionmanager.cpp session/katesessionmanagedialog.cpp - session/katesessionopendialog.cpp session/katesession.cpp katemdi.cpp @@ -47,6 +45,7 @@ ki18n_wrap_ui(KATE_LIBRARY_SRCS ui/sessionconfigwidget.ui + session/katesessionmanagedialog.ui ) qt5_add_resources( KATE_LIBRARY_SRCS data/kate.qrc ) diff --git a/kate/data/kateui.rc b/kate/data/kateui.rc --- a/kate/data/kateui.rc +++ b/kate/data/kateui.rc @@ -1,6 +1,6 @@ - + &File @@ -88,13 +88,11 @@ Sess&ions - + - - &Settings diff --git a/kate/katemainwindow.cpp b/kate/katemainwindow.cpp --- a/kate/katemainwindow.cpp +++ b/kate/katemainwindow.cpp @@ -383,11 +383,6 @@ a->setText(i18nc("Menu entry Session->New", "&New")); // Qt::QueuedConnection to avoid deletion of code that is executed when reducing the amount of mainwindows. (bug #227008) connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionNew()), Qt::QueuedConnection); - a = actionCollection()->addAction(QStringLiteral("sessions_open")); - a->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); - a->setText(i18n("&Open Session")); - // Qt::QueuedConnection to avoid deletion of code that is executed when reducing the amount of mainwindows. (bug #227008) - connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionOpen()), Qt::QueuedConnection); a = actionCollection()->addAction(QStringLiteral("sessions_save")); a->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); a->setText(i18n("&Save Session")); diff --git a/kate/session/katesessionchooser.h b/kate/session/katesessionchooser.h deleted file mode 100644 --- a/kate/session/katesessionchooser.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of the KDE project - * - * Copyright (C) 2005 Christoph Cullmann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __KATE_SESSION_CHOOSER_H__ -#define __KATE_SESSION_CHOOSER_H__ - -#include - -class QPushButton; -class QCheckBox; -class QTreeWidget; -class QTreeWidgetItem; - -#include "katesession.h" - -class KateSessionChooser : public QDialog -{ - Q_OBJECT - -public: - KateSessionChooser(QWidget *parent, const QString &lastSession); - ~KateSessionChooser() override; - - KateSession::Ptr selectedSession(); - bool reopenLastSession(); - - enum { - resultQuit = QDialog::Rejected, - resultOpen, - resultNew, - resultNone, - resultCopy - }; - -protected Q_SLOTS: - void slotCancel(); - void slotOpen(); - void slotNew(); - void slotCopySession(); - void slotDeleteSession(); - - /** - * selection has changed - */ - void selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - -private: - QTreeWidget *m_sessions; - QCheckBox *m_useLast; - QPushButton *m_openButton; -}; - -#endif - diff --git a/kate/session/katesessionchooser.cpp b/kate/session/katesessionchooser.cpp deleted file mode 100644 --- a/kate/session/katesessionchooser.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* This file is part of the KDE project - * - * Copyright (C) 2005 Christoph Cullmann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "katesessionchooser.h" - -#include "kateapp.h" -#include "katesessionmanager.h" -#include "katesessionchooseritem.h" -#include "katedebug.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -//BEGIN CHOOSER DIALOG - -KateSessionChooser::KateSessionChooser(QWidget *parent, const QString &lastSession) - : QDialog(parent) -{ - setWindowTitle(i18n("Session Chooser")); - QVBoxLayout *mainLayout = new QVBoxLayout(this); - - m_sessions = new QTreeWidget(this); - m_sessions->setMinimumSize(400, 200); - mainLayout->addWidget(m_sessions); - QStringList header; - header << i18n("Session Name"); - header << i18nc("The number of open documents", "Open Documents"); - header << QString(); - m_sessions->setHeaderLabels(header); - m_sessions->header()->setStretchLastSection(false); - m_sessions->header()->setSectionResizeMode(0, QHeaderView::Stretch); - m_sessions->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - m_sessions->header()->setSectionResizeMode(2, QHeaderView::Fixed); - m_sessions->header()->resizeSection(2, 32); - m_sessions->setRootIsDecorated(false); - m_sessions->setItemsExpandable(false); - m_sessions->setAllColumnsShowFocus(true); - m_sessions->setSelectionBehavior(QAbstractItemView::SelectRows); - m_sessions->setSelectionMode(QAbstractItemView::SingleSelection); - - qCDebug(LOG_KATE) << "Last session is:" << lastSession; - - KateSessionList slist = KateApp::self()->sessionManager()->sessionList(); - qSort(slist.begin(), slist.end(), KateSession::compareByName); - - foreach(const KateSession::Ptr & session, slist) { - KateSessionChooserItem *item = new KateSessionChooserItem(m_sessions, session); - QPushButton *tmp = new QPushButton(QIcon::fromTheme(QStringLiteral("document")), QString(), m_sessions); - QMenu *popup = new QMenu(tmp); - QAction *a = popup->addAction(i18n("Clone session settings")); - a->setData(QVariant::fromValue((void *)item)); - connect(a, SIGNAL(triggered()), this, SLOT(slotCopySession())); - a = popup->addAction(i18n("Delete this session")); - a->setData(QVariant::fromValue((void *)item)); - connect(a, SIGNAL(triggered()), this, SLOT(slotDeleteSession())); - tmp->setMenu(popup); - m_sessions->setItemWidget(item, 2, tmp); - - if (session->name() == lastSession) { - m_sessions->setCurrentItem(item); - } - } - - connect(m_sessions, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectionChanged(QTreeWidgetItem*,QTreeWidgetItem*))); - connect(m_sessions, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotOpen())); - - // bottom box - QHBoxLayout *hb = new QHBoxLayout(); - hb->setMargin(0); - mainLayout->addLayout(hb); - - m_useLast = new QCheckBox(i18n("&Always use this choice"), this); - hb->addWidget(m_useLast); - - // buttons - QDialogButtonBox *buttonBox = new QDialogButtonBox(this); - hb->addWidget(buttonBox); - - QPushButton *cancelButton = new QPushButton(); - KGuiItem::assign(cancelButton, KStandardGuiItem::quit()); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(slotCancel())); - buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole); - - m_openButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-open")), i18n("Open Session")); - m_openButton->setEnabled(m_sessions->currentIndex().isValid()); - m_openButton->setDefault(true); - m_openButton->setFocus(); - buttonBox->addButton(m_openButton, QDialogButtonBox::ActionRole); - connect(m_openButton, SIGNAL(clicked()), this, SLOT(slotOpen())); - - QPushButton *newButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-new")), i18n("New Session")); - buttonBox->addButton(newButton, QDialogButtonBox::ActionRole); - connect(newButton, SIGNAL(clicked()), this, SLOT(slotNew())); - - setResult(resultNone); - selectionChanged(nullptr, nullptr); -} - -KateSessionChooser::~KateSessionChooser() -{} - -void KateSessionChooser::slotCopySession() -{ - m_sessions->setCurrentItem((KateSessionChooserItem *)((QAction *)sender())->data().value()); - Q_ASSERT(static_cast(m_sessions->currentItem())); - done(resultCopy); -} - -void KateSessionChooser::slotDeleteSession() -{ - KateSessionChooserItem *item = (KateSessionChooserItem *)((QAction *)sender())->data().value(); - if (!item) { - return; - } - - KateApp::self()->sessionManager()->deleteSession(item->session); - m_sessions->removeItemWidget(item, 2); - delete item; - -} - -KateSession::Ptr KateSessionChooser::selectedSession() -{ - KateSessionChooserItem *item = static_cast(m_sessions->currentItem()); - - Q_ASSERT(item || ((result() != resultOpen) && (result() != resultCopy))); - - if (!item) { - return KateSession::Ptr(); - } - - return item->session; -} - -bool KateSessionChooser::reopenLastSession() -{ - return m_useLast->isChecked(); -} - -void KateSessionChooser::slotOpen() -{ - Q_ASSERT(static_cast(m_sessions->currentItem())); - done(resultOpen); -} - -void KateSessionChooser::slotNew() -{ - done(resultNew); -} - -void KateSessionChooser::slotCancel() -{ - done(resultQuit); -} - -void KateSessionChooser::selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *) -{ - Q_UNUSED(current); - m_openButton->setEnabled(true); -} - -//END CHOOSER DIALOG - diff --git a/kate/session/katesessionmanagedialog.h b/kate/session/katesessionmanagedialog.h --- a/kate/session/katesessionmanagedialog.h +++ b/kate/session/katesessionmanagedialog.h @@ -26,53 +26,192 @@ class QPushButton; class QTreeWidget; class QTreeWidgetItem; +class KateSessionChooserItem; + +#include "katesession.h" +#include "ui_katesessionmanagedialog.h" class KateSessionManageDialog : public QDialog + , public Ui::KateSessionManageDialogUi { Q_OBJECT public: + /** + * The normal ctor for manage mode + */ KateSessionManageDialog(QWidget *parent); + + /** + * The special ctor for chooser mode + * Set a differend window title, enables some extra widget and try to select + * the @p lastSession in the session list. + */ + KateSessionManageDialog(QWidget *parent, const QString &lastSession); ~KateSessionManageDialog() override; protected Q_SLOTS: /** - * close pressed + * Re-implemented to save in chooser mode users choice when needed and to + * exit the dialog with a return code of @c 0/1 fitting to the code of + * @p result to indicate that the user chose a session to open not. + * @see KateSessionManager::chooseSession() + * @param result has to be one of enum @c ResultCode */ - void slotClose(); + void done(int result) override; /** - * selection has changed + * To update the button states */ void selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); /** - * try to rename session + * Close the dialog and open the selected session */ - void rename(); + void openSession(); /** - * try to delete session + * Use the selected session as template for a new session */ - void del(); + void openSessionAsTemplate(); /** - * close dialog and open the selected session + * Open new anonymous session */ - void open() override; + void openNewSession(); + + /** + * Copy the selected session + */ + void copySession(); + + /** + * Try to rename the session hold by @c m_editByUser + * @see editDone(), editBegin(), m_editByUser + */ + void editApply(); + + /** + * Open the inline editor on the selected session, set @c m_editByUser to + * the selected session and connect @c QTreeWidget::itemChanged signal to + * @c editApply(). + * @see editDone(), editApply(), m_editByUser + */ + void editBegin(); + + /** + * Finish the edit process, reset intern settings. + * Calling this function without to call @c editApply() will abort edit. + */ + void editDone(); -private: /** - * update our list + * To close the dialog + */ + void closeDialog(); + + /** + * Slot for the delete button + * @see m_deleteList, deleteSessions() + */ + void updateDeleteList(); + + /** + * Update the list of sessions in @c m_sessionList and trigger some needed + * actions belong to the editing of session names. */ void updateSessionList(); + /** + * To enable/disable not useful buttons + */ + void dontAskToggled(); + + /** + * To change the sort order of the session list + */ + void changeSortOrder(); + + /** + * Slot for @c m_filterField + */ + void filterChanged(); + private: - QTreeWidget *m_sessions; - QPushButton *m_rename; - QPushButton *m_del; - QPushButton *m_openButton; + /** + * Result codes used to call @c done() + */ + enum ResultCode { + ResultQuit = QDialog::Rejected, + ResultOpen, + ResultNew, + }; + + /** + * Sort order of the session list + */ + enum SortOrder { + SortAlphabetical, + SortChronological, + }; + + /** + * Re-implemented to avoid crash when in edit state + */ + void closeEvent(QCloseEvent *event) override; + + /** + * Disables all buttons on the "normal" button stack page and the close button + */ + void disableButtons(); + + /** + * To handle the rename process + */ + bool eventFilter(QObject *object, QEvent *event) override; + + /** + * @return current selected item in @c m_sessionList or @c nullptr + */ + KateSessionChooserItem *currentSessionItem() const; + + /** + * @return current selected session in @c m_sessionList or empty @c KateSession::Ptr() + */ + KateSession::Ptr currentSelectedSession() const; + + /** + * Display @p item in a striking way to indicate that the session represent + * by @p item will be deleted + */ + void markItemAsToBeDeleted(QTreeWidgetItem *item); + + /** + * The item which is currently edited by the user or @c nullptr to indicate + * that nothing is on edit. + */ + KateSessionChooserItem *m_editByUser = nullptr; + + /** + * Used by @c updateSessionList() to choose a new current item + */ + QString m_prefferedSession; + + /** + * How the list of sessions has to be ordered + */ + int m_sortOrder = SortChronological; + + /** + * Used in dtor to do some savings or not + */ + bool m_chooserMode = false; + + /** + * Will filled with sessions to be deleted by @c updateDeleteList() and process + * by @c deleteSessions() + */ + QSet m_deleteList; }; #endif - diff --git a/kate/session/katesessionmanagedialog.cpp b/kate/session/katesessionmanagedialog.cpp --- a/kate/session/katesessionmanagedialog.cpp +++ b/kate/session/katesessionmanagedialog.cpp @@ -21,161 +21,502 @@ #include "katesessionmanagedialog.h" #include "kateapp.h" -#include "katesessionmanager.h" #include "katesessionchooseritem.h" +#include "katesessionmanager.h" +#include +#include #include #include +#include #include -#include -#include -#include #include -#include -#include -#include KateSessionManageDialog::KateSessionManageDialog(QWidget *parent) : QDialog(parent) { + setupUi(this); setWindowTitle(i18n("Manage Sessions")); + m_dontAskCheckBox->hide(); - QVBoxLayout *mainLayout = new QVBoxLayout(this); - setLayout(mainLayout); + m_sessionList->installEventFilter(this); + connect(m_sessionList, &QTreeWidget::currentItemChanged, this, &KateSessionManageDialog::selectionChanged); + connect(m_sessionList, &QTreeWidget::itemDoubleClicked, this, &KateSessionManageDialog::openSession); + m_sessionList->header()->moveSection(0, 1); // Re-order columns to "Files, Sessions" - QHBoxLayout *hb = new QHBoxLayout(); - mainLayout->addLayout(hb); + m_filterBox->installEventFilter(this); + connect(m_filterBox, &QLineEdit::textChanged, this, &KateSessionManageDialog::filterChanged); + connect(m_sortButton, &QPushButton::clicked, this, &KateSessionManageDialog::changeSortOrder); - m_sessions = new QTreeWidget(this); - m_sessions->setMinimumSize(400, 200); - hb->addWidget(m_sessions); - m_sessions->setColumnCount(2); - QStringList header; - header << i18n("Session Name"); - header << i18nc("The number of open documents", "Open Documents"); - m_sessions->setHeaderLabels(header); - m_sessions->setRootIsDecorated(false); - m_sessions->setItemsExpandable(false); - m_sessions->setAllColumnsShowFocus(true); - m_sessions->setSelectionBehavior(QAbstractItemView::SelectRows); - m_sessions->setSelectionMode(QAbstractItemView::SingleSelection); + //KGuiItem::assign(m_newButton, KStandardGuiItem::new()); // Missing + //KGuiItem::assign(m_newButton, KStandardGuiItem::open()); // Looks odd due to m_openButton + connect(m_newButton, &QPushButton::clicked, this, &KateSessionManageDialog::openNewSession); - connect(m_sessions, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectionChanged(QTreeWidgetItem*,QTreeWidgetItem*))); + KGuiItem::assign(m_openButton, KStandardGuiItem::open()); + m_openButton->setDefault(true); + connect(m_openButton, &QPushButton::clicked, this, &KateSessionManageDialog::openSession); - updateSessionList(); - m_sessions->resizeColumnToContents(0); + //KGuiItem::assign(m_templateButton, KStandardGuiItem::openTemplate()); // Missing + //KGuiItem::assign(m_templateButton, KStandardGuiItem::configure()); // Looks odd + connect(m_templateButton, &QPushButton::clicked, this, &KateSessionManageDialog::openSessionAsTemplate); - // right column buttons - QDialogButtonBox *rightButtons = new QDialogButtonBox(this); - rightButtons->setOrientation(Qt::Vertical); - hb->addWidget(rightButtons); + //KGuiItem::assign(m_copyButton, KStandardGuiItem::copy()); // Missing + //KGuiItem::assign(m_copyButton, KStandardGuiItem::configure()); // Looks odd + connect(m_copyButton, &QPushButton::clicked, this, &KateSessionManageDialog::copySession); - m_rename = new QPushButton(i18n("&Rename...")); - connect(m_rename, SIGNAL(clicked()), this, SLOT(rename())); - rightButtons->addButton(m_rename, QDialogButtonBox::ApplyRole); + //KGuiItem::assign(m_renameButton, KStandardGuiItem::rename()); // Missing + //KGuiItem::assign(m_renameButton, KStandardGuiItem::configure()); // Looks odd + connect(m_renameButton, &QPushButton::clicked, this, &KateSessionManageDialog::editBegin); - m_del = new QPushButton(); - KGuiItem::assign(m_del, KStandardGuiItem::del()); - connect(m_del, SIGNAL(clicked()), this, SLOT(del())); - rightButtons->addButton(m_del, QDialogButtonBox::ApplyRole); + connect(m_deleteButton, &QPushButton::clicked, this, &KateSessionManageDialog::updateDeleteList); - // dialog buttons - QDialogButtonBox *bottomButtons = new QDialogButtonBox(this); - mainLayout->addWidget(bottomButtons); + //KGuiItem::assign(m_closeButton, KStandardGuiItem::closeWindow()); // Which is better? + KGuiItem::assign(m_closeButton, KStandardGuiItem::close()); + connect(m_closeButton, &QPushButton::clicked, this, &KateSessionManageDialog::closeDialog); - QPushButton *closeButton = new QPushButton; - KGuiItem::assign(closeButton, KStandardGuiItem::close()); - closeButton->setDefault(true); - bottomButtons->addButton(closeButton, QDialogButtonBox::RejectRole); - connect(closeButton, SIGNAL(clicked()), this, SLOT(slotClose())); + connect(KateApp::self()->sessionManager(), &KateSessionManager::sessionListChanged, this, &KateSessionManageDialog::updateSessionList); + + changeSortOrder(); // Set order to SortAlphabetical, set button text and fill session list +} - m_openButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-open")), i18n("&Open")); - bottomButtons->addButton(m_openButton, QDialogButtonBox::AcceptRole); - connect(m_openButton, SIGNAL(clicked()), this, SLOT(open())); - // trigger action update - selectionChanged(nullptr, nullptr); +KateSessionManageDialog::KateSessionManageDialog(QWidget *parent, const QString &lastSession) + : KateSessionManageDialog(parent) +{ + setWindowTitle(i18n("Session Chooser")); + m_dontAskCheckBox->show(); + m_chooserMode = true; + connect(m_dontAskCheckBox, &QCheckBox::toggled, this, &KateSessionManageDialog::dontAskToggled); + + m_prefferedSession = lastSession; + changeSortOrder(); // Set order to SortChronological } + KateSessionManageDialog::~KateSessionManageDialog() {} -void KateSessionManageDialog::slotClose() + +void KateSessionManageDialog::dontAskToggled() { - done(0); + m_templateButton->setEnabled(!m_dontAskCheckBox->isChecked()); } -void KateSessionManageDialog::selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *) + +void KateSessionManageDialog::changeSortOrder() { - const bool validItem = (current != nullptr); + switch (m_sortOrder) { + case SortAlphabetical: + m_sortOrder = SortChronological; + m_sortButton->setText(i18n("Sort Alpabetical")); + //m_sortButton->setIcon(QIcon::fromTheme(QStringLiteral("FIXME"))); + break; + case SortChronological: + m_sortOrder = SortAlphabetical; + m_sortButton->setText(i18n("Sort Last Used")); + //m_sortButton->setIcon(QIcon::fromTheme(QStringLiteral("FIXME"))); + break; + } - m_rename->setEnabled(validItem); - m_del->setEnabled(validItem && (static_cast(current))->session != KateApp::self()->sessionManager()->activeSession()); - m_openButton->setEnabled(true); + updateSessionList(); } -void KateSessionManageDialog::rename() + +void KateSessionManageDialog::filterChanged() { - KateSessionChooserItem *item = static_cast(m_sessions->currentItem()); + static QPointer delay; - if (!item) { + if (!delay) { + delay = new QTimer(this); // Should be auto cleard by Qt when we die + delay->setSingleShot(true); + delay->setInterval(400); + connect(delay, &QTimer::timeout, this, &KateSessionManageDialog::updateSessionList); + } + + delay->start(); +} + + +void KateSessionManageDialog::done(int result) +{ + for (auto session : qAsConst(m_deleteList)) { + KateApp::self()->sessionManager()->deleteSession(session); + } + m_deleteList.clear(); // May not needed, but anyway + + if (ResultQuit == result) { + QDialog::done(0); return; } - bool ok = false; - QString name = QInputDialog::getText(QApplication::activeWindow(), // nasty trick:) - i18n("Specify New Name for Session"), i18n("Session name:"), - QLineEdit::Normal, item->session->name(), &ok); + if (m_chooserMode && m_dontAskCheckBox->isChecked()) { + // write back our nice boolean :) + KConfigGroup generalConfig(KSharedConfig::openConfig(), QStringLiteral("General")); + switch (result) { + case ResultOpen: + generalConfig.writeEntry("Startup Session", "last"); + break; + case ResultNew: + generalConfig.writeEntry("Startup Session", "new"); + break; + default: + break; + } + generalConfig.sync(); + } - if (!ok) { + QDialog::done(1); +} + + +void KateSessionManageDialog::selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + Q_UNUSED(previous); + + if (m_editByUser) { + editDone(); // Field was left unchanged, no need to apply return; } - if (name.isEmpty()) { - KMessageBox::sorry(this, i18n("To save a session, you must specify a name."), i18n("Missing Session Name")); + if (!current) { + m_openButton->setEnabled(false); + m_templateButton->setEnabled(false); + m_copyButton->setEnabled(false); + m_renameButton->setEnabled(false); + m_deleteButton->setEnabled(false); return; } - if (KateApp::self()->sessionManager()->renameSession(item->session, name)) { - updateSessionList(); + const KateSession::Ptr activeSession = KateApp::self()->sessionManager()->activeSession(); + const bool notActiveSession = !KateApp::self()->sessionManager()->sessionIsActive(currentSelectedSession()->name()); + + m_deleteButton->setEnabled(notActiveSession); + + if (m_deleteList.contains(currentSelectedSession())) { + //KGuiItem::assign(m_deleteButton, KStandardGuiItem::restore()); // Missing + m_deleteButton->setText(i18n("Restore")); // The kept trash icon looks not bad + m_openButton->setEnabled(false); + m_templateButton->setEnabled(false); + m_copyButton->setEnabled(true); // Looks a little strange but is OK + m_renameButton->setEnabled(false); + } else { + KGuiItem::assign(m_deleteButton, KStandardGuiItem::del()); + m_openButton->setEnabled(currentSelectedSession() != activeSession); + m_templateButton->setEnabled(true); + m_copyButton->setEnabled(true); + m_renameButton->setEnabled(true); } } -void KateSessionManageDialog::del() + +void KateSessionManageDialog::disableButtons() +{ + m_openButton->setEnabled(false); + m_newButton->setEnabled(false); + m_templateButton->setEnabled(false); + m_dontAskCheckBox->setEnabled(false); + m_copyButton->setEnabled(false); + m_renameButton->setEnabled(false); + m_deleteButton->setEnabled(false); + m_closeButton->setEnabled(false); + m_sortButton->setEnabled(false); + m_filterBox->setEnabled(false); +} + + +void KateSessionManageDialog::editBegin() { - KateSessionChooserItem *item = static_cast(m_sessions->currentItem()); + if (m_editByUser) { + qDebug() << "FATAL:editBegin: already in progress"; + return; + } + + KateSessionChooserItem *item = currentSessionItem(); if (!item) { return; } - KateApp::self()->sessionManager()->deleteSession(item->session); + disableButtons(); + + item->setFlags(item->flags() | Qt::ItemIsEditable); + m_sessionList->clearSelection(); + m_sessionList->editItem(item, 0); + + // Always apply changes user did, like Dolphin + connect(m_sessionList, &QTreeWidget::itemChanged, this, &KateSessionManageDialog::editApply); + connect(m_sessionList->itemWidget(item, 0), &QObject::destroyed, this, &KateSessionManageDialog::editApply); + + m_editByUser = item; // Do it last to block eventFilter() actions until we are ready +} + + +void KateSessionManageDialog::editDone() +{ + m_editByUser = nullptr; + disconnect(m_sessionList, &QTreeWidget::itemChanged, this, &KateSessionManageDialog::editApply); updateSessionList(); + + m_newButton->setEnabled(true); + m_dontAskCheckBox->setEnabled(true); + m_closeButton->setEnabled(true); + m_sortButton->setEnabled(true); + m_filterBox->setEnabled(true); + + m_sessionList->setFocus(); +} + + +void KateSessionManageDialog::editApply() +{ + if (!m_editByUser) { + return; + } + + KateApp::self()->sessionManager()->renameSession(m_editByUser->session, m_editByUser->text(0)); + editDone(); } -void KateSessionManageDialog::open() + +void KateSessionManageDialog::copySession() { - KateSessionChooserItem *item = static_cast(m_sessions->currentItem()); + KateSessionChooserItem *item = currentSessionItem(); + + if (!item) { + return; + } + + m_prefferedSession = KateApp::self()->sessionManager()->copySession(item->session); + m_sessionList->setFocus(); // Only needed when user abort +} + + +void KateSessionManageDialog::openSession() +{ + KateSessionChooserItem *item = currentSessionItem(); if (!item) { return; } hide(); KateApp::self()->sessionManager()->activateSession(item->session); - done(0); + done(ResultOpen); } + +void KateSessionManageDialog::openSessionAsTemplate() +{ + KateSessionChooserItem *item = currentSessionItem(); + + if (!item) { + return; + } + + hide(); + + KateSessionManager *sm = KateApp::self()->sessionManager(); + KateSession::Ptr ns = KateSession::createAnonymousFrom(item->session, sm->anonymousSessionFile()); + sm->activateSession(ns); + + done(ResultOpen); +} + + +void KateSessionManageDialog::openNewSession() +{ + hide(); + KateApp::self()->sessionManager()->sessionNew(); + done(ResultNew); +} + + +void KateSessionManageDialog::updateDeleteList() +{ + KateSessionChooserItem *item = currentSessionItem(); + + if (!item) { + return; + } + + const KateSession::Ptr session = item->session; + if (m_deleteList.contains(session)) { + m_deleteList.remove(session); + item->setForeground(0, QBrush(KColorScheme(QPalette::Active).foreground(KColorScheme::NormalText).color())); + item->setIcon(0, QIcon()); + item->setToolTip(0, QString()); + } else { + m_deleteList.insert(session); + markItemAsToBeDeleted(item); + } + + // To ease multiple deletions, move the selection + QTreeWidgetItem *newItem = m_sessionList->itemBelow(item) ? m_sessionList->itemBelow(item) : m_sessionList->topLevelItem(0); + m_sessionList->setCurrentItem(newItem); + m_sessionList->setFocus(); +} + + +void KateSessionManageDialog::markItemAsToBeDeleted(QTreeWidgetItem *item) +{ + item->setForeground(0, QBrush(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText).color())); + item->setIcon(0, QIcon::fromTheme(QStringLiteral("emblem-warning"))); + item->setToolTip(0, i18n("Session will be deleted on dialog close")); +} + + +void KateSessionManageDialog::closeDialog() +{ + done(ResultQuit); +} + + void KateSessionManageDialog::updateSessionList() { - m_sessions->clear(); + if (m_editByUser) { + // Don't crash accidentally an ongoing edit + return; + } + + KateSession::Ptr currSelSession = currentSelectedSession(); + KateSession::Ptr activeSession = KateApp::self()->sessionManager()->activeSession(); + + m_sessionList->clear(); KateSessionList slist = KateApp::self()->sessionManager()->sessionList(); - qSort(slist.begin(), slist.end(), KateSession::compareByName); + switch (m_sortOrder) { + case SortAlphabetical: std::sort (slist.begin(), slist.end(), KateSession::compareByName); break; + case SortChronological: std::sort (slist.begin(), slist.end(), KateSession::compareByTimeDesc); break; + } + + KateSessionChooserItem *prefferedItem = nullptr; + KateSessionChooserItem *currSessionItem = nullptr; + KateSessionChooserItem *activeSessionItem= nullptr; + + for (const KateSession::Ptr &session : qAsConst(slist)) { + if (!m_filterBox->text().isEmpty()) { + if (!session->name().contains(m_filterBox->text(), Qt::CaseInsensitive)) { + continue; + } + } + + KateSessionChooserItem *item = new KateSessionChooserItem(m_sessionList, session); + if (session == currSelSession) { + currSessionItem = item; + } else if (session == activeSession) { + activeSessionItem = item; + } else if (session->name() == m_prefferedSession) { + prefferedItem = item; + m_prefferedSession.clear(); + } + + if (m_deleteList.contains(session)) { + markItemAsToBeDeleted(item); + } + } + + m_sessionList->resizeColumnToContents(1); // Minimize "Files" column + + if (!prefferedItem) { + prefferedItem = currSessionItem ? currSessionItem : activeSessionItem; + } + + if (prefferedItem) { + m_sessionList->setCurrentItem(prefferedItem); + m_sessionList->scrollToItem(prefferedItem); + } else if (m_sessionList->topLevelItemCount() > 0) { + m_sessionList->setCurrentItem(m_sessionList->topLevelItem(0)); + } + + if (m_filterBox->hasFocus()){ + return; + } + + if (m_sessionList->topLevelItemCount() == 0) { + m_newButton->setFocus(); + } else { + m_sessionList->setFocus(); + } +} + + +KateSessionChooserItem *KateSessionManageDialog::currentSessionItem() const +{ + return static_cast(m_sessionList->currentItem()); +} + - foreach(const KateSession::Ptr & session, slist) { - new KateSessionChooserItem(m_sessions, session); +KateSession::Ptr KateSessionManageDialog::currentSelectedSession() const +{ + KateSessionChooserItem *item = currentSessionItem(); + + if (!item) { + return KateSession::Ptr(); } + + return item->session; } + +bool KateSessionManageDialog::eventFilter(QObject *object, QEvent *event) +{ + QKeyEvent *ke = static_cast(event); + + if (object == m_sessionList) { + if (!m_editByUser) { // No need for further action + return false; + } + + if (event->type() == QEvent::KeyPress) { + switch (ke->key()) { + // Avoid to apply changes with untypical keys/don't left edit field this way + case Qt::Key_Up : + case Qt::Key_Down : + case Qt::Key_PageUp : + case Qt::Key_PageDown : + return true; + default: + break; + } + + } else if (event->type() == QEvent::KeyRelease) { + switch (ke->key()) { + case Qt::Key_Escape : + editDone(); // Abort edit + break; + case Qt::Key_Return : + editApply(); + break; + default: + break; + } + } + +// if ( event->type() != QEvent::Paint +// && event->type() != QEvent::HoverMove ) { +// qDebug() << event; +// } + + } else if (object == m_filterBox) { + // Catch Return key to avoid to finish the dialog + if (event->type() == QEvent::KeyPress && (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)) { + updateSessionList(); + m_sessionList->setFocus(); + return true; + } + } + + return false; +} + + +void KateSessionManageDialog::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event); + + if (m_editByUser) { + // We must catch closeEvent here due to connected signal of QLineEdit::destroyed->editApply()->crash! + editDone(); // editApply() don't work, m_editByUser->text(0) will not updated from QLineEdit + } +} diff --git a/kate/session/katesessionmanagedialog.ui b/kate/session/katesessionmanagedialog.ui new file mode 100644 --- /dev/null +++ b/kate/session/katesessionmanagedialog.ui @@ -0,0 +1,240 @@ + + + KateSessionManageDialogUi + + + + 0 + 0 + 758 + 475 + + + + Form + + + + + + + + + + + 1 + 0 + + + + + + + Filter Sessions + + + true + + + + + + + + 0 + 0 + + + + Sort + + + + + + + + + false + + + false + + + true + + + + Session Name + + + + + Files + + + AlignLeading|AlignVCenter + + + + + + + + + + + + + + + + &Open + + + + .. + + + + + + + New Anonymous + + + + + + + Open as Template + + + + + + + Don't ask again + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Copy as ... + + + + + + + &Rename... + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Delete + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Close + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 220 + 10 + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + m_newButton + m_templateButton + m_dontAskCheckBox + m_copyButton + m_renameButton + m_deleteButton + m_closeButton + m_filterBox + m_sessionList + m_sortButton + m_openButton + + + + diff --git a/kate/session/katesessionmanager.h b/kate/session/katesessionmanager.h --- a/kate/session/katesessionmanager.h +++ b/kate/session/katesessionmanager.h @@ -32,6 +32,8 @@ { Q_OBJECT + friend class KateSessionManageDialog; + public: KateSessionManager(QObject *parent = nullptr, const QString &sessionsDir = QString()); ~KateSessionManager() override; @@ -95,11 +97,6 @@ */ void sessionNew(); - /** - * try to open a existing session - */ - void sessionOpen(); - /** * try to save current session */ @@ -121,6 +118,12 @@ */ void sessionChanged(); + /** + * Emitted whenever the session list has changed. + * @see sessionList() + */ + void sessionListChanged(); + /** * module internal APIs */ @@ -133,17 +136,31 @@ KateSession::Ptr giveSession(const QString &name); /** - * deletes session file and removes the session from sessions list + * Try to delete the @p session and removes the session from sessions list + * @param the session to delete + * @return true on success, false if @p session is currently in use + */ + bool deleteSession(KateSession::Ptr session); + + /** + * Try to copy the @p session to a new session @p newName. + * Will ask by @c askForNewSessionName() for a differend name when @p newName is already in use or is an + * empty string. + * @param newName is wished name of the new session + * @return the new session name on success, otherwise an empty string + * @see askForNewSessionName() */ - void deleteSession(KateSession::Ptr session); + QString copySession(KateSession::Ptr session, const QString &newName = QString()); /** - * renames the session to \p newName - * @param session pointer to the session - * @param newName new name of the session - * @return true if successful + * Try to rename the @p session to @p newName. + * Will ask by @c askForNewSessionName() for a differend name when @p newName is already in use or is an + * empty string. + * @param newName is wished new name of the session + * @return the new session name on success, otherwise an empty string + * @see askForNewSessionName() */ - bool renameSession(KateSession::Ptr session, const QString &newName); + QString renameSession(KateSession::Ptr session, const QString &newName = QString()); /** * activate a session @@ -164,15 +181,31 @@ private: /** - * Asks the user for a new session name. Used by save as for example. + * Ask the user for a new session name, when needed. + * @param session is the session to rename or copy + * @param newName is a preset value. Is @p newName not already in use is nothing asked + * @return a (currently) not used new session name or an empty string when + * user aborted or when @p newName is the current session name. + */ + QString askForNewSessionName(KateSession::Ptr session, const QString &newName = QString()); + + /** + * Try to generate a new session name from @p target by a number suffix. + * @param target is the base name + * @return a (currently) not used session name or an empty string */ - bool newSessionName(); + QString suggestNewSessionName(const QString &target); /** * returns session config file according to policy */ QString sessionFileForName(const QString &name) const; + /** + * @return true when @p session is active in any Kate instance, otherwise false + */ + bool sessionIsActive(const QString &session); + /** * returns session file for anonymous session */ diff --git a/kate/session/katesessionmanager.cpp b/kate/session/katesessionmanager.cpp --- a/kate/session/katesessionmanager.cpp +++ b/kate/session/katesessionmanager.cpp @@ -22,9 +22,7 @@ #include "katesessionmanager.h" -#include "katesessionchooser.h" #include "katesessionmanagedialog.h" -#include "katesessionopendialog.h" #include "kateapp.h" #include "katepluginmanager.h" @@ -70,8 +68,6 @@ connect(m_dirWatch, SIGNAL(dirty(QString)), this, SLOT(updateSessionList())); updateSessionList(); - - m_activeSession = KateSession::createAnonymous(anonymousSessionFile()); } KateSessionManager::~KateSessionManager() @@ -95,33 +91,34 @@ // write jump list actions to disk in the kate.desktop file updateJumpListActions(list); - // delete old items; - QMutableHashIterator i(m_sessions); + bool changed = false; - while (i.hasNext()) { - i.next(); - const int idx = list.indexOf(i.key()); - if (idx == -1) { // the key is invalid, remove it from m_session - if (i.value() != m_activeSession) { // if active, ignore missing config - i.remove(); - } - } else { // remove it from scan list - list.removeAt(idx); + // Add new sessions to our list + for (const QString session : qAsConst(list)) { + if (!m_sessions.contains(session)) { + const QString file = sessionFileForName(session); + m_sessions.insert(session, KateSession::create(file, session)); + changed = true; + } + } + // Remove gone sessions from our list + for (const QString session : m_sessions.keys()) { + if ((list.indexOf(session) < 0) && (m_sessions.value(session) != activeSession())) { + m_sessions.remove(session); + changed = true; } } - // load the new ones - foreach(const QString & newName, list) { - const QString file = sessionFileForName(newName); - m_sessions[newName] = KateSession::create(file, newName); + if (changed) { + emit sessionListChanged(); } } bool KateSessionManager::activateSession(KateSession::Ptr session, const bool closeAndSaveLast, const bool loadNew) { - if (m_activeSession == session) { + if (activeSession() == session) { return true; } @@ -249,34 +246,56 @@ KateSession::Ptr s = KateSession::create(sessionFileForName(name), name); saveSessionTo(s->config()); m_sessions[name] = s; + // Due to this add to m_sessions will updateSessionList() no signal emit, + // but it's importand to add. Otherwise could it be happen that m_activeSession + // is not part of m_sessions but a double + emit sessionListChanged(); + return s; } -void KateSessionManager::deleteSession(KateSession::Ptr session) +bool KateSessionManager::deleteSession(KateSession::Ptr session) { - QFile::remove(session->file()); - if (session != activeSession()) { - m_sessions.remove(session->name()); + if (sessionIsActive(session->name())) { + return false; } + + QFile::remove(session->file()); + m_sessions.remove(session->name()); + // Due to this remove from m_sessions will updateSessionList() no signal emit, + // but this way is there no delay between deletion and information + emit sessionListChanged(); + + return true; } -bool KateSessionManager::renameSession(KateSession::Ptr session, const QString &newName) +QString KateSessionManager::copySession(KateSession::Ptr session, const QString &newName) { - Q_ASSERT(!newName.isEmpty()); + const QString name = askForNewSessionName(session, newName); - if (session->name() == newName) { - return true; + if (name.isEmpty()) { + return name; } - const QString newFile = sessionFileForName(newName); + const QString newFile = sessionFileForName(name); - if (QFile::exists(newFile)) { - KMessageBox::sorry(QApplication::activeWindow(), - i18n("The session could not be renamed to \"%1\", there already exists another session with the same name", newName), - i18n("Session Renaming")); - return false; + KateSession::Ptr ns = KateSession::createFrom(session, newFile, name); + ns->config()->sync(); +// m_sessions.insert(name, ns); + + return name; +} + +QString KateSessionManager::renameSession(KateSession::Ptr session, const QString &newName) +{ + const QString name = askForNewSessionName(session, newName); + + if (name.isEmpty()) { + return name; } + const QString newFile = sessionFileForName(name); + session->config()->sync(); const QUrl srcUrl = QUrl::fromLocalFile(session->file()); @@ -287,18 +306,21 @@ KMessageBox::sorry(QApplication::activeWindow(), i18n("The session could not be renamed to \"%1\". Failed to write to \"%2\"", newName, newFile), i18n("Session Renaming")); - return false; + return QString(); } m_sessions[newName] = m_sessions.take(session->name()); session->setName(newName); session->setFile(newFile); + session->config()->sync(); + // updateSessionList() will this edit not notice, so force signal + emit sessionListChanged(); if (session == activeSession()) { emit sessionChanged(); } - return true; + return name; } void KateSessionManager::saveSessionTo(KConfig *sc) const @@ -346,11 +368,15 @@ bool KateSessionManager::saveActiveSession(bool rememberAsLast) { + if (!activeSession()) { + return false; + } + KConfig *sc = activeSession()->config(); saveSessionTo(sc); - if (rememberAsLast) { + if (rememberAsLast && !activeSession()->isAnonymous()) { KSharedConfigPtr c = KSharedConfig::openConfig(); c->group("General").writeEntry("Last Session", activeSession()->name()); c->sync(); @@ -378,126 +404,149 @@ return true; } - QScopedPointer chooser(new KateSessionChooser(nullptr, lastSession)); - const int res = chooser->exec(); - bool success = true; + return QScopedPointer(new KateSessionManageDialog(nullptr, lastSession))->exec(); +} - switch (res) { - case KateSessionChooser::resultOpen: { - KateSession::Ptr s = chooser->selectedSession(); // dialog guarantees this to be valid - success = activateSession(s, false); - break; - } +void KateSessionManager::sessionNew() +{ + activateSession(giveSession(QString())); +} - case KateSessionChooser::resultCopy: { - KateSession::Ptr s = chooser->selectedSession(); // dialog guarantees this to be valid - KateSession::Ptr ns = KateSession::createAnonymousFrom(s, anonymousSessionFile()); - activateSession(ns, false); - break; - } +void KateSessionManager::sessionSave() +{ + saveActiveSession(); // this is the optional point to handle saveSessionAs for anonymous session +} - // exit the app lateron - case KateSessionChooser::resultQuit: - return false; +void KateSessionManager::sessionSaveAs() +{ + const QString newName = askForNewSessionName(activeSession()); - case KateSessionChooser::resultNew: - default: - activateAnonymousSession(); - break; + if (newName.isEmpty()) { + return; } - // write back our nice boolean :) - if (success && chooser->reopenLastSession()) { - KConfigGroup generalConfig(KSharedConfig::openConfig(), QStringLiteral("General")); - - if (res == KateSessionChooser::resultOpen) { - generalConfig.writeEntry("Startup Session", "last"); - } else if (res == KateSessionChooser::resultNew) { - generalConfig.writeEntry("Startup Session", "new"); - } + activeSession()->config()->sync(); - generalConfig.sync(); - } + KateSession::Ptr ns = KateSession::createFrom(activeSession(), sessionFileForName(newName), newName); + m_activeSession = ns; + saveActiveSession(); - return success; + emit sessionChanged(); } -void KateSessionManager::sessionNew() +QString KateSessionManager::askForNewSessionName(KateSession::Ptr session, const QString &newName) { - activateSession(giveSession(QString())); -} + if (session->name() == newName && !session->isAnonymous()) { + return QString(); + } -void KateSessionManager::sessionOpen() -{ - QScopedPointer chooser(new KateSessionOpenDialog(nullptr)); + const QString messagePrompt = i18n("Session name:"); + const KLocalizedString messageExist = ki18n("There is already an existing session with your chosen name: %1\n" + "Please choose a different one."); + const QString messageEmpty = i18n("To save a session, you must specify a name."); - const int res = chooser->exec(); + QString messageTotal = messagePrompt; + QString name = newName; - if (res == KateSessionOpenDialog::resultCancel) { - return; - } + while (true) { + QString preset = name; + + if (name.isEmpty()) { + preset = suggestNewSessionName(session->name()); + messageTotal = messageEmpty + QStringLiteral("\n\n") + messagePrompt; + + } else if (QFile::exists(sessionFileForName(name))) { + preset = suggestNewSessionName(name); + if (preset.isEmpty()) { + // Very unlikely, but as fall back we keep users input + preset = name; + } + messageTotal = messageExist.subs(name).toString() + QStringLiteral("\n\n") + messagePrompt; + + } else { + return name; + } - KateSession::Ptr s = chooser->selectedSession(); + QInputDialog dlg(KateApp::self()->activeKateMainWindow()); + dlg.setInputMode(QInputDialog::TextInput); + if (session->isAnonymous()) { + dlg.setWindowTitle(i18n("Specify a name for this session")); + } else { + dlg.setWindowTitle(i18n("Specify a new name for session: %1", session->name())); + } + dlg.setLabelText(messageTotal); + dlg.setTextValue(preset); + dlg.resize(900,100); // FIXME Calc somehow a proper size + bool ok = dlg.exec(); + name = dlg.textValue(); - if (s) { - activateSession(s); + if (!ok) { + return QString(); + } } } -void KateSessionManager::sessionSave() +QString KateSessionManager::suggestNewSessionName(const QString &target) { - saveActiveSession(); // this is the optional point to handle saveSessionAs for anonymous session + if (target.isEmpty()) { + // Here could also a default name set or the current session name used + return QString(); + } + + const QString mask = QStringLiteral("%1 (%2)"); + QString name; + + for (int i = 2; i < 1000000; i++) { // Should be enough to get an unique name + name = mask.arg(target).arg(i); + + if (!QFile::exists(sessionFileForName(name))) { + return name; + } + } + + return QString(); } -void KateSessionManager::sessionSaveAs() +void KateSessionManager::sessionManage() { - if (newSessionName()) { - saveActiveSession(); - emit sessionChanged(); - } + // Q: Any benefit from using always heap/QScopedPointer? + QScopedPointer(new KateSessionManageDialog(KateApp::self()->activeKateMainWindow()))->exec(); } -bool KateSessionManager::newSessionName() + +bool KateSessionManager::sessionIsActive(const QString &session) { - bool alreadyExists = false; + // Try to avoid unneed action + if (activeSession() && activeSession()->name() == session) { + return true; + } - do { - bool ok = false; - const QString name = QInputDialog::getText(QApplication::activeWindow(), - i18n("Specify New Name for Current Session"), - alreadyExists ? i18n("There is already an existing session with your chosen name.\nPlease choose a different one\nSession name:") : i18n("Session name:"), - QLineEdit::Normal, activeSession()->name(), &ok); + QDBusConnectionInterface *i = QDBusConnection::sessionBus().interface(); + if (!i) { + return false; + } - if (!ok) { - return false; - } + // look up all running kate instances and there sessions + QDBusReply servicesReply = i->registeredServiceNames(); + QStringList services; + if (servicesReply.isValid()) { + services = servicesReply.value(); + } - if (name.isEmpty()) { - KMessageBox::sorry(nullptr, i18n("To save a session, you must specify a name."), i18n("Missing Session Name")); + for (const QString &s : qAsConst(services)) { + if (!s.startsWith(QStringLiteral("org.kde.kate-"))) { continue; } - const QString file = sessionFileForName(name); - if (QFile::exists(file)) { - alreadyExists = true; - continue; + KateRunningInstanceInfo rii(s); + if (rii.valid && rii.sessionName == session) { + return true; } + } - activeSession()->config()->sync(); - KateSession::Ptr ns = KateSession::createFrom(activeSession(), file, name); - m_activeSession = ns; - - emit sessionChanged(); - - alreadyExists = false; - } while (alreadyExists); - return true; + return false; } -void KateSessionManager::sessionManage() -{ - QScopedPointer(new KateSessionManageDialog(nullptr))->exec(); -} QString KateSessionManager::anonymousSessionFile() const { diff --git a/kate/session/katesessionopendialog.h b/kate/session/katesessionopendialog.h deleted file mode 100644 --- a/kate/session/katesessionopendialog.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of the KDE project - * - * Copyright (C) 2005 Christoph Cullmann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __KATE_SESSION_OPEN_DIALOG_H__ -#define __KATE_SESSION_OPEN_DIALOG_H__ - -#include - -class QPushButton; -class QTreeWidget; -class QTreeWidgetItem; - -#include "katesession.h" - -class KateSessionOpenDialog : public QDialog -{ - Q_OBJECT - -public: - KateSessionOpenDialog(QWidget *parent); - ~KateSessionOpenDialog() override; - - KateSession::Ptr selectedSession(); - - enum { - resultOk, - resultCancel - }; - -protected Q_SLOTS: - void slotCanceled(); - void slotOpen(); - - /** - * selection has changed - */ - void selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - -private: - QTreeWidget *m_sessions; - QPushButton *m_openButton; -}; - -#endif - diff --git a/kate/session/katesessionopendialog.cpp b/kate/session/katesessionopendialog.cpp deleted file mode 100644 --- a/kate/session/katesessionopendialog.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* This file is part of the KDE project - * - * Copyright (C) 2005 Christoph Cullmann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "katesessionopendialog.h" - -#include "kateapp.h" -#include "katesessionmanager.h" -#include "katesessionchooseritem.h" - -#include -#include - -#include -#include -#include -#include - -KateSessionOpenDialog::KateSessionOpenDialog(QWidget *parent) - : QDialog(parent) - -{ - setWindowTitle(i18n("Open Session")); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - setLayout(mainLayout); - - m_sessions = new QTreeWidget(this); - m_sessions->setMinimumSize(400, 200); - mainLayout->addWidget(m_sessions); - - QStringList header; - header << i18n("Session Name"); - header << i18nc("The number of open documents", "Open Documents"); - m_sessions->setHeaderLabels(header); - m_sessions->setRootIsDecorated(false); - m_sessions->setItemsExpandable(false); - m_sessions->setAllColumnsShowFocus(true); - m_sessions->setSelectionBehavior(QAbstractItemView::SelectRows); - m_sessions->setSelectionMode(QAbstractItemView::SingleSelection); - - KateSessionList slist = KateApp::self()->sessionManager()->sessionList(); - qSort(slist.begin(), slist.end(), KateSession::compareByName); - - foreach(const KateSession::Ptr & session, slist) { - new KateSessionChooserItem(m_sessions, session); - } - - m_sessions->resizeColumnToContents(0); - - connect(m_sessions, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectionChanged(QTreeWidgetItem*,QTreeWidgetItem*))); - connect(m_sessions, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotOpen())); - - // buttons - QDialogButtonBox *buttons = new QDialogButtonBox(this); - mainLayout->addWidget(buttons); - - QPushButton *cancelButton = new QPushButton; - KGuiItem::assign(cancelButton, KStandardGuiItem::cancel()); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(slotCanceled())); - buttons->addButton(cancelButton, QDialogButtonBox::RejectRole); - - m_openButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-open")), i18n("&Open")); - m_openButton->setDefault(true); - m_openButton->setEnabled(false); - connect(m_openButton, SIGNAL(clicked()), this, SLOT(slotOpen())); - buttons->addButton(m_openButton, QDialogButtonBox::AcceptRole); - - setResult(resultCancel); -} - -KateSessionOpenDialog::~KateSessionOpenDialog() -{} - -KateSession::Ptr KateSessionOpenDialog::selectedSession() -{ - KateSessionChooserItem *item = static_cast(m_sessions->currentItem()); - - if (!item) { - return KateSession::Ptr(); - } - - return item->session; -} - -void KateSessionOpenDialog::slotCanceled() -{ - done(resultCancel); -} - -void KateSessionOpenDialog::slotOpen() -{ - done(resultOk); -} - -void KateSessionOpenDialog::selectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *) -{ - Q_UNUSED(current); - m_openButton->setEnabled(true); -} -