diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9757466f..c37b3243 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -81,6 +81,7 @@ set(QTERM_SRC
src/propertiesdialog.cpp
src/bookmarkswidget.cpp
src/fontdialog.cpp
+ src/palettedialog.cpp
src/dbusaddressable.cpp
src/tab-switcher.cpp
src/qterminalutils.cpp
@@ -96,6 +97,7 @@ set(QTERM_MOC_SRC
src/propertiesdialog.h
src/bookmarkswidget.h
src/fontdialog.h
+ src/palettedialog.h
src/tab-switcher.h
)
@@ -128,6 +130,7 @@ set(QTERM_UI_SRC
src/forms/propertiesdialog.ui
src/forms/bookmarkswidget.ui
src/forms/fontdialog.ui
+ src/forms/palettedialog.ui
)
set(QTERM_RCC_SRC
diff --git a/src/forms/palettedialog.ui b/src/forms/palettedialog.ui
new file mode 100644
index 00000000..44eabcc9
--- /dev/null
+++ b/src/forms/palettedialog.ui
@@ -0,0 +1,565 @@
+
+
+ PaletteDialog
+
+
+
+ 0
+ 0
+ 450
+ 377
+
+
+
+ Chose your colors
+
+
+ true
+
+
+ -
+
+
+
+ 18
+
+
+
+ TextLabel
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
+ Drop a color
+
+
+
-
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Blue
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Dark Gray
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Light Gray
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Green
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Black
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Yellow
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Foreground
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Cyan
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Green
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Intense Background
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Intense Foreground
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Background
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Magenta
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Cyan
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Blue
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ White
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Red
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Red
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Bright Magenta
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+ QFrame::Shape::StyledPanel
+
+
+ Yellow
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ 4
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Color dialog
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
+
+
+ false
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ PaletteDialog
+ accept()
+
+
+ 226
+ 313
+
+
+ 226
+ 167
+
+
+
+
+ buttonBox
+ rejected()
+ PaletteDialog
+ reject()
+
+
+ 226
+ 313
+
+
+ 226
+ 167
+
+
+
+
+
diff --git a/src/forms/propertiesdialog.ui b/src/forms/propertiesdialog.ui
index 5090c3ae..3b5d38e2 100644
--- a/src/forms/propertiesdialog.ui
+++ b/src/forms/propertiesdialog.ui
@@ -6,14 +6,14 @@
0
0
- 700
- 700
+ 763
+ 638
Terminal settings
-
+
-
-
@@ -21,8 +21,7 @@
Appearance
-
- ..
+
-
@@ -38,8 +37,7 @@
Behavior
-
- ..
+
-
@@ -47,8 +45,7 @@
Shortcuts
-
- ..
+
-
@@ -56,8 +53,7 @@
Dropdown
-
- ..
+
-
@@ -65,8 +61,7 @@
Bookmarks
-
- ..
+
@@ -74,7 +69,7 @@
-
- QFrame::StyledPanel
+ QFrame::Shape::StyledPanel
0
@@ -99,7 +94,7 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
true
@@ -109,138 +104,60 @@
0
0
- 441
- 659
+ 460
+ 667
-
-
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- Font
-
-
- changeFontButton
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- QFrame::StyledPanel
-
-
-
-
-
- false
-
-
-
- -
-
-
- &Change...
-
-
-
-
-
-
- -
-
+
+
-
+
- Color scheme
+ Cursor shape
- colorSchemaCombo
+ keybCursorShape_comboBox
- -
-
+
-
+
- -
-
-
- Widget style
-
-
- styleComboBox
+
-
+
+
+ false
-
-
- -
-
-
- -
-
-
- Scrollbar position
+
+
+ 0
+ 0
+
-
- scrollBarPos_comboBox
+
+
-
-
- -
-
-
- -
-
-
- Tabs position
+
+ QToolButton::ToolButtonPopupMode::InstantPopup
-
- tabsPos_comboBox
+
+ Qt::ToolButtonStyle::ToolButtonIconOnly
- -
-
-
- -
-
+
-
+
+
+ QFrame::Shape::StyledPanel
+
- Cursor shape
+
-
- keybCursorShape_comboBox
+
+ false
- -
-
-
- -
+
-
Toggles usage of bold font face for rendering intense colors
@@ -250,64 +167,27 @@
- -
-
-
- Show terminal size on resize
-
-
-
- -
-
-
- Enable bi-directional text support
-
-
+
-
+
- -
-
-
- Specify whether box drawing characters should be drawn by QTerminal internally or left to underlying font rendering libraries.
-
+
-
+
- Use box drawing characters contained in the font
+ Color scheme
- -
-
+
-
+
- Terminal transparency
+ Tabs position
- termTransparencyBox
-
-
-
- -
-
-
- %
-
-
- 0
-
-
- 100
-
-
- 0
-
-
-
- -
-
-
- Background image:
+ tabsPos_comboBox
- -
+
-
-
@@ -322,13 +202,48 @@
-
-
+
- Background mode:
+ Background image:
- -
+
-
+
+
+ &Change...
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Font
+
+
+ changeFontButton
+
+
+
+
+
+
+ -
-
@@ -357,17 +272,54 @@
- -
-
-
- Start with preset:
+
-
+
+
+ Current Terminal
-
- terminalPresetComboBox
+
+
-
+
+
+ Draw a border
+
+
+
+ -
+
+
+ Set the current terminal on mouseover
+
+
+
+ -
+
+
+ Change window title based on the terminal
+
+
+
+ -
+
+
+ Change window icon based on the terminal
+
+
+
+
+
+
+ -
+
+
+ Specify whether box drawing characters should be drawn by QTerminal internally or left to underlying font rendering libraries.
+
+
+ Use box drawing characters contained in the font
- -
+
-
-
@@ -391,7 +343,33 @@
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+ -
+
+
-
+
+
+ Start with preset:
+
+
+ terminalPresetComboBox
+
+
+
+ -
Terminal margin
@@ -401,62 +379,179 @@
- -
+
-
+
+
+ Show terminal size on resize
+
+
+
+ -
+
+
+ Terminal transparency
+
+
+ termTransparencyBox
+
+
+
+ -
+
+
+ %
+
+
+ 0
+
+
+ 100
+
+
+ 0
+
+
+
+ -
+
+
+ -
+
+
+ Background mode:
+
+
+
+ -
+
+
+ Scrollbar position
+
+
+ scrollBarPos_comboBox
+
+
+
+ -
px
- -
-
-
- Current Terminal
+
-
+
+
+ -
+
+
+ Enable bi-directional text support
-
-
-
-
-
- Draw a border
-
-
-
- -
-
-
- Set the current terminal on mouseover
-
-
-
- -
-
-
- Change window title based on the terminal
-
-
-
- -
-
-
- Change window icon based on the terminal
-
-
-
-
- -
-
-
- Qt::Vertical
+
-
+
+
+ 20
-
-
- 20
- 0
-
+
-
+
+
+ Night scheme from
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+ to
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Widget style
-
+
+ styleComboBox
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ QToolButton::ToolButtonPopupMode::InstantPopup
+
+
+ Qt::ToolButtonStyle::ToolButtonIconOnly
+
+
+
+ -
+
+
+ false
+
+
@@ -484,7 +579,7 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
true
@@ -494,8 +589,8 @@
0
0
- 454
- 248
+ 382
+ 318
@@ -627,10 +722,10 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
- QSizePolicy::MinimumExpanding
+ QSizePolicy::Policy::MinimumExpanding
@@ -645,7 +740,7 @@
-
- Qt::Vertical
+ Qt::Orientation::Vertical
@@ -681,7 +776,7 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
true
@@ -691,15 +786,15 @@
0
0
- 347
- 530
+ 330
+ 593
-
- Qt::Vertical
+ Qt::Orientation::Vertical
@@ -891,7 +986,7 @@
<html><head/><body><p>Which behavior to emulate. Note that this does not have to match your operating system.</p><p>If you are not sure, use the <span style=" font-weight:600;">default</span> emulation.</p></body></html>
- Qt::RichText
+ Qt::TextFormat::RichText
true
@@ -923,10 +1018,10 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)true
- QAbstractItemView::ScrollPerPixel
+ QAbstractItemView::ScrollMode::ScrollPerPixel
- QAbstractItemView::ScrollPerPixel
+ QAbstractItemView::ScrollMode::ScrollPerPixel
true
@@ -982,7 +1077,7 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)
- QFormLayout::ExpandingFieldsGrow
+ QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow
-
@@ -1047,7 +1142,7 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)
- Qt::Vertical
+ Qt::Orientation::Vertical
@@ -1117,7 +1212,7 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)
- QPlainTextEdit::NoWrap
+ QPlainTextEdit::LineWrapMode::NoWrap
@@ -1131,10 +1226,10 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)
- Qt::Horizontal
+ Qt::Orientation::Horizontal
- QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+ QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
@@ -1222,5 +1317,85 @@ To remove/disable a Shortcut, at point 2 press only a modifier (like Shift)
+
+ nightSchema
+ toggled(bool)
+ nightSchemaCombo
+ setEnabled(bool)
+
+
+ 351
+ 91
+
+
+ 446
+ 120
+
+
+
+
+ nightSchema
+ toggled(bool)
+ label_4
+ setEnabled(bool)
+
+
+ 351
+ 91
+
+
+ 496
+ 91
+
+
+
+
+ nightSchema
+ toggled(bool)
+ nightSchemaStart
+ setEnabled(bool)
+
+
+ 351
+ 91
+
+
+ 452
+ 90
+
+
+
+
+ nightSchema
+ toggled(bool)
+ nightSchemaEnd
+ setEnabled(bool)
+
+
+ 351
+ 91
+
+
+ 540
+ 90
+
+
+
+
+ nightSchema
+ toggled(bool)
+ configNightSchema
+ setEnabled(bool)
+
+
+ 352
+ 94
+
+
+ 725
+ 125
+
+
+
diff --git a/src/palettedialog.cpp b/src/palettedialog.cpp
new file mode 100644
index 00000000..6bc8db90
--- /dev/null
+++ b/src/palettedialog.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * Copyright (C) 2025 by Thomas Lübking *
+ * thomas.luebking@gmail.com *
+ * *
+ * 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, see . *
+ ***************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+
+#include "palettedialog.h"
+
+PaletteDialog::PaletteDialog(QWidget *parent) : QDialog(parent)
+{
+ setupUi(this);
+ QColorDialog *cd = new QColorDialog(this);
+ cd->hide();
+ connect (colorbutton, SIGNAL(clicked()), cd, SLOT(show()));
+ connect (colorbutton, SIGNAL(clicked()), cd, SLOT(raise()));
+ QList tileLabels = tiles->findChildren();
+ for (QLabel *l : tileLabels)
+ l->installEventFilter(this);
+}
+
+void PaletteDialog::setColorSchemeName(QString name)
+{
+ nameLabel->setText(name);
+}
+
+#define IS_BACKGROUND objectName().contains(QLatin1String("Background"))
+#define IS_INTENSE objectName().contains(QLatin1String("Intense"))
+
+QMap PaletteDialog::colors()
+{
+ QMap map;
+ QList tileLabels = tiles->findChildren();
+ for (QLabel *l : tileLabels)
+ map[l->objectName()] = l->palette().color(l->IS_BACKGROUND ? l->backgroundRole() : l->foregroundRole());
+ return map;
+}
+
+int PaletteDialog::setColors(QMap map)
+{
+ int match = 0;
+ for (auto i = map.cbegin(), end = map.cend(); i != end; ++i) {
+ if (QLabel *l = tiles->findChild(i.key())) {
+ setColor(l, i.value());
+ ++match;
+ }
+ }
+ return match;
+}
+
+void PaletteDialog::setColor(QLabel *l, QColor c)
+{
+ if (l->IS_BACKGROUND) {
+ bool intense = l->IS_INTENSE;
+ QList tileLabels = tiles->findChildren();
+ for (QLabel *fl : tileLabels) {
+ if (fl->IS_INTENSE == intense) {
+ QPalette pal = fl->palette();
+ pal.setColor(fl->backgroundRole(), c);
+ fl->setPalette(pal);
+ }
+ }
+ } else {
+ QPalette pal = l->palette();
+ pal.setColor(l->foregroundRole(), c);
+ l->setPalette(pal);
+ if (l->objectName().contains(QLatin1String("Foreground"))) {
+ const QString name = QString::fromLatin1(l->IS_INTENSE ? "BackgroundIntense" : "Background");
+ if (QLabel *bl = tiles->findChild(name)) // Q_ASSERT
+ bl->setPalette(pal);
+ }
+ }
+}
+
+bool PaletteDialog::eventFilter(QObject *o, QEvent *e) {
+ if (e->type() == QEvent::DragEnter) {
+ QDropEvent *de = static_cast(e);
+ de->mimeData()->hasColor() ? de->accept() : de->ignore();
+ return false;
+ }
+ if (e->type() == QEvent::Drop) {
+ QDropEvent *de = static_cast(e);
+ if (!de->mimeData()->hasColor())
+ return false;
+ if (QLabel *l = qobject_cast(o))
+ setColor(l, qvariant_cast(de->mimeData()->colorData()));
+ return false;
+ }
+ return false;
+}
diff --git a/src/palettedialog.h b/src/palettedialog.h
new file mode 100644
index 00000000..bef6a529
--- /dev/null
+++ b/src/palettedialog.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (C) 2025 by Thomas Lübking *
+ * thomas.luebking@gmail.com *
+ * *
+ * 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, see . *
+ ***************************************************************************/
+
+#ifndef PALETTEDIALOG_H
+#define PALETTEDIALOG_H
+
+#include
+#include
+#include "ui_palettedialog.h"
+
+class PaletteDialog : public QDialog, Ui::PaletteDialog
+{
+ Q_OBJECT
+public:
+ PaletteDialog(QWidget *parent = nullptr);
+ void setColorSchemeName(QString name);
+ QMap colors();
+ int setColors(QMap);
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+private:
+ void setColor(QLabel *l, QColor c);
+};
+
+#endif // PALETTEDIALOG_H
\ No newline at end of file
diff --git a/src/properties.cpp b/src/properties.cpp
index d455d1e0..da6ee9fb 100644
--- a/src/properties.cpp
+++ b/src/properties.cpp
@@ -81,6 +81,9 @@ void Properties::loadSettings()
QApplication::setStyle(guiStyle);
colorScheme = m_settings->value(QLatin1String("colorScheme"), QLatin1String("Linux")).toString();
+ nightScheme = m_settings->value(QLatin1String("nightScheme"), QLatin1String("")).toString();
+ nightStart = m_settings->value(QLatin1String("nightStart"), QTime(21,0)).toTime();
+ nightEnd = m_settings->value(QLatin1String("nightEnd"), QTime(7,0)).toTime();
highlightCurrentTerminal = m_settings->value(QLatin1String("highlightCurrentTerminal"), true).toBool();
focusOnMoueOver = m_settings->value(QLatin1String("focusOnMoueOver"), false).toBool();
@@ -188,6 +191,9 @@ void Properties::saveSettings()
{
m_settings->setValue(QLatin1String("guiStyle"), guiStyle);
m_settings->setValue(QLatin1String("colorScheme"), colorScheme);
+ m_settings->setValue(QLatin1String("nightScheme"), nightScheme);
+ m_settings->setValue(QLatin1String("nightStart"), nightStart);
+ m_settings->setValue(QLatin1String("nightEnd"), nightEnd);
m_settings->setValue(QLatin1String("highlightCurrentTerminal"), highlightCurrentTerminal);
m_settings->setValue(QLatin1String("focusOnMoueOver"), focusOnMoueOver);
m_settings->setValue(QLatin1String("showTerminalSizeHint"), showTerminalSizeHint);
diff --git a/src/properties.h b/src/properties.h
index 34cf0a92..d503f7a2 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
typedef QString Session;
@@ -55,6 +56,9 @@ class Properties
QStringList shell;
QFont font;
QString colorScheme;
+ QString nightScheme;
+ QTime nightStart;
+ QTime nightEnd;
QString guiStyle;
bool highlightCurrentTerminal;
bool focusOnMoueOver;
diff --git a/src/propertiesdialog.cpp b/src/propertiesdialog.cpp
index 49da1d27..57f78378 100644
--- a/src/propertiesdialog.cpp
+++ b/src/propertiesdialog.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -28,6 +29,7 @@
#include "propertiesdialog.h"
#include "properties.h"
#include "fontdialog.h"
+#include "palettedialog.h"
#include "config.h"
#include "qterminalapp.h"
@@ -144,7 +146,43 @@ PropertiesDialog::PropertiesDialog(QWidget *parent)
int csix = colorSchemaCombo->findText(Properties::Instance()->colorScheme);
if (csix != -1)
colorSchemaCombo->setCurrentIndex(csix);
-
+ nightSchemaCombo->addItems(colorSchemes);
+ nightSchema->setChecked(!Properties::Instance()->nightScheme.isEmpty());
+ nightSchemaStart->setTime(Properties::Instance()->nightStart);
+ nightSchemaEnd->setTime(Properties::Instance()->nightEnd);
+ if (nightSchema->isChecked()) {
+ csix = nightSchemaCombo->findText(Properties::Instance()->nightScheme);
+ if (csix != -1)
+ nightSchemaCombo->setCurrentIndex(csix);
+ }
+ QMenu *schemeActions = new QMenu(this);
+ QAction *csNewAct = schemeActions->addAction(tr("New…"));
+ QAction *csEditAct = schemeActions->addAction(tr("Edit…"));
+ QAction *csImportAct = schemeActions->addAction(tr("Import…"));
+ schemeActions->addSeparator();
+ QAction *csDeleteAct = schemeActions->addAction(tr("Delete"));
+ configColorSchema->setMenu(schemeActions);
+ configNightSchema->setMenu(schemeActions);
+ connect(configColorSchema, &QToolButton::triggered, [=](QAction *act) {
+ if (act == csNewAct)
+ newColorScheme(colorSchemaCombo);
+ else if (act == csEditAct)
+ editColorScheme(colorSchemaCombo);
+ else if (act == csImportAct)
+ importColorScheme(colorSchemaCombo);
+ else if (act == csDeleteAct)
+ deleteColorScheme(colorSchemaCombo);
+ });
+ connect(configNightSchema, &QToolButton::triggered, [=](QAction *act) {
+ if (act == csNewAct)
+ newColorScheme(nightSchemaCombo);
+ else if (act == csEditAct)
+ editColorScheme(nightSchemaCombo);
+ else if (act == csImportAct)
+ importColorScheme(nightSchemaCombo);
+ else if (act == csDeleteAct)
+ deleteColorScheme(nightSchemaCombo);
+ });
backgroundImageLineEdit->setText(Properties::Instance()->backgroundImage);
backgroundModecomboBox->setCurrentIndex(Properties::Instance()->backgroundMode);
@@ -325,6 +363,9 @@ void PropertiesDialog::accept()
void PropertiesDialog::apply()
{
Properties::Instance()->colorScheme = colorSchemaCombo->currentText();
+ Properties::Instance()->nightScheme = nightSchema->isChecked() ? nightSchemaCombo->currentText() : QString();
+ Properties::Instance()->nightStart = nightSchemaStart->time();
+ Properties::Instance()->nightEnd = nightSchemaEnd->time();
Properties::Instance()->font = fontSampleLabel->font();//fontComboBox->currentFont();
Properties::Instance()->guiStyle = (styleComboBox->currentText() == tr("System Default")) ?
QString() : styleComboBox->currentText();
@@ -683,6 +724,163 @@ bool PropertiesDialog::eventFilter(QObject *object, QEvent *event)
return QDialog::eventFilter(object, event);
}
+void PropertiesDialog::newColorScheme(QComboBox *target)
+{
+ QString newName;
+ bool ok = false;
+ while (!ok) {
+ newName = QInputDialog::getText(this, tr("New Colorscheme"),
+ tr("Enter the name of the new colorscheme"),
+ QLineEdit::Normal, newName, &ok);
+ if (!ok)
+ return;
+ if (newName.contains(QLatin1Char('.'))) { // not allowed, see comment in ::import()
+ ok = false;
+ newName.replace(QLatin1Char('.'), QLatin1Char('-'));
+ continue;
+ }
+ if (target->findText(newName) > -1) {
+ ok = false;
+ for (int i = 1;;++i) {
+ if (target->findText(newName + QString::fromLatin1("_%1").arg(i)) < 0) {
+ newName = newName + QString::fromLatin1("_%1").arg(i);
+ break;
+ }
+ }
+ }
+ }
+ // create and edit newName
+ colorSchemaCombo->addItem(newName);
+ nightSchemaCombo->addItem(newName);
+ target->setCurrentText(newName);
+ editColorScheme(target);
+}
+
+void PropertiesDialog::editColorScheme(QComboBox *target)
+{
+ QString name = target->currentText();
+ QString writable = QFileInfo(QSettings().fileName()).canonicalPath() + QLatin1String("/color-schemes/")
+ + name + QLatin1String(".colorscheme");
+ QString readable;
+ QSettings *scheme = nullptr;
+ if (QFile::exists(writable)) {
+ scheme = new QSettings(writable, QSettings::IniFormat);
+ } else {
+ QStringList dirs = QStandardPaths::locateAll( QStandardPaths::GenericDataLocation,
+ QCoreApplication::applicationName(),
+ QStandardPaths::LocateDirectory)
+ + QStandardPaths::locateAll( QStandardPaths::GenericDataLocation,
+ QLatin1String("qtermwidget6"),
+ QStandardPaths::LocateDirectory);
+ dirs.removeDuplicates(); // QStandardPaths::locateAll() produces duplicates
+
+ for (const QString& dir : std::as_const(dirs)) {
+ readable = dir + QLatin1String("/color-schemes/") + name + QLatin1String(".colorscheme");
+ if (QFile::exists(readable)) {
+ scheme = new QSettings(readable, QSettings::IniFormat);
+ break;
+ }
+ }
+ }
+ PaletteDialog dlg;
+ dlg.setColorSchemeName(name);
+
+ QMap colors;
+ if (scheme) {
+ QStringList keys = scheme->allKeys().filter(QLatin1String("/Color"));
+ for (const QString &key : std::as_const(keys)) {
+ QStringList nac = scheme->value(key).toStringList();
+ if (nac.size() < 3) {
+ qDebug() << "not a color" << key << scheme->value(key);
+ continue;
+ }
+ colors[key.section(QLatin1Char('/'),0,0)] = QColor(nac.at(0).toShort(), nac.at(1).toShort(), nac.at(2).toShort());
+ }
+ }
+ dlg.setColors(colors);
+
+ if (dlg.exec()) {
+ if (!readable.isEmpty())
+ QFile::copy(readable, writable);
+ if (scheme && scheme->fileName() != writable) {
+ delete scheme;
+ scheme = nullptr;
+ }
+ if (!scheme)
+ scheme = new QSettings(writable, QSettings::IniFormat);
+ colors = dlg.colors();
+ for (auto i = colors.cbegin(), end = colors.cend(); i != end; ++i) {
+ QColor c = i.value();
+ QStringList nac;
+ nac << QString::number(c.red()) << QString::number(c.green()) << QString::number(c.blue());
+ scheme->setValue(i.key() + QLatin1String("/Color"), nac);
+ }
+ scheme->sync();
+ }
+ delete scheme;
+}
+
+void PropertiesDialog::importColorScheme(QComboBox *target)
+{
+ Q_UNUSED(target)
+ const QString dir = QFileInfo(QSettings().fileName()).canonicalPath() + QLatin1String("/color-schemes/");
+ QStringList imports = QFileDialog::getOpenFileNames(this, tr("Import Color Schemes"),
+ QString(), QString::fromLatin1("*.colorscheme"));
+ if (imports.isEmpty())
+ return;
+ if (!QDir(dir).exists())
+ QDir().mkpath(dir);
+ QStringList baddies, collies;
+ for (QString import : imports) {
+ if (!QSettings(import, QSettings::IniFormat).allKeys().contains(QString::fromLatin1("Color0/Color"))) {
+ baddies << import;
+ continue;
+ }
+ // sanitize name. QTermWidget handles them by the files basename, if the import includes
+ // multiple dots like "fancy.dark.colorscheme" this will cause a collision there
+ // so we need to make sure the imports stay unambigious and replace inner dot's with
+ // dashes ("·" would be nice by maybe don't rely on utf8 too much)
+ QString newName = QFileInfo(import).fileName();
+ newName = newName.left(newName.lastIndexOf(QLatin1String(".colorscheme"), -1))
+ .replace(QLatin1Char('.'), QLatin1Char('-'));
+
+ QString dst = dir + newName + QLatin1String(".colorscheme");
+ if (QFile::exists(dst)) {
+ collies << import;
+ continue;
+ }
+ QFile::copy(import, dst);
+ colorSchemaCombo->addItem(newName);
+ nightSchemaCombo->addItem(newName);
+ }
+ /// @todo QTermWidget doesn't pick up in the new items
+ if (!(baddies.isEmpty() && collies.isEmpty())) {
+ QString message;
+ if (!baddies.isEmpty())
+ message += tr("These files don't have a Color0/Color entry - not color schemes?- ")
+ + baddies.join(QString::fromLatin1("
- ")) + QString::fromLatin1("
");
+ if (!collies.isEmpty())
+ message += tr("These schemes already exist- ")
+ + collies.join(QString::fromLatin1("
- ")) + QString::fromLatin1("
");
+ QMessageBox::warning(this, tr("Some files could not be imported"), message);
+ }
+}
+
+void PropertiesDialog::deleteColorScheme(QComboBox *target)
+{
+ const QString name = target->currentText();
+ QString path = QFileInfo(QSettings().fileName()).canonicalPath() + QLatin1String("/color-schemes/")
+ + name + QLatin1String(".colorscheme");
+ if (QFile::exists(path)) {
+ QFile::remove(path);
+ colorSchemaCombo->removeItem(colorSchemaCombo->findText(name));
+ nightSchemaCombo->removeItem(nightSchemaCombo->findText(name));
+ return;
+ }
+ QMessageBox::warning(this, tr("%1 could not be removed").arg(target->currentText()),
+ tr("%1 is not a personal scheme and could not be removed").arg(target->currentText()));
+}
+
/*
void PropertiesDialog::setupShortcuts()
{
diff --git a/src/propertiesdialog.h b/src/propertiesdialog.h
index 4ebbd263..50961545 100644
--- a/src/propertiesdialog.h
+++ b/src/propertiesdialog.h
@@ -76,6 +76,11 @@ class PropertiesDialog : public QDialog, Ui::PropertiesDialog
KeySequenceEdit *dropShortCutEdit;
QPushButton *exampleBookmarksButton;
+ void newColorScheme(QComboBox *target);
+ void editColorScheme(QComboBox *target);
+ void importColorScheme(QComboBox *target);
+ void deleteColorScheme(QComboBox *target);
+
private slots:
void apply();
void accept() override;