File indexing completed on 2024-05-05 05:53:55

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 // Own
0008 #include "ProfileSettings.h"
0009 
0010 // Qt
0011 #include <QFileInfo>
0012 #include <QStandardPaths>
0013 
0014 // Konsole
0015 #include "delegates/ProfileShortcutDelegate.h"
0016 #include "profile/ProfileManager.h"
0017 #include "profile/ProfileModel.h"
0018 #include "session/Session.h"
0019 #include "session/SessionController.h"
0020 #include "session/SessionManager.h"
0021 #include "terminalDisplay/TerminalDisplay.h"
0022 #include "widgets/EditProfileDialog.h"
0023 
0024 using namespace Konsole;
0025 
0026 ProfileSettings::ProfileSettings(QWidget *parent)
0027     : QWidget(parent)
0028 {
0029     setupUi(this);
0030 
0031     profileListView->setModel(ProfileModel::instance());
0032     profileListView->setItemDelegateForColumn(ProfileModel::SHORTCUT, new ShortcutItemDelegate(this));
0033     profileListView->setSelectionMode(QAbstractItemView::SingleSelection);
0034     connect(ProfileModel::instance(), &QAbstractItemModel::modelReset, this, [this] {
0035         setAsDefaultButton->setEnabled(currentProfile() != nullptr);
0036     });
0037 
0038     // double clicking the profile name opens the profile edit dialog
0039     connect(profileListView, &QAbstractItemView::doubleClicked, this, &Konsole::ProfileSettings::doubleClicked);
0040 
0041     // populate the table with profiles
0042     populateTable();
0043 
0044     // setup buttons
0045     newProfileButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
0046     editProfileButton->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
0047     deleteProfileButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
0048     setAsDefaultButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")));
0049 
0050     connect(newProfileButton, &QPushButton::clicked, this, &Konsole::ProfileSettings::createProfile);
0051     connect(editProfileButton, &QPushButton::clicked, this, &Konsole::ProfileSettings::editSelected);
0052     connect(deleteProfileButton, &QPushButton::clicked, this, &Konsole::ProfileSettings::deleteSelected);
0053     connect(setAsDefaultButton, &QPushButton::clicked, this, &Konsole::ProfileSettings::setSelectedAsDefault);
0054 }
0055 
0056 ProfileSettings::~ProfileSettings() = default;
0057 
0058 void ProfileSettings::slotAccepted()
0059 {
0060     ProfileManager::instance()->saveSettings();
0061 }
0062 
0063 void ProfileSettings::doubleClicked(const QModelIndex &idx)
0064 {
0065     if (idx.column() == ProfileModel::NAME) {
0066         editSelected();
0067     }
0068 }
0069 
0070 void ProfileSettings::populateTable()
0071 {
0072     QStyleOptionViewItem opt;
0073     opt.features = QStyleOptionViewItem::HasCheckIndicator | QStyleOptionViewItem::HasDecoration;
0074     auto *listHeader = profileListView->header();
0075 
0076     profileListView->resizeColumnToContents(ProfileModel::NAME);
0077 
0078     listHeader->setSectionResizeMode(ProfileModel::NAME, QHeaderView::ResizeMode::Stretch);
0079     listHeader->setSectionResizeMode(ProfileModel::SHORTCUT, QHeaderView::ResizeMode::ResizeToContents);
0080     listHeader->setStretchLastSection(false);
0081     listHeader->setSectionsMovable(false);
0082 
0083     profileListView->hideColumn(ProfileModel::PROFILE);
0084 
0085     // listen for changes in the table selection and update the state of the form's buttons
0086     // accordingly.
0087     //
0088     // it appears that the selection model is changed when the model itself is replaced,
0089     // so the signals need to be reconnected each time the model is updated.
0090     connect(profileListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Konsole::ProfileSettings::tableSelectionChanged);
0091 }
0092 
0093 void ProfileSettings::tableSelectionChanged(const QItemSelection &selected)
0094 {
0095     newProfileButton->setEnabled(true);
0096 
0097     if (selected.isEmpty()) {
0098         editProfileButton->setEnabled(false);
0099         deleteProfileButton->setEnabled(false);
0100         setAsDefaultButton->setEnabled(false);
0101         return;
0102     }
0103 
0104     const auto profile = currentProfile();
0105     const bool isNotDefault = profile != ProfileManager::instance()->defaultProfile();
0106 
0107     editProfileButton->setEnabled(profile && profile->isEditable());
0108 
0109     // Do not allow the current default profile of the session to be removed
0110     deleteProfileButton->setEnabled(profile && isNotDefault && profile->isDeletable());
0111 
0112     setAsDefaultButton->setEnabled(isNotDefault);
0113 }
0114 
0115 void ProfileSettings::deleteSelected()
0116 {
0117     const auto profile = currentProfile();
0118 
0119     // The "Delete" button is disabled for the current default profile
0120     Q_ASSERT(profile != ProfileManager::instance()->defaultProfile());
0121 
0122     ProfileManager::instance()->deleteProfile(profile);
0123 }
0124 
0125 void ProfileSettings::setSelectedAsDefault()
0126 {
0127     if (!currentProfile()) {
0128         return;
0129     }
0130     ProfileManager::instance()->setDefaultProfile(currentProfile());
0131     // do not allow the new default session type to be removed
0132     deleteProfileButton->setEnabled(false);
0133     setAsDefaultButton->setEnabled(false);
0134 }
0135 
0136 void ProfileSettings::createProfile()
0137 {
0138     auto newProfile = Profile::Ptr(new Profile(ProfileManager::instance()->builtinProfile()));
0139 
0140     // If a profile is selected, clone its properties, otherwise the
0141     // the built-in profile's properties will be used
0142     if (currentProfile()) {
0143         newProfile->clone(currentProfile(), true);
0144     }
0145 
0146     const QString uniqueName = ProfileManager::instance()->generateUniqueName();
0147     newProfile->setProperty(Profile::Name, uniqueName);
0148     newProfile->setProperty(Profile::UntranslatedName, uniqueName);
0149 
0150     auto *dialog = new EditProfileDialog(this);
0151     dialog->setAttribute(Qt::WA_DeleteOnClose);
0152     dialog->setModal(true);
0153     dialog->setProfile(newProfile, EditProfileDialog::NewProfile);
0154     dialog->selectProfileName();
0155 
0156     dialog->show();
0157 }
0158 void ProfileSettings::editSelected()
0159 {
0160     const auto profile = currentProfile();
0161 
0162     // Uneditable profiles can only be cloned using the "New" button.
0163     if (!(profile && profile->isEditable())) {
0164         return;
0165     }
0166 
0167     auto *dialog = new EditProfileDialog(this);
0168     dialog->setAttribute(Qt::WA_DeleteOnClose);
0169     dialog->setModal(true);
0170     dialog->setProfile(profile);
0171     dialog->show();
0172 }
0173 
0174 Profile::Ptr ProfileSettings::currentProfile() const
0175 {
0176     QItemSelectionModel *selection = profileListView->selectionModel();
0177 
0178     if ((selection == nullptr) || !selection->hasSelection()) {
0179         return Profile::Ptr();
0180     }
0181 
0182     return selection->selectedIndexes().at(ProfileModel::PROFILE).data(ProfileModel::ProfilePtrRole).value<Profile::Ptr>();
0183 }
0184 
0185 #include "moc_ProfileSettings.cpp"