diff --git a/src/ColorSchemeEditor.cpp b/src/ColorSchemeEditor.cpp index d302399f..43a909c9 100644 --- a/src/ColorSchemeEditor.cpp +++ b/src/ColorSchemeEditor.cpp @@ -1,347 +1,347 @@ /* 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 "ColorSchemeEditor.h" // Qt #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include // Konsole #include "ui_ColorSchemeEditor.h" #include "ColorScheme.h" #include "CharacterColor.h" #include "Shortcut_p.h" using namespace Konsole; // colorTable is half the length of _table in ColorScheme class // since intense colors are in a separated column const int COLOR_TABLE_ROW_LENGTH = TABLE_COLORS / 3; const int NAME_COLUMN = 0; // column 0 : color names const int COLOR_COLUMN = 1; // column 1 : actual colors const int INTENSE_COLOR_COLUMN = 2; // column 2 : intense colors const int FAINT_COLOR_COLUMN = 3; // column 2 : faint colors ColorSchemeEditor::ColorSchemeEditor(QWidget *parent) : QDialog(parent), _isNewScheme(false), _ui(nullptr), _colors(nullptr) { auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Apply); auto mainWidget = new QWidget(this); auto mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(mainWidget); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); connect(buttonBox, &QDialogButtonBox::accepted, this, &ColorSchemeEditor::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &ColorSchemeEditor::reject); mainLayout->addWidget(buttonBox); connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme); connect(okButton, &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme); // ui _ui = new Ui::ColorSchemeEditor(); _ui->setupUi(mainWidget); // description edit _ui->descriptionEdit->setClearButtonEnabled(true); connect(_ui->descriptionEdit, &QLineEdit::textChanged, this, &Konsole::ColorSchemeEditor::setDescription); // transparency slider QFontMetrics metrics(font()); _ui->transparencyPercentLabel->setMinimumWidth(metrics.width(QStringLiteral("100%"))); connect(_ui->transparencySlider, &QSlider::valueChanged, this, &Konsole::ColorSchemeEditor::setTransparencyPercentLabel); // blur behind window connect(_ui->blurCheckBox, &QCheckBox::toggled, this, &Konsole::ColorSchemeEditor::setBlur); // randomized background connect(_ui->randomizedBackgroundCheck, &QCheckBox::toggled, this, &Konsole::ColorSchemeEditor::setRandomizedBackgroundColor); // wallpaper stuff auto dirModel = new QFileSystemModel(this); dirModel->setFilter(QDir::AllEntries); dirModel->setRootPath(QStringLiteral("/")); auto completer = new QCompleter(this); completer->setModel(dirModel); _ui->wallpaperPath->setCompleter(completer); _ui->wallpaperPath->setClearButtonEnabled(true); _ui->wallpaperSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("image-x-generic"))); connect(_ui->wallpaperSelectButton, &QToolButton::clicked, this, &Konsole::ColorSchemeEditor::selectWallpaper); connect(_ui->wallpaperPath, &QLineEdit::textChanged, this, &Konsole::ColorSchemeEditor::wallpaperPathChanged); // color table _ui->colorTable->setColumnCount(4); _ui->colorTable->setRowCount(COLOR_TABLE_ROW_LENGTH); QStringList labels; labels << i18nc("@label:listbox Column header text for color names", "Name") << i18nc("@label:listbox Column header text for the actual colors", "Color") << i18nc("@label:listbox Column header text for the actual intense colors", "Intense color") << i18nc("@label:listbox Column header text for the actual faint colors", "Faint color"); _ui->colorTable->setHorizontalHeaderLabels(labels); // Set resize mode for colorTable columns _ui->colorTable->horizontalHeader()->setSectionResizeMode(NAME_COLUMN, QHeaderView::ResizeToContents); _ui->colorTable->horizontalHeader()->setSectionResizeMode(COLOR_COLUMN, QHeaderView::Stretch); _ui->colorTable->horizontalHeader()->setSectionResizeMode(INTENSE_COLOR_COLUMN, QHeaderView::Stretch); _ui->colorTable->horizontalHeader()->setSectionResizeMode(FAINT_COLOR_COLUMN, QHeaderView::Stretch); QTableWidgetItem *item = new QTableWidgetItem(QStringLiteral("Test")); _ui->colorTable->setItem(0, 0, item); _ui->colorTable->verticalHeader()->hide(); connect(_ui->colorTable, &QTableWidget::itemClicked, this, &Konsole::ColorSchemeEditor::editColorItem); // warning label when transparency is not available _ui->transparencyWarningWidget->setWordWrap(true); _ui->transparencyWarningWidget->setCloseButtonVisible(false); _ui->transparencyWarningWidget->setMessageType(KMessageWidget::Warning); if (KWindowSystem::compositingActive()) { _ui->transparencyWarningWidget->setVisible(false); } else { _ui->transparencyWarningWidget->setText(i18nc("@info:status", "The background transparency setting will not" " be used because your desktop does not appear to support" " transparent windows.")); } } ColorSchemeEditor::~ColorSchemeEditor() { delete _colors; delete _ui; } void ColorSchemeEditor::editColorItem(QTableWidgetItem *item) { // ignore if this is not a color column if (item->column() != COLOR_COLUMN && item->column() != INTENSE_COLOR_COLUMN && item->column() != FAINT_COLOR_COLUMN) { return; } QColor color = item->background().color(); color = QColorDialog::getColor(color); if (color.isValid()) { item->setBackground(color); int colorSchemeRow = item->row(); // Intense colors row are in the middle third of the color table if (item->column() == INTENSE_COLOR_COLUMN) { colorSchemeRow += COLOR_TABLE_ROW_LENGTH; } // and the faint color rows are in the middle third of the color table if (item->column() == FAINT_COLOR_COLUMN) { colorSchemeRow += 2*COLOR_TABLE_ROW_LENGTH; } ColorEntry entry(_colors->colorEntry(colorSchemeRow)); entry = color; _colors->setColorTableEntry(colorSchemeRow, entry); emit colorsChanged(_colors); } } void ColorSchemeEditor::selectWallpaper() { // Get supported image formats and convert to QString for getOpenFileName() const QList mimeTypes = QImageReader::supportedImageFormats(); QString fileFormats = QStringLiteral("("); - Q_FOREACH (const QByteArray &mime, mimeTypes) { + for (const QByteArray &mime : mimeTypes) { fileFormats += QStringLiteral("*.%1 ").arg(QLatin1String(mime)); } fileFormats += QLatin1String(")"); const QString fileName = QFileDialog::getOpenFileName(this, i18nc("@title:window", "Select wallpaper image file"), _ui->wallpaperPath->text(), i18nc("@label:textbox Filter in file open dialog", "Supported Images") + fileFormats); if (!fileName.isEmpty()) { _ui->wallpaperPath->setText(fileName); } } void ColorSchemeEditor::wallpaperPathChanged(const QString &path) { if (path.isEmpty()) { _colors->setWallpaper(path); } else { QFileInfo i(path); if (i.exists() && i.isFile() && i.isReadable()) { _colors->setWallpaper(path); } } } void ColorSchemeEditor::setDescription(const QString &description) { if (_colors != nullptr) { _colors->setDescription(description); } if (_ui->descriptionEdit->text() != description) { _ui->descriptionEdit->setText(description); } } void ColorSchemeEditor::setTransparencyPercentLabel(int percent) { _ui->transparencyPercentLabel->setText(QStringLiteral("%1%").arg(percent)); const qreal opacity = (100.0 - percent) / 100.0; _colors->setOpacity(opacity); } void ColorSchemeEditor::setBlur(bool blur) { _colors->setBlur(blur); } void ColorSchemeEditor::setRandomizedBackgroundColor(bool randomized) { _colors->setRandomizedBackgroundColor(randomized); } void ColorSchemeEditor::setup(const ColorScheme *scheme, bool isNewScheme) { _isNewScheme = isNewScheme; delete _colors; _colors = new ColorScheme(*scheme); if (_isNewScheme) { setWindowTitle(i18nc("@title:window", "New Color Scheme")); setDescription(QStringLiteral("New Color Scheme")); } else { setWindowTitle(i18nc("@title:window", "Edit Color Scheme")); } // setup description edit _ui->descriptionEdit->setText(_colors->description()); // setup color table setupColorTable(_colors); // setup transparency slider const int transparencyPercent = qRound((1 - _colors->opacity()) * 100); _ui->transparencySlider->setValue(transparencyPercent); setTransparencyPercentLabel(transparencyPercent); // blur behind window checkbox _ui->blurCheckBox->setChecked(scheme->blur()); // randomized background color checkbox _ui->randomizedBackgroundCheck->setChecked(scheme->randomizedBackgroundColor()); // wallpaper stuff _ui->wallpaperPath->setText(scheme->wallpaper()->path()); } void ColorSchemeEditor::setupColorTable(const ColorScheme *colors) { ColorEntry table[TABLE_COLORS]; colors->getColorTable(table); for (int row = 0; row < COLOR_TABLE_ROW_LENGTH; row++) { QTableWidgetItem *nameItem = new QTableWidgetItem(ColorScheme::translatedColorNameForIndex(row)); nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable); auto colorItem = new QTableWidgetItem(); colorItem->setBackground(table[row]); colorItem->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); colorItem->setToolTip(i18nc("@info:tooltip", "Click to choose color")); auto colorItemIntense = new QTableWidgetItem(); colorItemIntense->setBackground(table[COLOR_TABLE_ROW_LENGTH + row]); colorItemIntense->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); colorItemIntense->setToolTip(i18nc("@info:tooltip", "Click to choose intense color")); auto colorItemFaint = new QTableWidgetItem(); colorItemFaint->setBackground(table[2*COLOR_TABLE_ROW_LENGTH + row]); colorItemFaint->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); colorItemFaint->setToolTip(i18nc("@info:tooltip", "Click to choose Faint color")); _ui->colorTable->setItem(row, NAME_COLUMN, nameItem); _ui->colorTable->setItem(row, COLOR_COLUMN, colorItem); _ui->colorTable->setItem(row, INTENSE_COLOR_COLUMN, colorItemIntense); _ui->colorTable->setItem(row, FAINT_COLOR_COLUMN, colorItemFaint); } // ensure that color names are as fully visible as possible _ui->colorTable->resizeColumnToContents(0); } ColorScheme &ColorSchemeEditor::colorScheme() const { return *_colors; } bool ColorSchemeEditor::isNewScheme() const { return _isNewScheme; } void ColorSchemeEditor::saveColorScheme() { emit colorSchemeSaveRequested(colorScheme(), _isNewScheme); } diff --git a/src/ColorSchemeManager.cpp b/src/ColorSchemeManager.cpp index 1b3228a0..f5052555 100644 --- a/src/ColorSchemeManager.cpp +++ b/src/ColorSchemeManager.cpp @@ -1,259 +1,259 @@ /* This source file is part of Konsole, a terminal emulator. 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 "ColorSchemeManager.h" #include "konsoledebug.h" // Qt #include #include #include #include // KDE #include using namespace Konsole; ColorSchemeManager::ColorSchemeManager() : _colorSchemes(QHash()), _haveLoadedAll(false) { } ColorSchemeManager::~ColorSchemeManager() { qDeleteAll(_colorSchemes); } Q_GLOBAL_STATIC(ColorSchemeManager, theColorSchemeManager) ColorSchemeManager* ColorSchemeManager::instance() { return theColorSchemeManager; } void ColorSchemeManager::loadAllColorSchemes() { int success = 0; int failed = 0; QStringList nativeColorSchemes = listColorSchemes(); foreach (const QString &colorScheme, nativeColorSchemes) { if (loadColorScheme(colorScheme)) { success++; } else { failed++; } } if (failed > 0) { qCDebug(KonsoleDebug) << "failed to load " << failed << " color schemes."; } _haveLoadedAll = true; } QList ColorSchemeManager::allColorSchemes() { if (!_haveLoadedAll) { loadAllColorSchemes(); } return _colorSchemes.values(); } bool ColorSchemeManager::loadColorScheme(const QString &filePath) { if (!pathIsColorScheme(filePath) || !QFile::exists(filePath)) { return false; } auto name = colorSchemeNameFromPath(filePath); KConfig config(filePath, KConfig::NoGlobals); auto scheme = new ColorScheme(); scheme->setName(name); scheme->read(config); if (scheme->name().isEmpty()) { qCDebug(KonsoleDebug) << "Color scheme in" << filePath << "does not have a valid name and was not loaded."; delete scheme; return false; } if (!_colorSchemes.contains(name)) { _colorSchemes.insert(scheme->name(), scheme); } else { //qDebug() << "color scheme with name" << scheme->name() << "has already been" << // "found, ignoring."; delete scheme; } return true; } bool ColorSchemeManager::unloadColorScheme(const QString &filePath) { if (!pathIsColorScheme(filePath)) { return false; } auto name = colorSchemeNameFromPath(filePath); delete _colorSchemes.take(name); return true; } QString ColorSchemeManager::colorSchemeNameFromPath(const QString &path) { if (!pathIsColorScheme(path)) { return QString(); } return QFileInfo(path).completeBaseName(); } QStringList ColorSchemeManager::listColorSchemes() { QStringList colorschemes; const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("konsole"), QStandardPaths::LocateDirectory); colorschemes.reserve(dirs.size()); - Q_FOREACH (const QString &dir, dirs) { + for (const QString &dir : dirs) { const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.colorscheme")); - Q_FOREACH (const QString &file, fileNames) { + for (const QString &file : fileNames) { colorschemes.append(dir + QLatin1Char('/') + file); } } return colorschemes; } const ColorScheme ColorSchemeManager::_defaultColorScheme; const ColorScheme *ColorSchemeManager::defaultColorScheme() const { return &_defaultColorScheme; } void ColorSchemeManager::addColorScheme(ColorScheme *scheme) { // remove existing colorscheme with the same name if (_colorSchemes.contains(scheme->name())) { delete _colorSchemes.take(scheme->name()); } _colorSchemes.insert(scheme->name(), scheme); // save changes to disk const QString dir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/konsole/"); QDir().mkpath(dir); const QString path = dir + scheme->name() + QStringLiteral(".colorscheme"); KConfig config(path, KConfig::NoGlobals); scheme->write(config); } bool ColorSchemeManager::deleteColorScheme(const QString &name) { Q_ASSERT(_colorSchemes.contains(name)); // look up the path and delete QString path = findColorSchemePath(name); if (QFile::remove(path)) { delete _colorSchemes.take(name); return true; } else { qCDebug(KonsoleDebug)<<"Failed to remove color scheme -"< 1); } diff --git a/src/KeyboardTranslatorManager.cpp b/src/KeyboardTranslatorManager.cpp index 040145e6..883e715c 100644 --- a/src/KeyboardTranslatorManager.cpp +++ b/src/KeyboardTranslatorManager.cpp @@ -1,227 +1,227 @@ /* This source file is part of Konsole, a terminal emulator. 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 "KeyboardTranslatorManager.h" #include "konsoledebug.h" // Qt #include #include #include #include using namespace Konsole; KeyboardTranslatorManager::KeyboardTranslatorManager() : _haveLoadedAll(false), _fallbackTranslator(nullptr), _translators(QHash()) { _fallbackTranslator = new FallbackKeyboardTranslator(); } KeyboardTranslatorManager::~KeyboardTranslatorManager() { qDeleteAll(_translators); delete _fallbackTranslator; } Q_GLOBAL_STATIC(KeyboardTranslatorManager, theKeyboardTranslatorManager) KeyboardTranslatorManager* KeyboardTranslatorManager::instance() { return theKeyboardTranslatorManager; } void KeyboardTranslatorManager::addTranslator(KeyboardTranslator *translator) { _translators.insert(translator->name(), translator); if (!saveTranslator(translator)) { qCDebug(KonsoleDebug) << "Unable to save translator" << translator->name() << "to disk."; } } bool KeyboardTranslatorManager::deleteTranslator(const QString &name) { Q_ASSERT(_translators.contains(name)); // locate and delete QString path = findTranslatorPath(name); if (QFile::remove(path)) { _translators.remove(name); return true; } else { qCDebug(KonsoleDebug) << "Failed to remove translator - " << path; return false; } } bool KeyboardTranslatorManager::isTranslatorDeletable(const QString &name) const { const QString &dir = QFileInfo(findTranslatorPath(name)).path(); return QFileInfo(dir).isWritable(); } bool KeyboardTranslatorManager::isTranslatorResettable(const QString &name) const { const QStringList &paths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("konsole/") + name + QStringLiteral(".keytab")); return (paths.count() > 1); } const QString KeyboardTranslatorManager::findTranslatorPath(const QString &name) const { return QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("konsole/") + name + QStringLiteral(".keytab")); } void KeyboardTranslatorManager::findTranslators() { QStringList list; const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("konsole"), QStandardPaths::LocateDirectory); list.reserve(dirs.size()); - Q_FOREACH (const QString &dir, dirs) { + for (const QString &dir : dirs) { const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.keytab")); - Q_FOREACH (const QString &file, fileNames) { + for (const QString &file : fileNames) { list.append(dir + QLatin1Char('/') + file); } } // add the name of each translator to the list and associated // the name with a null pointer to indicate that the translator // has not yet been loaded from disk foreach (const QString &translatorPath, list) { QString name = QFileInfo(translatorPath).completeBaseName(); if (!_translators.contains(name)) { _translators.insert(name, nullptr); } } _haveLoadedAll = true; } const KeyboardTranslator *KeyboardTranslatorManager::findTranslator(const QString &name) { if (name.isEmpty()) { return defaultTranslator(); } if (_translators.contains(name) && _translators[name] != nullptr) { return _translators[name]; } KeyboardTranslator *translator = loadTranslator(name); if (translator != nullptr) { _translators[name] = translator; } else if (!name.isEmpty()) { qCDebug(KonsoleDebug) << "Unable to load translator" << name; } return translator; } bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator *translator) { const QString dir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/konsole/"); QDir().mkpath(dir); const QString path = dir + translator->name() + QStringLiteral(".keytab"); ////qDebug() << "Saving translator to" << path; QFile destination(path); if (!destination.open(QIODevice::WriteOnly | QIODevice::Text)) { qCDebug(KonsoleDebug) << "Unable to save keyboard translation:" << destination.errorString(); return false; } { KeyboardTranslatorWriter writer(&destination); writer.writeHeader(translator->description()); foreach (const KeyboardTranslator::Entry &entry, translator->entries()) { writer.writeEntry(entry); } } destination.close(); return true; } KeyboardTranslator *KeyboardTranslatorManager::loadTranslator(const QString &name) { const QString &path = findTranslatorPath(name); QFile source(path); if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text)) { return nullptr; } return loadTranslator(&source, name); } KeyboardTranslator *KeyboardTranslatorManager::loadTranslator(QIODevice *source, const QString &name) { auto translator = new KeyboardTranslator(name); KeyboardTranslatorReader reader(source); translator->setDescription(reader.description()); while (reader.hasNextEntry()) { translator->addEntry(reader.nextEntry()); } source->close(); if (!reader.parseError()) { return translator; } else { delete translator; return nullptr; } } const KeyboardTranslator *KeyboardTranslatorManager::defaultTranslator() { // Try to find the default.keytab file if it exists, otherwise // fall back to the internal hard-coded fallback translator const KeyboardTranslator *translator = findTranslator(QStringLiteral("default")); if (translator == nullptr) { translator = _fallbackTranslator; } return translator; } const QStringList KeyboardTranslatorManager::allTranslators() { if (!_haveLoadedAll) { findTranslators(); } return _translators.keys(); } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index ea3d26ae..9d25f0f0 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1,890 +1,890 @@ /* Copyright 2006-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 "MainWindow.h" // Qt #include #include // KDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Konsole #include "BookmarkHandler.h" #include "SessionController.h" #include "ProfileList.h" #include "Session.h" #include "ViewContainer.h" #include "ViewManager.h" #include "SessionManager.h" #include "ProfileManager.h" #include "KonsoleSettings.h" #include "WindowSystemInfo.h" #include "TerminalDisplay.h" #include "settings/FileLocationSettings.h" #include "settings/GeneralSettings.h" #include "settings/ProfileSettings.h" #include "settings/TabBarSettings.h" using namespace Konsole; MainWindow::MainWindow() : KXmlGuiWindow(), _viewManager(nullptr), _bookmarkHandler(nullptr), _toggleMenuBarAction(nullptr), _newTabMenuAction(nullptr), _pluggedController(nullptr), _menuBarInitialVisibility(true), _menuBarInitialVisibilityApplied(false) { if (!KonsoleSettings::saveGeometryOnExit()) { // If we are not using the global Konsole save geometry on exit, // remove all Height and Width from [MainWindow] from konsolerc // Each screen resolution will have entries (Width 1280=619) KSharedConfigPtr konsoleConfig = KSharedConfig::openConfig(QStringLiteral("konsolerc")); KConfigGroup group = konsoleConfig->group("MainWindow"); QMap configEntries = group.entryMap(); QMapIterator i(configEntries); while (i.hasNext()) { i.next(); if (i.key().startsWith(QLatin1String("Width")) || i.key().startsWith(QLatin1String("Height"))) { group.deleteEntry(i.key()); } } } updateUseTransparency(); // create actions for menus setupActions(); // create view manager _viewManager = new ViewManager(this, actionCollection()); connect(_viewManager, &Konsole::ViewManager::empty, this, &Konsole::MainWindow::close); connect(_viewManager, &Konsole::ViewManager::activeViewChanged, this, &Konsole::MainWindow::activeViewChanged); connect(_viewManager, &Konsole::ViewManager::unplugController, this, &Konsole::MainWindow::disconnectController); connect(_viewManager, &Konsole::ViewManager::viewPropertiesChanged, bookmarkHandler(), &Konsole::BookmarkHandler::setViews); connect(_viewManager, &Konsole::ViewManager::blurSettingChanged, this, &Konsole::MainWindow::setBlur); connect(_viewManager, &Konsole::ViewManager::updateWindowIcon, this, &Konsole::MainWindow::updateWindowIcon); connect(_viewManager, &Konsole::ViewManager::newViewWithProfileRequest, this, &Konsole::MainWindow::newFromProfile); connect(_viewManager, &Konsole::ViewManager::newViewRequest, this, &Konsole::MainWindow::newTab); connect(_viewManager, &Konsole::ViewManager::viewDetached, this, &Konsole::MainWindow::viewDetached); setCentralWidget(_viewManager->widget()); // disable automatically generated accelerators in top-level // menu items - to avoid conflicting with Alt+[Letter] shortcuts // in terminal applications KAcceleratorManager::setNoAccel(menuBar()); // create menus createGUI(); // remember the original menu accelerators for later use rememberMenuAccelerators(); // replace standard shortcuts which cannot be used in a terminal // emulator (as they are reserved for use by terminal applications) correctStandardShortcuts(); setProfileList(new ProfileList(false, this)); // this must come at the end applyKonsoleSettings(); connect(KonsoleSettings::self(), &Konsole::KonsoleSettings::configChanged, this, &Konsole::MainWindow::applyKonsoleSettings); } void MainWindow::updateUseTransparency() { if (!WindowSystemInfo::HAVE_TRANSPARENCY) { return; } bool useTranslucency = KWindowSystem::compositingActive(); setAttribute(Qt::WA_TranslucentBackground, useTranslucency); setAttribute(Qt::WA_NoSystemBackground, false); WindowSystemInfo::HAVE_TRANSPARENCY = useTranslucency; } void MainWindow::rememberMenuAccelerators() { foreach (QAction *menuItem, menuBar()->actions()) { QString itemText = menuItem->text(); menuItem->setData(itemText); } } // remove accelerators for standard menu items (eg. &File, &View, &Edit) // etc. which are defined in kdelibs/kdeui/xmlgui/ui_standards.rc, again, // to avoid conflicting with Alt+[Letter] terminal shortcuts // // TODO - Modify XMLGUI so that it allows the text for standard actions // defined in ui_standards.rc to be re-defined in the local application // XMLGUI file (konsoleui.rc in this case) - the text for standard items // can then be redefined there to exclude the standard accelerators void MainWindow::removeMenuAccelerators() { foreach (QAction *menuItem, menuBar()->actions()) { menuItem->setText(menuItem->text().replace(QLatin1Char('&'), QString())); } } void MainWindow::restoreMenuAccelerators() { foreach (QAction *menuItem, menuBar()->actions()) { QString itemText = menuItem->data().toString(); menuItem->setText(itemText); } } void MainWindow::correctStandardShortcuts() { // replace F1 shortcut for help contents QAction *helpAction = actionCollection()->action(QStringLiteral("help_contents")); if (helpAction != nullptr) { actionCollection()->setDefaultShortcut(helpAction, QKeySequence()); } // replace Ctrl+B shortcut for bookmarks only if user hasn't already // changed the shortcut; however, if the user changed it to Ctrl+B // this will still get changed to Ctrl+Shift+B QAction *bookmarkAction = actionCollection()->action(QStringLiteral("add_bookmark")); if ((bookmarkAction != nullptr) && bookmarkAction->shortcut() == QKeySequence(Konsole::ACCEL + Qt::Key_B)) { actionCollection()->setDefaultShortcut(bookmarkAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_B); } } ViewManager *MainWindow::viewManager() const { return _viewManager; } void MainWindow::disconnectController(SessionController *controller) { disconnect(controller, &Konsole::SessionController::titleChanged, this, &Konsole::MainWindow::activeViewTitleChanged); disconnect(controller, &Konsole::SessionController::rawTitleChanged, this, &Konsole::MainWindow::updateWindowCaption); disconnect(controller, &Konsole::SessionController::iconChanged, this, &Konsole::MainWindow::updateWindowIcon); if (auto view = controller->view()) { view->removeEventFilter(this); } // KXmlGuiFactory::removeClient() will try to access actions associated // with the controller internally, which may not be valid after the controller // itself is no longer valid (after the associated session and or view have // been destroyed) if (controller->isValid()) { guiFactory()->removeClient(controller); } } void MainWindow::activeViewChanged(SessionController *controller) { // associate bookmark menu with current session bookmarkHandler()->setActiveView(controller); disconnect(bookmarkHandler(), &Konsole::BookmarkHandler::openUrl, nullptr, nullptr); connect(bookmarkHandler(), &Konsole::BookmarkHandler::openUrl, controller, &Konsole::SessionController::openUrl); if (!_pluggedController.isNull()) { disconnectController(_pluggedController); } Q_ASSERT(controller); _pluggedController = controller; _pluggedController->view()->installEventFilter(this); setBlur(ViewManager::profileHasBlurEnabled(SessionManager::instance()->sessionProfile(_pluggedController->session()))); // listen for title changes from the current session connect(controller, &Konsole::SessionController::titleChanged, this, &Konsole::MainWindow::activeViewTitleChanged); connect(controller, &Konsole::SessionController::rawTitleChanged, this, &Konsole::MainWindow::updateWindowCaption); connect(controller, &Konsole::SessionController::iconChanged, this, &Konsole::MainWindow::updateWindowIcon); controller->setShowMenuAction(_toggleMenuBarAction); guiFactory()->addClient(controller); // update session title to match newly activated session activeViewTitleChanged(controller); // Update window icon to newly activated session's icon updateWindowIcon(); } void MainWindow::activeViewTitleChanged(ViewProperties *properties) { Q_UNUSED(properties); updateWindowCaption(); } void MainWindow::updateWindowCaption() { if (_pluggedController.isNull()) { return; } const QString &title = _pluggedController->title(); const QString &userTitle = _pluggedController->userTitle(); // use tab title as caption by default QString caption = title; // use window title as caption when this setting is enabled // if the userTitle is empty, use a blank space (using an empty string // removes the dash — before the application name; leaving the dash // looks better) if (KonsoleSettings::showWindowTitleOnTitleBar()) { !userTitle.isEmpty() ? caption = userTitle : caption = QStringLiteral(" "); } setCaption(caption); } void MainWindow::updateWindowIcon() { if ((!_pluggedController.isNull()) && !_pluggedController->icon().isNull()) { setWindowIcon(_pluggedController->icon()); } } void MainWindow::setupActions() { KActionCollection *collection = actionCollection(); // File Menu _newTabMenuAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "&New Tab"), collection); collection->setDefaultShortcut(_newTabMenuAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_T); collection->setShortcutsConfigurable(_newTabMenuAction, true); _newTabMenuAction->setAutoRepeat(false); connect(_newTabMenuAction, &KActionMenu::triggered, this, [this] { newTab(_viewManager->activeContainer());}); collection->addAction(QStringLiteral("new-tab"), _newTabMenuAction); collection->setShortcutsConfigurable(_newTabMenuAction, true); QAction* menuAction = collection->addAction(QStringLiteral("clone-tab")); menuAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-duplicate"))); menuAction->setText(i18nc("@action:inmenu", "&Clone Tab")); collection->setDefaultShortcut(menuAction, QKeySequence()); menuAction->setAutoRepeat(false); connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::cloneTab); menuAction = collection->addAction(QStringLiteral("new-window")); menuAction->setIcon(QIcon::fromTheme(QStringLiteral("window-new"))); menuAction->setText(i18nc("@action:inmenu", "New &Window")); collection->setDefaultShortcut(menuAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_N); menuAction->setAutoRepeat(false); connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::newWindow); menuAction = collection->addAction(QStringLiteral("close-window")); menuAction->setIcon(QIcon::fromTheme(QStringLiteral("window-close"))); menuAction->setText(i18nc("@action:inmenu", "Close Window")); collection->setDefaultShortcut(menuAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_Q); connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::close); // Bookmark Menu KActionMenu *bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), collection); _bookmarkHandler = new BookmarkHandler(collection, bookmarkMenu->menu(), true, this); collection->addAction(QStringLiteral("bookmark"), bookmarkMenu); connect(_bookmarkHandler, &Konsole::BookmarkHandler::openUrls, this, &Konsole::MainWindow::openUrls); // Settings Menu _toggleMenuBarAction = KStandardAction::showMenubar(menuBar(), SLOT(setVisible(bool)), collection); collection->setDefaultShortcut(_toggleMenuBarAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_M); // Full Screen menuAction = KStandardAction::fullScreen(this, SLOT(viewFullScreen(bool)), this, collection); collection->setDefaultShortcut(menuAction, Qt::Key_F11); KStandardAction::configureNotifications(this, SLOT(configureNotifications()), collection); KStandardAction::keyBindings(this, SLOT(showShortcutsDialog()), collection); KStandardAction::preferences(this, SLOT(showSettingsDialog()), collection); menuAction = collection->addAction(QStringLiteral("manage-profiles")); menuAction->setText(i18nc("@action:inmenu", "Manage Profiles...")); menuAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::showManageProfilesDialog); // Set up an shortcut-only action for activating menu bar. menuAction = collection->addAction(QStringLiteral("activate-menu")); menuAction->setText(i18nc("@item", "Activate Menu")); collection->setDefaultShortcut(menuAction, Konsole::ACCEL + Qt::SHIFT + Qt::Key_F10); connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::activateMenuBar); } void MainWindow::viewFullScreen(bool fullScreen) { if (fullScreen) { setWindowState(windowState() | Qt::WindowFullScreen); } else { setWindowState(windowState() & ~Qt::WindowFullScreen); } } BookmarkHandler *MainWindow::bookmarkHandler() const { return _bookmarkHandler; } void MainWindow::setProfileList(ProfileList *list) { profileListChanged(list->actions()); connect(list, &Konsole::ProfileList::profileSelected, this, [this](const Profile::Ptr &profile) { newFromProfile(_viewManager->activeContainer(), profile);}); connect(list, &Konsole::ProfileList::actionsChanged, this, &Konsole::MainWindow::profileListChanged); } void MainWindow::profileListChanged(const QList &sessionActions) { // If only 1 profile is to be shown in the menu, only display // it if it is the non-default profile. if (sessionActions.size() > 2) { // Update the 'New Tab' KActionMenu if (_newTabMenuAction->menu() != nullptr) { _newTabMenuAction->menu()->clear(); } else { _newTabMenuAction->setMenu(new QMenu()); } foreach (QAction *sessionAction, sessionActions) { _newTabMenuAction->menu()->addAction(sessionAction); // NOTE: defaultProfile seems to not work here, sigh. Profile::Ptr profile = ProfileManager::instance()->defaultProfile(); if (profile && profile->name() == sessionAction->text().remove(QLatin1Char('&'))) { QIcon icon(KIconLoader::global()->loadIcon(profile->icon(), KIconLoader::Small, 0, KIconLoader::DefaultState, QStringList(QStringLiteral("emblem-favorite")))); sessionAction->setIcon(icon); _newTabMenuAction->menu()->setDefaultAction(sessionAction); QFont actionFont = sessionAction->font(); actionFont.setBold(true); sessionAction->setFont(actionFont); } } } else { if (_newTabMenuAction->menu() != nullptr) { _newTabMenuAction->menu()->clear(); } else { _newTabMenuAction->setMenu(new QMenu()); } Profile::Ptr profile = ProfileManager::instance()->defaultProfile(); // NOTE: Compare names w/o any '&' if (sessionActions.size() == 2 && sessionActions[1]->text().remove(QLatin1Char('&')) != profile->name()) { _newTabMenuAction->menu()->addAction(sessionActions[1]); } else { _newTabMenuAction->menu()->deleteLater(); } } } QString MainWindow::activeSessionDir() const { if (!_pluggedController.isNull()) { if (Session *session = _pluggedController->session()) { // For new tabs to get the correct working directory, // force the updating of the currentWorkingDirectory. session->getDynamicTitle(); } return _pluggedController->currentDir(); } else { return QString(); } } void MainWindow::openUrls(const QList &urls) { Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile(); - Q_FOREACH (const auto &url, urls) { + for (const auto &url : urls) { if (url.isLocalFile()) { createSession(_viewManager->activeContainer(), defaultProfile, url.path()); } else if (url.scheme() == QLatin1String("ssh")) { createSSHSession(_viewManager->activeContainer(), defaultProfile, url); } } } void MainWindow::newTab(TabbedViewContainer *tabWidget) { Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile(); createSession(tabWidget, defaultProfile, activeSessionDir()); } void MainWindow::cloneTab() { Q_ASSERT(_pluggedController); Session *session = _pluggedController->session(); Profile::Ptr profile = SessionManager::instance()->sessionProfile(session); if (profile) { createSession(_viewManager->activeContainer(), profile, activeSessionDir()); } else { // something must be wrong: every session should be associated with profile Q_ASSERT(false); newTab(_viewManager->activeContainer()); } } Session *MainWindow::createSession(TabbedViewContainer *tabWidget, Profile::Ptr profile, const QString &directory) { if (!profile) { profile = ProfileManager::instance()->defaultProfile(); } Session *session = SessionManager::instance()->createSession(profile); if (!directory.isEmpty() && profile->startInCurrentSessionDir()) { session->setInitialWorkingDirectory(directory); } session->addEnvironmentEntry(QStringLiteral("KONSOLE_DBUS_WINDOW=/Windows/%1").arg(_viewManager->managerId())); // create view before starting the session process so that the session // doesn't suffer a change in terminal size right after the session // starts. Some applications such as GNU Screen and Midnight Commander // don't like this happening _viewManager->createView(tabWidget, session); return session; } Session *MainWindow::createSSHSession(TabbedViewContainer *tabWidget, Profile::Ptr profile, const QUrl &url) { if (!profile) { profile = ProfileManager::instance()->defaultProfile(); } Session *session = SessionManager::instance()->createSession(profile); QString sshCommand = QStringLiteral("ssh "); if (url.port() > -1) { sshCommand += QStringLiteral("-p %1 ").arg(url.port()); } if (!url.userName().isEmpty()) { sshCommand += (url.userName() + QLatin1Char('@')); } if (!url.host().isEmpty()) { sshCommand += url.host(); } session->sendTextToTerminal(sshCommand, QLatin1Char('\r')); // create view before starting the session process so that the session // doesn't suffer a change in terminal size right after the session // starts. some applications such as GNU Screen and Midnight Commander // don't like this happening _viewManager->createView(tabWidget, session); return session; } void MainWindow::setFocus() { _viewManager->activeView()->setFocus(); } void MainWindow::newWindow() { Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile(); emit newWindowRequest(defaultProfile, activeSessionDir()); } bool MainWindow::queryClose() { // Do not ask for confirmation during log out and power off // TODO: rework the dealing of this case to make it has its own confirmation // dialog. if (qApp->isSavingSession()) { return true; } // Check what processes are running, excluding the shell QStringList processesRunning; const auto uniqueSessions = QSet::fromList(_viewManager->sessions()); foreach (Session *session, uniqueSessions) { if ((session == nullptr) || !session->isForegroundProcessActive()) { continue; } const QString defaultProc = session->program().split(QLatin1Char('/')).last(); const QString currentProc = session->foregroundProcessName().split(QLatin1Char('/')).last(); if (currentProc.isEmpty()) { continue; } if (defaultProc != currentProc) { processesRunning.append(currentProc); } } // Get number of open tabs const int openTabs = _viewManager->viewProperties().count(); // If no processes running (except the shell) and no extra tabs, just close if (processesRunning.count() == 0 && openTabs < 2) { return true; } // NOTE: Some, if not all, of the below KWindowSystem calls are only // implemented under x11 (KDE4.8 kdelibs/kdeui/windowmanagement). // make sure the window is shown on current desktop and is not minimized KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop()); if (isMinimized()) { KWindowSystem::unminimizeWindow(winId(), true); } int result; if (!processesRunning.isEmpty()) { result = KMessageBox::warningYesNoCancelList(this, i18ncp("@info", "There is a process running in this window. " "Do you still want to quit?", "There are %1 processes running in this window. " "Do you still want to quit?", processesRunning.count()), processesRunning, i18nc("@title", "Confirm Close"), KGuiItem(i18nc("@action:button", "Close &Window"), QStringLiteral("window-close")), KGuiItem(i18nc("@action:button", "Close Current &Tab"), QStringLiteral("tab-close")), KStandardGuiItem::cancel(), QStringLiteral("CloseAllTabs")); } else { result = KMessageBox::warningYesNoCancel(this, i18nc("@info", "There are %1 open tabs in this window. " "Do you still want to quit?", openTabs), i18nc("@title", "Confirm Close"), KGuiItem(i18nc("@action:button", "Close &Window"), QStringLiteral("window-close")), KGuiItem(i18nc("@action:button", "Close Current &Tab"), QStringLiteral("tab-close")), KStandardGuiItem::cancel(), QStringLiteral("CloseAllEmptyTabs")); } switch (result) { case KMessageBox::Yes: return true; case KMessageBox::No: if ((!_pluggedController.isNull()) && (!_pluggedController->session().isNull())) { disconnectController(_pluggedController); _pluggedController->session()->closeInNormalWay(); } return false; case KMessageBox::Cancel: return false; } return true; } void MainWindow::saveProperties(KConfigGroup &group) { _viewManager->saveSessions(group); } void MainWindow::readProperties(const KConfigGroup &group) { _viewManager->restoreSessions(group); } void MainWindow::saveGlobalProperties(KConfig *config) { SessionManager::instance()->saveSessions(config); } void MainWindow::readGlobalProperties(KConfig *config) { SessionManager::instance()->restoreSessions(config); } void MainWindow::syncActiveShortcuts(KActionCollection *dest, const KActionCollection *source) { foreach (QAction *qAction, source->actions()) { if (QAction *destQAction = dest->action(qAction->objectName())) { destQAction->setShortcut(qAction->shortcut()); } } } void MainWindow::showShortcutsDialog() { KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this); // add actions from this window and the current session controller foreach (KXMLGUIClient *client, guiFactory()->clients()) { dialog.addCollection(client->actionCollection()); } if (dialog.configure()) { // sync shortcuts for non-session actions (defined in "konsoleui.rc") in other main windows foreach (QWidget *mainWindowWidget, QApplication::topLevelWidgets()) { auto *mainWindow = qobject_cast(mainWindowWidget); if ((mainWindow != nullptr) && mainWindow != this) { syncActiveShortcuts(mainWindow->actionCollection(), actionCollection()); } } // sync shortcuts for session actions (defined in "sessionui.rc") in other session controllers. // Controllers which are currently plugged in (ie. their actions are part of the current menu) // must be updated immediately via syncActiveShortcuts(). Other controllers will be updated // when they are plugged into a main window. foreach (SessionController *controller, SessionController::allControllers()) { controller->reloadXML(); if ((controller->factory() != nullptr) && controller != _pluggedController) { syncActiveShortcuts(controller->actionCollection(), _pluggedController->actionCollection()); } } } } void MainWindow::newFromProfile(TabbedViewContainer *tabWidget, const Profile::Ptr &profile) { createSession(tabWidget, profile, activeSessionDir()); } void MainWindow::showManageProfilesDialog() { showSettingsDialog(true); } void MainWindow::showSettingsDialog(const bool showProfilePage) { if (KConfigDialog::showDialog(QStringLiteral("settings"))) { return; } KConfigDialog *settingsDialog = new KConfigDialog(this, QStringLiteral("settings"), KonsoleSettings::self()); settingsDialog->setFaceType(KPageDialog::Tabbed); auto generalSettings = new GeneralSettings(settingsDialog); settingsDialog->addPage(generalSettings, i18nc("@title Preferences page name", "General"), QStringLiteral("utilities-terminal")); auto profileSettings = new ProfileSettings(settingsDialog); KPageWidgetItem *profilePage = settingsDialog->addPage(profileSettings, i18nc("@title Preferences page name", "Profiles"), QStringLiteral("configure")); auto tabBarSettings = new TabBarSettings(settingsDialog); settingsDialog->addPage(tabBarSettings, i18nc("@title Preferences page name", "TabBar"), QStringLiteral("system-run")); auto fileLocationSettings = new FileLocationSettings(settingsDialog); settingsDialog->addPage(fileLocationSettings, i18nc("@title Preferences page name", "File Location"), QStringLiteral("configure")); if (showProfilePage) { settingsDialog->setCurrentPage(profilePage); } settingsDialog->show(); } void MainWindow::applyKonsoleSettings() { setMenuBarInitialVisibility(KonsoleSettings::showMenuBarByDefault()); setRemoveWindowTitleBarAndFrame(KonsoleSettings::removeWindowTitleBarAndFrame()); if (KonsoleSettings::allowMenuAccelerators()) { restoreMenuAccelerators(); } else { removeMenuAccelerators(); } _viewManager->setNavigationBehavior(KonsoleSettings::newTabBehavior()); setAutoSaveSettings(QStringLiteral("MainWindow"), KonsoleSettings::saveGeometryOnExit()); updateWindowCaption(); } void MainWindow::activateMenuBar() { const QList menuActions = menuBar()->actions(); if (menuActions.isEmpty()) { return; } // Show menubar if it is hidden at the moment if (menuBar()->isHidden()) { menuBar()->setVisible(true); _toggleMenuBarAction->setChecked(true); } // First menu action should be 'File' QAction *menuAction = menuActions.first(); // TODO: Handle when menubar is top level (MacOS) menuBar()->setActiveAction(menuAction); } void MainWindow::configureNotifications() { KNotifyConfigWidget::configure(this); } void MainWindow::setBlur(bool blur) { if (_pluggedController.isNull()) { return; } if (!_pluggedController->isKonsolePart()) { KWindowEffects::enableBlurBehind(winId(), blur); } } void MainWindow::setMenuBarInitialVisibility(bool visible) { _menuBarInitialVisibility = visible; } void MainWindow::setRemoveWindowTitleBarAndFrame(bool frameless) { // This is used to check if the window is in "opening" state // And avoid the visibility change when we change the window flag bool oldVisibility = isVisible(); if (frameless) { setWindowFlags(Qt::FramelessWindowHint); } else { setWindowFlags(Qt::Widget); } if (oldVisibility && !isVisible()) { setVisible(true); } } void MainWindow::showEvent(QShowEvent *event) { // Make sure the 'initial' visibility is applied only once. if (!_menuBarInitialVisibilityApplied) { // the initial visibility of menubar should be applied at this last // moment. Otherwise, the initial visibility will be determined by // what KMainWindow has automatically stored in konsolerc, but not by // what users has explicitly configured . menuBar()->setVisible(_menuBarInitialVisibility); _toggleMenuBarAction->setChecked(_menuBarInitialVisibility); _menuBarInitialVisibilityApplied = true; if (!KonsoleSettings::saveGeometryOnExit()) { resize(sizeHint()); } } // Call parent method KXmlGuiWindow::showEvent(event); } void MainWindow::triggerAction(const QString &name) const { if (auto action = actionCollection()->action(name)) { if (action->isEnabled()) { action->trigger(); } } } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == _pluggedController->view()) { switch(event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: switch(static_cast(event)->button()) { case Qt::ForwardButton: triggerAction(QStringLiteral("next-view")); break; case Qt::BackButton: triggerAction(QStringLiteral("previous-view")); break; default: ; } default: ; } } return KXmlGuiWindow::eventFilter(obj, event); } bool MainWindow::focusNextPrevChild(bool) { // In stand-alone konsole, always disable implicit focus switching // through 'Tab' and 'Shift+Tab' // // Kpart is another different story return false; } diff --git a/src/ProfileReader.cpp b/src/ProfileReader.cpp index 2c253647..41a2c55e 100644 --- a/src/ProfileReader.cpp +++ b/src/ProfileReader.cpp @@ -1,126 +1,126 @@ /* This source file is part of Konsole, a terminal emulator. Copyright 2006-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 "ProfileReader.h" // Qt #include #include // KDE #include #include // Konsole #include "ShellCommand.h" using namespace Konsole; // FIXME: A dup line from Profile.cpp - redo these static const char GENERAL_GROUP[] = "General"; static const char FEATURES_GROUP[] = "Terminal Features"; static const char URLHINTS_KEY[] = "EnableUrlHints"; static const char URLHINTSMODIFIERS_KEY[] = "UrlHintsModifiers"; ProfileReader::ProfileReader() = default; ProfileReader::~ProfileReader() = default; QStringList ProfileReader::findProfiles() { QStringList profiles; const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("konsole"), QStandardPaths::LocateDirectory); profiles.reserve(dirs.size()); - Q_FOREACH (const QString& dir, dirs) { + for (const QString& dir : dirs) { const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.profile")); - Q_FOREACH (const QString& file, fileNames) { + for (const QString& file : fileNames) { profiles.append(dir + QLatin1Char('/') + file); } } return profiles; } void ProfileReader::readProperties(const KConfig& config, Profile::Ptr profile, const Profile::PropertyInfo* properties) { const char* groupName = nullptr; KConfigGroup group; while (properties->name != nullptr) { if (properties->group != nullptr) { if (groupName == nullptr || qstrcmp(groupName, properties->group) != 0) { group = config.group(properties->group); groupName = properties->group; } QString name(QLatin1String(properties->name)); if (group.hasKey(name)) { profile->setProperty(properties->property, group.readEntry(name, QVariant(properties->type))); } } properties++; } } bool ProfileReader::readProfile(const QString& path , Profile::Ptr profile , QString& parentProfile) { if (!QFile::exists(path)) { return false; } KConfig config(path, KConfig::NoGlobals); KConfigGroup general = config.group(GENERAL_GROUP); if (general.hasKey("Parent")) { parentProfile = general.readEntry("Parent"); } if (general.hasKey("Command")) { ShellCommand shellCommand(general.readEntry("Command")); profile->setProperty(Profile::Command, shellCommand.command()); profile->setProperty(Profile::Arguments, shellCommand.arguments()); } // Check if the user earlier had set the URL hints option, and in that case set the default // URL hints modifier to the earlier default. if (config.hasGroup(FEATURES_GROUP)) { KConfigGroup features = config.group(FEATURES_GROUP); if (features.hasKey(URLHINTS_KEY)) { bool enable = features.readEntry(URLHINTS_KEY, false); if (enable && !features.hasKey(URLHINTSMODIFIERS_KEY)) { features.writeEntry(URLHINTSMODIFIERS_KEY, int(Qt::ControlModifier)); } features.deleteEntry(URLHINTS_KEY); } } profile->setProperty(Profile::UntranslatedName, general.readEntryUntranslated("Name")); // Read remaining properties readProperties(config, profile, Profile::DefaultPropertyNames); return true; }