ColorSchemeEditor.cpp 11.8 KB
Newer Older
1
/*
2
    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

    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.
*/

20 21 22
// Own
#include "ColorSchemeEditor.h"

23
// Qt
Dirk Mueller's avatar
Dirk Mueller committed
24
#include <QtGui/QFontMetrics>
25
#include <QtCore/QFileInfo>
26 27
#include <QCompleter>
#include <QFileSystemModel>
Kurt Hindenburg's avatar
Kurt Hindenburg committed
28
#include <QtCore/QUrl>
Michal Humpula's avatar
Michal Humpula committed
29
#include <QtGui/QIcon>
30 31
#include <QFileDialog>
#include <QImageReader>
32 33

// KDE
Laurent Montel's avatar
Laurent Montel committed
34
#include <QColorDialog>
35
#include <KWindowSystem>
Alex Richardson's avatar
Alex Richardson committed
36
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
37 38 39
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
40 41 42

// Konsole
#include "ui_ColorSchemeEditor.h"
Jekyll Wu's avatar
Jekyll Wu committed
43
#include "ColorScheme.h"
44
#include "CharacterColor.h"
45
#include "Shortcut_p.h"
46 47 48

using namespace Konsole;

49 50
// colorTable is half the length of _table in ColorScheme class
// since intense colors are in a separated column
51
const int COLOR_TABLE_ROW_LENGTH =  TABLE_COLORS / 3;
52 53 54 55

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
56
const int FAINT_COLOR_COLUMN = 3;    // column 2 : faint colors
57

Kurt Hindenburg's avatar
Kurt Hindenburg committed
58
ColorSchemeEditor::ColorSchemeEditor(QWidget* aParent)
Laurent Montel's avatar
Laurent Montel committed
59
    : QDialog(aParent)
Kurt Hindenburg's avatar
Kurt Hindenburg committed
60
    , _isNewScheme(false)
61 62
    , _colors(0)
{
Kurt Hindenburg's avatar
Kurt Hindenburg committed
63 64 65
    auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Apply);
    auto mainWidget = new QWidget(this);
    auto mainLayout = new QVBoxLayout;
Laurent Montel's avatar
Laurent Montel committed
66 67 68 69
    setLayout(mainLayout);
    mainLayout->addWidget(mainWidget);
    QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
    okButton->setDefault(true);
70
    okButton->setShortcut(Konsole::ACCEL | Qt::Key_Return);
Laurent Montel's avatar
Laurent Montel committed
71 72
    connect(buttonBox, &QDialogButtonBox::accepted, this, &ColorSchemeEditor::accept);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &ColorSchemeEditor::reject);
Laurent Montel's avatar
Laurent Montel committed
73 74 75
    mainLayout->addWidget(buttonBox);
    connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme);
    connect(okButton, &QPushButton::clicked, this, &Konsole::ColorSchemeEditor::saveColorScheme);
76 77

    // ui
78
    _ui = new Ui::ColorSchemeEditor();
Laurent Montel's avatar
Laurent Montel committed
79
    _ui->setupUi(mainWidget);
80 81

    // description edit
Kurt Hindenburg's avatar
Kurt Hindenburg committed
82
    _ui->descriptionEdit->setClearButtonEnabled(true);
Laurent Montel's avatar
Laurent Montel committed
83
    connect(_ui->descriptionEdit , &QLineEdit::textChanged , this , &Konsole::ColorSchemeEditor::setDescription);
84 85 86

    // transparency slider
    QFontMetrics metrics(font());
87
    _ui->transparencyPercentLabel->setMinimumWidth(metrics.width(QStringLiteral("100%")));
88

89
    connect(_ui->transparencySlider , &QSlider::valueChanged , this , &Konsole::ColorSchemeEditor::setTransparencyPercentLabel);
90

91
    // randomized background
Laurent Montel's avatar
Laurent Montel committed
92
    connect(_ui->randomizedBackgroundCheck , &QCheckBox::toggled , this , &Konsole::ColorSchemeEditor::setRandomizedBackgroundColor);
93

Jekyll Wu's avatar
Jekyll Wu committed
94
    // wallpaper stuff
Kurt Hindenburg's avatar
Kurt Hindenburg committed
95
    auto dirModel = new QFileSystemModel(this);
96 97
    dirModel->setFilter(QDir::AllEntries);
    dirModel->setRootPath(QString('/'));
Kurt Hindenburg's avatar
Kurt Hindenburg committed
98
    auto completer = new QCompleter(this);
Kurt Hindenburg's avatar
Kurt Hindenburg committed
99
    completer->setModel(dirModel);
100 101
    _ui->wallpaperPath->setCompleter(completer);

Kurt Hindenburg's avatar
Kurt Hindenburg committed
102
    _ui->wallpaperPath->setClearButtonEnabled(true);
Michal Humpula's avatar
Michal Humpula committed
103
    _ui->wallpaperSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("image-x-generic")));
Jekyll Wu's avatar
Jekyll Wu committed
104

Laurent Montel's avatar
Laurent Montel committed
105 106
    connect(_ui->wallpaperSelectButton, &QToolButton::clicked, this, &Konsole::ColorSchemeEditor::selectWallpaper);
    connect(_ui->wallpaperPath, &QLineEdit::textChanged, this, &Konsole::ColorSchemeEditor::wallpaperPathChanged);
Jekyll Wu's avatar
Jekyll Wu committed
107

108
    // color table
109
    _ui->colorTable->setColumnCount(4);
110
    _ui->colorTable->setRowCount(COLOR_TABLE_ROW_LENGTH);
111 112

    QStringList labels;
113 114
    labels << i18nc("@label:listbox Column header text for color names", "Name")
           << i18nc("@label:listbox Column header text for the actual colors", "Color")
115 116
           << 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");
117 118
    _ui->colorTable->setHorizontalHeaderLabels(labels);

119
    // Set resize mode for colorTable columns
120 121 122
    _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);
123
    _ui->colorTable->horizontalHeader()->setSectionResizeMode(FAINT_COLOR_COLUMN, QHeaderView::Stretch);
124

125
    QTableWidgetItem* item = new QTableWidgetItem(QStringLiteral("Test"));
Kurt Hindenburg's avatar
Kurt Hindenburg committed
126
    _ui->colorTable->setItem(0, 0, item);
127 128 129

    _ui->colorTable->verticalHeader()->hide();

Laurent Montel's avatar
Laurent Montel committed
130
    connect(_ui->colorTable , &QTableWidget::itemClicked , this , &Konsole::ColorSchemeEditor::editColorItem);
131

Jekyll Wu's avatar
Jekyll Wu committed
132
    // warning label when transparency is not available
133 134 135 136
    _ui->transparencyWarningWidget->setWordWrap(true);
    _ui->transparencyWarningWidget->setCloseButtonVisible(false);
    _ui->transparencyWarningWidget->setMessageType(KMessageWidget::Warning);

Kurt Hindenburg's avatar
Kurt Hindenburg committed
137
    if (KWindowSystem::compositingActive()) {
138
        _ui->transparencyWarningWidget->setVisible(false);
Kurt Hindenburg's avatar
Kurt Hindenburg committed
139
    } else {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
140
        _ui->transparencyWarningWidget->setText(i18nc("@info:status",
Kurt Hindenburg's avatar
Kurt Hindenburg committed
141 142 143
                                                "The background transparency setting will not"
                                                " be used because your desktop does not appear to support"
                                                " transparent windows."));
144
    }
145
}
146 147 148 149 150
ColorSchemeEditor::~ColorSchemeEditor()
{
    delete _colors;
    delete _ui;
}
Kurt Hindenburg's avatar
Kurt Hindenburg committed
151
void ColorSchemeEditor::editColorItem(QTableWidgetItem* item)
152 153
{
    // ignore if this is not a color column
154
    if (item->column() != COLOR_COLUMN && item->column() != INTENSE_COLOR_COLUMN && item->column() != FAINT_COLOR_COLUMN) {
155 156
        return;
    }
157

158
    QColor color = item->background().color();
159
    color = QColorDialog::getColor(color);
Laurent Montel's avatar
Laurent Montel committed
160
    if ( color.isValid() ) {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
161
        item->setBackground(color);
162

163
        int colorSchemeRow = item->row();
164
        // Intense colors row are in the middle third of the color table
165
        if (item->column() == INTENSE_COLOR_COLUMN) {
166
            colorSchemeRow += COLOR_TABLE_ROW_LENGTH;
167
        }
168

169 170 171 172 173
        // 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;
        }

174
        ColorEntry entry(_colors->colorEntry(colorSchemeRow));
175
        entry.color = color;
176
        _colors->setColorTableEntry(colorSchemeRow, entry);
177

Kurt Hindenburg's avatar
Kurt Hindenburg committed
178
        emit colorsChanged(_colors);
179
    }
180
}
181 182
void ColorSchemeEditor::selectWallpaper()
{
183 184
    // Get supported image formats and convert to QString for getOpenFileName()
    const QList<QByteArray> mimeTypes = QImageReader::supportedImageFormats();
185
    QString fileFormats = QStringLiteral("(");
186
    Q_FOREACH (const QByteArray &mime, mimeTypes) {
187
        fileFormats += QStringLiteral("*.%1 ").arg(QLatin1String(mime));
188
    }
189
    fileFormats += QLatin1String(")");
190 191

    const QString fileName = QFileDialog::getOpenFileName(this,
192
                             i18nc("@title:window", "Select wallpaper image file"),
193
                             _ui->wallpaperPath->text(),
194
                             i18nc("Filter in file open dialog", "Supported Images") + fileFormats);
195

196 197
    if (!fileName.isEmpty())
        _ui->wallpaperPath->setText(fileName);
198 199 200
}
void ColorSchemeEditor::wallpaperPathChanged(const QString& path)
{
Jekyll Wu's avatar
Jekyll Wu committed
201
    if (path.isEmpty()) {
202
        _colors->setWallpaper(path);
203
    } else {
204 205 206 207 208 209
        QFileInfo i(path);

        if (i.exists() && i.isFile() && i.isReadable())
            _colors->setWallpaper(path);
    }
}
210 211
void ColorSchemeEditor::setDescription(const QString& text)
{
Kurt Hindenburg's avatar
Kurt Hindenburg committed
212
    if (_colors)
213 214
        _colors->setDescription(text);

Kurt Hindenburg's avatar
Kurt Hindenburg committed
215
    if (_ui->descriptionEdit->text() != text)
216 217 218 219
        _ui->descriptionEdit->setText(text);
}
void ColorSchemeEditor::setTransparencyPercentLabel(int percent)
{
220
    _ui->transparencyPercentLabel->setText(QStringLiteral("%1%").arg(percent));
221

Jekyll Wu's avatar
Jekyll Wu committed
222
    const qreal opacity = (100.0 - percent) / 100.0;
223 224
    _colors->setOpacity(opacity);
}
Jekyll Wu's avatar
Jekyll Wu committed
225 226 227 228
void ColorSchemeEditor::setRandomizedBackgroundColor(bool randomize)
{
    _colors->setRandomizedBackgroundColor(randomize);
}
Kurt Hindenburg's avatar
Kurt Hindenburg committed
229
void ColorSchemeEditor::setup(const ColorScheme* scheme, bool isNewScheme)
230
{
Kurt Hindenburg's avatar
Kurt Hindenburg committed
231 232
    _isNewScheme = isNewScheme;

233
    delete _colors;
234 235 236

    _colors = new ColorScheme(*scheme);

237
    if (_isNewScheme) {
Laurent Montel's avatar
Laurent Montel committed
238
        setWindowTitle(i18n("New Color Scheme"));
239 240
        setDescription(i18n("New Color Scheme"));
    } else {
Laurent Montel's avatar
Laurent Montel committed
241
        setWindowTitle(i18n("Edit Color Scheme"));
242 243
    }

244 245 246 247 248 249 250
    // setup description edit
    _ui->descriptionEdit->setText(_colors->description());

    // setup color table
    setupColorTable(_colors);

    // setup transparency slider
Kurt Hindenburg's avatar
Kurt Hindenburg committed
251
    const int transparencyPercent = qRound((1 - _colors->opacity()) * 100);
252 253
    _ui->transparencySlider->setValue(transparencyPercent);
    setTransparencyPercentLabel(transparencyPercent);
254 255

    // randomized background color checkbox
Kurt Hindenburg's avatar
Kurt Hindenburg committed
256
    _ui->randomizedBackgroundCheck->setChecked(scheme->randomizedBackgroundColor());
257 258

    // wallpaper stuff
Kurt Hindenburg's avatar
Kurt Hindenburg committed
259
    _ui->wallpaperPath->setText(scheme->wallpaper()->path());
260 261 262
}
void ColorSchemeEditor::setupColorTable(const ColorScheme* colors)
{
263 264
    ColorEntry table[TABLE_COLORS];
    colors->getColorTable(table);
265

266
    for (int row = 0; row < COLOR_TABLE_ROW_LENGTH; row++) {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
267
        QTableWidgetItem* nameItem = new QTableWidgetItem(ColorScheme::translatedColorNameForIndex(row));
Kurt Hindenburg's avatar
Kurt Hindenburg committed
268
        nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable);
269

Kurt Hindenburg's avatar
Kurt Hindenburg committed
270
        auto colorItem = new QTableWidgetItem();
Kurt Hindenburg's avatar
Kurt Hindenburg committed
271 272
        colorItem->setBackground(table[row].color);
        colorItem->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable);
273
        colorItem->setToolTip(i18nc("@info:tooltip", "Click to choose color"));
274

Kurt Hindenburg's avatar
Kurt Hindenburg committed
275
        auto colorItemIntense = new QTableWidgetItem();
276 277 278
        colorItemIntense->setBackground(table[COLOR_TABLE_ROW_LENGTH + row].color);
        colorItemIntense->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable);
        colorItemIntense->setToolTip(i18nc("@info:tooltip", "Click to choose intense color"));
279

Kurt Hindenburg's avatar
Kurt Hindenburg committed
280
        auto colorItemFaint = new QTableWidgetItem();
281 282 283 284
        colorItemFaint->setBackground(table[2*COLOR_TABLE_ROW_LENGTH + row].color);
        colorItemFaint->setFlags(colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable);
        colorItemFaint->setToolTip(i18nc("@info:tooltip", "Click to choose Faint color"));

285 286 287
        _ui->colorTable->setItem(row, NAME_COLUMN, nameItem);
        _ui->colorTable->setItem(row, COLOR_COLUMN, colorItem);
        _ui->colorTable->setItem(row, INTENSE_COLOR_COLUMN, colorItemIntense);
288
        _ui->colorTable->setItem(row, FAINT_COLOR_COLUMN, colorItemFaint);
289
    }
290 291
    // ensure that color names are as fully visible as possible
    _ui->colorTable->resizeColumnToContents(0);
292 293 294

    // set the widget height to the table content
    _ui->colorTable->setFixedHeight(_ui->colorTable->verticalHeader()->length() + _ui->colorTable->horizontalHeader()->height() + 2);
295
}
296

297
ColorScheme& ColorSchemeEditor::colorScheme() const
298
{
299
    return *_colors;
300
}
Kurt Hindenburg's avatar
Kurt Hindenburg committed
301 302 303 304
bool ColorSchemeEditor::isNewScheme() const
{
    return _isNewScheme;
}
305 306 307 308
void ColorSchemeEditor::saveColorScheme()
{
    emit colorSchemeSaveRequested(colorScheme(), _isNewScheme);
}
309