Configure Konsole dialog GUI redesign

Summary:
* Use custom dialog and configuraton classes, as counterparts from KF5
  are bugged. The KF5 versions should be fixed and used here.
  * Create new KConfigDialog-like class and use it to show existing
    configuration pages.
  * Create KConfigDialogManager-like class for managing QButtonGroups.

* Remove help button from configuration dialog. There is nothing about
  configuration dialog options in the help.

* Profile Settings:
  * Use QTreeView instead of QTableView - it highlights whole lines,
    aligns header names to the left, etc. Basically it looks like lists
    in file manager or e.g. plugin list in Kate.
  * Use (default) QStyledItemDelegate with checkbox instead of custom
    delegate (tick mark) in favorite/show column.
  * Change default profile item style - it now has italics font and
    "(default)" suffix.
  * Disable "Delete" button when default profile is selected
  * Use slightly extended QKeySequenceEditor. KKeySequenceWidget looks
    heavily out of place in a tree view. New editor supports some
    control keys:
    * Esc key cancels key capture.
    * Del/backspace removes shortcut.
    * Enter confirms shortcut immediately.
    * Tab/backtab commits currently edited shorcut and moves to
      next/previous shortcut.
  * Shortcuts for non visible profiles use disabled text color.
  * Note about visibility and shortcuts

* Rename "File Location" to "Temporary Files"
  * Enable path selector only when "custom" is selected
  * Place paths directly in labels

* Disable all tabbar settings except visibility when visibility is set
  to "Never"

* Minor string changes.

**Screenshots**

{F6893460}
{F6893461}
{F6893462}
{F6893463}

BUG: 404096
FIXED-IN: 19.08.0

Reviewers: #konsole, #vdg, ngraham

Reviewed By: #vdg, ngraham

Subscribers: ngraham, hindenburg, #vdg, konsole-devel, #konsole

Tags: #konsole, #vdg

Differential Revision: https://phabricator.kde.org/D20816
This commit is contained in:
Mariusz Glebocki
2019-06-15 12:50:13 -04:00
committed by Kurt Hindenburg
parent 023c529042
commit a8ec9ad28a
16 changed files with 1835 additions and 1004 deletions

View File

@@ -151,7 +151,7 @@ ki18n_wrap_ui(konsoleprivate_SRCS ColorSchemeEditor.ui
HistorySizeDialog.ui
HistorySizeWidget.ui
PrintOptions.ui
settings/FileLocationSettings.ui
settings/TemporaryFilesSettings.ui
settings/GeneralSettings.ui
settings/PartInfo.ui
settings/ProfileSettings.ui
@@ -175,7 +175,8 @@ set(konsole_KDEINIT_SRCS
Application.cpp
MainWindow.cpp
main.cpp
settings/FileLocationSettings.cpp
settings/ConfigurationDialog.cpp
settings/TemporaryFilesSettings.cpp
settings/GeneralSettings.cpp
settings/ProfileSettings.cpp
settings/TabBarSettings.cpp)

View File

@@ -305,7 +305,7 @@
</sizepolicy>
</property>
<property name="text">
<string comment="@info">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Settings → Configure Konsole → General → Use current window size on next startup&lt;/span&gt; must be disabled for these entries to work.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string comment="@info">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Settings → Configure Konsole → General → Remember window size&lt;/span&gt; must be disabled for these entries to work.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

View File

@@ -57,7 +57,8 @@
#include "KonsoleSettings.h"
#include "WindowSystemInfo.h"
#include "TerminalDisplay.h"
#include "settings/FileLocationSettings.h"
#include "settings/ConfigurationDialog.h"
#include "settings/TemporaryFilesSettings.h"
#include "settings/GeneralSettings.h"
#include "settings/ProfileSettings.h"
#include "settings/TabBarSettings.h"
@@ -723,39 +724,39 @@ void MainWindow::showManageProfilesDialog()
void MainWindow::showSettingsDialog(const bool showProfilePage)
{
if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
static ConfigurationDialog *confDialog = nullptr;
if (confDialog) {
confDialog->show();
return;
}
KConfigDialog *settingsDialog = new KConfigDialog(this, QStringLiteral("settings"), KonsoleSettings::self());
settingsDialog->setFaceType(KPageDialog::List);
confDialog = new ConfigurationDialog(this, KonsoleSettings::self());
auto generalSettings = new GeneralSettings(settingsDialog);
settingsDialog->addPage(generalSettings,
i18nc("@title Preferences page name", "General"),
QStringLiteral("utilities-terminal"));
const QString generalPageName = i18nc("@title Preferences page name", "General");
auto *generalPage = new KPageWidgetItem(new GeneralSettings(confDialog), generalPageName);
generalPage->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
confDialog->addPage(generalPage, true);
auto profileSettings = new ProfileSettings(settingsDialog);
KPageWidgetItem *profilePage = settingsDialog->addPage(profileSettings,
i18nc("@title Preferences page name",
"Profiles"),
QStringLiteral("configure"));
const QString profilePageName = i18nc("@title Preferences page name", "Profiles");
auto profilePage = new KPageWidgetItem(new ProfileSettings(confDialog), profilePageName);
profilePage->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
confDialog->addPage(profilePage, true);
auto tabBarSettings = new TabBarSettings(settingsDialog);
settingsDialog->addPage(tabBarSettings,
i18nc("@title Preferences page name", "TabBar"),
QStringLiteral("system-run"));
const QString tabBarPageName = i18nc("@title Preferences page name", "Tab Bar");
auto tabBarPage = new KPageWidgetItem(new TabBarSettings(confDialog), tabBarPageName);
tabBarPage->setIcon(QIcon::fromTheme(QStringLiteral("system-run")));
confDialog->addPage(tabBarPage, true);
auto fileLocationSettings = new FileLocationSettings(settingsDialog);
settingsDialog->addPage(fileLocationSettings,
i18nc("@title Preferences page name", "File Location"),
QStringLiteral("configure"));
const QString temporaryFilesPageName = i18nc("@title Preferences page name", "Temporary Files");
auto temporaryFilesPage = new KPageWidgetItem(new TemporaryFilesSettings(confDialog), temporaryFilesPageName);
temporaryFilesPage->setIcon(QIcon::fromTheme(QStringLiteral("inode-directory")));
confDialog->addPage(temporaryFilesPage, true);
if (showProfilePage) {
settingsDialog->setCurrentPage(profilePage);
confDialog->setCurrentPage(profilePage);
}
settingsDialog->show();
confDialog->show();
}
void MainWindow::applyKonsoleSettings()

View File

@@ -0,0 +1,165 @@
/*
Copyright 2019 by Mariusz Glebocki <mglb@arccos-1.net>
Based on KConfigDialog from KConfigWidgets
Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
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.
*/
// Own
#include "ConfigurationDialog.h"
// Qt
#include <QPushButton>
#include <QDialogButtonBox>
// KDE
#include <KLocalizedString>
#include <KConfigDialogManager>
#include <KCoreConfigSkeleton>
using namespace Konsole;
const QString ConfigDialogButtonGroupManager::ManagedNamePrefix = QStringLiteral("kcfg_");
ConfigurationDialog::ConfigurationDialog(QWidget *parent, KCoreConfigSkeleton *config)
: KPageDialog(parent)
{
setWindowTitle(i18nc("@title:window", "Configure"));
// Setting this after modifying buttonBox results in initial focus set to buttonBox.
setFaceType(KPageDialog::List);
buttonBox()->setStandardButtons(QDialogButtonBox::RestoreDefaults
| QDialogButtonBox::Ok
| QDialogButtonBox::Apply
| QDialogButtonBox::Cancel);
connect(buttonBox()->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
this, &ConfigurationDialog::updateButtons);
connect(buttonBox()->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
this, &ConfigurationDialog::updateButtons);
_manager = new KConfigDialogManager(this, config);
connect(_manager, SIGNAL(settingsChanged()), this, SLOT(settingsChangedSlot()));
connect(_manager, SIGNAL(widgetModified()), this, SLOT(updateButtons()));
connect(buttonBox()->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
_manager, &KConfigDialogManager::updateSettings);
connect(buttonBox()->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
_manager, &KConfigDialogManager::updateSettings);
connect(buttonBox()->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked,
_manager, &KConfigDialogManager::updateWidgets);
connect(buttonBox()->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
_manager, &KConfigDialogManager::updateWidgetsDefault);
_groupManager = new ConfigDialogButtonGroupManager(this, config);
connect(_groupManager, SIGNAL(settingsChanged()), this, SLOT(settingsChangedSlot()));
connect(_groupManager, SIGNAL(widgetModified()), this, SLOT(updateButtons()));
connect(buttonBox()->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
_groupManager, &ConfigDialogButtonGroupManager::updateSettings);
connect(buttonBox()->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
_groupManager, &ConfigDialogButtonGroupManager::updateSettings);
connect(buttonBox()->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked,
_groupManager, &ConfigDialogButtonGroupManager::updateWidgets);
connect(buttonBox()->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
_groupManager, &ConfigDialogButtonGroupManager::updateWidgetsDefault);
setApplyButtonEnabled(false);
}
void ConfigurationDialog::addPage(KPageWidgetItem *item, bool manage)
{
Q_ASSERT(item);
Q_ASSERT(item->widget());
KPageDialog::addPage(item);
if (manage) {
_manager->addWidget(item->widget());
_groupManager->addChildren(item->widget());
}
if (_shown && manage) {
QPushButton *defaultButton = buttonBox()->button(QDialogButtonBox::RestoreDefaults);
if (defaultButton) {
bool isDefault = defaultButton->isEnabled() && _manager->isDefault();
defaultButton->setEnabled(!isDefault);
}
}
}
void ConfigurationDialog::updateButtons()
{
static bool onlyOnce = false;
if (onlyOnce) {
return;
}
onlyOnce = true;
bool has_changed = _manager->hasChanged() || _groupManager->hasChanged();
setApplyButtonEnabled(has_changed);
bool is_default = _manager->isDefault() && _groupManager->isDefault();
setRestoreDefaultsButtonEnabled(!is_default);
emit widgetModified();
onlyOnce = false;
}
void ConfigurationDialog::settingsChangedSlot()
{
updateButtons();
emit settingsChanged();
}
void ConfigurationDialog::setApplyButtonEnabled(bool enabled)
{
QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
if (applyButton) {
applyButton->setEnabled(enabled);
}
}
void ConfigurationDialog::setRestoreDefaultsButtonEnabled(bool enabled)
{
QPushButton *restoreDefaultsButton = buttonBox()->button(QDialogButtonBox::RestoreDefaults);
if (restoreDefaultsButton) {
restoreDefaultsButton->setEnabled(enabled);
}
}
void Konsole::ConfigurationDialog::showEvent(QShowEvent *event)
{
if (!_shown) {
_manager->updateWidgets();
_groupManager->updateWidgets();
bool hasChanged = _manager->hasChanged() || _groupManager->hasChanged();
setApplyButtonEnabled(hasChanged);
bool isDefault = _manager->isDefault() || _groupManager->isDefault();
setRestoreDefaultsButtonEnabled(!isDefault);
_shown = true;
}
KPageDialog::showEvent(event);
}

View File

@@ -0,0 +1,289 @@
/*
Copyright 2019 by Mariusz Glebocki <mglb@arccos-1.net>
Based on KConfigDialog and KConfigDialogManager from KConfigWidgets
Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
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 CONFIGURATIONDIALOG_H
#define CONFIGURATIONDIALOG_H
// Qt
#include <QWidget>
#include <QButtonGroup>
#include <QAbstractButton>
#include <QTimer>
#include <QMap>
// KDE
#include <KPageDialog>
#include <KCoreConfigSkeleton>
#include <QDebug>
// Konsole
#include "konsoleprivate_export.h"
class KConfig;
class KCoreConfigSkeleton;
class KConfigDialogManager;
namespace Konsole {
class ConfigDialogButtonGroupManager;
// KConfigDialog-like class, as the original KConfigDialog wraps
// all pages in QScrollArea. KConfigDialog, when fixed, should
// be source compatible with this class, so simple class replace
// should suffice.
class KONSOLEPRIVATE_EXPORT ConfigurationDialog: public KPageDialog
{
Q_OBJECT
Q_SIGNALS:
void widgetModified();
void settingsChanged();
public:
explicit ConfigurationDialog(QWidget *parent, KCoreConfigSkeleton *config);
~ConfigurationDialog() override = default;
void addPage(KPageWidgetItem *item, bool manage);
protected Q_SLOTS:
void updateButtons();
void settingsChangedSlot();
protected:
void setApplyButtonEnabled(bool enabled);
void setRestoreDefaultsButtonEnabled(bool enabled);
void showEvent(QShowEvent *event) override;
private:
Q_DISABLE_COPY(ConfigurationDialog)
KConfigDialogManager *_manager = nullptr;
ConfigDialogButtonGroupManager *_groupManager = nullptr;
bool _shown = false;
};
// KConfigDialogManager-like class for managing QButtonGroups,
// which are not supported by KConfigDialogManager yet. When
// support will be available in minimum KF5 used by Konsole,
// just remove this class and all expressions which refer to it.
class ConfigDialogButtonGroupManager: public QObject
{
Q_OBJECT
public:
ConfigDialogButtonGroupManager(QObject *parent, KCoreConfigSkeleton *config)
: QObject(parent)
, _config(config)
{
Q_ASSERT(config);
connect(_config, &KCoreConfigSkeleton::configChanged,
this, &ConfigDialogButtonGroupManager::updateWidgets);
}
void addChildren(const QObject *parentObj)
{
for (const QObject *child: parentObj->children()) {
if (!child->objectName().startsWith(ManagedNamePrefix)) {
continue;
}
const char *className = child->metaObject()->className();
if (qstrcmp(className, "QButtonGroup") == 0) {
add(qobject_cast<const QButtonGroup *>(child));
}
}
}
void add(const QButtonGroup *obj)
{
Q_ASSERT(obj->exclusive());
connect(obj, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled),
this, &ConfigDialogButtonGroupManager::setButtonState, Qt::UniqueConnection);
_groups.append(obj);
}
bool hasChanged() const {
for(const QButtonGroup *group: qAsConst(_groups)) {
int value = buttonToEnumValue(group->checkedButton());
const auto enumItem = groupToConfigItemEnum(group);
if(!enumItem->isEqual(value)) {
return true;
}
}
return false;
}
bool isDefault() const {
bool useDefaults = _config->useDefaults(true);
bool result = !hasChanged();
_config->useDefaults(useDefaults);
return result;
}
Q_SIGNALS:
void settingsChanged();
void widgetModified();
public Q_SLOTS:
void updateWidgets()
{
bool prevSignalsBlocked = signalsBlocked();
bool changed = false;
blockSignals(true);
for(const QButtonGroup *group: qAsConst(_groups)) {
auto *enumItem = groupToConfigItemEnum(group);
if(!enumItem) {
continue;
}
int value = enumItem->value();
const QString &valueName = enumItem->choices().at(value).name;
QAbstractButton *currentButton = nullptr;
for(auto &button: group->buttons()) {
if(button->objectName() == valueName) {
currentButton = button;
break;
}
}
if(!currentButton) {
return;
}
currentButton->setChecked(true);
changed = true;
}
blockSignals(prevSignalsBlocked);
if(changed) {
QTimer::singleShot(0, this, &ConfigDialogButtonGroupManager::widgetModified);
}
}
void updateWidgetsDefault() {
bool useDefaults = _config->useDefaults(true);
updateWidgets();
_config->useDefaults(useDefaults);
}
void updateSettings() {
bool updateConfig = false;
for(const QButtonGroup *group: qAsConst(_groups)) {
auto *enumItem = groupToConfigItemEnum(group);
if(!enumItem) {
continue;
}
const auto *currentButton = group->checkedButton();
if(!currentButton) {
continue;
}
const int value = buttonToEnumValue(currentButton);
if(value < 0) {
continue;
}
if(!enumItem->isEqual(value)) {
enumItem->setValue(value);
updateConfig = true;
}
}
if(updateConfig) {
_config->save();
emit settingsChanged();
}
}
protected Q_SLOTS:
void setButtonState(QAbstractButton *button, bool checked)
{
Q_ASSERT(button);
Q_ASSERT(button->group());
if(!checked) {
// Both deselected and selected buttons trigger this slot, ignore the deselected one
return;
}
auto *enumItem = groupToConfigItemEnum(button->group());
if(!enumItem) {
return;
}
int value = buttonToEnumValue(button);
if(value < 0) {
return;
}
emit settingsChanged();
}
private:
// Returns configuration item associated with the group
KCoreConfigSkeleton::ItemEnum * groupToConfigItemEnum(const QButtonGroup *group) const {
Q_ASSERT(group);
const QString key = group->objectName().mid(ManagedNamePrefix.length());
auto *item = _config->findItem(key);
if(!item) {
return nullptr;
}
auto *enumItem = dynamic_cast<KCoreConfigSkeleton::ItemEnum *>(item);
if(!enumItem) {
return nullptr;
}
return enumItem;
}
// Returns a value the button represents in its group
int buttonToEnumValue(const QAbstractButton *button) const {
Q_ASSERT(button);
Q_ASSERT(button->group());
if(_buttonValues.contains(button)) {
return _buttonValues[button];
}
const auto *enumItem = groupToConfigItemEnum(button->group());
if(!enumItem) {
return -1;
}
const auto &choices = enumItem->choices();
const QString buttonName = button->objectName();
int value = -1;
for(int i = 0; i < choices.size(); ++i) {
if(buttonName == choices.at(i).name) {
value = i;
break;
}
}
_buttonValues[button] = value;
return value;
}
static const QString ManagedNamePrefix;
mutable QMap<const QAbstractButton *, int> _buttonValues;
KCoreConfigSkeleton *_config = nullptr;
QList<const QButtonGroup *> _groups;
};
}
#endif // CONFIGURATIONDIALOG_H

View File

@@ -1,41 +0,0 @@
/*
Copyright 2015 Kurt Hindenburg <kurt.hindenburg@gmail.com>
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) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor appro-
ved by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
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, see http://www.gnu.org/licenses/.
*/
// Own
#include "FileLocationSettings.h"
#include <QDir>
#include <QStandardPaths>
using namespace Konsole;
FileLocationSettings::FileLocationSettings(QWidget* aParent) : QWidget(aParent)
{
setupUi(this);
// TODO: worth adding gauge on free disk space?
useSystemLocationText->setText(QDir::tempPath());
useUsersHomeLocationText->setText(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
kcfg_scrollbackUseSpecifiedLocationDirectory->setMode(KFile::Directory);
}
FileLocationSettings::~FileLocationSettings() = default;

View File

@@ -1,252 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileLocationSettings</class>
<widget class="QWidget" name="FileLocationSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>494</width>
<height>354</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="ButtonGroup1">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Scrollback File Location&lt;/b&gt;&lt;p&gt;Use this groupbox to determine where Konsole will store the scrollback files.&lt;/p&gt;</string>
</property>
<property name="title">
<string>Scrollback File Location</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>These settings only apply when Profile-&gt;Scrolling-&gt;Unlimited scrollback is selected.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="kcfg_scrollbackUseSystemLocation">
<property name="text">
<string>Use system &amp;location</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="useSystemLocationText">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="kcfg_scrollbackUseCacheLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use user specific location</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="useUsersHomeLocationText">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="kcfg_scrollbackUseSpecifiedLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use specified loca&amp;tion</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="KUrlRequester" name="kcfg_scrollbackUseSpecifiedLocationDirectory">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="filter" stdset="0">
<string>text/css</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string>For the 'Use user specific location', any application using KonsolePart will have the app name instead of konsole.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string>For any changes to take effect, quit Konsole and restart.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>50</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>528</width>
<height>448</height>
<width>385</width>
<height>384</height>
</rect>
</property>
<property name="sizePolicy">
@@ -16,254 +16,291 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_1">
<property name="title">
<string>Konsole Window</string>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="11" column="1">
<widget class="QCheckBox" name="kcfg_SearchReverseSearch">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Sets whether search should start from the bottom</string>
</property>
<property name="text">
<string>Search backwards</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="kcfg_ShowMenuBarByDefault">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show menubar by default</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="kcfg_ShowTerminalSizeHint">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show hint for terminal size after resizing</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="kcfg_SaveGeometryOnExit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>If enabled, profile settings will be ignored</string>
</property>
<property name="text">
<string>Use current window size on next startup</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="kcfg_UseSingleInstance">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>When launching Konsole re-use existing process if possible</string>
</property>
<property name="text">
<string>Run all Konsole windows in a single process</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="kcfg_AllowMenuAccelerators">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable menu accelerators</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="kcfg_ShowWindowTitleOnTitleBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show window title on the titlebar</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="kcfg_RemoveWindowTitleBarAndFrame">
<property name="text">
<string>Remove window titlebar and frame</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="kcfg_AllowMenuAccelerators">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable menu accelerators</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="kcfg_SearchCaseSensitive">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Sets whether the search is case sensitive</string>
</property>
<property name="text">
<string>Case sensitive</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="kcfg_ShowMenuBarByDefault">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show menubar</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="kcfg_SaveGeometryOnExit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>If enabled, profile settings will be ignored</string>
</property>
<property name="text">
<string>Remember window size</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="kcfg_ShowWindowTitleOnTitleBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show window title on the titlebar</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="kcfg_UseSingleInstance">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>When launching Konsole re-use existing process if possible</string>
</property>
<property name="text">
<string>Run all Konsole windows in a single process</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="kcfg_RemoveWindowTitleBarAndFrame">
<property name="text">
<string>Remove window titlebar and frame</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="kcfg_SearchHighlightMatches">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Highlight all matches</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="kcfg_ShowTerminalSizeHint">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show hint for terminal size after resizing</string>
</property>
</widget>
</item>
<item row="13" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Notifications:</string>
</property>
</widget>
</item>
<item row="8" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="13" column="1">
<layout class="QHBoxLayout" stretch="0,1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="enableAllMessagesButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>All dialogs will be shown again</string>
</property>
<property name="text">
<string>Enable all &quot;Don't Ask Again&quot; messages</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="label">
<property name="text">
<string>Process and window:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="kcfg_SearchRegExpression">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Match using regular expressions</string>
</property>
</widget>
</item>
<item row="12" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Default Search Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="kcfg_SearchCaseSensitive">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Sets whether the search is case sensitive</string>
</property>
<property name="text">
<string>Search is case sensitive</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="kcfg_SearchRegExpression">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Match using regular expressions</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="kcfg_SearchHighlightMatches">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Highlight all search matches</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="kcfg_SearchReverseSearch">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Sets whether search should start from the bottom</string>
</property>
<property name="text">
<string>Search backwards</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Notifications</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>117</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="enableAllMessagesButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>All dialogs will be shown again</string>
</property>
<property name="text">
<string>Enable all &quot;Don't Ask Again&quot; messages</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>116</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>60</height>
<height>40</height>
</size>
</property>
</spacer>

View File

@@ -19,14 +19,15 @@
// Own
#include "ProfileSettings.h"
#include <QPainter>
// Qt
#include <QFileInfo>
#include <QStandardPaths>
#include <QStandardItem>
#include <QKeyEvent>
// KDE
#include <KKeySequenceWidget>
#include <KLocalizedString>
#include <KIconLoader>
#include <QPushButton>
@@ -47,16 +48,10 @@ ProfileSettings::ProfileSettings(QWidget* aParent)
{
setupUi(this);
// hide vertical header
sessionTable->verticalHeader()->hide();
sessionTable->setShowGrid(false);
sessionTable->setItemDelegateForColumn(FavoriteStatusColumn, new FavoriteItemDelegate(this));
sessionTable->setItemDelegateForColumn(ShortcutColumn, new ShortcutItemDelegate(this));
sessionTable->setEditTriggers(sessionTable->editTriggers() | QAbstractItemView::SelectedClicked);
profilesList->setItemDelegateForColumn(ShortcutColumn, new ShortcutItemDelegate(this));
// double clicking the profile name opens the profile edit dialog
connect(sessionTable, &QTableView::doubleClicked, this, &Konsole::ProfileSettings::doubleClicked);
connect(profilesList, &QAbstractItemView::doubleClicked, this, &Konsole::ProfileSettings::doubleClicked);
// populate the table with profiles
populateTable();
@@ -65,12 +60,7 @@ ProfileSettings::ProfileSettings(QWidget* aParent)
connect(ProfileManager::instance(), &Konsole::ProfileManager::profileAdded, this, &Konsole::ProfileSettings::addItems);
connect(ProfileManager::instance(), &Konsole::ProfileManager::profileRemoved, this, &Konsole::ProfileSettings::removeItems);
connect(ProfileManager::instance(), &Konsole::ProfileManager::profileChanged, this, &Konsole::ProfileSettings::updateItems);
connect(ProfileManager::instance() , &Konsole::ProfileManager::favoriteStatusChanged, this, &Konsole::ProfileSettings::updateFavoriteStatus);
// resize the session table to the full width of the table
sessionTable->horizontalHeader()->setHighlightSections(false);
sessionTable->horizontalHeader()->setStretchLastSection(true);
sessionTable->resizeColumnsToContents();
connect(ProfileManager::instance(), &Konsole::ProfileManager::favoriteStatusChanged, this, &Konsole::ProfileSettings::updateFavoriteStatus);
// setup buttons
connect(newProfileButton, &QPushButton::clicked, this, &Konsole::ProfileSettings::createProfile);
@@ -91,8 +81,26 @@ void ProfileSettings::itemDataChanged(QStandardItem* item)
{
if (item->column() == ShortcutColumn) {
QKeySequence sequence = QKeySequence::fromString(item->text());
ProfileManager::instance()->setShortcut(item->data(ShortcutRole).value<Profile::Ptr>(),
QStandardItem *idItem = item->model()->item(item->row(), ProfileColumn);
ProfileManager::instance()->setShortcut(idItem->data(ProfilePtrRole).value<Profile::Ptr>(),
sequence);
} else if (item->column() == FavoriteStatusColumn) {
QStandardItem *idItem = item->model()->item(item->row(), ProfileColumn);
const bool isFavorite = item->checkState() == Qt::Checked;
ProfileManager::instance()->setFavorite(idItem->data(ProfilePtrRole).value<Profile::Ptr>(),
isFavorite);
updateShortcutField(item->model()->item(item->row(), ShortcutColumn), isFavorite);
}
}
void ProfileSettings::updateShortcutField(QStandardItem *item, bool isFavorite) const
{
if(isFavorite) {
item->setToolTip(i18nc("@info:tooltip", "Double click to change shortcut"));
item->setForeground(palette().color(QPalette::Normal, QPalette::Text));
} else {
item->setToolTip(i18nc("@info:tooltip", "Shortcut won't work while the profile is not marked as visible."));
item->setForeground(palette().color(QPalette::Disabled, QPalette::Text));
}
}
@@ -100,7 +108,7 @@ int ProfileSettings::rowForProfile(const Profile::Ptr &profile) const
{
const int rowCount = _sessionModel->rowCount();
for (int i = 0; i < rowCount; i++) {
if (_sessionModel->item(i, ProfileNameColumn)->data(ProfileKeyRole)
if (_sessionModel->item(i, ProfileColumn)->data(ProfilePtrRole)
.value<Profile::Ptr>() == profile) {
return i;
}
@@ -124,36 +132,39 @@ void ProfileSettings::updateItems(const Profile::Ptr &profile)
}
const auto items = QList<QStandardItem*> {
_sessionModel->item(row, ProfileNameColumn),
_sessionModel->item(row, FavoriteStatusColumn),
_sessionModel->item(row, ShortcutColumn)
_sessionModel->item(row, ProfileNameColumn),
_sessionModel->item(row, ShortcutColumn),
_sessionModel->item(row, ProfileColumn),
};
updateItemsForProfile(profile, items);
}
void ProfileSettings::updateItemsForProfile(const Profile::Ptr &profile, const QList<QStandardItem*>& items) const
{
// "Enabled" checkbox
const auto isEnabled = ProfileManager::instance()->findFavorites().contains(profile);
items[FavoriteStatusColumn]->setCheckState(isEnabled ? Qt::Checked : Qt::Unchecked);
items[FavoriteStatusColumn]->setCheckable(true);
items[FavoriteStatusColumn]->setToolTip(
i18nc("@info:tooltip List item's checkbox for making item (profile) visible in a menu",
"Show profile in menu"));
// Profile Name
items[ProfileNameColumn]->setText(profile->name());
if (!profile->icon().isEmpty()) {
items[ProfileNameColumn]->setIcon(QIcon::fromTheme(profile->icon()));
}
items[ProfileNameColumn]->setData(QVariant::fromValue(profile), ProfileKeyRole);
// only allow renaming the profile from the edit profile dialog
// so as to use ProfileManager::checkProfileName()
items[ProfileNameColumn]->setEditable(false);
// Favorite Status
const auto isFavorite = ProfileManager::instance()->findFavorites().contains(profile);
const auto icon = isFavorite ? QIcon::fromTheme(QStringLiteral("dialog-ok-apply")) : QIcon();
items[FavoriteStatusColumn]->setData(icon, Qt::DecorationRole);
items[FavoriteStatusColumn]->setData(QVariant::fromValue(profile), ProfileKeyRole);
items[FavoriteStatusColumn]->setToolTip(i18nc("@info:tooltip", "Click to toggle status"));
// Shortcut
const auto shortcut = ProfileManager::instance()->shortcut(profile).toString();
items[ShortcutColumn]->setText(shortcut);
items[ShortcutColumn]->setData(QVariant::fromValue(profile), ShortcutRole);
items[ShortcutColumn]->setToolTip(i18nc("@info:tooltip", "Double click to change shortcut"));
updateShortcutField(items[ShortcutColumn], isEnabled);
// Profile ID (pointer to profile) - intended to be hidden in a view
items[ProfileColumn]->setData(QVariant::fromValue(profile), ProfilePtrRole);
}
void ProfileSettings::doubleClicked(const QModelIndex &index)
@@ -174,7 +185,8 @@ void ProfileSettings::addItems(const Profile::Ptr &profile)
const auto items = QList<QStandardItem*> {
new QStandardItem(),
new QStandardItem(),
new QStandardItem()
new QStandardItem(),
new QStandardItem(),
};
updateItemsForProfile(profile, items);
@@ -182,15 +194,55 @@ void ProfileSettings::addItems(const Profile::Ptr &profile)
}
void ProfileSettings::populateTable()
{
Q_ASSERT(!sessionTable->model());
Q_ASSERT(!profilesList->model());
sessionTable->setModel(_sessionModel);
profilesList->setModel(_sessionModel);
_sessionModel->clear();
// setup session table
_sessionModel->setHorizontalHeaderLabels({i18nc("@title:column Profile label", "Name"),
i18nc("@title:column Display profile in file menu", "Show"),
i18nc("@title:column Profile shortcut text", "Shortcut")});
_sessionModel->setHorizontalHeaderLabels({
QString(), // set using header item below
i18nc("@title:column Profile name", "Name"),
i18nc("@title:column Profile keyboard shortcut", "Shortcut"),
QString(),
});
auto *favoriteColumnHeaderItem = new QStandardItem();
favoriteColumnHeaderItem->setIcon(QIcon::fromTheme(QStringLiteral("visibility")));
favoriteColumnHeaderItem->setToolTip(
i18nc("@info:tooltip List item's checkbox for making item (profile) visible in a menu",
"Show profile in menu"));
_sessionModel->setHorizontalHeaderItem(FavoriteStatusColumn, favoriteColumnHeaderItem);
// Calculate favorite column width. resizeColumnToContents()
// is not used because it takes distance between checkbox and
// text into account, but there is no text and it looks weird.
const int headerMargin = style()->pixelMetric(QStyle::PM_HeaderMargin, nullptr,
profilesList->header());
const int iconWidth = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr,
profilesList->header());
const int favoriteHeaderWidth = headerMargin * 2 + iconWidth;
QStyleOptionViewItem opt;
opt.features = QStyleOptionViewItem::HasCheckIndicator | QStyleOptionViewItem::HasDecoration;
const QRect checkBoxRect = style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
&opt, profilesList);
// When right edge is at x < 0 it is assumed the checkbox is
// placed on the right item's side and the margin between right
// checkbox edge and right item edge should be used.
const int checkBoxMargin = checkBoxRect.right() >= 0 ? checkBoxRect.x()
: 0 - checkBoxRect.right();
const int favoriteItemWidth = checkBoxMargin * 2 + checkBoxRect.width();
auto *listHeader = profilesList->header();
profilesList->setColumnWidth(FavoriteStatusColumn,
qMax(favoriteHeaderWidth, favoriteItemWidth));
profilesList->resizeColumnToContents(ProfileNameColumn);
listHeader->setSectionResizeMode(FavoriteStatusColumn, QHeaderView::ResizeMode::Fixed);
listHeader->setSectionResizeMode(ProfileNameColumn, QHeaderView::ResizeMode::Stretch);
listHeader->setSectionResizeMode(ShortcutColumn, QHeaderView::ResizeMode::ResizeToContents);
listHeader->setStretchLastSection(false);
listHeader->setSectionsMovable(false);
profilesList->hideColumn(ProfileColumn);
QList<Profile::Ptr> profiles = ProfileManager::instance()->allProfiles();
ProfileManager::instance()->sortProfiles(profiles);
@@ -207,51 +259,53 @@ void ProfileSettings::populateTable()
//
// it appears that the selection model is changed when the model itself is replaced,
// so the signals need to be reconnected each time the model is updated.
connect(sessionTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Konsole::ProfileSettings::tableSelectionChanged);
sessionTable->selectRow(0);
connect(profilesList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Konsole::ProfileSettings::tableSelectionChanged);
}
void ProfileSettings::updateDefaultItem()
{
Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile();
const QString defaultItemSuffix = i18nc("Default list item's name suffix (with separator)", " (default)");
const int rowCount = _sessionModel->rowCount();
for (int i = 0; i < rowCount; i++) {
QStandardItem* item = _sessionModel->item(i);
QStandardItem* item = _sessionModel->item(i, ProfileNameColumn);
QFont itemFont = item->font();
QStandardItem* profileIdItem = _sessionModel->item(i, ProfileColumn);
auto profile = profileIdItem->data().value<Profile::Ptr>();
const bool isDefault = (defaultProfile == profile);
const QString cleanItemName = profile != nullptr ? profile->name() : QString();
bool isDefault = (defaultProfile == item->data().value<Profile::Ptr>());
if (isDefault && !itemFont.bold()) {
QIcon icon(KIconLoader::global()->loadIcon(defaultProfile->icon(), KIconLoader::Small, 0, KIconLoader::DefaultState, QStringList(QStringLiteral("emblem-favorite"))));
item->setIcon(icon);
itemFont.setBold(true);
if (isDefault) {
itemFont.setItalic(true);
item->setFont(itemFont);
} else if (!isDefault && itemFont.bold()) {
QModelIndex index = _sessionModel->index(i, ProfileNameColumn);
Profile::Ptr profile = index.data(ProfileSettings::ProfileKeyRole).value<Profile::Ptr>();
if (profile != nullptr) {
item->setIcon(QIcon::fromTheme(profile->icon()));
}
itemFont.setBold(false);
item->setText(cleanItemName + defaultItemSuffix);
} else if (!isDefault) {
// FIXME: use default font
itemFont.setItalic(false);
item->setFont(itemFont);
item->setText(cleanItemName);
}
}
}
void ProfileSettings::tableSelectionChanged(const QItemSelection&)
{
const int selectedRows = sessionTable->selectionModel()->selectedRows().count();
const ProfileManager* manager = ProfileManager::instance();
const bool isNotDefault = (selectedRows > 0) && currentProfile() != manager->defaultProfile();
const bool isDeletable = (selectedRows > 1) ||
(selectedRows == 1 && isProfileDeletable(currentProfile()));
bool isNotDefault = true;
bool isDeletable = true;
newProfileButton->setEnabled(selectedRows < 2);
const auto profiles = selectedProfiles();
for (const auto &profile: profiles) {
isNotDefault = isNotDefault && (profile != manager->defaultProfile());
isDeletable = isDeletable && isProfileDeletable(profile);
}
newProfileButton->setEnabled(profiles.count() < 2);
// FIXME: At some point editing 2+ profiles no longer works
editProfileButton->setEnabled(selectedRows == 1);
editProfileButton->setEnabled(profiles.count() == 1);
// do not allow the default session type to be removed
deleteProfileButton->setEnabled(isDeletable && isNotDefault);
setAsDefaultButton->setEnabled(isNotDefault && (selectedRows < 2));
deleteProfileButton->setEnabled(isDeletable && isNotDefault && (profiles.count() > 0));
setAsDefaultButton->setEnabled(isNotDefault && (profiles.count() == 1));
}
void ProfileSettings::deleteSelected()
{
@@ -272,26 +326,6 @@ void ProfileSettings::setSelectedAsDefault()
updateDefaultItem();
}
void ProfileSettings::moveUpSelected()
{
Q_ASSERT(_sessionModel);
const int rowIndex = sessionTable->currentIndex().row();
const QList<QStandardItem*>items = _sessionModel->takeRow(rowIndex);
_sessionModel->insertRow(rowIndex - 1, items);
sessionTable->selectRow(rowIndex - 1);
}
void ProfileSettings::moveDownSelected()
{
Q_ASSERT(_sessionModel);
const int rowIndex = sessionTable->currentIndex().row();
const QList<QStandardItem*>items = _sessionModel->takeRow(rowIndex);
_sessionModel->insertRow(rowIndex + 1, items);
sessionTable->selectRow(rowIndex + 1);
}
void ProfileSettings::createProfile()
{
// setup a temporary profile which is a clone of the selected profile
@@ -302,6 +336,7 @@ void ProfileSettings::createProfile()
auto newProfile = Profile::Ptr(new Profile(ProfileManager::instance()->fallbackProfile()));
newProfile->clone(sourceProfile, true);
// TODO: add number suffix when the name is taken
newProfile->setProperty(Profile::Name, i18nc("@item This will be used as part of the file name", "New Profile"));
newProfile->setProperty(Profile::UntranslatedName, QStringLiteral("New Profile"));
newProfile->setProperty(Profile::MenuIndex, QStringLiteral("0"));
@@ -351,14 +386,14 @@ void ProfileSettings::editSelected()
QList<Profile::Ptr> ProfileSettings::selectedProfiles() const
{
QList<Profile::Ptr> list;
QItemSelectionModel* selection = sessionTable->selectionModel();
QItemSelectionModel* selection = profilesList->selectionModel();
if (selection == nullptr) {
return list;
}
foreach(const QModelIndex & index, selection->selectedIndexes()) {
if (index.column() == ProfileNameColumn) {
list << index.data(ProfileKeyRole).value<Profile::Ptr>();
if (index.column() == ProfileColumn) {
list << index.data(ProfilePtrRole).value<Profile::Ptr>();
}
}
@@ -366,14 +401,14 @@ QList<Profile::Ptr> ProfileSettings::selectedProfiles() const
}
Profile::Ptr ProfileSettings::currentProfile() const
{
QItemSelectionModel* selection = sessionTable->selectionModel();
QItemSelectionModel* selection = profilesList->selectionModel();
if ((selection == nullptr) || selection->selectedRows().count() != 1) {
return Profile::Ptr();
}
return selection->
selectedIndexes().first().data(ProfileKeyRole).value<Profile::Ptr>();
return selection->
selectedIndexes().at(ProfileColumn).data(ProfilePtrRole).value<Profile::Ptr>();
}
bool ProfileSettings::isProfileDeletable(Profile::Ptr profile) const
{
@@ -395,19 +430,17 @@ void ProfileSettings::updateFavoriteStatus(const Profile::Ptr &profile, bool fav
const int rowCount = _sessionModel->rowCount();
for (int i = 0; i < rowCount; i++) {
QModelIndex index = _sessionModel->index(i, FavoriteStatusColumn);
if (index.data(ProfileKeyRole).value<Profile::Ptr>() == profile) {
// FIXME: On desktops without this icon, it is impossible to
// determine if a profile is a favorite in this dialog.
// Consider changing to using QStandardItem::setCheckable
const QIcon icon = favorite ? QIcon::fromTheme(QStringLiteral("dialog-ok-apply")) : QIcon();
_sessionModel->setData(index, icon, Qt::DecorationRole);
auto *item = _sessionModel->item(i, ProfileColumn);
if (item->data(ProfilePtrRole).value<Profile::Ptr>() == profile) {
auto *favoriteItem = _sessionModel->item(i, FavoriteStatusColumn);
favoriteItem->setCheckState(favorite ? Qt::Checked : Qt::Unchecked);
break;
}
}
}
void ProfileSettings::setShortcutEditorVisible(bool visible)
{
sessionTable->setColumnHidden(ShortcutColumn, !visible);
profilesList->setColumnHidden(ShortcutColumn, !visible);
}
void StyledBackgroundPainter::drawBackground(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex&)
@@ -420,55 +453,15 @@ void StyledBackgroundPainter::drawBackground(QPainter* painter, const QStyleOpti
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
}
// This adds a checkmark and the appropriate background in the "Show"
// column of the Manage Profiles->Profiles page.
FavoriteItemDelegate::FavoriteItemDelegate(QObject* aParent)
: QStyledItemDelegate(aParent)
{
}
void FavoriteItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
// See implementation of QStyledItemDelegate::paint()
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
StyledBackgroundPainter::drawBackground(painter, opt, index);
int margin = (opt.rect.height() - opt.decorationSize.height()) / 2;
margin++;
opt.rect.setTop(opt.rect.top() + margin);
opt.rect.setBottom(opt.rect.bottom() - margin);
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
icon.paint(painter, opt.rect, Qt::AlignCenter);
}
bool FavoriteItemDelegate::editorEvent(QEvent* aEvent, QAbstractItemModel*,
const QStyleOptionViewItem&, const QModelIndex& index)
{
if (aEvent->type() == QEvent::MouseButtonPress ||
aEvent->type() == QEvent::KeyPress ||
aEvent->type() == QEvent::MouseButtonDblClick) {
Profile::Ptr profile = index.data(ProfileSettings::ProfileKeyRole).value<Profile::Ptr>();
const bool isFavorite = ProfileManager::instance()->findFavorites().contains(profile);
ProfileManager::instance()->setFavorite(profile, !isFavorite);
}
return true;
}
ShortcutItemDelegate::ShortcutItemDelegate(QObject* aParent)
: QStyledItemDelegate(aParent),
_modifiedEditors(QSet<QWidget *>()),
_itemsBeingEdited(QSet<QModelIndex>())
{
}
void ShortcutItemDelegate::editorModified(const QKeySequence& keys)
void ShortcutItemDelegate::editorModified()
{
Q_UNUSED(keys);
auto* editor = qobject_cast<KKeySequenceWidget*>(sender());
auto* editor = qobject_cast<FilteredKeySequenceEdit*>(sender());
Q_ASSERT(editor);
_modifiedEditors.insert(editor);
emit commitData(editor);
@@ -483,7 +476,7 @@ void ShortcutItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* mod
return;
}
QString shortcut = qobject_cast<KKeySequenceWidget*>(editor)->keySequence().toString();
QString shortcut = qobject_cast<FilteredKeySequenceEdit *>(editor)->keySequence().toString();
model->setData(index, shortcut, Qt::DisplayRole);
_modifiedEditors.remove(editor);
@@ -493,13 +486,11 @@ QWidget* ShortcutItemDelegate::createEditor(QWidget* aParent, const QStyleOption
{
_itemsBeingEdited.insert(index);
auto editor = new KKeySequenceWidget(aParent);
editor->setFocusPolicy(Qt::StrongFocus);
editor->setModifierlessAllowed(false);
auto editor = new FilteredKeySequenceEdit(aParent);
QString shortcutString = index.data(Qt::DisplayRole).toString();
editor->setKeySequence(QKeySequence::fromString(shortcutString));
connect(editor, &KKeySequenceWidget::keySequenceChanged, this, &Konsole::ShortcutItemDelegate::editorModified);
editor->captureKeySequence();
connect(editor, &QKeySequenceEdit::editingFinished, this, &Konsole::ShortcutItemDelegate::editorModified);
editor->setFocus(Qt::FocusReason::MouseFocusReason);
return editor;
}
void ShortcutItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
@@ -512,3 +503,43 @@ void ShortcutItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem&
}
}
QSize Konsole::ShortcutItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const QString shortcutString = index.data(Qt::DisplayRole).toString();
QFontMetrics fm = option.fontMetrics;
static const int editorMargins = 16; // chosen empirically
const int width = fm.horizontalAdvance(shortcutString + QStringLiteral(", ..."))
+ editorMargins;
return QSize(width, QStyledItemDelegate::sizeHint(option, index).height());
}
void Konsole::ShortcutItemDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const
{
_itemsBeingEdited.remove(index);
_modifiedEditors.remove(editor);
editor->deleteLater();
}
void Konsole::FilteredKeySequenceEdit::keyPressEvent(QKeyEvent *event)
{
if(event->modifiers() == Qt::NoModifier) {
switch(event->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
emit editingFinished();
return;
case Qt::Key_Backspace:
case Qt::Key_Delete:
clear();
emit editingFinished();
event->accept();
return;
default:
event->accept();
return;
}
}
QKeySequenceEdit::keyPressEvent(event);
}

View File

@@ -23,6 +23,7 @@
// Qt
#include <QStyledItemDelegate>
#include <QSet>
#include <QKeySequenceEdit>
// KDE
@@ -45,7 +46,6 @@ class ProfileSettings : public QWidget, private Ui::ProfileSettings
{
Q_OBJECT
friend class FavoriteItemDelegate;
friend class ShortcutItemDelegate;
public:
@@ -72,8 +72,6 @@ private Q_SLOTS:
void setSelectedAsDefault();
void createProfile();
void editSelected();
void moveUpSelected();
void moveDownSelected();
void itemDataChanged(QStandardItem *item);
@@ -99,6 +97,7 @@ private:
// their default / non-default profile status
void updateDefaultItem();
void updateItemsForProfile(const Profile::Ptr &profile,const QList<QStandardItem *> &items) const;
void updateShortcutField(QStandardItem *item, bool isFavorite) const;
// updates the profile table to be in sync with the
// session manager
void populateTable();
@@ -106,11 +105,17 @@ private:
QStandardItemModel *_sessionModel;
static const int ProfileNameColumn = 0;
static const int FavoriteStatusColumn = 1;
static const int ShortcutColumn = 2;
static const int ProfileKeyRole = Qt::UserRole + 1;
static const int ShortcutRole = Qt::UserRole + 1;
enum Column {
FavoriteStatusColumn = 0,
ProfileNameColumn = 1,
ShortcutColumn = 2,
ProfileColumn = 3,
};
enum Role {
ProfilePtrRole = Qt::UserRole + 1,
ShortcutRole,
};
};
class StyledBackgroundPainter
@@ -120,17 +125,15 @@ public:
const QModelIndex &index);
};
class FavoriteItemDelegate : public QStyledItemDelegate
class FilteredKeySequenceEdit: public QKeySequenceEdit
{
Q_OBJECT
public:
explicit FavoriteItemDelegate(QObject *parent = nullptr);
explicit FilteredKeySequenceEdit(QWidget *parent = nullptr): QKeySequenceEdit(parent) {}
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
const QModelIndex &index) Q_DECL_OVERRIDE;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE;
protected:
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
};
class ShortcutItemDelegate : public QStyledItemDelegate
@@ -146,9 +149,12 @@ public:
const QModelIndex &index) const Q_DECL_OVERRIDE;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE;
void destroyEditor(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
private Q_SLOTS:
void editorModified(const QKeySequence &keys);
void editorModified();
private:
mutable QSet<QWidget *> _modifiedEditors;

View File

@@ -6,105 +6,137 @@
<rect>
<x>0</x>
<y>0</y>
<width>645</width>
<height>315</height>
<width>384</width>
<height>384</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="5">
<widget class="QTableView" name="sessionTable">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="newProfileButton">
<property name="toolTip">
<string>Create a new profile based upon the selected profile</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;New Profile...</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="editProfileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Edit the selected profile(s)</string>
</property>
<property name="text">
<string>&amp;Edit Profile...</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="deleteProfileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Delete the selected profile(s)</string>
</property>
<property name="text">
<string>&amp;Delete Profile</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="setAsDefaultButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Set the selected profile as the default for new terminal sessions</string>
</property>
<property name="text">
<string>&amp;Set as Default</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="shortcutInfoLabel">
<property name="text">
<string>The 'Show' column must be checked for these shortcuts to work.</string>
<string>Profiles marked as visible will appear in context and File menu. A shortcut for switching current terminal's profile can be assigned to each entry. However, only shortcuts of visible profiles will work.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,1">
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="newProfileButton">
<property name="toolTip">
<string>Create a new profile based upon the selected profile</string>
</property>
<property name="text">
<string>&amp;New...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editProfileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Edit the selected profile(s)</string>
</property>
<property name="text">
<string>&amp;Edit...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteProfileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Delete the selected profile(s)</string>
</property>
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="setAsDefaultButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Set the selected profile as the default for new terminal sessions</string>
</property>
<property name="text">
<string>&amp;Set as Default</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QTreeView" name="profilesList">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>8</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>

View File

@@ -26,6 +26,16 @@ using namespace Konsole;
TabBarSettings::TabBarSettings(QWidget* aParent) : QWidget(aParent)
{
setupUi(this);
// Enable CSS file selector only when tabbar is visible and custom css is active
const auto updateStyleSheetFileEnable = [this](bool) {
kcfg_TabBarUserStyleSheetFile->setEnabled(kcfg_TabBarUseUserStyleSheet->isChecked()
&& !AlwaysHideTabBar->isChecked());
};
connect(kcfg_TabBarUseUserStyleSheet, &QAbstractButton::toggled,
this, updateStyleSheetFileEnable);
connect(AlwaysHideTabBar, &QAbstractButton::toggled,
this, updateStyleSheetFileEnable);
}
TabBarSettings::~TabBarSettings() = default;

View File

@@ -6,201 +6,295 @@
<rect>
<x>0</x>
<y>0</y>
<width>503</width>
<height>375</height>
<width>384</width>
<height>512</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_1">
<property name="title">
<string>Appearance</string>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
<property name="spacing">
<number>6</number>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Tab bar position:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_TabBarVisibility">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Always Show Tab Bar</string>
</property>
</item>
<item>
<property name="text">
<string>Show Tab Bar When Needed</string>
</property>
</item>
<item>
<property name="text">
<string>Always Hide Tab Bar</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_1">
<property name="text">
<string>Tab bar visibility:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_TabBarPosition">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Above Terminal Area</string>
</property>
</item>
<item>
<property name="text">
<string>Below Terminal Area</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_CloseTabButton">
<property name="text">
<string>Close Tab button:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_CloseTabButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>On each tab</string>
</property>
</item>
<item>
<property name="text">
<string>On the tab bar</string>
</property>
</item>
<item>
<property name="text">
<string comment="Do not show a close button">None</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="kcfg_NewTabButton">
<property name="text">
<string>Show 'New Tab' button</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_ExpandTabWidth">
<property name="text">
<string>Expand Individual Tab Widths to Full Window</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="KUrlRequester" name="kcfg_TabBarUserStyleSheetFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="filter" stdset="0">
<string>text/css</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_TabBarUseUserStyleSheet">
<property name="text">
<string>Use user-defined stylesheet</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_CloseTabOnMiddleMouseButton">
<property name="text">
<string>Close tab on middle-click</string>
</property>
</widget>
</item>
</layout>
</widget>
<item row="2" column="1" colspan="2">
<widget class="QRadioButton" name="AlwaysHideTabBar">
<property name="text">
<string>&amp;Never</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_TabBarVisibility</string>
</attribute>
</widget>
</item>
<item row="16" column="1" colspan="2">
<widget class="QCheckBox" name="kcfg_TabBarUseUserStyleSheet">
<property name="text">
<string>Use user-defined stylesheet:</string>
</property>
</widget>
</item>
<item row="12" column="1" colspan="2">
<widget class="QRadioButton" name="PutNewTabAfterCurrentTab">
<property name="text">
<string>After c&amp;urrent tab</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_NewTabBehavior</string>
</attribute>
</widget>
</item>
<item row="14" column="1" colspan="2">
<widget class="QCheckBox" name="kcfg_CloseTabOnMiddleMouseButton">
<property name="text">
<string>Close tab on middle-click</string>
</property>
</widget>
</item>
<item row="17" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="1" colspan="2">
<widget class="QRadioButton" name="None">
<property name="text">
<string comment="Do not show a close button">None</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_CloseTabButton</string>
</attribute>
</widget>
</item>
<item row="7" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="showCloseTabButtonLabel">
<property name="text">
<string>Show Close Tab button:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="17" column="2">
<widget class="KUrlRequester" name="kcfg_TabBarUserStyleSheetFile">
<property name="enabled">
<bool>false</bool>
</property>
<property name="filter" stdset="0">
<string>text/css</string>
</property>
<property name="placeholderText" stdset="0">
<string comment="@info:placeholder Optional file path is empty">(none)</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<widget class="QRadioButton" name="OnTabBar">
<property name="text">
<string>On &amp;the tab bar</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_CloseTabButton</string>
</attribute>
</widget>
</item>
<item row="13" column="2">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="1" colspan="2">
<widget class="QRadioButton" name="OnEachTab">
<property name="text">
<string>On each tab</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_CloseTabButton</string>
</attribute>
</widget>
</item>
<item row="14" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="miscellaneousLabel">
<property name="text">
<string>Miscellaneous:</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="putNewTabsLabel">
<property name="text">
<string>Put new tabs:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QLabel" name="positionLabel">
<property name="text">
<string>Position:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="11" column="1" colspan="2">
<widget class="QRadioButton" name="PutNewTabAtTheEnd">
<property name="text">
<string>At the end</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_NewTabBehavior</string>
</attribute>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QRadioButton" name="ShowTabBarWhenNeeded">
<property name="text">
<string>When needed</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_TabBarVisibility</string>
</attribute>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QRadioButton" name="AlwaysShowTabBar">
<property name="text">
<string>A&amp;lways</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_TabBarVisibility</string>
</attribute>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QRadioButton" name="Bottom">
<property name="text">
<string>Below terminal area</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_TabBarPosition</string>
</attribute>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QRadioButton" name="Top">
<property name="text">
<string>Above terminal area</string>
</property>
<attribute name="buttonGroup">
<string notr="true">kcfg_TabBarPosition</string>
</attribute>
</widget>
</item>
<item row="15" column="1" colspan="2">
<widget class="QCheckBox" name="kcfg_ExpandTabWidth">
<property name="text">
<string>Expand individual tab widths to full window</string>
</property>
</widget>
</item>
<item row="10" column="2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="showTabBarLabel">
<property name="text">
<string>Show:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Behavior</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>New tab behavior:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KComboBox" name="kcfg_NewTabBehavior">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Put New Tab At The End</string>
</property>
</item>
<item>
<property name="text">
<string>Put New Tab After Current Tab</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -208,7 +302,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>4</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -216,11 +310,6 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
@@ -228,6 +317,252 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>ShowTabBarWhenNeeded</tabstop>
<tabstop>AlwaysShowTabBar</tabstop>
<tabstop>AlwaysHideTabBar</tabstop>
<tabstop>Bottom</tabstop>
<tabstop>Top</tabstop>
<tabstop>OnEachTab</tabstop>
<tabstop>OnTabBar</tabstop>
<tabstop>None</tabstop>
<tabstop>PutNewTabAtTheEnd</tabstop>
<tabstop>PutNewTabAfterCurrentTab</tabstop>
<tabstop>kcfg_CloseTabOnMiddleMouseButton</tabstop>
<tabstop>kcfg_ExpandTabWidth</tabstop>
<tabstop>kcfg_TabBarUseUserStyleSheet</tabstop>
</tabstops>
<resources/>
<connections/>
<connections>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_TabBarUseUserStyleSheet</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>420</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>PutNewTabAfterCurrentTab</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>320</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_CloseTabOnMiddleMouseButton</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>368</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>None</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>246</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>showCloseTabButtonLabel</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>21</x>
<y>194</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>OnTabBar</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>220</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>Bottom</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>146</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>OnEachTab</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>194</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>miscellaneousLabel</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>63</x>
<y>368</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>putNewTabsLabel</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>21</x>
<y>294</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>positionLabel</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>21</x>
<y>120</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>PutNewTabAtTheEnd</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>294</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>Top</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>120</y>
</hint>
</hints>
</connection>
<connection>
<sender>AlwaysHideTabBar</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_ExpandTabWidth</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>141</x>
<y>394</y>
</hint>
</hints>
</connection>
</connections>
<buttongroups>
<buttongroup name="kcfg_TabBarPosition"/>
<buttongroup name="kcfg_NewTabBehavior"/>
<buttongroup name="kcfg_TabBarVisibility"/>
<buttongroup name="kcfg_CloseTabButton"/>
</buttongroups>
</ui>

View File

@@ -0,0 +1,55 @@
/*
Copyright 2015 Kurt Hindenburg <kurt.hindenburg@gmail.com>
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) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor appro-
ved by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
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, see http://www.gnu.org/licenses/.
*/
// Own
#include "TemporaryFilesSettings.h"
// Qt
#include <QStandardPaths>
using namespace Konsole;
TemporaryFilesSettings::TemporaryFilesSettings(QWidget* aParent) : QWidget(aParent)
{
setupUi(this);
const QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
#ifdef Q_OS_UNIX
// Use "~" instead of full path. It looks nice and helps
// in cases when home path is realy long.
const QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
if(cachePath.startsWith(homePath)) {
cachePath.replace(0, homePath.length(), QStringLiteral("~"));
}
#endif
// There's no way of doing this with strings placed in .ui file
kcfg_scrollbackUseSystemLocation->setText(
i18nc("@option:radio File location; <filename>%1</filename>: path to directory placeholder",
"System temporary directory (%1)", tempPath));
kcfg_scrollbackUseCacheLocation->setText(
i18nc("@option:radio File location; <filename>%1</filename>: path to directory placeholder",
"User cache directory (%1)", cachePath));
kcfg_scrollbackUseSpecifiedLocationDirectory->setMode(KFile::Directory);
}

View File

@@ -21,16 +21,16 @@
#ifndef FILELOCATIONSETTINGS_H
#define FILELOCATIONSETTINGS_H
#include "ui_FileLocationSettings.h"
#include "ui_TemporaryFilesSettings.h"
namespace Konsole {
class FileLocationSettings : public QWidget, private Ui::FileLocationSettings
class TemporaryFilesSettings : public QWidget, private Ui::TemporaryFilesSettings
{
Q_OBJECT
public:
explicit FileLocationSettings(QWidget *aParent = nullptr);
~FileLocationSettings() Q_DECL_OVERRIDE;
explicit TemporaryFilesSettings(QWidget *aParent = nullptr);
~TemporaryFilesSettings() override = default;
};
}

View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TemporaryFilesSettings</class>
<widget class="QWidget" name="TemporaryFilesSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>384</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1">
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Scrollback file location:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="KUrlRequester" name="kcfg_scrollbackUseSpecifiedLocationDirectory">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="filter" stdset="0">
<string>text/css</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QRadioButton" name="kcfg_scrollbackUseCacheLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true" comment="Actual value set in code">User cache directory (...)</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QRadioButton" name="kcfg_scrollbackUseSpecifiedLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string comment="@option:radio Custom (file location); followed by text entry field">Custom:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" colspan="2">
<widget class="QRadioButton" name="kcfg_scrollbackUseSystemLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true" comment="Actual value set in code">System temporary directory (...)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>50</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>kcfg_scrollbackUseSpecifiedLocation</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_scrollbackUseSpecifiedLocationDirectory</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>146</x>
<y>66</y>
</hint>
<hint type="destinationlabel">
<x>186</x>
<y>85</y>
</hint>
</hints>
</connection>
</connections>
</ui>