diff --git a/src/EditProfileDialog.cpp b/src/EditProfileDialog.cpp index f250d21b..842c4ef8 100644 --- a/src/EditProfileDialog.cpp +++ b/src/EditProfileDialog.cpp @@ -1,1363 +1,1365 @@ /* Copyright 2007-2008 by Robert Knight 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 // KDE #include #if KDE_IS_VERSION(4, 9, 1) #include #else #include #endif #include #include #include #include #include #include #include #include #include #include // Konsole #include "ColorScheme.h" #include "ColorSchemeManager.h" #include "ColorSchemeEditor.h" #include "ui_EditProfileDialog.h" #include "KeyBindingEditor.h" #include "KeyboardTranslator.h" #include "KeyboardTranslatorManager.h" #include "ProfileManager.h" #include "ShellCommand.h" #include "WindowSystemInfo.h" #include "Enumeration.h" using namespace Konsole; EditProfileDialog::EditProfileDialog(QWidget* aParent) : KDialog(aParent) , _delayedPreviewTimer(new QTimer(this)) , _colorDialog(0) { setCaption(i18n("Edit Profile")); setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Apply); // disable the apply button , since no modification has been made enableButtonApply(false); connect(this, SIGNAL(applyClicked()), this, SLOT(save())); connect(_delayedPreviewTimer, SIGNAL(timeout()), this, SLOT(delayedPreviewActivate())); _ui = new Ui::EditProfileDialog(); _ui->setupUi(mainWidget()); // 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, SIGNAL(currentChanged(int)), this, SLOT(preparePage(int))); 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(); enableButtonApply(false); } void EditProfileDialog::reject() { unpreviewAll(); KDialog::reject(); } void EditProfileDialog::accept() { Q_ASSERT(_profile); Q_ASSERT(_tempProfile); 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.

")); return; } save(); unpreviewAll(); KDialog::accept(); } 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 += ','; // limit caption length to prevent very long window titles if (maxLength > 0 && caption.length() > maxLength) { caption += "..."; 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); setCaption(i18np("Editing profile: %2", "Editing %1 profiles: %2", group->profiles().count(), caption)); } else { setCaption(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; } 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->emptyNameWarningWidget->setWordWrap(false); _ui->emptyNameWarningWidget->setCloseButtonVisible(false); _ui->emptyNameWarningWidget->setMessageType(KMessageWidget::Warning); ProfileGroup::Ptr group = profile->asGroup(); if (!group || group->profiles().count() < 2) { _ui->profileNameEdit->setText(profile->name()); - _ui->profileNameEdit->setClearButtonShown(true); + _ui->profileNameEdit->setClearButtonEnabled(true); _ui->emptyNameWarningWidget->setVisible(profile->name().isEmpty()); _ui->emptyNameWarningWidget->setText(i18n("Profile name is empty.")); } else { _ui->profileNameEdit->setText(groupProfileNames(group, -1)); _ui->profileNameEdit->setEnabled(false); _ui->profileNameLabel->setEnabled(false); _ui->emptyNameWarningWidget->setVisible(false); } } ShellCommand command(profile->command() , profile->arguments()); _ui->commandEdit->setText(command.fullCommand()); - KUrlCompletion* exeCompletion = new KUrlCompletion(KUrlCompletion::ExeCompletion); - exeCompletion->setParent(this); - exeCompletion->setDir(QUrl()); - _ui->commandEdit->setCompletionObject(exeCompletion); +#pragma message("Look at this setCompletionObject again") +// KUrlCompletion* exeCompletion = new KUrlCompletion(KUrlCompletion::ExeCompletion); +// exeCompletion->setParent(this); +// exeCompletion->setDir(QUrl()); +// _ui->commandEdit->setCompletionObject(exeCompletion); _ui->initialDirEdit->setText(profile->defaultWorkingDirectory()); - KUrlCompletion* dirCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); - dirCompletion->setParent(this); - _ui->initialDirEdit->setCompletionObject(dirCompletion); - _ui->initialDirEdit->setClearButtonShown(true); +#pragma message("Look at this setCompletionObject again") +// KUrlCompletion* dirCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); +// dirCompletion->setParent(this); +// _ui->initialDirEdit->setCompletionObject(dirCompletion); + _ui->initialDirEdit->setClearButtonEnabled(true); _ui->dirSelectButton->setIcon(KIcon("folder-open")); _ui->iconSelectButton->setIcon(KIcon(profile->icon())); _ui->startInSameDirButton->setChecked(profile->startInCurrentSessionDir()); // window options _ui->showTerminalSizeHintButton->setChecked(profile->showTerminalSizeHint()); _ui->saveGeometryOnExitButton->setChecked(profile->saveGeometryOnExit()); // signals and slots connect(_ui->dirSelectButton, SIGNAL(clicked()), this, SLOT(selectInitialDir())); connect(_ui->iconSelectButton, SIGNAL(clicked()), this, SLOT(selectIcon())); connect(_ui->startInSameDirButton, SIGNAL(toggled(bool)), this , SLOT(startInSameDir(bool))); connect(_ui->profileNameEdit, SIGNAL(textChanged(QString)), this, SLOT(profileNameChanged(QString))); connect(_ui->initialDirEdit, SIGNAL(textChanged(QString)), this, SLOT(initialDirChanged(QString))); connect(_ui->commandEdit, SIGNAL(textChanged(QString)), this, SLOT(commandChanged(QString))); connect(_ui->environmentEditButton , SIGNAL(clicked()), this, SLOT(showEnvironmentEditor())); connect(_ui->saveGeometryOnExitButton, SIGNAL(toggled(bool)), this, SLOT(saveGeometryOnExit(bool))); connect(_ui->showTerminalSizeHintButton, SIGNAL(toggled(bool)), this, SLOT(showTerminalSizeHint(bool))); } void EditProfileDialog::showEnvironmentEditor() { const Profile::Ptr profile = lookupProfile(); QWeakPointer dialog = new KDialog(this); KTextEdit* edit = new KTextEdit(dialog.data()); QStringList currentEnvironment = profile->environment(); edit->setPlainText(currentEnvironment.join("\n")); edit->setToolTip(i18nc("@info:tooltip", "One environment variable per line")); dialog.data()->setPlainCaption(i18n("Edit Environment")); dialog.data()->setMainWidget(edit); if (dialog.data()->exec() == QDialog::Accepted) { QStringList newEnvironment = edit->toPlainText().split('\n'); updateTempProfileProperty(Profile::Environment, newEnvironment); } delete dialog.data(); } void EditProfileDialog::setupTabsPage(const Profile::Ptr profile) { // tab title format _ui->renameTabWidget->setTabTitleText(profile->localTabTitleFormat()); _ui->renameTabWidget->setRemoteTabTitleText(profile->remoteTabTitleFormat()); connect(_ui->renameTabWidget, SIGNAL(tabTitleFormatChanged(QString)), this, SLOT(tabTitleFormatChanged(QString))); connect(_ui->renameTabWidget, SIGNAL(remoteTabTitleFormatChanged(QString)), this, SLOT(remoteTabTitleFormatChanged(QString))); // tab monitoring const int silenceSeconds = profile->silenceSeconds(); _ui->silenceSecondsSpinner->setValue(silenceSeconds); _ui->silenceSecondsSpinner->setSuffix(ki18ncp("Unit of time", " second", " seconds")); connect(_ui->silenceSecondsSpinner, SIGNAL(valueChanged(int)), this, SLOT(silenceSecondsChanged(int))); } void EditProfileDialog::saveGeometryOnExit(bool value) { updateTempProfileProperty(Profile::SaveGeometryOnExit, 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(KIcon(icon)); updateTempProfileProperty(Profile::Icon, icon); } } void EditProfileDialog::profileNameChanged(const QString& text) { _ui->emptyNameWarningWidget->setVisible(text.isEmpty()); updateTempProfileProperty(Profile::Name, text); updateTempProfileProperty(Profile::UntranslatedName, text); 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() { #pragma message("Fix crashes with KFileDialog") const KUrl url = KFileDialog::getExistingDirectoryUrl(KUrl(_ui->initialDirEdit->text()), this, i18n("Select Initial Directory")); if (!url.isEmpty()) _ui->initialDirEdit->setText(url.path()); } void EditProfileDialog::setupAppearancePage(const Profile::Ptr profile) { ColorSchemeViewDelegate* 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->editColorSchemeButton->setEnabled(false); _ui->removeColorSchemeButton->setEnabled(false); // setup color list updateColorSchemeList(true); _ui->colorSchemeList->setMouseTracking(true); _ui->colorSchemeList->installEventFilter(this); _ui->colorSchemeList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); connect(_ui->colorSchemeList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(colorSchemeSelected())); connect(_ui->colorSchemeList, SIGNAL(entered(QModelIndex)), this, SLOT(previewColorScheme(QModelIndex))); updateColorSchemeButtons(); connect(_ui->editColorSchemeButton, SIGNAL(clicked()), this, SLOT(editColorScheme())); connect(_ui->removeColorSchemeButton, SIGNAL(clicked()), this, SLOT(removeColorScheme())); connect(_ui->newColorSchemeButton, SIGNAL(clicked()), this, SLOT(newColorScheme())); // 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); connect(_ui->fontSizeInput, SIGNAL(valueChanged(double)), this, SLOT(setFontSize(double))); connect(_ui->selectFontButton, SIGNAL(clicked()), this, SLOT(showFontDialog())); // setup font smoothing _ui->antialiasTextButton->setChecked(antialias); connect(_ui->antialiasTextButton, SIGNAL(toggled(bool)), this, SLOT(setAntialiasText(bool))); _ui->boldIntenseButton->setChecked(profile->boldIntense()); connect(_ui->boldIntenseButton, SIGNAL(toggled(bool)), this, SLOT(setBoldIntense(bool))); _ui->enableMouseWheelZoomButton->setChecked(profile->mouseWheelZoomEnabled()); connect(_ui->enableMouseWheelZoomButton, SIGNAL(toggled(bool)), this, SLOT(toggleMouseWheelZoom(bool))); } 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::toggleMouseWheelZoom(bool enable) { updateTempProfileProperty(Profile::MouseWheelZoomEnabled, enable); } void EditProfileDialog::updateColorSchemeList(bool selectCurrentScheme) { if (!_ui->colorSchemeList->model()) _ui->colorSchemeList->setModel(new QStandardItemModel(this)); const QString& name = lookupProfile()->colorScheme(); const ColorScheme* currentScheme = ColorSchemeManager::instance()->findColorScheme(name); QStandardItemModel* model = qobject_cast(_ui->colorSchemeList->model()); Q_ASSERT(model); model->clear(); QStandardItem* selectedItem = 0; 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->setFlags(item->flags()); if (currentScheme == scheme) selectedItem = item; model->appendRow(item); } model->sort(0); if (selectCurrentScheme && selectedItem) { _ui->colorSchemeList->updateGeometry(); _ui->colorSchemeList->selectionModel()->setCurrentIndex(selectedItem->index() , QItemSelectionModel::Select); // update transparency warning label updateTransparencyWarning(); } } void EditProfileDialog::updateKeyBindingsList(bool selectCurrentTranslator) { if (!_ui->keyBindingList->model()) _ui->keyBindingList->setModel(new QStandardItemModel(this)); const QString& name = lookupProfile()->keyBindings(); KeyboardTranslatorManager* keyManager = KeyboardTranslatorManager::instance(); const KeyboardTranslator* currentTranslator = keyManager->findTranslator(name); QStandardItemModel* model = qobject_cast(_ui->keyBindingList->model()); Q_ASSERT(model); model->clear(); QStandardItem* selectedItem = 0; QStringList translatorNames = keyManager->allTranslators(); foreach(const QString& translatorName, translatorNames) { const KeyboardTranslator* translator = keyManager->findTranslator(translatorName); QStandardItem* item = new QStandardItem(translator->description()); item->setEditable(false); item->setData(QVariant::fromValue(translator), Qt::UserRole + 1); item->setIcon(KIcon("preferences-desktop-keyboard")); if (translator == currentTranslator) selectedItem = item; model->appendRow(item); } model->sort(0); if (selectCurrentTranslator && selectedItem) { _ui->keyBindingList->selectionModel()->setCurrentIndex(selectedItem->index() , QItemSelectionModel::Select); } } bool EditProfileDialog::eventFilter(QObject* watched , QEvent* aEvent) { if (watched == _ui->colorSchemeList && aEvent->type() == QEvent::Leave) { if (_tempProfile->isPropertySet(Profile::ColorScheme)) preview(Profile::ColorScheme, _tempProfile->colorScheme()); else unpreview(Profile::ColorScheme); } if (watched == _ui->fontPreviewLabel && aEvent->type() == QEvent::FontChange) { const QFont& labelFont = _ui->fontPreviewLabel->font(); _ui->fontPreviewLabel->setText(i18n("%1", labelFont.family())); } return KDialog::eventFilter(watched, aEvent); } void EditProfileDialog::unpreviewAll() { _delayedPreviewTimer->stop(); _delayedPreviewProperties.clear(); QHash map; QHashIterator iter(_previewedProperties); while (iter.hasNext()) { iter.next(); map.insert((Profile::Property)iter.key(), iter.value()); } // undo any preview changes if (!map.isEmpty()) ProfileManager::instance()->changeProfile(_profile, map, false); } void EditProfileDialog::unpreview(int aProperty) { _delayedPreviewProperties.remove(aProperty); if (!_previewedProperties.contains(aProperty)) return; QHash map; map.insert((Profile::Property)aProperty, _previewedProperties[aProperty]); ProfileManager::instance()->changeProfile(_profile, map, false); _previewedProperties.remove(aProperty); } void EditProfileDialog::delayedPreview(int aProperty , const QVariant& value) { _delayedPreviewProperties.insert(aProperty, 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 aProperty , const QVariant& value) { QHash map; map.insert((Profile::Property)aProperty, value); _delayedPreviewProperties.remove(aProperty); 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((Profile::Property)aProperty).isNull()) return; if (!_previewedProperties.contains(aProperty)) { _previewedProperties.insert(aProperty , original->property((Profile::Property)aProperty)); } // 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()) { const QString& name = selected.first().data(Qt::UserRole + 1).value()->name(); if (ColorSchemeManager::instance()->deleteColorScheme(name)) _ui->colorSchemeList->model()->removeRow(selected.first().row()); } } void EditProfileDialog::showColorSchemeEditor(bool isNewScheme) { // Finding selected ColorScheme QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes(); QAbstractItemModel* model = _ui->colorSchemeList->model(); const ColorScheme* colors = 0; 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) { closeColorSchemeEditor(); } _colorDialog = new ColorSchemeEditor(this); connect(_colorDialog, SIGNAL(colorSchemeSaveRequested(ColorScheme,bool)), this, SLOT(saveColorScheme(ColorScheme,bool))); _colorDialog->setup(colors, isNewScheme); _colorDialog->show(); } void EditProfileDialog::closeColorSchemeEditor() { if (_colorDialog) { _colorDialog->close(); delete _colorDialog; } } void EditProfileDialog::newColorScheme() { showColorSchemeEditor(true); } void EditProfileDialog::editColorScheme() { showColorSchemeEditor(false); } void EditProfileDialog::saveColorScheme(const ColorScheme& scheme, bool isNewScheme) { ColorScheme* 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); updateColorSchemeList(true); 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) { updateTempProfileProperty(Profile::ColorScheme, colors->name()); previewColorScheme(selected.first()); updateTransparencyWarning(); } } updateColorSchemeButtons(); } void EditProfileDialog::updateColorSchemeButtons() { enableIfNonEmptySelection(_ui->editColorSchemeButton, _ui->colorSchemeList->selectionModel()); enableIfNonEmptySelection(_ui->removeColorSchemeButton, _ui->colorSchemeList->selectionModel()); } void EditProfileDialog::updateKeyBindingsButtons() { enableIfNonEmptySelection(_ui->editKeyBindingsButton, _ui->keyBindingList->selectionModel()); enableIfNonEmptySelection(_ui->removeKeyBindingsButton, _ui->keyBindingList->selectionModel()); } 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 aProperty, const QVariant & value) { _tempProfile->setProperty(aProperty, value); updateButtonApply(); } void EditProfileDialog::updateButtonApply() { bool userModified = false; QHashIterator iter(_tempProfile->setProperties()); while (iter.hasNext()) { iter.next(); Profile::Property aProperty = iter.key(); QVariant value = iter.value(); // for previewed property if (_previewedProperties.contains(static_cast(aProperty))) { if (value != _previewedProperties.value(static_cast(aProperty))) { userModified = true; break; } // for not-previewed property } else if ((value != _profile->property(aProperty))) { userModified = true; break; } } enableButtonApply(userModified); } void EditProfileDialog::setupKeyboardPage(const Profile::Ptr /* profile */) { // setup translator list updateKeyBindingsList(true); connect(_ui->keyBindingList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(keyBindingSelected())); connect(_ui->newKeyBindingsButton, SIGNAL(clicked()), this, SLOT(newKeyBinding())); updateKeyBindingsButtons(); connect(_ui->editKeyBindingsButton, SIGNAL(clicked()), this, SLOT(editKeyBinding())); connect(_ui->removeKeyBindingsButton, SIGNAL(clicked()), this, SLOT(removeKeyBinding())); } 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) { 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 = 0; if (!selected.isEmpty()) translator = model->data(selected.first(), Qt::UserRole + 1).value(); else translator = KeyboardTranslatorManager::instance()->defaultTranslator(); Q_ASSERT(translator); QWeakPointer dialog = new KDialog(this); if (isNewTranslator) dialog.data()->setCaption(i18n("New Key Binding List")); else dialog.data()->setCaption(i18n("Edit Key Binding List")); KeyBindingEditor* editor = new KeyBindingEditor; dialog.data()->setMainWidget(editor); if (translator) editor->setup(translator); if (isNewTranslator) editor->setDescription(i18n("New Key Binding List")); if (dialog.data()->exec() == QDialog::Accepted) { KeyboardTranslator* newTranslator = new KeyboardTranslator(*editor->translator()); if (isNewTranslator) newTranslator->setName(newTranslator->description()); KeyboardTranslatorManager::instance()->addTranslator(newTranslator); updateKeyBindingsList(); const QString& currentTranslator = lookupProfile() ->property(Profile::KeyBindings); if (newTranslator->name() == currentTranslator) { updateTempProfileProperty(Profile::KeyBindings, newTranslator->name()); } } delete dialog.data(); } void EditProfileDialog::newKeyBinding() { showKeyBindingEditor(true); } void EditProfileDialog::editKeyBinding() { showKeyBindingEditor(false); } void EditProfileDialog::setupCheckBoxes(BooleanOption* options , const Profile::Ptr profile) { while (options->button != 0) { options->button->setChecked(profile->property(options->property)); connect(options->button, SIGNAL(toggled(bool)), this, options->slot); ++options; } } void EditProfileDialog::setupRadio(RadioOption* possibilities , int actual) { while (possibilities->button != 0) { if (possibilities->value == actual) possibilities->button->setChecked(true); else possibilities->button->setChecked(false); connect(possibilities->button, SIGNAL(clicked()), this, possibilities->slot); ++possibilities; } } void EditProfileDialog::setupScrollingPage(const Profile::Ptr profile) { // setup scrollbar radio int scrollBarPosition = profile->property(Profile::ScrollBarPosition); RadioOption positions[] = { {_ui->scrollBarHiddenButton, Enum::ScrollBarHidden, SLOT(hideScrollBar())}, {_ui->scrollBarLeftButton, Enum::ScrollBarLeft, SLOT(showScrollBarLeft())}, {_ui->scrollBarRightButton, Enum::ScrollBarRight, SLOT(showScrollBarRight())}, {0, 0, 0} }; setupRadio(positions , scrollBarPosition); // setup scrollback type radio int scrollBackType = profile->property(Profile::HistoryMode); _ui->historySizeWidget->setMode(Enum::HistoryModeEnum(scrollBackType)); connect(_ui->historySizeWidget, SIGNAL(historyModeChanged(Enum::HistoryModeEnum)), this, SLOT(historyModeChanged(Enum::HistoryModeEnum))); // setup scrollback line count spinner const int historySize = profile->historySize(); _ui->historySizeWidget->setLineCount(historySize); // setup scrollpageamount type radio int scrollFullPage = profile->property(Profile::ScrollFullPage); RadioOption pageamounts[] = { {_ui->scrollHalfPage, Enum::ScrollPageHalf, SLOT(scrollHalfPage())}, {_ui->scrollFullPage, Enum::ScrollPageFull, SLOT(scrollFullPage())}, {0, 0, 0} }; setupRadio(pageamounts, scrollFullPage); // signals and slots connect(_ui->historySizeWidget, SIGNAL(historySizeChanged(int)), this, SLOT(historySizeChanged(int))); } 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) { BooleanOption options[] = { { _ui->underlineLinksButton , Profile::UnderlineLinksEnabled, SLOT(toggleUnderlineLinks(bool)) }, { _ui->ctrlRequiredForDragButton, Profile::CtrlRequiredForDrag, SLOT(toggleCtrlRequiredForDrag(bool)) }, { _ui->copyTextToClipboardButton , Profile::AutoCopySelectedText, SLOT(toggleCopyTextToClipboard(bool)) }, { _ui->trimTrailingSpacesButton , Profile::TrimTrailingSpacesInSelectedText, SLOT(toggleTrimTrailingSpacesInSelectedText(bool)) }, { _ui->openLinksByDirectClickButton , Profile::OpenLinksByDirectClickEnabled, SLOT(toggleOpenLinksByDirectClick(bool)) }, { 0 , Profile::Property(0) , 0 } }; setupCheckBoxes(options , profile); // setup middle click paste mode const int middleClickPasteMode = profile->property(Profile::MiddleClickPasteMode); RadioOption pasteModes[] = { {_ui->pasteFromX11SelectionButton, Enum::PasteFromX11Selection, SLOT(pasteFromX11Selection())}, {_ui->pasteFromClipboardButton, Enum::PasteFromClipboard, SLOT(pasteFromClipboard())}, {0, 0, 0} }; setupRadio(pasteModes , middleClickPasteMode); // interaction options _ui->wordCharacterEdit->setText(profile->wordCharacters()); connect(_ui->wordCharacterEdit, SIGNAL(textChanged(QString)), this, SLOT(wordCharactersChanged(QString))); int tripleClickMode = profile->property(Profile::TripleClickMode); _ui->tripleClickModeCombo->setCurrentIndex(tripleClickMode); connect(_ui->tripleClickModeCombo, SIGNAL(activated(int)), this, SLOT(TripleClickModeChanged(int))); _ui->openLinksByDirectClickButton->setEnabled(_ui->underlineLinksButton->isChecked()); _ui->enableMouseWheelZoomButton->setChecked(profile->mouseWheelZoomEnabled()); connect(_ui->enableMouseWheelZoomButton, SIGNAL(toggled(bool)), this, SLOT(toggleMouseWheelZoom(bool))); } void EditProfileDialog::setupAdvancedPage(const Profile::Ptr profile) { BooleanOption options[] = { { _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)) }, { 0 , Profile::Property(0) , 0 } }; setupCheckBoxes(options , profile); const int lineSpacing = profile->lineSpacing(); _ui->lineSpacingSpinner->setValue(lineSpacing); connect(_ui->lineSpacingSpinner, SIGNAL(valueChanged(int)), this, SLOT(lineSpacingChanged(int))); // cursor options if (profile->useCustomCursorColor()) _ui->customCursorColorButton->setChecked(true); else _ui->autoCursorColorButton->setChecked(true); _ui->customColorSelectButton->setColor(profile->customCursorColor()); connect(_ui->customCursorColorButton, SIGNAL(clicked()), this, SLOT(customCursorColor())); connect(_ui->autoCursorColorButton, SIGNAL(clicked()), this, SLOT(autoCursorColor())); connect(_ui->customColorSelectButton, SIGNAL(changed(QColor)), SLOT(customCursorColorChanged(QColor))); int shape = profile->property(Profile::CursorShape); _ui->cursorShapeCombo->setCurrentIndex(shape); connect(_ui->cursorShapeCombo, SIGNAL(activated(int)), this, SLOT(setCursorShape(int))); // encoding options QAction* codecAction = new KCodecAction(this); _ui->selectEncodingButton->setMenu(codecAction->menu()); connect(codecAction, SIGNAL(triggered(QTextCodec*)), this, SLOT(setDefaultCodec(QTextCodec*))); _ui->characterEncodingLabel->setText(profile->defaultEncoding()); } void EditProfileDialog::setDefaultCodec(QTextCodec* codec) { QString name = QString(codec->name()); updateTempProfileProperty(Profile::DefaultEncoding, name); _ui->characterEncodingLabel->setText(codec->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); _ui->openLinksByDirectClickButton->setEnabled(enable); } void EditProfileDialog::toggleCtrlRequiredForDrag(bool enable) { updateTempProfileProperty(Profile::CtrlRequiredForDrag, enable); } void EditProfileDialog::toggleOpenLinksByDirectClick(bool enable) { updateTempProfileProperty(Profile::OpenLinksByDirectClickEnabled, enable); } void EditProfileDialog::toggleCopyTextToClipboard(bool enable) { updateTempProfileProperty(Profile::AutoCopySelectedText, 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::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() { QString sampleText = QString("ell 'lL', one '1', little eye 'i', big eye"); sampleText += QString("'I', lL1iI, Zero '0', little oh 'o', big oh 'O', 0oO"); sampleText += QString("`~!@#$%^&*()_+-=[]\\{}|:\";'<>?,./"); sampleText += QString("0123456789"); sampleText += QString("\nThe Quick Brown Fox Jumps Over The Lazy Dog\n"); sampleText += i18n("--- Type anything in this box ---"); QFont currentFont = _ui->fontPreviewLabel->font(); QWeakPointer dialog = new KFontDialog(this, KFontChooser::FixedFontsOnly); dialog.data()->setWindowTitle(i18n("Select Fixed Width Font")); dialog.data()->setFont(currentFont, true); // TODO (hindenburg): When https://git.reviewboard.kde.org/r/103357 is // committed, change the below. // Use text more fitting to show font differences in a terminal QList chooserList = dialog.data()->findChildren(); if (!chooserList.isEmpty()) chooserList.at(0)->setSampleText(sampleText); connect(dialog.data(), SIGNAL(fontSelected(QFont)), this, SLOT(fontSelected(QFont))); if (dialog.data()->exec() == QDialog::Rejected) fontSelected(currentFont); delete dialog.data(); } 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(); Q_ASSERT(scheme); if (!scheme) return; bool transparencyAvailable = KWindowSystem::compositingActive(); painter->setRenderHint(QPainter::Antialiasing); // draw background painter->setPen(QPen(scheme->foregroundColor() , 1)); // radial gradient for background // from a lightened version of the scheme's background color in the center to // a darker version at the outer edge QColor color = scheme->backgroundColor(); QRectF backgroundRect = QRectF(option.rect).adjusted(1.5, 1.5, -1.5, -1.5); QRadialGradient backgroundGradient(backgroundRect.center() , backgroundRect.width() / 2); backgroundGradient.setColorAt(0 , color.lighter(105)); backgroundGradient.setColorAt(1 , color.darker(115)); const int backgroundRectXRoundness = 4; const int backgroundRectYRoundness = 30; QPainterPath backgroundRectPath(backgroundRect.topLeft()); backgroundRectPath.addRoundRect(backgroundRect , backgroundRectXRoundness , backgroundRectYRoundness); if (transparencyAvailable) { painter->save(); color.setAlphaF(scheme->opacity()); painter->setCompositionMode(QPainter::CompositionMode_Source); painter->setBrush(backgroundGradient); painter->drawPath(backgroundRectPath); painter->restore(); } else { painter->setBrush(backgroundGradient); painter->drawPath(backgroundRectPath); } // draw stripe at the side using scheme's foreground color painter->setPen(QPen(Qt::NoPen)); QPainterPath path(option.rect.topLeft()); path.lineTo(option.rect.width() / 10.0 , option.rect.top()); path.lineTo(option.rect.bottomLeft()); path.lineTo(option.rect.topLeft()); painter->setBrush(scheme->foregroundColor()); painter->drawPath(path.intersected(backgroundRectPath)); // draw highlight // with a linear gradient going from translucent white to transparent QLinearGradient gradient(option.rect.topLeft() , option.rect.bottomLeft()); gradient.setColorAt(0 , QColor(255, 255, 255, 90)); gradient.setColorAt(1 , Qt::transparent); painter->setBrush(gradient); painter->drawRoundRect(backgroundRect , 4 , 30); //const bool isChecked = index.data(Qt::CheckStateRole) == Qt::Checked; const bool isSelected = option.state & QStyle::State_Selected; // draw border on selected items if (isSelected) { //|| isChecked ) static const int selectedBorderWidth = 6; painter->setBrush(QBrush(Qt::NoBrush)); QPen pen; QColor highlightColor = option.palette.highlight().color(); if (isSelected) highlightColor.setAlphaF(1.0); else highlightColor.setAlphaF(0.7); pen.setBrush(highlightColor); pen.setWidth(selectedBorderWidth); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); painter->drawRect(option.rect.adjusted(selectedBorderWidth / 2, selectedBorderWidth / 2, -selectedBorderWidth / 2, -selectedBorderWidth / 2)); } // draw color scheme name using scheme's foreground color QPen pen(scheme->foregroundColor()); painter->setPen(pen); painter->drawText(option.rect , Qt::AlignCenter , index.data(Qt::DisplayRole).value()); } QSize ColorSchemeViewDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const { const int width = 200; qreal colorWidth = (qreal)width / TABLE_COLORS; int margin = 5; qreal heightForWidth = (colorWidth * 2) + option.fontMetrics.height() + margin; // temporary return QSize(width, static_cast(heightForWidth)); } diff --git a/src/EditProfileDialog.ui b/src/EditProfileDialog.ui index 82298cfe..616e345c 100644 --- a/src/EditProfileDialog.ui +++ b/src/EditProfileDialog.ui @@ -1,1305 +1,1300 @@ EditProfileDialog 0 0 594 551 0 0 0 0 true General General true 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 Icon: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 64 64 0 0 Select the icon displayed on tabs using this profile 48 48 Qt::Horizontal 20 20 Environment: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit the list of environment variables and associated values Edit... Window true 0 0 Set the window size and position for this profile when exiting Save window size and position on exit 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 QAbstractItemView::ScrollPerPixel Create a new color scheme based upon the selected scheme New... Edit the selected color scheme Edit... Delete the selected color scheme Remove Qt::Vertical 20 20 Font true Preview: 1 0 FONT PREVIEW TEXT Qt::ElideRight Text size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 4.000000000000000 999.000000000000000 1.000000000000000 1 Select the font used in this profile Select Font... Qt::Horizontal 40 20 Smooth fonts Draw intense colors in bold font Scrolling Scrollback true Scroll Bar true 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 0 0 Hide the scroll bar Hide 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 20 Keyboard Key Bindings true Key bindings control how combinations of keystrokes in the terminal window are converted into the stream of characters which are sent to the current terminal program. true 32 32 Create a new key bindings list based upon the selected bindings New... Edit the selected key bindings list Edit... Delete the selected key bindings list Remove Qt::Vertical 20 20 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 Automatically copy selected text into clipboard Copy on select Trim trailing spaces in selected text, useful in some instances Trim trailing spaces Qt::Horizontal 561 5 Mouse middle button: Paste from selection Paste from clipboard Miscellaneous true Text recognized as a link or an email address will be underlined when hovered by the mouse pointer. Underline links Qt::Horizontal QSizePolicy::Fixed 10 20 false Text recognized as a link or an email address can be opened by direct mouse click. Open links by direct click Selected text will require control key plus click to drag. Require Ctrl key for drag and drop Pressing Ctrl+scrollwheel will increase/decrease the text size. Allow Ctrl+scrollwheel to zoom text size Qt::Vertical 20 328 Advanced Terminal Features true 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 KDoubleNumInput QWidget
knuminput.h
KColorButton QPushButton
kcolorbutton.h
KComboBox QComboBox
kcombobox.h
- - KLineEdit - QLineEdit -
klineedit.h
-
KIntSpinBox QSpinBox
knuminput.h
KSqueezedTextLabel QLabel
ksqueezedtextlabel.h
KMessageWidget QFrame
kmessagewidget.h
1
Konsole::RenameTabWidget QWidget
RenameTabWidget.h
Konsole::HistorySizeWidget QWidget
HistorySizeWidget.h