File indexing completed on 2024-04-28 05:50:38
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 // Own 0008 #include "ColorSchemeEditor.h" 0009 0010 #include "../config-konsole.h" 0011 0012 // Qt 0013 #include <QColorDialog> 0014 #include <QCompleter> 0015 #include <QDialogButtonBox> 0016 #include <QFileDialog> 0017 #include <QFileInfo> 0018 #include <QFileSystemModel> 0019 #include <QFontMetrics> 0020 #include <QIcon> 0021 #include <QImageReader> 0022 #include <QMetaEnum> 0023 #include <QPushButton> 0024 #include <QVBoxLayout> 0025 0026 // KDE 0027 #include <KLocalizedString> 0028 0029 // Konsole 0030 #include "../characters/CharacterColor.h" 0031 #include "ColorScheme.h" 0032 #include "ui_ColorSchemeEditor.h" 0033 0034 using namespace Konsole; 0035 0036 // colorTable is one third the length of _table in ColorScheme class, 0037 // because intense and faint colors are in separate columns 0038 const int COLOR_TABLE_ROW_LENGTH = TABLE_COLORS / 3; 0039 0040 const int NAME_COLUMN = 0; // column 0 : color names 0041 const int COLOR_COLUMN = 1; // column 1 : actual colors 0042 const int INTENSE_COLOR_COLUMN = 2; // column 2 : intense colors 0043 const int FAINT_COLOR_COLUMN = 3; // column 2 : faint colors 0044 0045 ColorSchemeEditor::ColorSchemeEditor(bool supportsTransparentWindows, QWidget *parent) 0046 : QDialog(parent) 0047 , _isNewScheme(false) 0048 , _ui(nullptr) 0049 { 0050 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply); 0051 auto mainWidget = new QWidget(this); 0052 auto mainLayout = new QVBoxLayout; 0053 setLayout(mainLayout); 0054 mainLayout->addWidget(mainWidget); 0055 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0056 okButton->setDefault(true); 0057 connect(buttonBox, &QDialogButtonBox::accepted, this, &ColorSchemeEditor::accept); 0058 connect(buttonBox, &QDialogButtonBox::rejected, this, &ColorSchemeEditor::reject); 0059 mainLayout->addWidget(buttonBox); 0060 connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme); 0061 connect(okButton, &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme); 0062 0063 // ui 0064 _ui = new Ui::ColorSchemeEditor(); 0065 _ui->setupUi(mainWidget); 0066 0067 // description edit 0068 _ui->descriptionEdit->setClearButtonEnabled(true); 0069 connect(_ui->descriptionEdit, &QLineEdit::textChanged, this, &Konsole::ColorSchemeEditor::setDescription); 0070 0071 // transparency slider 0072 QFontMetrics metrics(font()); 0073 _ui->transparencyPercentLabel->setMinimumWidth(metrics.boundingRect(QStringLiteral("100%")).width()); 0074 0075 connect(_ui->transparencySlider, &QSlider::valueChanged, this, &Konsole::ColorSchemeEditor::setTransparencyPercentLabel); 0076 0077 // blur behind window 0078 connect(_ui->blurCheckBox, &QCheckBox::toggled, this, &Konsole::ColorSchemeEditor::setBlur); 0079 0080 // randomized background 0081 connect(_ui->randomizedBackgroundCheck, &QCheckBox::toggled, this, &Konsole::ColorSchemeEditor::setRandomizedBackgroundColor); 0082 0083 // wallpaper stuff 0084 auto dirModel = new QFileSystemModel(this); 0085 dirModel->setFilter(QDir::AllEntries); 0086 dirModel->setRootPath(QStringLiteral("/")); 0087 auto completer = new QCompleter(this); 0088 completer->setModel(dirModel); 0089 _ui->wallpaperPath->setCompleter(completer); 0090 0091 _ui->wallpaperPath->setClearButtonEnabled(true); 0092 _ui->wallpaperSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("image-x-generic"))); 0093 0094 connect(_ui->wallpaperTransparencySlider, &QSlider::valueChanged, this, &Konsole::ColorSchemeEditor::setWallpaperOpacity); 0095 0096 connect(_ui->wallpaperSelectButton, &QToolButton::clicked, this, &Konsole::ColorSchemeEditor::selectWallpaper); 0097 connect(_ui->wallpaperPath, &QLineEdit::textChanged, this, &Konsole::ColorSchemeEditor::wallpaperPathChanged); 0098 0099 connect(_ui->wallpaperScalingType, &QComboBox::currentIndexChanged, this, &Konsole::ColorSchemeEditor::scalingTypeChanged); 0100 connect(_ui->wallpaperHorizontalAnchorSlider, &QSlider::valueChanged, this, &Konsole::ColorSchemeEditor::horizontalAnchorChanged); 0101 connect(_ui->wallpaperVerticalAnchorSlider, &QSlider::valueChanged, this, &Konsole::ColorSchemeEditor::verticalAnchorChanged); 0102 0103 connect(_ui->wallpaperFlipType, &QComboBox::currentIndexChanged, this, &Konsole::ColorSchemeEditor::flipTypeChanged); 0104 0105 // color table 0106 _ui->colorTable->setColumnCount(4); 0107 _ui->colorTable->setRowCount(COLOR_TABLE_ROW_LENGTH); 0108 0109 QStringList labels; 0110 labels << i18nc("@label:listbox Column header text for color names", "Name") << i18nc("@label:listbox Column header text for the actual colors", "Color") 0111 << i18nc("@label:listbox Column header text for the actual intense colors", "Intense color") 0112 << i18nc("@label:listbox Column header text for the actual faint colors", "Faint color"); 0113 _ui->colorTable->setHorizontalHeaderLabels(labels); 0114 0115 // Set resize mode for colorTable columns 0116 _ui->colorTable->horizontalHeader()->setSectionResizeMode(NAME_COLUMN, QHeaderView::ResizeToContents); 0117 _ui->colorTable->horizontalHeader()->setSectionResizeMode(COLOR_COLUMN, QHeaderView::Stretch); 0118 _ui->colorTable->horizontalHeader()->setSectionResizeMode(INTENSE_COLOR_COLUMN, QHeaderView::Stretch); 0119 _ui->colorTable->horizontalHeader()->setSectionResizeMode(FAINT_COLOR_COLUMN, QHeaderView::Stretch); 0120 0121 QTableWidgetItem *item = new QTableWidgetItem(QStringLiteral("Test")); 0122 _ui->colorTable->setItem(0, 0, item); 0123 0124 _ui->colorTable->verticalHeader()->hide(); 0125 0126 connect(_ui->colorTable, &QTableWidget::itemClicked, this, &Konsole::ColorSchemeEditor::editColorItem); 0127 0128 // warning label when transparency is not available 0129 _ui->transparencyWarningWidget->setWordWrap(true); 0130 _ui->transparencyWarningWidget->setCloseButtonVisible(false); 0131 _ui->transparencyWarningWidget->setMessageType(KMessageWidget::Warning); 0132 0133 if (supportsTransparentWindows) { 0134 _ui->transparencyWarningWidget->setVisible(false); 0135 } else { 0136 _ui->transparencyWarningWidget->setText(i18nc("@info:status", 0137 "The background transparency setting will not" 0138 " be used because your desktop does not appear to support" 0139 " transparent windows.")); 0140 } 0141 } 0142 0143 ColorSchemeEditor::~ColorSchemeEditor() 0144 { 0145 delete _ui; 0146 } 0147 0148 void ColorSchemeEditor::editColorItem(QTableWidgetItem *item) 0149 { 0150 // ignore if this is not a color column 0151 if (item->column() != COLOR_COLUMN && item->column() != INTENSE_COLOR_COLUMN && item->column() != FAINT_COLOR_COLUMN) { 0152 return; 0153 } 0154 0155 QColor color = item->background().color(); 0156 color = QColorDialog::getColor(color); 0157 if (color.isValid()) { 0158 item->setBackground(color); 0159 0160 int colorSchemeRow = item->row(); 0161 // Intense colors row are in the middle third of the color table 0162 if (item->column() == INTENSE_COLOR_COLUMN) { 0163 colorSchemeRow += COLOR_TABLE_ROW_LENGTH; 0164 } 0165 0166 // and the faint color rows are in the final third of the color table 0167 if (item->column() == FAINT_COLOR_COLUMN) { 0168 colorSchemeRow += 2 * COLOR_TABLE_ROW_LENGTH; 0169 } 0170 0171 _colors->setColorTableEntry(colorSchemeRow, color); 0172 0173 Q_EMIT colorsChanged(_colors); 0174 } 0175 } 0176 0177 void ColorSchemeEditor::selectWallpaper() 0178 { 0179 // Get supported image formats and convert to QString for getOpenFileName() 0180 const QList<QByteArray> mimeTypes = QImageReader::supportedImageFormats(); 0181 QString fileFormats = QStringLiteral("("); 0182 for (const QByteArray &mime : mimeTypes) { 0183 fileFormats += QStringLiteral("*.%1 ").arg(QLatin1String(mime)); 0184 } 0185 fileFormats += QLatin1String(")"); 0186 0187 const QString fileName = QFileDialog::getOpenFileName(this, 0188 i18nc("@title:window", "Select wallpaper image file"), 0189 _ui->wallpaperPath->text(), 0190 i18nc("@label:textbox Filter in file open dialog", "Supported Images") + fileFormats); 0191 0192 if (!fileName.isEmpty()) { 0193 _ui->wallpaperPath->setText(fileName); 0194 } 0195 } 0196 0197 void ColorSchemeEditor::setWallpaperOpacity(int percent) 0198 { 0199 _ui->wallpaperTransparencyPercentLabel->setText(QStringLiteral("%1%").arg(percent)); 0200 0201 const qreal opacity = (100.0 - percent) / 100.0; 0202 _colors->setWallpaper(_colors->wallpaper()->path(), 0203 _colors->wallpaper()->style(), 0204 _colors->wallpaper()->anchor(), 0205 opacity, 0206 _colors->wallpaper()->flipType()); 0207 } 0208 0209 void ColorSchemeEditor::wallpaperPathChanged(const QString &path) 0210 { 0211 if (path.isEmpty()) { 0212 _colors->setWallpaper(path, 0213 _colors->wallpaper()->style(), 0214 _colors->wallpaper()->anchor(), 0215 _colors->wallpaper()->opacity(), 0216 _colors->wallpaper()->flipType()); 0217 enableWallpaperSettings(false); 0218 } else { 0219 QFileInfo i(path); 0220 0221 if (i.exists() && i.isFile() && i.isReadable()) { 0222 _colors->setWallpaper(path, 0223 _colors->wallpaper()->style(), 0224 _colors->wallpaper()->anchor(), 0225 _colors->wallpaper()->opacity(), 0226 _colors->wallpaper()->flipType()); 0227 enableWallpaperSettings(true); 0228 } 0229 } 0230 } 0231 0232 void ColorSchemeEditor::scalingTypeChanged(int styleIndex) 0233 { 0234 const char *flipType = QMetaEnum::fromType<ColorSchemeWallpaper::FlipType>().valueToKey(_colors->wallpaper()->flipType()); 0235 const char *style = QMetaEnum::fromType<ColorSchemeWallpaper::FillStyle>().valueToKey(styleIndex); 0236 _colors->setWallpaper(_colors->wallpaper()->path(), 0237 QString::fromLatin1(style), 0238 _colors->wallpaper()->anchor(), 0239 _colors->wallpaper()->opacity(), 0240 QString::fromLatin1(flipType)); 0241 } 0242 0243 void ColorSchemeEditor::flipTypeChanged(int flipTypeIndex) 0244 { 0245 const char *fillStyle = QMetaEnum::fromType<ColorSchemeWallpaper::FillStyle>().valueToKey(_colors->wallpaper()->style()); 0246 const char *flipType = QMetaEnum::fromType<ColorSchemeWallpaper::FlipType>().valueToKey(flipTypeIndex); 0247 _colors->setWallpaper(_colors->wallpaper()->path(), 0248 QString::fromLatin1(fillStyle), 0249 _colors->wallpaper()->anchor(), 0250 _colors->wallpaper()->opacity(), 0251 QString::fromLatin1(flipType)); 0252 } 0253 0254 void ColorSchemeEditor::horizontalAnchorChanged(int pos) 0255 { 0256 QPointF anch = _colors->wallpaper()->anchor(); 0257 _colors->setWallpaper(_colors->wallpaper()->path(), 0258 _colors->wallpaper()->style(), 0259 QPointF(pos / 2.0, anch.y()), 0260 _colors->wallpaper()->opacity(), 0261 _colors->wallpaper()->flipType()); 0262 switch (pos) { 0263 case 2: 0264 _ui->wallpaperHorizontalAnchorPosition->setText(QString::fromLatin1("Right")); 0265 break; 0266 case 1: 0267 _ui->wallpaperHorizontalAnchorPosition->setText(QString::fromLatin1("Center")); 0268 break; 0269 case 0: 0270 default: 0271 _ui->wallpaperHorizontalAnchorPosition->setText(QString::fromLatin1("Left")); 0272 break; 0273 } 0274 } 0275 0276 void ColorSchemeEditor::verticalAnchorChanged(int pos) 0277 { 0278 QPointF anch = _colors->wallpaper()->anchor(); 0279 _colors->setWallpaper(_colors->wallpaper()->path(), 0280 _colors->wallpaper()->style(), 0281 QPointF(anch.x(), pos / 2.0), 0282 _colors->wallpaper()->opacity(), 0283 _colors->wallpaper()->flipType()); 0284 switch (pos) { 0285 case 2: 0286 _ui->wallpaperVerticalAnchorPosition->setText(QString::fromLatin1("Bottom")); 0287 break; 0288 case 1: 0289 _ui->wallpaperVerticalAnchorPosition->setText(QString::fromLatin1("Middle")); 0290 break; 0291 case 0: 0292 default: 0293 _ui->wallpaperVerticalAnchorPosition->setText(QString::fromLatin1("Top")); 0294 break; 0295 } 0296 } 0297 0298 void ColorSchemeEditor::setDescription(const QString &description) 0299 { 0300 if (_colors != nullptr) { 0301 _colors->setDescription(description); 0302 } 0303 0304 if (_ui->descriptionEdit->text() != description) { 0305 _ui->descriptionEdit->setText(description); 0306 } 0307 } 0308 0309 void ColorSchemeEditor::setTransparencyPercentLabel(int percent) 0310 { 0311 _ui->transparencyPercentLabel->setText(QStringLiteral("%1%").arg(percent)); 0312 0313 const qreal opacity = (100.0 - percent) / 100.0; 0314 _colors->setOpacity(opacity); 0315 } 0316 0317 void ColorSchemeEditor::setBlur(bool blur) 0318 { 0319 _colors->setBlur(blur); 0320 } 0321 0322 void ColorSchemeEditor::setRandomizedBackgroundColor(bool randomized) 0323 { 0324 _colors->setColorRandomization(randomized); 0325 } 0326 0327 void ColorSchemeEditor::setup(const std::shared_ptr<const ColorScheme> &scheme, bool isNewScheme) 0328 { 0329 _isNewScheme = isNewScheme; 0330 0331 _colors = std::make_shared<ColorScheme>(*scheme); 0332 0333 if (_isNewScheme) { 0334 setWindowTitle(i18nc("@title:window", "New Color Scheme")); 0335 setDescription(QStringLiteral("New Color Scheme")); 0336 } else { 0337 setWindowTitle(i18nc("@title:window", "Edit Color Scheme")); 0338 } 0339 0340 // setup description edit 0341 _ui->descriptionEdit->setText(_colors->description()); 0342 0343 // setup color table 0344 setupColorTable(_colors); 0345 0346 // setup transparency slider 0347 const int colorTransparencyPercent = qRound((1 - _colors->opacity()) * 100); 0348 const int wallpaperTransparencyPercent = qRound((1 - _colors->wallpaper()->opacity()) * 100); 0349 _ui->transparencySlider->setValue(colorTransparencyPercent); 0350 _ui->wallpaperTransparencySlider->setValue(wallpaperTransparencyPercent); 0351 setTransparencyPercentLabel(colorTransparencyPercent); 0352 setWallpaperOpacity(wallpaperTransparencyPercent); 0353 0354 // blur behind window checkbox 0355 _ui->blurCheckBox->setChecked(scheme->blur()); 0356 0357 // randomized background color checkbox 0358 _ui->randomizedBackgroundCheck->setChecked(scheme->isColorRandomizationEnabled()); 0359 0360 // wallpaper stuff 0361 int ax = qRound(scheme->wallpaper()->anchor().x() * 2.0); 0362 int ay = qRound(scheme->wallpaper()->anchor().y() * 2.0); 0363 _ui->wallpaperPath->setText(scheme->wallpaper()->path()); 0364 _ui->wallpaperScalingType->setCurrentIndex(scheme->wallpaper()->style()); 0365 _ui->wallpaperFlipType->setCurrentIndex(scheme->wallpaper()->flipType()); 0366 _ui->wallpaperHorizontalAnchorSlider->setValue(ax); 0367 _ui->wallpaperVerticalAnchorSlider->setValue(ay); 0368 enableWallpaperSettings(!scheme->wallpaper()->isNull()); 0369 } 0370 0371 void ColorSchemeEditor::setupColorTable(const std::shared_ptr<ColorScheme> &colors) 0372 { 0373 QColor table[TABLE_COLORS]; 0374 colors->getColorTable(table); 0375 0376 for (int row = 0; row < COLOR_TABLE_ROW_LENGTH; row++) { 0377 QTableWidgetItem *nameItem = new QTableWidgetItem(ColorScheme::translatedColorNameForIndex(row)); 0378 nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable); 0379 0380 auto colorItem = new QTableWidgetItem(); 0381 colorItem->setBackground(table[row]); 0382 colorItem->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); 0383 colorItem->setToolTip(i18nc("@info:tooltip", "Click to choose color")); 0384 0385 auto colorItemIntense = new QTableWidgetItem(); 0386 colorItemIntense->setBackground(table[COLOR_TABLE_ROW_LENGTH + row]); 0387 colorItemIntense->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); 0388 colorItemIntense->setToolTip(i18nc("@info:tooltip", "Click to choose intense color")); 0389 0390 auto colorItemFaint = new QTableWidgetItem(); 0391 colorItemFaint->setBackground(table[2 * COLOR_TABLE_ROW_LENGTH + row]); 0392 colorItemFaint->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable); 0393 colorItemFaint->setToolTip(i18nc("@info:tooltip", "Click to choose Faint color")); 0394 0395 _ui->colorTable->setItem(row, NAME_COLUMN, nameItem); 0396 _ui->colorTable->setItem(row, COLOR_COLUMN, colorItem); 0397 _ui->colorTable->setItem(row, INTENSE_COLOR_COLUMN, colorItemIntense); 0398 _ui->colorTable->setItem(row, FAINT_COLOR_COLUMN, colorItemFaint); 0399 } 0400 // ensure that color names are as fully visible as possible 0401 _ui->colorTable->resizeColumnToContents(0); 0402 } 0403 0404 ColorScheme &ColorSchemeEditor::colorScheme() const 0405 { 0406 return *_colors; 0407 } 0408 0409 bool ColorSchemeEditor::isNewScheme() const 0410 { 0411 return _isNewScheme; 0412 } 0413 0414 void ColorSchemeEditor::saveColorScheme() 0415 { 0416 Q_EMIT colorSchemeSaveRequested(colorScheme(), _isNewScheme); 0417 } 0418 0419 void ColorSchemeEditor::enableWallpaperSettings(bool enable) 0420 { 0421 _ui->wallpaperHorizontalAnchorSlider->setEnabled(enable); 0422 _ui->wallpaperVerticalAnchorSlider->setEnabled(enable); 0423 _ui->wallpaperTransparencySlider->setEnabled(enable); 0424 _ui->wallpaperScalingType->setEnabled(enable); 0425 _ui->wallpaperFlipType->setEnabled(enable); 0426 } 0427 0428 #include "moc_ColorSchemeEditor.cpp"