diff --git a/CMakeLists.txt b/CMakeLists.txt index 655c7f61..f611595e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,95 +1,103 @@ # Konsole project # KDE Application Version, managed by release script set (KDE_APPLICATIONS_VERSION_MAJOR "18") set (KDE_APPLICATIONS_VERSION_MINOR "11") set (KDE_APPLICATIONS_VERSION_MICRO "70") set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") # minimal requirements cmake_minimum_required (VERSION 3.0 FATAL_ERROR) set (QT_MIN_VERSION "5.6.0") set (KF5_MIN_VERSION "5.6.0") # Release script will create bugzilla versions project(konsole VERSION ${KDE_APPLICATIONS_VERSION}) find_package(ECM 1.6.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMOptionalAddSubdirectory) include(ECMInstallIcons) include(ECMSetupVersion) include(ECMMarkNonGuiExecutable) include(ECMGenerateHeaders) include(GenerateExportHeader) include(FeatureSummary) include(ECMQtDeclareLoggingCategory) ecm_setup_version(${KDE_APPLICATIONS_VERSION} VARIABLE_PREFIX KONSOLEPRIVATE SOVERSION ${KDE_APPLICATIONS_VERSION_MAJOR} ) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core DBus PrintSupport Widgets ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED Bookmarks Completion Config ConfigWidgets CoreAddons Crash GuiAddons DBusAddons - I18n IconThemes Init KIO NewStuff NewStuffCore + I18n IconThemes Init KIO Parts Pty Service WidgetsAddons WindowSystem XmlGui DBusAddons GlobalAccel ) option(WITHOUT_KNOTIFY "Build without KNotify support" OFF) if (NOT WITHOUT_KNOTIFY) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED Notifications NotifyConfig ) endif() +option(WITHOUT_KNEWSTUFF "Build without KNewStuff support" OFF) + +if (NOT WITHOUT_KNEWSTUFF) + find_package(KF5 ${KF5_MIN_VERSION} REQUIRED + NewStuff NewStuffCore + ) +endif() + find_package(KF5DocTools ${KF5_MIN_VERSION}) set_package_properties(KF5DocTools PROPERTIES DESCRIPTION "Tools to generate documentation" TYPE OPTIONAL ) if(NOT APPLE) find_package(X11) set_package_properties(X11 PROPERTIES TYPE OPTIONAL) endif() set(HAVE_X11 ${X11_FOUND}) # See above includes for defaults add_definitions( -DQT_STRICT_ITERATORS -DQT_NO_URL_CAST_FROM_STRING -Wno-deprecated-declarations ) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ) add_subdirectory( src ) add_subdirectory( data ) add_subdirectory( desktop ) if (KF5DocTools_FOUND) add_subdirectory( doc/manual ) endif() add_subdirectory( tools ) install( FILES konsole.categories DESTINATION ${KDE_INSTALL_CONFDIR} ) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5e129b1..5bbe41c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,226 +1,230 @@ # cmake-options : -DCMAKE_DISABLE_FIND_PACKAGE_LibKonq=TRUE or FALSE; default is FALSE add_definitions(-DTRANSLATION_DOMAIN=\"konsole\") # When Qt5.9+ is required, consider using QOperatingSystemVersion ### Too many crashes/issues with detaching on MacOSX IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(ENABLE_DETACHING 0) else() set(ENABLE_DETACHING 1) endif() ### Handle DragonFlyBSD here instead of using __DragonFly__ IF(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") set(HAVE_OS_DRAGONFLYBSD 1) else() set(HAVE_OS_DRAGONFLYBSD 0) endif() include(CheckIncludeFiles) include(ECMAddAppIcon) configure_file(config-konsole.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-konsole.h) ### Tests if(BUILD_TESTING) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED) add_subdirectory(autotests) add_subdirectory(tests) endif() ### Security concerns about sendText and runCommand dbus methods being public option(REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS "Konsole: remove sendText and runCommand dbus methods" OFF) ### Development tools option(KONSOLE_BUILD_FONTEMBEDDER "Konsole: build fontembedder executable" OFF) option(KONSOLE_GENERATE_LINEFONT "Konsole: regenerate LineFont file" OFF) option(KONSOLE_BUILD_UNI2CHARACTERWIDTH "Konsole: build uni2characterwidth executable" OFF) ### Konsole source files shared between embedded terminal and main application # qdbuscpp2xml -m Session.h -o org.kde.konsole.Session.xml # qdbuscpp2xml -M -s ViewManager.h -o org.kde.konsole.Konsole.xml # Generate dbus .xml files; do not store .xml in source folder qt5_generate_dbus_interface(Session.h org.kde.konsole.Session.xml OPTIONS -m) qt5_generate_dbus_interface(ViewManager.h org.kde.konsole.Window.xml OPTIONS -m) qt5_add_dbus_adaptor(sessionadaptors_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Session.xml Session.h Konsole::Session) qt5_add_dbus_adaptor(windowadaptors_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Window.xml ViewManager.h Konsole::ViewManager) set(konsoleprivate_SRCS ${sessionadaptors_SRCS} ${windowadaptors_SRCS} BookmarkHandler.cpp ColorScheme.cpp ColorSchemeManager.cpp ColorSchemeEditor.cpp CopyInputDialog.cpp EditProfileDialog.cpp Emulation.cpp DetachableTabBar.cpp Filter.cpp History.cpp HistorySizeDialog.cpp HistorySizeWidget.cpp IncrementalSearchBar.cpp KeyBindingEditor.cpp KeyboardTranslator.cpp KeyboardTranslatorManager.cpp ProcessInfo.cpp Profile.cpp ProfileList.cpp ProfileReader.cpp ProfileWriter.cpp ProfileManager.cpp Pty.cpp RenameTabDialog.cpp RenameTabWidget.cpp Screen.cpp ScreenWindow.cpp ScrollState.cpp Session.cpp SessionController.cpp SessionManager.cpp SessionListModel.cpp ShellCommand.cpp TabTitleFormatButton.cpp TerminalCharacterDecoder.cpp ExtendedCharTable.cpp TerminalDisplay.cpp TerminalDisplayAccessible.cpp ViewContainer.cpp ViewManager.cpp ViewProperties.cpp ViewSplitter.cpp Vt102Emulation.cpp ZModemDialog.cpp PrintOptions.cpp WindowSystemInfo.cpp CharacterWidth.cpp ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Window.xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Session.xml) ecm_qt_declare_logging_category(konsoleprivate_SRCS HEADER konsoledebug.h IDENTIFIER KonsoleDebug CATEGORY_NAME org.kde.konsole) kconfig_add_kcfg_files(konsoleprivate_SRCS settings/KonsoleSettings.kcfgc) set(konsole_LIBS KF5::XmlGui Qt5::PrintSupport Qt5::Xml KF5::WindowSystem KF5::GuiAddons KF5::IconThemes KF5::Bookmarks KF5::I18n KF5::Pty KF5::KIOWidgets KF5::DBusAddons KF5::GlobalAccel - KF5::NewStuff ) + if (NOT WITHOUT_KNOTIFY) list(APPEND konsole_LIBS KF5::Notifications) endif() +if (NOT WITHOUT_KNEWSTUFF) + list(APPEND konsole_LIBS KF5::NewStuff) +endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") #kinfo_getfile() is in libutil list(APPEND konsole_LIBS util) endif() ### Konsole Application ki18n_wrap_ui(konsoleprivate_SRCS ColorSchemeEditor.ui CopyInputDialog.ui EditProfileDialog.ui KeyBindingEditor.ui RenameTabDialog.ui RenameTabWidget.ui HistorySizeDialog.ui HistorySizeWidget.ui PrintOptions.ui settings/FileLocationSettings.ui settings/GeneralSettings.ui settings/PartInfo.ui settings/ProfileSettings.ui settings/TabBarSettings.ui) # add the resource files for the ui files qt5_add_resources( konsoleprivate_SRCS ../desktop/konsole.qrc) add_library(konsoleprivate ${konsoleprivate_SRCS}) generate_export_header(konsoleprivate BASE_NAME konsoleprivate) target_link_libraries(konsoleprivate PUBLIC ${konsole_LIBS}) set_target_properties(konsoleprivate PROPERTIES VERSION ${KONSOLEPRIVATE_VERSION_STRING} SOVERSION ${KONSOLEPRIVATE_SOVERSION} ) install(TARGETS konsoleprivate ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) set(konsole_KDEINIT_SRCS Application.cpp MainWindow.cpp main.cpp settings/FileLocationSettings.cpp settings/GeneralSettings.cpp settings/ProfileSettings.cpp settings/TabBarSettings.cpp) # Sets the icon on Windows and OSX file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/*.png") ecm_add_app_icon(kdeinit_konsole ICONS ${ICONS_SRCS}) kf5_add_kdeinit_executable(konsole ${konsole_KDEINIT_SRCS}) set(konsole_KDEINIT_LIBS KF5::XmlGui KF5::WindowSystem KF5::Bookmarks KF5::I18n KF5::KIOWidgets KF5::Crash ) if (NOT WITHOUT_KNOTIFY) list(APPEND konsole_KDEINIT_LIBS KF5::NotifyConfig) endif() target_link_libraries(kdeinit_konsole konsoleprivate ${konsole_KDEINIT_LIBS} ) if(APPLE) set_target_properties(konsole PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.konsole" MACOSX_BUNDLE_BUNDLE_NAME "Konsole" MACOSX_BUNDLE_DISPLAY_NAME "Konsole" MACOSX_BUNDLE_INFO_STRING "Konsole, the KDE terminal emulator" MACOSX_BUNDLE_LONG_VERSION_STRING "Konsole ${KDE_APPLICATIONS_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}" MACOSX_BUNDLE_BUNDLE_VERSION "${KDE_APPLICATIONS_VERSION}" MACOSX_BUNDLE_COPYRIGHT "1997-2016 The Konsole Developers") endif() install(TARGETS kdeinit_konsole konsole ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) ### Embedded Konsole KPart set(konsolepart_PART_SRCS Part.cpp settings/PartInfo.cpp settings/ProfileSettings.cpp) add_library(konsolepart MODULE ${konsolepart_PART_SRCS}) generate_export_header(konsolepart BASE_NAME konsole) kcoreaddons_desktop_to_json(konsolepart ../desktop/konsolepart.desktop) set_target_properties(konsolepart PROPERTIES DEFINE_SYMBOL KONSOLE_PART) target_link_libraries(konsolepart KF5::Parts KF5::XmlGui konsoleprivate) install(TARGETS konsolepart DESTINATION ${KDE_INSTALL_PLUGINDIR}) diff --git a/src/EditProfileDialog.cpp b/src/EditProfileDialog.cpp index 24b50461..0046cf55 100644 --- a/src/EditProfileDialog.cpp +++ b/src/EditProfileDialog.cpp @@ -1,1756 +1,1778 @@ /* Copyright 2007-2008 by Robert Knight Copyright 2018 by Harald Sitter 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 "EditProfileDialog.h" // Standard #include // Qt #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include -#include #include +#ifndef WITHOUT_KNEWSTUFF +#include +#endif + // Konsole #include "ColorSchemeManager.h" #include "ui_EditProfileDialog.h" #include "KeyBindingEditor.h" #include "KeyboardTranslator.h" #include "KeyboardTranslatorManager.h" #include "ProfileManager.h" #include "ShellCommand.h" #include "WindowSystemInfo.h" #include "Shortcut_p.h" using namespace Konsole; EditProfileDialog::EditProfileDialog(QWidget *aParent) : QDialog(aParent), _ui(nullptr), _tempProfile(nullptr), _profile(nullptr), _pageNeedsUpdate(QVector()), _previewedProperties(QHash()), _delayedPreviewProperties(QHash()), _delayedPreviewTimer(new QTimer(this)), _colorDialog(nullptr), mButtonBox(nullptr) { setWindowTitle(i18n("Edit Profile")); mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Apply); auto mainWidget = new QWidget(this); auto mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(mainWidget); QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); connect(mButtonBox, &QDialogButtonBox::accepted, this, &Konsole::EditProfileDialog::accept); connect(mButtonBox, &QDialogButtonBox::rejected, this, &Konsole::EditProfileDialog::reject); // disable the apply button , since no modification has been made mButtonBox->button(QDialogButtonBox::Apply)->setEnabled(false); connect(mButtonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &Konsole::EditProfileDialog::apply); connect(_delayedPreviewTimer, &QTimer::timeout, this, &Konsole::EditProfileDialog::delayedPreviewActivate); _ui = new Ui::EditProfileDialog(); _ui->setupUi(mainWidget); +#ifndef WITHOUT_KNEWSTUFF + _downloadColorSchemeButton = new KNS3::Button(_ui->groupBox); + _ui->gridLayout3->addWidget(_downloadColorSchemeButton, 5, 1, 1, 1); +#endif mainLayout->addWidget(mButtonBox); // there are various setupXYZPage() methods to load the items // for each page and update their states to match the profile // being edited. // // these are only called when needed ( ie. when the user clicks // the tab to move to that page ). // // the _pageNeedsUpdate vector keeps track of the pages that have // not been updated since the last profile change and will need // to be refreshed when the user switches to them _pageNeedsUpdate.resize(_ui->tabWidget->count()); connect(_ui->tabWidget, &QTabWidget::currentChanged, this, &Konsole::EditProfileDialog::preparePage); createTempProfile(); } EditProfileDialog::~EditProfileDialog() { delete _ui; } void EditProfileDialog::save() { if (_tempProfile->isEmpty()) { return; } ProfileManager::instance()->changeProfile(_profile, _tempProfile->setProperties()); // ensure that these settings are not undone by a call // to unpreview() QHashIterator iter(_tempProfile->setProperties()); while (iter.hasNext()) { iter.next(); _previewedProperties.remove(iter.key()); } createTempProfile(); mButtonBox->button(QDialogButtonBox::Apply)->setEnabled(false); } void EditProfileDialog::reject() { unpreviewAll(); QDialog::reject(); } void EditProfileDialog::accept() { // if the Apply button is disabled then no settings were changed // or the changes have already been saved by apply() if (mButtonBox->button(QDialogButtonBox::Apply)->isEnabled()) { if (!isValidProfileName()) { return; } save(); } unpreviewAll(); QDialog::accept(); } void EditProfileDialog::apply() { if (!isValidProfileName()) { return; } save(); } bool EditProfileDialog::isValidProfileName() { Q_ASSERT(_profile); Q_ASSERT(_tempProfile); // check whether the user has enough permissions to save the profile QFileInfo fileInfo(_profile->path()); if (fileInfo.exists() && !fileInfo.isWritable()) { if (!_tempProfile->isPropertySet(Profile::Name) || (_tempProfile->name() == _profile->name())) { KMessageBox::sorry(this, i18n("

Konsole does not have permission to save this profile to:
\"%1\"

" "

To be able to save settings you can either change the permissions " "of the profile configuration file or change the profile name to save " "the settings to a new profile.

", _profile->path())); return false; } } const QList existingProfiles = ProfileManager::instance()->allProfiles(); QStringList otherExistingProfileNames; foreach(auto existingProfile, existingProfiles) { if (existingProfile->name() != _profile->name()) { otherExistingProfileNames.append(existingProfile->name()); } } if ((_tempProfile->isPropertySet(Profile::Name) && _tempProfile->name().isEmpty()) || (_profile->name().isEmpty() && _tempProfile->name().isEmpty())) { KMessageBox::sorry(this, i18n("

Each profile must have a name before it can be saved " "into disk.

")); // revert the name in the dialog _ui->profileNameEdit->setText(_profile->name()); selectProfileName(); return false; } else if (!_tempProfile->name().isEmpty() && otherExistingProfileNames.contains(_tempProfile->name())) { KMessageBox::sorry(this, i18n("

A profile with this name already exists.

")); // revert the name in the dialog _ui->profileNameEdit->setText(_profile->name()); selectProfileName(); return false; } else { return true; } } QString EditProfileDialog::groupProfileNames(const ProfileGroup::Ptr group, int maxLength) { QString caption; int count = group->profiles().count(); for (int i = 0; i < count; i++) { caption += group->profiles()[i]->name(); if (i < (count - 1)) { caption += QLatin1Char(','); // limit caption length to prevent very long window titles if (maxLength > 0 && caption.length() > maxLength) { caption += QLatin1String("..."); break; } } } return caption; } void EditProfileDialog::updateCaption(const Profile::Ptr profile) { const int MAX_GROUP_CAPTION_LENGTH = 25; ProfileGroup::Ptr group = profile->asGroup(); if (group && group->profiles().count() > 1) { QString caption = groupProfileNames(group, MAX_GROUP_CAPTION_LENGTH); setWindowTitle(i18np("Editing profile: %2", "Editing %1 profiles: %2", group->profiles().count(), caption)); } else { setWindowTitle(i18n("Edit Profile \"%1\"", profile->name())); } } void EditProfileDialog::setProfile(Profile::Ptr profile) { Q_ASSERT(profile); _profile = profile; // update caption updateCaption(profile); // mark each page of the dialog as out of date // and force an update of the currently visible page // // the other pages will be updated as necessary _pageNeedsUpdate.fill(true); preparePage(_ui->tabWidget->currentIndex()); if (_tempProfile) { createTempProfile(); } } const Profile::Ptr EditProfileDialog::lookupProfile() const { return _profile; } const QString EditProfileDialog::currentColorSchemeName() const { const QString ¤tColorSchemeName = lookupProfile()->colorScheme(); return currentColorSchemeName; } void EditProfileDialog::preparePage(int page) { const Profile::Ptr profile = lookupProfile(); Q_ASSERT(_pageNeedsUpdate.count() > page); Q_ASSERT(profile); QWidget *pageWidget = _ui->tabWidget->widget(page); if (_pageNeedsUpdate[page]) { if (pageWidget == _ui->generalTab) { setupGeneralPage(profile); } else if (pageWidget == _ui->tabsTab) { setupTabsPage(profile); } else if (pageWidget == _ui->appearanceTab) { setupAppearancePage(profile); } else if (pageWidget == _ui->scrollingTab) { setupScrollingPage(profile); } else if (pageWidget == _ui->keyboardTab) { setupKeyboardPage(profile); } else if (pageWidget == _ui->mouseTab) { setupMousePage(profile); } else if (pageWidget == _ui->advancedTab) { setupAdvancedPage(profile); } else { Q_ASSERT(false); } _pageNeedsUpdate[page] = false; } } void EditProfileDialog::selectProfileName() { _ui->profileNameEdit->setFocus(); _ui->profileNameEdit->selectAll(); } void EditProfileDialog::setupGeneralPage(const Profile::Ptr profile) { // basic profile options { _ui->profileNameEdit->setPlaceholderText(i18nc("@label:textbox", "Enter descriptive label")); ProfileGroup::Ptr group = profile->asGroup(); if (!group || group->profiles().count() < 2) { _ui->profileNameEdit->setText(profile->name()); _ui->profileNameEdit->setClearButtonEnabled(true); } else { _ui->profileNameEdit->setText(groupProfileNames(group, -1)); _ui->profileNameEdit->setEnabled(false); _ui->profileNameLabel->setEnabled(false); } } ShellCommand command(profile->command(), profile->arguments()); _ui->commandEdit->setText(command.fullCommand()); // If a "completion" is requested, consider changing this to KLineEdit // and using KCompletion. _ui->initialDirEdit->setText(profile->defaultWorkingDirectory()); _ui->initialDirEdit->setClearButtonEnabled(true); _ui->dirSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("folder-open"))); _ui->iconSelectButton->setIcon(QIcon::fromTheme(profile->icon())); _ui->startInSameDirButton->setChecked(profile->startInCurrentSessionDir()); // terminal options _ui->terminalColumnsEntry->setValue(profile->terminalColumns()); _ui->terminalRowsEntry->setValue(profile->terminalRows()); // window options _ui->showTerminalSizeHintButton->setChecked(profile->showTerminalSizeHint()); // signals and slots connect(_ui->dirSelectButton, &QToolButton::clicked, this, &Konsole::EditProfileDialog::selectInitialDir); connect(_ui->iconSelectButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::selectIcon); connect(_ui->startInSameDirButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::startInSameDir); connect(_ui->profileNameEdit, &QLineEdit::textChanged, this, &Konsole::EditProfileDialog::profileNameChanged); connect(_ui->initialDirEdit, &QLineEdit::textChanged, this, &Konsole::EditProfileDialog::initialDirChanged); connect(_ui->commandEdit, &QLineEdit::textChanged, this, &Konsole::EditProfileDialog::commandChanged); connect(_ui->environmentEditButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::showEnvironmentEditor); connect(_ui->terminalColumnsEntry, static_cast(&QSpinBox::valueChanged), this, &Konsole::EditProfileDialog::terminalColumnsEntryChanged); connect(_ui->terminalRowsEntry, static_cast(&QSpinBox::valueChanged), this, &Konsole::EditProfileDialog::terminalRowsEntryChanged); connect(_ui->showTerminalSizeHintButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::showTerminalSizeHint); } void EditProfileDialog::showEnvironmentEditor() { bool ok; const Profile::Ptr profile = lookupProfile(); QStringList currentEnvironment; // The user could re-open the environment editor before clicking // OK/Apply in the parent edit profile dialog, so we make sure // to show the new environment vars if (_tempProfile->isPropertySet(Profile::Environment)) { currentEnvironment = _tempProfile->environment(); } else { currentEnvironment = profile->environment(); } QString text = QInputDialog::getMultiLineText(this, i18n("Edit Environment"), i18n("One environment variable per line"), currentEnvironment.join(QStringLiteral("\n")), &ok); QStringList newEnvironment; if (ok) { if(!text.isEmpty()) { newEnvironment = text.split(QLatin1Char('\n')); updateTempProfileProperty(Profile::Environment, newEnvironment); } else { // the user could have removed all entries so we return an empty list updateTempProfileProperty(Profile::Environment, newEnvironment); } } } void EditProfileDialog::setupTabsPage(const Profile::Ptr profile) { // tab title format _ui->renameTabWidget->setTabTitleText(profile->localTabTitleFormat()); _ui->renameTabWidget->setRemoteTabTitleText(profile->remoteTabTitleFormat()); connect(_ui->renameTabWidget, &Konsole::RenameTabWidget::tabTitleFormatChanged, this, &Konsole::EditProfileDialog::tabTitleFormatChanged); connect(_ui->renameTabWidget, &Konsole::RenameTabWidget::remoteTabTitleFormatChanged, this, &Konsole::EditProfileDialog::remoteTabTitleFormatChanged); // tab monitoring const int silenceSeconds = profile->silenceSeconds(); _ui->silenceSecondsSpinner->setValue(silenceSeconds); _ui->silenceSecondsSpinner->setSuffix(i18n(" second(s)")); connect(_ui->silenceSecondsSpinner, static_cast(&QSpinBox::valueChanged), this, &Konsole::EditProfileDialog::silenceSecondsChanged); } void EditProfileDialog::terminalColumnsEntryChanged(int value) { updateTempProfileProperty(Profile::TerminalColumns, value); } void EditProfileDialog::terminalRowsEntryChanged(int value) { updateTempProfileProperty(Profile::TerminalRows, value); } void EditProfileDialog::showTerminalSizeHint(bool value) { updateTempProfileProperty(Profile::ShowTerminalSizeHint, value); } void EditProfileDialog::tabTitleFormatChanged(const QString &format) { updateTempProfileProperty(Profile::LocalTabTitleFormat, format); } void EditProfileDialog::remoteTabTitleFormatChanged(const QString &format) { updateTempProfileProperty(Profile::RemoteTabTitleFormat, format); } void EditProfileDialog::silenceSecondsChanged(int seconds) { updateTempProfileProperty(Profile::SilenceSeconds, seconds); } void EditProfileDialog::selectIcon() { const QString &icon = KIconDialog::getIcon(KIconLoader::Desktop, KIconLoader::Application, false, 0, false, this); if (!icon.isEmpty()) { _ui->iconSelectButton->setIcon(QIcon::fromTheme(icon)); updateTempProfileProperty(Profile::Icon, icon); } } void EditProfileDialog::profileNameChanged(const QString &name) { updateTempProfileProperty(Profile::Name, name); updateTempProfileProperty(Profile::UntranslatedName, name); updateCaption(_tempProfile); } void EditProfileDialog::startInSameDir(bool sameDir) { updateTempProfileProperty(Profile::StartInCurrentSessionDir, sameDir); } void EditProfileDialog::initialDirChanged(const QString &dir) { updateTempProfileProperty(Profile::Directory, dir); } void EditProfileDialog::commandChanged(const QString &command) { ShellCommand shellCommand(command); updateTempProfileProperty(Profile::Command, shellCommand.command()); updateTempProfileProperty(Profile::Arguments, shellCommand.arguments()); } void EditProfileDialog::selectInitialDir() { const QUrl url = QFileDialog::getExistingDirectoryUrl(this, i18n("Select Initial Directory"), QUrl::fromUserInput(_ui->initialDirEdit-> text())); if (!url.isEmpty()) { _ui->initialDirEdit->setText(url.path()); } } void EditProfileDialog::setupAppearancePage(const Profile::Ptr profile) { auto delegate = new ColorSchemeViewDelegate(this); _ui->colorSchemeList->setItemDelegate(delegate); _ui->transparencyWarningWidget->setVisible(false); _ui->transparencyWarningWidget->setWordWrap(true); _ui->transparencyWarningWidget->setCloseButtonVisible(false); _ui->transparencyWarningWidget->setMessageType(KMessageWidget::Warning); _ui->colorSchemeMessageWidget->setVisible(false); _ui->colorSchemeMessageWidget->setWordWrap(true); _ui->colorSchemeMessageWidget->setCloseButtonVisible(false); _ui->colorSchemeMessageWidget->setMessageType(KMessageWidget::Warning); _ui->editColorSchemeButton->setEnabled(false); _ui->removeColorSchemeButton->setEnabled(false); _ui->resetColorSchemeButton->setEnabled(false); - _ui->downloadColorSchemeButton->setConfigFile(QStringLiteral("konsole.knsrc")); +#ifndef WITHOUT_KNEWSTUFF + _downloadColorSchemeButton->setConfigFile(QStringLiteral("konsole.knsrc")); +#endif // setup color list // select the colorScheme used in the current profile updateColorSchemeList(currentColorSchemeName()); _ui->colorSchemeList->setMouseTracking(true); _ui->colorSchemeList->installEventFilter(this); _ui->colorSchemeList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); connect(_ui->colorSchemeList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Konsole::EditProfileDialog::colorSchemeSelected); connect(_ui->colorSchemeList, &QListView::entered, this, &Konsole::EditProfileDialog::previewColorScheme); updateColorSchemeButtons(); connect(_ui->editColorSchemeButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::editColorScheme); connect(_ui->removeColorSchemeButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::removeColorScheme); connect(_ui->newColorSchemeButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::newColorScheme); - connect(_ui->downloadColorSchemeButton, &KNS3::Button::dialogFinished, this, + +#ifndef WITHOUT_KNEWSTUFF + connect(_downloadColorSchemeButton, &KNS3::Button::dialogFinished, this, &Konsole::EditProfileDialog::gotNewColorSchemes); +#endif connect(_ui->resetColorSchemeButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::resetColorScheme); // setup font preview const bool antialias = profile->antiAliasFonts(); QFont profileFont = profile->font(); profileFont.setStyleStrategy(antialias ? QFont::PreferAntialias : QFont::NoAntialias); _ui->fontPreviewLabel->installEventFilter(this); _ui->fontPreviewLabel->setFont(profileFont); setFontInputValue(profileFont); // Always set to unchecked _ui->showAllFontsButton->setChecked(false); connect(_ui->showAllFontsButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::showAllFontsButtonWarning); connect(_ui->fontSizeInput, static_cast(&QDoubleSpinBox::valueChanged), this, &Konsole::EditProfileDialog::setFontSize); connect(_ui->selectFontButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::showFontDialog); // setup font smoothing _ui->antialiasTextButton->setChecked(antialias); connect(_ui->antialiasTextButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::setAntialiasText); _ui->boldIntenseButton->setChecked(profile->boldIntense()); connect(_ui->boldIntenseButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::setBoldIntense); _ui->useFontLineCharactersButton->setChecked(profile->useFontLineCharacters()); connect(_ui->useFontLineCharactersButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::useFontLineCharacters); _ui->enableMouseWheelZoomButton->setChecked(profile->mouseWheelZoomEnabled()); connect(_ui->enableMouseWheelZoomButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::toggleMouseWheelZoom); } void EditProfileDialog::showAllFontsButtonWarning(bool enable) { if (enable) { KMessageBox::information(this, QStringLiteral( "By its very nature, a terminal program requires font characters that are equal width (monospace). Any non monospaced font may cause display issues. This should not be necessary except in rare cases."), QStringLiteral("Warning")); } } void EditProfileDialog::setAntialiasText(bool enable) { QFont profileFont = _ui->fontPreviewLabel->font(); profileFont.setStyleStrategy(enable ? QFont::PreferAntialias : QFont::NoAntialias); // update preview to reflect text smoothing state fontSelected(profileFont); updateTempProfileProperty(Profile::AntiAliasFonts, enable); } void EditProfileDialog::setBoldIntense(bool enable) { preview(Profile::BoldIntense, enable); updateTempProfileProperty(Profile::BoldIntense, enable); } void EditProfileDialog::useFontLineCharacters(bool enable) { preview(Profile::UseFontLineCharacters, enable); updateTempProfileProperty(Profile::UseFontLineCharacters, enable); } void EditProfileDialog::toggleMouseWheelZoom(bool enable) { updateTempProfileProperty(Profile::MouseWheelZoomEnabled, enable); } void EditProfileDialog::toggleAlternateScrolling(bool enable) { updateTempProfileProperty(Profile::AlternateScrolling, enable); } void EditProfileDialog::updateColorSchemeList(const QString &selectedColorSchemeName) { if (_ui->colorSchemeList->model() == nullptr) { _ui->colorSchemeList->setModel(new QStandardItemModel(this)); } const ColorScheme *selectedColorScheme = ColorSchemeManager::instance()->findColorScheme(selectedColorSchemeName); QStandardItemModel *model = qobject_cast(_ui->colorSchemeList->model()); Q_ASSERT(model); model->clear(); QStandardItem *selectedItem = nullptr; QList schemeList = ColorSchemeManager::instance()->allColorSchemes(); foreach (const ColorScheme *scheme, schemeList) { QStandardItem *item = new QStandardItem(scheme->description()); item->setData(QVariant::fromValue(scheme), Qt::UserRole + 1); item->setData(QVariant::fromValue(_profile->font()), Qt::UserRole + 2); item->setFlags(item->flags()); // if selectedColorSchemeName is not empty then select that scheme // after saving the changes in the colorScheme editor if (selectedColorScheme == scheme) { selectedItem = item; } model->appendRow(item); } model->sort(0); if (selectedItem != nullptr) { _ui->colorSchemeList->updateGeometry(); _ui->colorSchemeList->selectionModel()->setCurrentIndex(selectedItem->index(), QItemSelectionModel::Select); // update transparency warning label updateTransparencyWarning(); } } void EditProfileDialog::updateKeyBindingsList(const QString &selectKeyBindingsName) { if (_ui->keyBindingList->model() == nullptr) { _ui->keyBindingList->setModel(new QStandardItemModel(this)); } QStandardItemModel *model = qobject_cast(_ui->keyBindingList->model()); Q_ASSERT(model); model->clear(); QStandardItem *selectedItem = nullptr; const QStringList &translatorNames = _keyManager->allTranslators(); for (const QString &translatorName : translatorNames) { const KeyboardTranslator *translator = _keyManager->findTranslator(translatorName); if (translator == nullptr) { continue; } QStandardItem *item = new QStandardItem(translator->description()); item->setEditable(false); item->setData(QVariant::fromValue(translator), Qt::UserRole + 1); item->setData(QVariant::fromValue(_keyManager->findTranslatorPath(translatorName)), Qt::ToolTipRole); item->setData(QVariant::fromValue(_profile->font()), Qt::UserRole + 2); item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-keyboard"))); if (selectKeyBindingsName == translatorName) { selectedItem = item; } model->appendRow(item); } model->sort(0); if (selectedItem != nullptr) { _ui->keyBindingList->selectionModel()->setCurrentIndex(selectedItem->index(), QItemSelectionModel::Select); } } bool EditProfileDialog::eventFilter(QObject *watched, QEvent *event) { if (watched == _ui->colorSchemeList && event->type() == QEvent::Leave) { if (_tempProfile->isPropertySet(Profile::ColorScheme)) { preview(Profile::ColorScheme, _tempProfile->colorScheme()); } else { unpreview(Profile::ColorScheme); } } if (watched == _ui->fontPreviewLabel && event->type() == QEvent::FontChange) { const QFont &labelFont = _ui->fontPreviewLabel->font(); _ui->fontPreviewLabel->setText(i18n("%1", labelFont.family())); } return QDialog::eventFilter(watched, event); } void EditProfileDialog::unpreviewAll() { _delayedPreviewTimer->stop(); _delayedPreviewProperties.clear(); QHash map; QHashIterator iter(_previewedProperties); while (iter.hasNext()) { iter.next(); map.insert(static_cast(iter.key()), iter.value()); } // undo any preview changes if (!map.isEmpty()) { ProfileManager::instance()->changeProfile(_profile, map, false); } } void EditProfileDialog::unpreview(int property) { _delayedPreviewProperties.remove(property); if (!_previewedProperties.contains(property)) { return; } QHash map; map.insert(static_cast(property), _previewedProperties[property]); ProfileManager::instance()->changeProfile(_profile, map, false); _previewedProperties.remove(property); } void EditProfileDialog::delayedPreview(int property, const QVariant &value) { _delayedPreviewProperties.insert(property, value); _delayedPreviewTimer->stop(); _delayedPreviewTimer->start(300); } void EditProfileDialog::delayedPreviewActivate() { Q_ASSERT(qobject_cast(sender())); QMutableHashIterator iter(_delayedPreviewProperties); if (iter.hasNext()) { iter.next(); preview(iter.key(), iter.value()); } } void EditProfileDialog::preview(int property, const QVariant &value) { QHash map; map.insert(static_cast(property), value); _delayedPreviewProperties.remove(property); const Profile::Ptr original = lookupProfile(); // skip previews for profile groups if the profiles in the group // have conflicting original values for the property // // TODO - Save the original values for each profile and use to unpreview properties ProfileGroup::Ptr group = original->asGroup(); if (group && group->profiles().count() > 1 && original->property(static_cast(property)).isNull()) { return; } if (!_previewedProperties.contains(property)) { _previewedProperties.insert(property, original->property(static_cast(property))); } // temporary change to color scheme ProfileManager::instance()->changeProfile(_profile, map, false); } void EditProfileDialog::previewColorScheme(const QModelIndex &index) { const QString &name = index.data(Qt::UserRole + 1).value()->name(); delayedPreview(Profile::ColorScheme, name); } void EditProfileDialog::removeColorScheme() { QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); if (selected.isEmpty()) { return; } +#ifndef WITHOUT_KNEWSTUFF // The actual delete runs async because we need to on-demand query // files managed by KNS. Deleting files managed by KNS screws up the // KNS states (entry gets shown as installed when in fact we deleted it). auto *manager = new KNSCore::DownloadManager(QStringLiteral("konsole.knsrc"), this); connect(manager, &KNSCore::DownloadManager::searchResult, [=](const KNSCore::EntryInternal::List &entries) { const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); Q_ASSERT(!name.isEmpty()); bool uninstalled = false; // Check if the theme was installed by KNS, if so uninstall it through // there and unload it. for (auto entry : entries) { for (const auto &file : entry.installedFiles()) { if (ColorSchemeManager::colorSchemeNameFromPath(file) != name) { continue; } // Make sure the manager can unload it before uninstalling it. if (ColorSchemeManager::instance()->unloadColorScheme(file)) { manager->uninstallEntry(entry); uninstalled = true; } } if (uninstalled) { break; } } // If KNS wasn't able to remove it is a custom theme and we'll drop // it manually. if (!uninstalled) { uninstalled = ColorSchemeManager::instance()->deleteColorScheme(name); } if (uninstalled) { _ui->colorSchemeList->model()->removeRow(selected.first().row()); } manager->deleteLater(); }); manager->checkForInstalled(); +#else //WITHOUT_KNEWSTUFF + const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); + bool uninstalled = ColorSchemeManager::instance()->deleteColorScheme(name); + if (uninstalled) { + _ui->colorSchemeList->model()->removeRow(selected.first().row()); + } +#endif //WITHOUT_KNEWSTUFF } +#ifndef WITHOUT_KNEWSTUFF void EditProfileDialog::gotNewColorSchemes(const KNS3::Entry::List &changedEntries) { int failures = 0; for (auto entry : changedEntries) { switch (entry.status()) { case KNS3::Entry::Installed: for (const auto &file : entry.installedFiles()) { if (ColorSchemeManager::instance()->loadColorScheme(file)) { continue; } qWarning() << "Failed to load file" << file; ++failures; } if (failures == entry.installedFiles().size()) { _ui->colorSchemeMessageWidget->setText( xi18nc("@info", "Scheme %1 failed to load.", entry.name())); _ui->colorSchemeMessageWidget->animatedShow(); QTimer::singleShot(8000, _ui->colorSchemeMessageWidget, &KMessageWidget::animatedHide); } break; case KNS3::Entry::Deleted: for (const auto &file : entry.uninstalledFiles()) { if (ColorSchemeManager::instance()->unloadColorScheme(file)) { continue; } qWarning() << "Failed to unload file" << file; // If unloading fails we do not care. Iff the scheme failed here // it either wasn't loaded or was invalid to begin with. } break; case KNS3::Entry::Invalid: case KNS3::Entry::Installing: case KNS3::Entry::Downloadable: case KNS3::Entry::Updateable: case KNS3::Entry::Updating: // Not interesting. break; } } updateColorSchemeList(currentColorSchemeName()); } +#endif //WITHOUT_KNEWSTUFF void EditProfileDialog::resetColorScheme() { QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); ColorSchemeManager::instance()->deleteColorScheme(name); // select the colorScheme used in the current profile updateColorSchemeList(currentColorSchemeName()); } } void EditProfileDialog::showColorSchemeEditor(bool isNewScheme) { // Finding selected ColorScheme QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); QAbstractItemModel *model = _ui->colorSchemeList->model(); const ColorScheme *colors = nullptr; if (!selected.isEmpty()) { colors = model->data(selected.first(), Qt::UserRole + 1).value(); } else { colors = ColorSchemeManager::instance()->defaultColorScheme(); } Q_ASSERT(colors); // Setting up ColorSchemeEditor ui // close any running ColorSchemeEditor if (_colorDialog != nullptr) { closeColorSchemeEditor(); } _colorDialog = new ColorSchemeEditor(this); connect(_colorDialog, &Konsole::ColorSchemeEditor::colorSchemeSaveRequested, this, &Konsole::EditProfileDialog::saveColorScheme); _colorDialog->setup(colors, isNewScheme); _colorDialog->show(); } void EditProfileDialog::closeColorSchemeEditor() { if (_colorDialog != nullptr) { _colorDialog->close(); delete _colorDialog; } } void EditProfileDialog::newColorScheme() { showColorSchemeEditor(true); } void EditProfileDialog::editColorScheme() { showColorSchemeEditor(false); } void EditProfileDialog::saveColorScheme(const ColorScheme &scheme, bool isNewScheme) { auto newScheme = new ColorScheme(scheme); // if this is a new color scheme, pick a name based on the description if (isNewScheme) { newScheme->setName(newScheme->description()); } ColorSchemeManager::instance()->addColorScheme(newScheme); const QString &selectedColorSchemeName = newScheme->name(); // select the edited or the new colorScheme after saving the changes updateColorSchemeList(selectedColorSchemeName); preview(Profile::ColorScheme, newScheme->name()); } void EditProfileDialog::colorSchemeSelected() { QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { QAbstractItemModel *model = _ui->colorSchemeList->model(); const ColorScheme *colors = model->data(selected.first(), Qt::UserRole + 1).value(); if (colors != nullptr) { updateTempProfileProperty(Profile::ColorScheme, colors->name()); previewColorScheme(selected.first()); updateTransparencyWarning(); } } updateColorSchemeButtons(); } void EditProfileDialog::updateColorSchemeButtons() { enableIfNonEmptySelection(_ui->editColorSchemeButton, _ui->colorSchemeList->selectionModel()); QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); bool isResettable = ColorSchemeManager::instance()->canResetColorScheme(name); _ui->resetColorSchemeButton->setEnabled(isResettable); bool isDeletable = ColorSchemeManager::instance()->isColorSchemeDeletable(name); // if a colorScheme can be restored then it can't be deleted _ui->removeColorSchemeButton->setEnabled(isDeletable && !isResettable); } else { _ui->removeColorSchemeButton->setEnabled(false); _ui->resetColorSchemeButton->setEnabled(false); } } void EditProfileDialog::updateKeyBindingsButtons() { QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { _ui->editKeyBindingsButton->setEnabled(true); const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); bool isResettable = _keyManager->isTranslatorResettable(name); _ui->resetKeyBindingsButton->setEnabled(isResettable); bool isDeletable = _keyManager->isTranslatorDeletable(name); // if a key bindings scheme can be reset then it can't be deleted _ui->removeKeyBindingsButton->setEnabled(isDeletable && !isResettable); } } void EditProfileDialog::enableIfNonEmptySelection(QWidget *widget, QItemSelectionModel *selectionModel) { widget->setEnabled(selectionModel->hasSelection()); } void EditProfileDialog::updateTransparencyWarning() { // zero or one indexes can be selected foreach (const QModelIndex &index, _ui->colorSchemeList->selectionModel()->selectedIndexes()) { bool needTransparency = index.data(Qt::UserRole + 1).value()->opacity() < 1.0; if (!needTransparency) { _ui->transparencyWarningWidget->setHidden(true); } else if (!KWindowSystem::compositingActive()) { _ui->transparencyWarningWidget->setText(i18n( "This color scheme uses a transparent background" " which does not appear to be supported on your" " desktop")); _ui->transparencyWarningWidget->setHidden(false); } else if (!WindowSystemInfo::HAVE_TRANSPARENCY) { _ui->transparencyWarningWidget->setText(i18n( "Konsole was started before desktop effects were enabled." " You need to restart Konsole to see transparent background.")); _ui->transparencyWarningWidget->setHidden(false); } } } void EditProfileDialog::createTempProfile() { _tempProfile = Profile::Ptr(new Profile); _tempProfile->setHidden(true); } void EditProfileDialog::updateTempProfileProperty(Profile::Property property, const QVariant &value) { _tempProfile->setProperty(property, value); updateButtonApply(); } void EditProfileDialog::updateButtonApply() { bool userModified = false; QHashIterator iter(_tempProfile->setProperties()); while (iter.hasNext()) { iter.next(); Profile::Property property = iter.key(); QVariant value = iter.value(); // for previewed property if (_previewedProperties.contains(static_cast(property))) { if (value != _previewedProperties.value(static_cast(property))) { userModified = true; break; } // for not-previewed property // // for the Profile::KeyBindings property, if it's set in the _tempProfile // then the user opened the edit key bindings dialog and clicked // OK, and could have add/removed a key bindings rule } else if (property == Profile::KeyBindings || (value != _profile->property(property))) { userModified = true; break; } } mButtonBox->button(QDialogButtonBox::Apply)->setEnabled(userModified); } void EditProfileDialog::setupKeyboardPage(const Profile::Ptr /* profile */) { // setup translator list updateKeyBindingsList(lookupProfile()->keyBindings()); connect(_ui->keyBindingList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Konsole::EditProfileDialog::keyBindingSelected); connect(_ui->newKeyBindingsButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::newKeyBinding); _ui->editKeyBindingsButton->setEnabled(false); _ui->removeKeyBindingsButton->setEnabled(false); _ui->resetKeyBindingsButton->setEnabled(false); updateKeyBindingsButtons(); connect(_ui->editKeyBindingsButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::editKeyBinding); connect(_ui->removeKeyBindingsButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::removeKeyBinding); connect(_ui->resetKeyBindingsButton, &QPushButton::clicked, this, &Konsole::EditProfileDialog::resetKeyBindings); } void EditProfileDialog::keyBindingSelected() { QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { QAbstractItemModel *model = _ui->keyBindingList->model(); const KeyboardTranslator *translator = model->data(selected.first(), Qt::UserRole + 1) .value(); if (translator != nullptr) { updateTempProfileProperty(Profile::KeyBindings, translator->name()); } } updateKeyBindingsButtons(); } void EditProfileDialog::removeKeyBinding() { QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); if (KeyboardTranslatorManager::instance()->deleteTranslator(name)) { _ui->keyBindingList->model()->removeRow(selected.first().row()); } } } void EditProfileDialog::showKeyBindingEditor(bool isNewTranslator) { QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes(); QAbstractItemModel *model = _ui->keyBindingList->model(); const KeyboardTranslator *translator = nullptr; if (!selected.isEmpty()) { translator = model->data(selected.first(), Qt::UserRole + 1).value(); } else { translator = _keyManager->defaultTranslator(); } Q_ASSERT(translator); auto editor = new KeyBindingEditor(this); if (translator != nullptr) { editor->setup(translator, lookupProfile()->keyBindings(), isNewTranslator); } connect(editor, &Konsole::KeyBindingEditor::updateKeyBindingsListRequest, this, &Konsole::EditProfileDialog::updateKeyBindingsList); connect(editor, &Konsole::KeyBindingEditor::updateTempProfileKeyBindingsRequest, this, &Konsole::EditProfileDialog::updateTempProfileProperty); editor->exec(); } void EditProfileDialog::newKeyBinding() { showKeyBindingEditor(true); } void EditProfileDialog::editKeyBinding() { showKeyBindingEditor(false); } void EditProfileDialog::resetKeyBindings() { QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes(); if (!selected.isEmpty()) { const QString &name = selected.first().data(Qt::UserRole + 1).value()->name(); _keyManager->deleteTranslator(name); // find and load the translator _keyManager->findTranslator(name); updateKeyBindingsList(name); } } void EditProfileDialog::setupCheckBoxes(const QVector& options, const Profile::Ptr profile) { for(const auto& option : options) { option.button->setChecked(profile->property(option.property)); connect(option.button, SIGNAL(toggled(bool)), this, option.slot); } } void EditProfileDialog::setupRadio(const QVector& possibilities, int actual) { for(const auto& possibility : possibilities) { possibility.button->setChecked(possibility.value == actual); connect(possibility.button, SIGNAL(clicked()), this, possibility.slot); } } void EditProfileDialog::setupScrollingPage(const Profile::Ptr profile) { // setup scrollbar radio int scrollBarPosition = profile->property(Profile::ScrollBarPosition); const auto positions = QVector{ {_ui->scrollBarHiddenButton, Enum::ScrollBarHidden, SLOT(hideScrollBar())}, {_ui->scrollBarLeftButton, Enum::ScrollBarLeft, SLOT(showScrollBarLeft())}, {_ui->scrollBarRightButton, Enum::ScrollBarRight, SLOT(showScrollBarRight())}}; setupRadio(positions, scrollBarPosition); // setup scrollback type radio int scrollBackType = profile->property(Profile::HistoryMode); _ui->historySizeWidget->setMode(Enum::HistoryModeEnum(scrollBackType)); connect(_ui->historySizeWidget, &Konsole::HistorySizeWidget::historyModeChanged, this, &Konsole::EditProfileDialog::historyModeChanged); // setup scrollback line count spinner const int historySize = profile->historySize(); _ui->historySizeWidget->setLineCount(historySize); // setup scrollpageamount type radio int scrollFullPage = profile->property(Profile::ScrollFullPage); const auto pageamounts = QVector{ {_ui->scrollHalfPage, Enum::ScrollPageHalf, SLOT(scrollHalfPage())}, {_ui->scrollFullPage, Enum::ScrollPageFull, SLOT(scrollFullPage())} }; setupRadio(pageamounts, scrollFullPage); // signals and slots connect(_ui->historySizeWidget, &Konsole::HistorySizeWidget::historySizeChanged, this, &Konsole::EditProfileDialog::historySizeChanged); } void EditProfileDialog::historySizeChanged(int lineCount) { updateTempProfileProperty(Profile::HistorySize, lineCount); } void EditProfileDialog::historyModeChanged(Enum::HistoryModeEnum mode) { updateTempProfileProperty(Profile::HistoryMode, mode); } void EditProfileDialog::hideScrollBar() { updateTempProfileProperty(Profile::ScrollBarPosition, Enum::ScrollBarHidden); } void EditProfileDialog::showScrollBarLeft() { updateTempProfileProperty(Profile::ScrollBarPosition, Enum::ScrollBarLeft); } void EditProfileDialog::showScrollBarRight() { updateTempProfileProperty(Profile::ScrollBarPosition, Enum::ScrollBarRight); } void EditProfileDialog::scrollFullPage() { updateTempProfileProperty(Profile::ScrollFullPage, Enum::ScrollPageFull); } void EditProfileDialog::scrollHalfPage() { updateTempProfileProperty(Profile::ScrollFullPage, Enum::ScrollPageHalf); } void EditProfileDialog::setupMousePage(const Profile::Ptr profile) { const auto options = QVector{ { _ui->underlineLinksButton, Profile::UnderlineLinksEnabled, SLOT(toggleUnderlineLinks(bool)) }, { _ui->underlineFilesButton, Profile::UnderlineFilesEnabled, SLOT(toggleUnderlineFiles(bool)) }, { _ui->ctrlRequiredForDragButton, Profile::CtrlRequiredForDrag, SLOT(toggleCtrlRequiredForDrag(bool)) }, { _ui->copyTextAsHTMLButton, Profile::CopyTextAsHTML, SLOT(toggleCopyTextAsHTML(bool)) }, { _ui->copyTextToClipboardButton, Profile::AutoCopySelectedText, SLOT(toggleCopyTextToClipboard(bool)) }, { _ui->trimLeadingSpacesButton, Profile::TrimLeadingSpacesInSelectedText, SLOT(toggleTrimLeadingSpacesInSelectedText(bool)) }, { _ui->trimTrailingSpacesButton, Profile::TrimTrailingSpacesInSelectedText, SLOT(toggleTrimTrailingSpacesInSelectedText(bool)) }, { _ui->openLinksByDirectClickButton, Profile::OpenLinksByDirectClickEnabled, SLOT(toggleOpenLinksByDirectClick(bool)) }, { _ui->dropUrlsAsText, Profile::DropUrlsAsText, SLOT(toggleDropUrlsAsText(bool)) }, { _ui->enableAlternateScrollingButton, Profile::AlternateScrolling, SLOT(toggleAlternateScrolling(bool)) } }; setupCheckBoxes(options, profile); // setup middle click paste mode const int middleClickPasteMode = profile->property(Profile::MiddleClickPasteMode); const auto pasteModes = QVector { {_ui->pasteFromX11SelectionButton, Enum::PasteFromX11Selection, SLOT(pasteFromX11Selection())}, {_ui->pasteFromClipboardButton, Enum::PasteFromClipboard, SLOT(pasteFromClipboard())} }; setupRadio(pasteModes, middleClickPasteMode); // interaction options _ui->wordCharacterEdit->setText(profile->wordCharacters()); connect(_ui->wordCharacterEdit, &QLineEdit::textChanged, this, &Konsole::EditProfileDialog::wordCharactersChanged); int tripleClickMode = profile->property(Profile::TripleClickMode); _ui->tripleClickModeCombo->setCurrentIndex(tripleClickMode); connect(_ui->tripleClickModeCombo, static_cast(&KComboBox::activated), this, &Konsole::EditProfileDialog::TripleClickModeChanged); _ui->openLinksByDirectClickButton->setEnabled(_ui->underlineLinksButton->isChecked() || _ui->underlineFilesButton->isChecked()); _ui->enableMouseWheelZoomButton->setChecked(profile->mouseWheelZoomEnabled()); connect(_ui->enableMouseWheelZoomButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::toggleMouseWheelZoom); } void EditProfileDialog::setupAdvancedPage(const Profile::Ptr profile) { const auto options = QVector{ { _ui->enableBlinkingTextButton, Profile::BlinkingTextEnabled, SLOT(toggleBlinkingText(bool)) }, { _ui->enableFlowControlButton, Profile::FlowControlEnabled, SLOT(toggleFlowControl(bool)) }, { _ui->enableBlinkingCursorButton, Profile::BlinkingCursorEnabled, SLOT(toggleBlinkingCursor(bool)) }, { _ui->enableBidiRenderingButton, Profile::BidiRenderingEnabled, SLOT(togglebidiRendering(bool)) }, { _ui->enableReverseUrlHints, Profile::ReverseUrlHints, SLOT(toggleReverseUrlHints(bool)) } }; setupCheckBoxes(options, profile); // Setup the URL hints modifier checkboxes { int modifiers = profile->property(Profile::UrlHintsModifiers); _ui->urlHintsModifierShift->setChecked((modifiers &Qt::ShiftModifier) != 0u); _ui->urlHintsModifierCtrl->setChecked((modifiers &Qt::ControlModifier) != 0u); _ui->urlHintsModifierAlt->setChecked((modifiers &Qt::AltModifier) != 0u); _ui->urlHintsModifierMeta->setChecked((modifiers &Qt::MetaModifier) != 0u); connect(_ui->urlHintsModifierShift, &QCheckBox::toggled, this, &EditProfileDialog::updateUrlHintsModifier); connect(_ui->urlHintsModifierCtrl, &QCheckBox::toggled, this, &EditProfileDialog::updateUrlHintsModifier); connect(_ui->urlHintsModifierAlt, &QCheckBox::toggled, this, &EditProfileDialog::updateUrlHintsModifier); connect(_ui->urlHintsModifierMeta, &QCheckBox::toggled, this, &EditProfileDialog::updateUrlHintsModifier); } const int lineSpacing = profile->lineSpacing(); _ui->lineSpacingSpinner->setValue(lineSpacing); connect(_ui->lineSpacingSpinner, static_cast(&QSpinBox::valueChanged), this, &Konsole::EditProfileDialog::lineSpacingChanged); // cursor options if (profile->useCustomCursorColor()) { _ui->customCursorColorButton->setChecked(true); } else { _ui->autoCursorColorButton->setChecked(true); } _ui->customColorSelectButton->setColor(profile->customCursorColor()); connect(_ui->customCursorColorButton, &QRadioButton::clicked, this, &Konsole::EditProfileDialog::customCursorColor); connect(_ui->autoCursorColorButton, &QRadioButton::clicked, this, &Konsole::EditProfileDialog::autoCursorColor); connect(_ui->customColorSelectButton, &KColorButton::changed, this, &Konsole::EditProfileDialog::customCursorColorChanged); int shape = profile->property(Profile::CursorShape); _ui->cursorShapeCombo->setCurrentIndex(shape); connect(_ui->cursorShapeCombo, static_cast(&KComboBox::activated), this, &Konsole::EditProfileDialog::setCursorShape); // encoding options auto codecAction = new KCodecAction(this); _ui->selectEncodingButton->setMenu(codecAction->menu()); connect(codecAction, static_cast(&KCodecAction::triggered), this, &Konsole::EditProfileDialog::setDefaultCodec); _ui->characterEncodingLabel->setText(profile->defaultEncoding()); } void EditProfileDialog::setDefaultCodec(QTextCodec *codec) { QString name = QString::fromLocal8Bit(codec->name()); updateTempProfileProperty(Profile::DefaultEncoding, name); _ui->characterEncodingLabel->setText(name); } void EditProfileDialog::customCursorColorChanged(const QColor &color) { updateTempProfileProperty(Profile::CustomCursorColor, color); // ensure that custom cursor colors are enabled _ui->customCursorColorButton->click(); } void EditProfileDialog::wordCharactersChanged(const QString &text) { updateTempProfileProperty(Profile::WordCharacters, text); } void EditProfileDialog::autoCursorColor() { updateTempProfileProperty(Profile::UseCustomCursorColor, false); } void EditProfileDialog::customCursorColor() { updateTempProfileProperty(Profile::UseCustomCursorColor, true); } void EditProfileDialog::setCursorShape(int index) { updateTempProfileProperty(Profile::CursorShape, index); } void EditProfileDialog::togglebidiRendering(bool enable) { updateTempProfileProperty(Profile::BidiRenderingEnabled, enable); } void EditProfileDialog::lineSpacingChanged(int spacing) { updateTempProfileProperty(Profile::LineSpacing, spacing); } void EditProfileDialog::toggleBlinkingCursor(bool enable) { updateTempProfileProperty(Profile::BlinkingCursorEnabled, enable); } void EditProfileDialog::toggleUnderlineLinks(bool enable) { updateTempProfileProperty(Profile::UnderlineLinksEnabled, enable); bool enableClick = _ui->underlineFilesButton->isChecked() || enable; _ui->openLinksByDirectClickButton->setEnabled(enableClick); } void EditProfileDialog::toggleUnderlineFiles(bool enable) { updateTempProfileProperty(Profile::UnderlineFilesEnabled, enable); bool enableClick = _ui->underlineLinksButton->isChecked() || enable; _ui->openLinksByDirectClickButton->setEnabled(enableClick); } void EditProfileDialog::toggleCtrlRequiredForDrag(bool enable) { updateTempProfileProperty(Profile::CtrlRequiredForDrag, enable); } void EditProfileDialog::toggleDropUrlsAsText(bool enable) { updateTempProfileProperty(Profile::DropUrlsAsText, enable); } void EditProfileDialog::toggleOpenLinksByDirectClick(bool enable) { updateTempProfileProperty(Profile::OpenLinksByDirectClickEnabled, enable); } void EditProfileDialog::toggleCopyTextAsHTML(bool enable) { updateTempProfileProperty(Profile::CopyTextAsHTML, enable); } void EditProfileDialog::toggleCopyTextToClipboard(bool enable) { updateTempProfileProperty(Profile::AutoCopySelectedText, enable); } void EditProfileDialog::toggleTrimLeadingSpacesInSelectedText(bool enable) { updateTempProfileProperty(Profile::TrimLeadingSpacesInSelectedText, enable); } void EditProfileDialog::toggleTrimTrailingSpacesInSelectedText(bool enable) { updateTempProfileProperty(Profile::TrimTrailingSpacesInSelectedText, enable); } void EditProfileDialog::pasteFromX11Selection() { updateTempProfileProperty(Profile::MiddleClickPasteMode, Enum::PasteFromX11Selection); } void EditProfileDialog::pasteFromClipboard() { updateTempProfileProperty(Profile::MiddleClickPasteMode, Enum::PasteFromClipboard); } void EditProfileDialog::TripleClickModeChanged(int newValue) { updateTempProfileProperty(Profile::TripleClickMode, newValue); } void EditProfileDialog::updateUrlHintsModifier(bool) { Qt::KeyboardModifiers modifiers; if (_ui->urlHintsModifierShift->isChecked()) { modifiers |= Qt::ShiftModifier; } if (_ui->urlHintsModifierCtrl->isChecked()) { modifiers |= Qt::ControlModifier; } if (_ui->urlHintsModifierAlt->isChecked()) { modifiers |= Qt::AltModifier; } if (_ui->urlHintsModifierMeta->isChecked()) { modifiers |= Qt::MetaModifier; } updateTempProfileProperty(Profile::UrlHintsModifiers, int(modifiers)); } void EditProfileDialog::toggleReverseUrlHints(bool enable) { updateTempProfileProperty(Profile::ReverseUrlHints, enable); } void EditProfileDialog::toggleBlinkingText(bool enable) { updateTempProfileProperty(Profile::BlinkingTextEnabled, enable); } void EditProfileDialog::toggleFlowControl(bool enable) { updateTempProfileProperty(Profile::FlowControlEnabled, enable); } void EditProfileDialog::fontSelected(const QFont &aFont) { QFont previewFont = aFont; setFontInputValue(aFont); _ui->fontPreviewLabel->setFont(previewFont); preview(Profile::Font, aFont); updateTempProfileProperty(Profile::Font, aFont); } void EditProfileDialog::showFontDialog() { QFont currentFont = _ui->fontPreviewLabel->font(); bool showAllFonts = _ui->showAllFontsButton->isChecked(); bool result; if (showAllFonts) { currentFont = QFontDialog::getFont(&result, currentFont, this, i18n("Select Any Font")); } else { currentFont = QFontDialog::getFont(&result, currentFont, this, i18n("Select Fixed Width Font"), QFontDialog::MonospacedFonts); } if (!result) { return; } fontSelected(currentFont); } void EditProfileDialog::setFontSize(double pointSize) { QFont newFont = _ui->fontPreviewLabel->font(); newFont.setPointSizeF(pointSize); _ui->fontPreviewLabel->setFont(newFont); preview(Profile::Font, newFont); updateTempProfileProperty(Profile::Font, newFont); } void EditProfileDialog::setFontInputValue(const QFont &aFont) { _ui->fontSizeInput->setValue(aFont.pointSizeF()); } ColorSchemeViewDelegate::ColorSchemeViewDelegate(QObject *aParent) : QAbstractItemDelegate(aParent) { } void ColorSchemeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const ColorScheme *scheme = index.data(Qt::UserRole + 1).value(); QFont profileFont = index.data(Qt::UserRole + 2).value(); Q_ASSERT(scheme); if (scheme == nullptr) { return; } painter->setRenderHint(QPainter::Antialiasing); // Draw background QStyle *style = option.widget != nullptr ? option.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, option.widget); // Draw name QPalette::ColorRole textColor = ((option.state & QStyle::State_Selected) != 0) ? QPalette::HighlightedText : QPalette::Text; painter->setPen(option.palette.color(textColor)); painter->setFont(option.font); // Determine width of sample text using profile's font const QString sampleText = i18n("AaZz09..."); QFontMetrics profileFontMetrics(profileFont); const int sampleTextWidth = profileFontMetrics.width(sampleText); painter->drawText(option.rect.adjusted(sampleTextWidth + 15, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, index.data(Qt::DisplayRole).toString()); // Draw the preview const int x = option.rect.left(); const int y = option.rect.top(); QRect previewRect(x + 4, y + 4, sampleTextWidth + 8, option.rect.height() - 8); bool transparencyAvailable = KWindowSystem::compositingActive(); if (transparencyAvailable) { painter->save(); QColor color = scheme->backgroundColor(); color.setAlphaF(scheme->opacity()); painter->setPen(Qt::NoPen); painter->setCompositionMode(QPainter::CompositionMode_Source); painter->setBrush(color); painter->drawRect(previewRect); painter->restore(); } else { painter->setPen(Qt::NoPen); painter->setBrush(scheme->backgroundColor()); painter->drawRect(previewRect); } // draw color scheme name using scheme's foreground color QPen pen(scheme->foregroundColor()); painter->setPen(pen); // TODO: respect antialias setting painter->setFont(profileFont); painter->drawText(previewRect, Qt::AlignCenter, sampleText); } QSize ColorSchemeViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex & /*index*/) const { const int width = 200; const int margin = 5; const int colorWidth = width / TABLE_COLORS; const int heightForWidth = (colorWidth * 2) + option.fontMetrics.height() + margin; // temporary return QSize(width, heightForWidth); } diff --git a/src/EditProfileDialog.h b/src/EditProfileDialog.h index d97edb22..994f8eda 100644 --- a/src/EditProfileDialog.h +++ b/src/EditProfileDialog.h @@ -1,319 +1,332 @@ /* Copyright 2007-2008 by Robert Knight Copyright 2018 by Harald Sitter 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 EDITPROFILEDIALOG_H #define EDITPROFILEDIALOG_H +// config +#include "config-konsole.h" + // Qt #include #include #include #include // KDE +#ifndef WITHOUT_KNEWSTUFF #include +#include +#endif // Konsole #include "Profile.h" #include "Enumeration.h" #include "ColorScheme.h" #include "ColorSchemeEditor.h" #include "KeyboardTranslatorManager.h" class QAbstractButton; class QItemSelectionModel; class QTextCodec; class QDialogButtonBox; namespace Ui { class EditProfileDialog; } namespace Konsole { /** * A dialog which allows the user to edit a profile. * After the dialog is created, it can be initialized with the settings * for a profile using setProfile(). When the user makes changes to the * dialog and accepts the changes, the dialog will update the * profile in the SessionManager by calling the SessionManager's * changeProfile() method. * * Some changes made in the dialog are preview-only changes which cause * the SessionManager's changeProfile() method to be called with * the persistent argument set to false. These changes are then * un-done when the dialog is closed. */ class KONSOLEPRIVATE_EXPORT EditProfileDialog : public QDialog { Q_OBJECT public: /** Constructs a new dialog with the specified parent. */ explicit EditProfileDialog(QWidget *parent = nullptr); ~EditProfileDialog() Q_DECL_OVERRIDE; /** * Initializes the dialog with the settings for the specified session * type. * * When the dialog closes, the profile will be updated in the SessionManager * with the altered settings. * * @param profile The profile to be edited */ void setProfile(Profile::Ptr profile); /** * Selects the text in the profile name edit area. * When the dialog is being used to create a new profile, * this can be used to draw the user's attention to the profile name * and make it easy for them to change it. */ void selectProfileName(); const Profile::Ptr lookupProfile() const; public Q_SLOTS: // reimplemented void accept() Q_DECL_OVERRIDE; // reimplemented void reject() Q_DECL_OVERRIDE; void apply(); protected: bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: // sets up the specified tab page if necessary void preparePage(int); // saves changes to profile void save(); // general page void selectInitialDir(); void selectIcon(); void profileNameChanged(const QString &name); void initialDirChanged(const QString &dir); void startInSameDir(bool); void commandChanged(const QString &command); void tabTitleFormatChanged(const QString &format); void remoteTabTitleFormatChanged(const QString &format); void terminalColumnsEntryChanged(int); void terminalRowsEntryChanged(int); void showTerminalSizeHint(bool); void showEnvironmentEditor(); void silenceSecondsChanged(int); // appearance page void setFontSize(double pointSize); void setFontInputValue(const QFont &); void showAllFontsButtonWarning(bool enable); void setAntialiasText(bool enable); void setBoldIntense(bool enable); void useFontLineCharacters(bool enable); void showFontDialog(); void newColorScheme(); void editColorScheme(); void saveColorScheme(const ColorScheme &scheme, bool isNewScheme); void removeColorScheme(); + +#ifndef WITHOUT_KNEWSTUFF void gotNewColorSchemes(const KNS3::Entry::List &changedEntries); +#endif /** * Deletes the selected colorscheme from the user's home dir location * so that the original one from the system-wide location can be used * instead */ void resetColorScheme(); void colorSchemeSelected(); void previewColorScheme(const QModelIndex &index); void fontSelected(const QFont &); void toggleMouseWheelZoom(bool enable); // scrolling page void historyModeChanged(Enum::HistoryModeEnum mode); void historySizeChanged(int); void hideScrollBar(); void showScrollBarLeft(); void showScrollBarRight(); void scrollFullPage(); void scrollHalfPage(); // keyboard page void editKeyBinding(); void newKeyBinding(); void keyBindingSelected(); void removeKeyBinding(); void resetKeyBindings(); // mouse page void toggleUnderlineFiles(bool enable); void toggleUnderlineLinks(bool); void toggleOpenLinksByDirectClick(bool); void toggleCtrlRequiredForDrag(bool); void toggleDropUrlsAsText(bool); void toggleCopyTextToClipboard(bool); void toggleCopyTextAsHTML(bool); void toggleTrimLeadingSpacesInSelectedText(bool); void toggleTrimTrailingSpacesInSelectedText(bool); void pasteFromX11Selection(); void pasteFromClipboard(); void toggleAlternateScrolling(bool enable); void TripleClickModeChanged(int); void wordCharactersChanged(const QString &); // advanced page void toggleBlinkingText(bool); void toggleFlowControl(bool); void togglebidiRendering(bool); void lineSpacingChanged(int); void toggleBlinkingCursor(bool); void updateUrlHintsModifier(bool); void toggleReverseUrlHints(bool); void setCursorShape(int); void autoCursorColor(); void customCursorColor(); void customCursorColorChanged(const QColor &); void setDefaultCodec(QTextCodec *); // apply the first previewed changes stored up by delayedPreview() void delayedPreviewActivate(); private: Q_DISABLE_COPY(EditProfileDialog) // initialize various pages of the dialog void setupGeneralPage(const Profile::Ptr profile); void setupTabsPage(const Profile::Ptr profile); void setupAppearancePage(const Profile::Ptr profile); void setupKeyboardPage(const Profile::Ptr profile); void setupScrollingPage(const Profile::Ptr profile); void setupAdvancedPage(const Profile::Ptr profile); void setupMousePage(const Profile::Ptr info); // Returns the name of the colorScheme used in the current profile const QString currentColorSchemeName() const; // select @p selectedColorSchemeName after the changes are saved // in the colorScheme editor void updateColorSchemeList(const QString &selectedColorSchemeName = QString()); void updateColorSchemeButtons(); // Convenience method KeyboardTranslatorManager *_keyManager = KeyboardTranslatorManager::instance(); // Updates the key bindings list widget on the Keyboard tab and selects // @p selectTranslatorName void updateKeyBindingsList(const QString &selectTranslatorName = QString()); void updateKeyBindingsButtons(); void showKeyBindingEditor(bool isNewTranslator); void showColorSchemeEditor(bool isNewScheme); void closeColorSchemeEditor(); void preview(int property, const QVariant &value); void delayedPreview(int property, const QVariant &value); void unpreview(int property); void unpreviewAll(); void enableIfNonEmptySelection(QWidget *widget, QItemSelectionModel *selectionModel); void updateCaption(const Profile::Ptr profile); void updateTransparencyWarning(); // Update _tempProfile in a way of respecting the apply button. // When used with some previewed property, this method should // always come after the preview operation. void updateTempProfileProperty(Profile::Property, const QVariant &value); // helper method for creating an empty & hidden profile and assigning // it to _tempProfile. void createTempProfile(); // Enable or disable apply button, used only within // updateTempProfileProperty(). void updateButtonApply(); static QString groupProfileNames(const ProfileGroup::Ptr group, int maxLength = -1); struct RadioOption { QAbstractButton *button; int value; const char *slot; }; void setupRadio(const QVector& possibilities, int actual); struct BooleanOption { QAbstractButton *button; Profile::Property property; const char *slot; }; void setupCheckBoxes(const QVector& options, const Profile::Ptr profile); // returns false if: // - the profile name is empty // - the name matches the name of an already existing profile // - the existing profile config file is read-only // otherwise returns true. bool isValidProfileName(); Ui::EditProfileDialog *_ui; Profile::Ptr _tempProfile; Profile::Ptr _profile; // keeps track of pages which need to be updated to match the current // profile. all elements in this vector are set to true when the // profile is changed and individual elements are set to false // after an update by a call to ensurePageLoaded() QVector _pageNeedsUpdate; QHash _previewedProperties; QHash _delayedPreviewProperties; QTimer *_delayedPreviewTimer; ColorSchemeEditor *_colorDialog; QDialogButtonBox *mButtonBox; + +#ifndef WITHOUT_KNEWSTUFF + KNS3::Button *_downloadColorSchemeButton; +#endif }; /** * A delegate which can display and edit color schemes in a view. */ class ColorSchemeViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: explicit ColorSchemeViewDelegate(QObject *parent = nullptr); // reimplemented 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; }; } #endif // EDITPROFILEDIALOG_H diff --git a/src/EditProfileDialog.ui b/src/EditProfileDialog.ui index 480f7927..18896113 100644 --- a/src/EditProfileDialog.ui +++ b/src/EditProfileDialog.ui @@ -1,1576 +1,1564 @@ EditProfileDialog 0 0 594 536 0 0 0 0 0 0 0 true General General true 0 0 64 64 0 0 Select the icon displayed on tabs using this profile 48 48 Qt::Horizontal QSizePolicy::Fixed 20 20 Profile name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter A descriptive name for the profile Command: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter The command to execute when new terminal sessions are created using this profile Qt::LeftToRight Initial directory: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter The initial working directory for new terminal sessions using this profile Qt::LeftToRight Choose the initial directory ... Start in same directory as current tab Environment: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit the list of environment variables and associated values Edit... Qt::Horizontal 81 20 Terminal Size true Columns 1 500 Rows 1 Qt::Horizontal QSizePolicy::Fixed 40 20 This will not alter any open windows. Qt::Horizontal 81 20 Qt::Horizontal QSizePolicy::Fixed 40 20 Configure Konsole->General->Use current window size on next startup must be disabled for these entries to work. true Window true Show terminal size in columns and lines in the center of window after resizing Show hint for terminal size after resizing Qt::Vertical 20 20 Tabs Tab Titles true Tab Monitoring true Threshold for continuous silence: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter The threshold for continuous silence to be detected by Konsole 1 3600 Qt::Horizontal 20 20 Qt::Vertical 20 10 Appearance 0 1 Color Scheme && Background true Reset the selected color scheme settings to the default values Defaults Delete the selected color scheme Remove QAbstractItemView::ScrollPerPixel - - - - Get New... - - - Create a new color scheme based upon the selected scheme New... Qt::Vertical 20 20 Edit the selected color scheme Edit... QFrame::StyledPanel QFrame::Raised Font true Preview: 1 0 KSqueezedTextLabel Qt::ElideRight Text size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 4.000000000000000 999.000000000000000 1.000000000000000 Select the font used in this profile Select Font... Show all fonts instead of the monospaced fonts Show All Fonts Qt::Horizontal 40 20 Smooth fonts Draw intense colors in bold font Use the selected font for line characters instead of the builtin code Use line characters contained in font Scrolling Scrollback true Scroll Bar true 0 0 Hide the scroll bar Hide 0 0 Show the scroll bar on the left side of the terminal window Show on left side 0 0 Show the scroll bar on the right side of the terminal window Show on right side Scroll Page Up/Down Amount true Scroll the page the half height of window Half Page Height Scroll the page the full height of window Full Page Height Qt::Vertical 20 1 Keyboard Key Bindings true Key bindings control how combinations of keystrokes in the terminal window are converted into the stream of characters that is then sent to the current terminal program. For more information on how to customize the key bindings check the Konsole Handbook. true 32 32 Create a new key bindings scheme based upon the selected bindings New... Edit the selected key bindings scheme Edit... Delete the selected key bindings scheme Remove Qt::Vertical 20 20 Reset the selected key bindings scheme to its default values Defaults Mouse Select Text true Characters considered part of a word when double clicking: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Characters which are considered part of a word when double-clicking to select whole words in the terminal Triple-click select: Which part of current line should be selected with triple click . The whole current line From mouse position to the end of line Copy && Paste true Trim leading spaces in selected text, useful in some instances Trim leading spaces Trim trailing spaces in selected text, useful in some instances Trim trailing spaces Mouse middle button: Paste from clipboard Paste from selection Automatically copy selected text into clipboard Copy on select Copy text as HTML (including formatting, font faces, colors... etc) Copy text as HTML Miscellaneous true Text recognized as a file will be underlined when hovered by the mouse pointer. Underline files Selected text will require control key plus click to drag. Require Ctrl key for drag && drop Always paste dropped files and URLs as text without offering move, copy and link actions. Disable drag && drop menu for files && URLs Mouse scroll wheel will emulate up/down key presses in programs that use the Alternate Screen buffer (e.g. less) Enable Alternate Screen buffer scrolling Qt::Horizontal QSizePolicy::Fixed 10 20 false 0 0 Text recognized as a file, link or an email address can be opened by direct mouse click. Open by direct click Text recognized as a link or an email address will be underlined when hovered by the mouse pointer. Underline links Pressing Ctrl+scrollwheel will increase/decrease the text size. Allow Ctrl+scrollwheel to zoom text size Advanced Terminal Features true Show URL hints when these keys are pressed: Qt::Horizontal QSizePolicy::Fixed 20 20 Shift Control Alt Meta Number URL hints in reverse, starting from the bottom Reverse URL hint numbering 0 0 Allow terminal programs to create blinking sections of text Allow blinking text 0 0 Allow the output to be suspended by pressing Ctrl+S Enable flow control using Ctrl+S, Ctrl+Q 0 0 Enable Bi-Directional display on terminals (valid for Arabic, Farsi or Hebrew only) Enable Bi-Directional text rendering Line Spacing: The number of pixels between two lines 0 5 Qt::Horizontal 40 20 Cursor true 0 0 Make the cursor blink regularly Blinking cursor Cursor shape: Change the shape of the cursor Block I-Beam Underline Qt::Horizontal 40 20 0 0 Set the cursor to match the color of the character underneath it. Set cursor color to match current character 0 0 Use a custom, fixed color for the cursor Custom cursor color: 0 0 Select the color used to draw the cursor Qt::Horizontal 40 20 Encoding true Default character encoding: 0 0 DEFAULTENCODING Select Qt::Vertical 20 20 KComboBox QComboBox
kcombobox.h
- - KNS3::Button - QPushButton -
KNS3/Button
-
KColorButton QPushButton
kcolorbutton.h
KSqueezedTextLabel QLabel
ksqueezedtextlabel.h
KMessageWidget QFrame
kmessagewidget.h
1
Konsole::RenameTabWidget QWidget
RenameTabWidget.h
Konsole::HistorySizeWidget QWidget
HistorySizeWidget.h
diff --git a/src/config-konsole.h.cmake b/src/config-konsole.h.cmake index 70773748..95bc8fa0 100644 --- a/src/config-konsole.h.cmake +++ b/src/config-konsole.h.cmake @@ -1,14 +1,15 @@ #define KONSOLE_VERSION "${KDE_APPLICATIONS_VERSION}" /* Defined if you want detaching enabled */ #cmakedefine ENABLE_DETACHING 1 /* Defined if on DragonFly BSD */ #cmakedefine HAVE_OS_DRAGONFLYBSD 1 #cmakedefine01 HAVE_X11 /* If defined, remove public access to dbus sendInput/runCommand */ #cmakedefine REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS #cmakedefine WITHOUT_KNOTIFY +#cmakedefine WITHOUT_KNEWSTUFF