1 /***********************************************************************
2 *
3 * Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2019 Graeme Gott <graeme@gottcode.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***********************************************************************/
19
20 #include "theme_dialog.h"
21
22 #include "color_button.h"
23 #include "font_combobox.h"
24 #include "image_button.h"
25 #include "theme.h"
26 #include "theme_renderer.h"
27
28 #include <QApplication>
29 #include <QCheckBox>
30 #include <QComboBox>
31 #include <QDesktopWidget>
32 #include <QDialogButtonBox>
33 #include <QDoubleValidator>
34 #include <QFile>
35 #include <QFormLayout>
36 #include <QGroupBox>
37 #include <QImageReader>
38 #include <QLabel>
39 #include <QLineEdit>
40 #include <QScrollArea>
41 #include <QSettings>
42 #include <QSpinBox>
43 #include <QTabWidget>
44 #include <QVBoxLayout>
45
46 #include <cmath>
47
48 //-----------------------------------------------------------------------------
49
50 // Exported by QtGui
51 void qt_blurImage(QPainter* p, QImage& blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
52
53 //-----------------------------------------------------------------------------
54
ThemeDialog(Theme & theme,QWidget * parent)55 ThemeDialog::ThemeDialog(Theme& theme, QWidget* parent)
56 : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint),
57 m_theme(theme)
58 {
59 setWindowTitle(tr("Edit Theme"));
60 setWindowModality(Qt::WindowModal);
61
62 // Create name edit
63 m_name = new QLineEdit(this);
64 m_name->setText(m_theme.name());
65 connect(m_name, &QLineEdit::textChanged, this, &ThemeDialog::checkNameAvailable);
66
67 QHBoxLayout* name_layout = new QHBoxLayout;
68 name_layout->setContentsMargins(0, 0, 0, 0);
69 name_layout->addWidget(new QLabel(tr("Name:"), this));
70 name_layout->addWidget(m_name);
71
72
73 // Create scrollarea
74 QWidget* contents = new QWidget(this);
75
76 QScrollArea* scroll = new QScrollArea(this);
77 scroll->setWidget(contents);
78 scroll->setWidgetResizable(true);
79
80
81 // Create text group
82 QGroupBox* text_group = new QGroupBox(tr("Text"), contents);
83
84 m_text_color = new ColorButton(text_group);
85 m_text_color->setColor(m_theme.textColor());
86 connect(m_text_color, &ColorButton::changed, this, &ThemeDialog::renderPreview);
87
88 m_font_names = new FontComboBox(text_group);
89 m_font_names->setEditable(false);
90 m_font_names->setCurrentFont(m_theme.textFont());
91 connect(m_font_names, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::fontChanged);
92 connect(m_font_names, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::renderPreview);
93
94 m_font_sizes = new QComboBox(text_group);
95 m_font_sizes->setEditable(true);
96 m_font_sizes->setMinimumContentsLength(3);
97 connect(m_font_sizes, &QComboBox::editTextChanged, this, &ThemeDialog::renderPreview);
98 fontChanged();
99
100 m_misspelled_color = new ColorButton(text_group);
101 m_misspelled_color->setColor(m_theme.misspelledColor());
102 connect(m_misspelled_color, &ColorButton::changed, this, &ThemeDialog::renderPreview);
103
104 QHBoxLayout* font_layout = new QHBoxLayout;
105 font_layout->addWidget(m_font_names);
106 font_layout->addWidget(m_font_sizes);
107
108 QFormLayout* text_layout = new QFormLayout(text_group);
109 text_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
110 text_layout->addRow(tr("Color:"), m_text_color);
111 text_layout->addRow(tr("Font:"), font_layout);
112 text_layout->addRow(tr("Misspelled:"), m_misspelled_color);
113
114
115 // Create background group
116 QGroupBox* background_group = new QGroupBox(tr("Window Background"), contents);
117
118 m_background_color = new ColorButton(background_group);
119 m_background_color->setColor(m_theme.backgroundColor());
120 connect(m_background_color, &ColorButton::changed, this, &ThemeDialog::renderPreview);
121
122 m_background_image = new ImageButton(background_group);
123 m_background_image->setImage(m_theme.backgroundImage(), m_theme.backgroundPath());
124 connect(m_background_image, &ImageButton::changed, this, &ThemeDialog::imageChanged);
125
126 m_clear_image = new QPushButton(tr("Remove"), background_group);
127 connect(m_clear_image, &QPushButton::clicked, m_background_image, &ImageButton::unsetImage);
128
129 m_background_type = new QComboBox(background_group);
130 m_background_type->addItems(QStringList() << tr("No Image") << tr("Tiled") << tr("Centered") << tr("Stretched") << tr("Scaled") << tr("Zoomed"));
131 m_background_type->setCurrentIndex(m_theme.backgroundType());
132 connect(m_background_type, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::renderPreview);
133
134 QVBoxLayout* image_layout = new QVBoxLayout;
135 image_layout->setSpacing(0);
136 image_layout->setContentsMargins(0, 0, 0, 0);
137 image_layout->addWidget(m_background_image);
138 image_layout->addWidget(m_clear_image);
139
140 QFormLayout* background_layout = new QFormLayout(background_group);
141 background_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
142 background_layout->addRow(tr("Color:"), m_background_color);
143 background_layout->addRow(tr("Image:"), image_layout);
144 background_layout->addRow(tr("Type:"), m_background_type);
145
146
147 // Create foreground group
148 QGroupBox* foreground_group = new QGroupBox(tr("Text Background"), contents);
149
150 m_foreground_color = new ColorButton(foreground_group);
151 m_foreground_color->setColor(m_theme.foregroundColor());
152 connect(m_foreground_color, &ColorButton::changed, this, &ThemeDialog::renderPreview);
153
154 m_foreground_opacity = new QSpinBox(foreground_group);
155 m_foreground_opacity->setCorrectionMode(QSpinBox::CorrectToNearestValue);
156 m_foreground_opacity->setSuffix(QLocale().percent());
157 m_foreground_opacity->setRange(theme.foregroundOpacity().minimumValue(), theme.foregroundOpacity().maximumValue());
158 m_foreground_opacity->setValue(m_theme.foregroundOpacity());
159 connect(m_foreground_opacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
160
161 m_foreground_position = new QComboBox(foreground_group);
162 m_foreground_position->addItems(QStringList() << tr("Left") << tr("Centered") << tr("Right") << tr("Stretched"));
163 m_foreground_position->setCurrentIndex(m_theme.foregroundPosition());
164 connect(m_foreground_position, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::positionChanged);
165
166 m_foreground_width = new QSpinBox(foreground_group);
167 m_foreground_width->setCorrectionMode(QSpinBox::CorrectToNearestValue);
168 m_foreground_width->setSuffix(tr(" pixels"));
169 m_foreground_width->setRange(theme.foregroundWidth().minimumValue(), theme.foregroundWidth().maximumValue());
170 m_foreground_width->setValue(m_theme.foregroundWidth());
171 m_foreground_width->setEnabled(m_theme.foregroundPosition() != 3);
172 connect(m_foreground_width, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
173
174 QFormLayout* foreground_layout = new QFormLayout(foreground_group);
175 foreground_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
176 foreground_layout->addRow(tr("Color:"), m_foreground_color);
177 foreground_layout->addRow(tr("Opacity:"), m_foreground_opacity);
178 foreground_layout->addRow(tr("Position:"), m_foreground_position);
179 foreground_layout->addRow(tr("Width:"), m_foreground_width);
180
181
182 // Create rounding group
183 m_round_corners = new QGroupBox(tr("Round Text Background Corners"), contents);
184 m_round_corners->setCheckable(true);
185 m_round_corners->setChecked(m_theme.roundCornersEnabled());
186 connect(m_round_corners, &QGroupBox::clicked, this, &ThemeDialog::renderPreview);
187
188 m_corner_radius = new QSpinBox(m_round_corners);
189 m_corner_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
190 m_corner_radius->setSuffix(tr(" pixels"));
191 m_corner_radius->setRange(theme.cornerRadius().minimumValue(), theme.cornerRadius().maximumValue());
192 m_corner_radius->setValue(m_theme.cornerRadius());
193 connect(m_corner_radius, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
194
195 QFormLayout* corner_layout = new QFormLayout(m_round_corners);
196 corner_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
197 corner_layout->addRow(tr("Radius:"), m_corner_radius);
198
199
200 // Create blur group
201 m_blur = new QGroupBox(tr("Blur Text Background"), contents);
202 m_blur->setCheckable(true);
203 m_blur->setChecked(m_theme.blurEnabled());
204 connect(m_blur, &QGroupBox::clicked, this, &ThemeDialog::renderPreview);
205
206 m_blur_radius = new QSpinBox(m_blur);
207 m_blur_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
208 m_blur_radius->setSuffix(tr(" pixels"));
209 m_blur_radius->setRange(theme.blurRadius().minimumValue(), theme.blurRadius().maximumValue());
210 m_blur_radius->setValue(m_theme.blurRadius());
211 connect(m_blur_radius, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
212
213 QFormLayout* blur_layout = new QFormLayout(m_blur);
214 blur_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
215 blur_layout->addRow(tr("Radius:"), m_blur_radius);
216
217
218 // Create shadow group
219 m_shadow = new QGroupBox(tr("Text Background Drop Shadow"), contents);
220 m_shadow->setCheckable(true);
221 m_shadow->setChecked(m_theme.shadowEnabled());
222 connect(m_shadow, &QGroupBox::clicked, this, &ThemeDialog::renderPreview);
223
224 m_shadow_color = new ColorButton(m_shadow);
225 m_shadow_color->setColor(m_theme.shadowColor());
226 connect(m_shadow_color, &ColorButton::changed, this, &ThemeDialog::renderPreview);
227
228 m_shadow_radius = new QSpinBox(m_shadow);
229 m_shadow_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
230 m_shadow_radius->setSuffix(tr(" pixels"));
231 m_shadow_radius->setRange(theme.shadowRadius().minimumValue(), theme.shadowRadius().maximumValue());
232 m_shadow_radius->setValue(m_theme.shadowRadius());
233 connect(m_shadow_radius, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
234
235 m_shadow_offset = new QSpinBox(m_shadow);
236 m_shadow_offset->setCorrectionMode(QSpinBox::CorrectToNearestValue);
237 m_shadow_offset->setSuffix(tr(" pixels"));
238 m_shadow_offset->setRange(theme.shadowOffset().minimumValue(), theme.shadowOffset().maximumValue());
239 m_shadow_offset->setValue(m_theme.shadowOffset());
240 connect(m_shadow_offset, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
241
242 QFormLayout* shadow_layout = new QFormLayout(m_shadow);
243 shadow_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
244 shadow_layout->addRow(tr("Color:"), m_shadow_color);
245 shadow_layout->addRow(tr("Radius:"), m_shadow_radius);
246 shadow_layout->addRow(tr("Vertical Offset:"), m_shadow_offset);
247
248
249 // Create margins group
250 QGroupBox* margins_group = new QGroupBox(tr("Margins"), contents);
251
252 m_foreground_margin = new QSpinBox(margins_group);
253 m_foreground_margin->setCorrectionMode(QSpinBox::CorrectToNearestValue);
254 m_foreground_margin->setSuffix(tr(" pixels"));
255 m_foreground_margin->setRange(theme.foregroundMargin().minimumValue(), theme.foregroundMargin().maximumValue());
256 m_foreground_margin->setValue(m_theme.foregroundMargin());
257 connect(m_foreground_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
258
259 m_foreground_padding = new QSpinBox(margins_group);
260 m_foreground_padding->setCorrectionMode(QSpinBox::CorrectToNearestValue);
261 m_foreground_padding->setSuffix(tr(" pixels"));
262 m_foreground_padding->setRange(theme.foregroundPadding().minimumValue(), theme.foregroundPadding().maximumValue());
263 m_foreground_padding->setValue(m_theme.foregroundPadding());
264 connect(m_foreground_padding, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
265
266 QFormLayout* margins_layout = new QFormLayout(margins_group);
267 margins_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
268 margins_layout->addRow(tr("Window:"), m_foreground_margin);
269 margins_layout->addRow(tr("Page:"), m_foreground_padding);
270
271
272 // Create line spacing group
273 QGroupBox* line_spacing = new QGroupBox(tr("Line Spacing"), contents);
274
275 m_line_spacing_type = new QComboBox(line_spacing);
276 m_line_spacing_type->setEditable(false);
277 m_line_spacing_type->addItems(QStringList() << tr("Single") << tr("1.5 Lines") << tr("Double") << tr("Proportional"));
278 m_line_spacing_type->setCurrentIndex(3);
279
280 m_line_spacing = new QSpinBox(line_spacing);
281 m_line_spacing->setSuffix(QLocale().percent());
282 m_line_spacing->setRange(theme.lineSpacing().minimumValue(), theme.lineSpacing().maximumValue());
283 m_line_spacing->setValue(m_theme.lineSpacing());
284 m_line_spacing->setEnabled(false);
285
286 switch (m_theme.lineSpacing()) {
287 case 100: m_line_spacing_type->setCurrentIndex(0); break;
288 case 150: m_line_spacing_type->setCurrentIndex(1); break;
289 case 200: m_line_spacing_type->setCurrentIndex(2); break;
290 default: m_line_spacing->setEnabled(true); break;
291 }
292 connect(m_line_spacing_type, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::lineSpacingChanged);
293 connect(m_line_spacing_type, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeDialog::renderPreview);
294 connect(m_line_spacing, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
295
296 QFormLayout* line_spacing_layout = new QFormLayout(line_spacing);
297 line_spacing_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
298 line_spacing_layout->addRow(tr("Type:"), m_line_spacing_type);
299 line_spacing_layout->addRow(tr("Height:"), m_line_spacing);
300
301
302 // Create paragraph spacing group
303 QGroupBox* paragraph_spacing = new QGroupBox(tr("Paragraph Spacing"), contents);
304
305 m_tab_width = new QSpinBox(paragraph_spacing);
306 m_tab_width->setSuffix(tr(" pixels"));
307 m_tab_width->setRange(theme.tabWidth().minimumValue(), theme.tabWidth().maximumValue());
308 m_tab_width->setValue(m_theme.tabWidth());
309 connect(m_tab_width, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
310
311 m_spacing_above_paragraph = new QSpinBox(paragraph_spacing);
312 m_spacing_above_paragraph->setSuffix(tr(" pixels"));
313 m_spacing_above_paragraph->setRange(theme.spacingAboveParagraph().minimumValue(), theme.spacingAboveParagraph().maximumValue());
314 m_spacing_above_paragraph->setValue(m_theme.spacingAboveParagraph());
315 connect(m_spacing_above_paragraph, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
316
317 m_spacing_below_paragraph = new QSpinBox(paragraph_spacing);
318 m_spacing_below_paragraph->setSuffix(tr(" pixels"));
319 m_spacing_below_paragraph->setRange(theme.spacingBelowParagraph().minimumValue(), theme.spacingBelowParagraph().maximumValue());
320 m_spacing_below_paragraph->setValue(m_theme.spacingBelowParagraph());
321 connect(m_spacing_below_paragraph, QOverload<int>::of(&QSpinBox::valueChanged), this, &ThemeDialog::renderPreview);
322
323 m_indent_first_line = new QCheckBox(tr("Indent first line"), paragraph_spacing);
324 m_indent_first_line->setChecked(m_theme.indentFirstLine());
325 connect(m_indent_first_line, &QCheckBox::toggled, this, &ThemeDialog::renderPreview);
326
327 QFormLayout* paragraph_spacing_layout = new QFormLayout(paragraph_spacing);
328 paragraph_spacing_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
329 paragraph_spacing_layout->addRow(tr("Tab Width:"), m_tab_width);
330 paragraph_spacing_layout->addRow(tr("Above:"), m_spacing_above_paragraph);
331 paragraph_spacing_layout->addRow(tr("Below:"), m_spacing_below_paragraph);
332 paragraph_spacing_layout->addRow("", m_indent_first_line);
333
334
335 // Create preview
336 m_preview = new QLabel(this);
337 m_preview->setAlignment(Qt::AlignCenter);
338 m_preview->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
339
340 QPixmap pixmap(480, 270);
341 pixmap.fill(palette().window().color());
342 m_preview->setPixmap(pixmap);
343
344 m_theme_renderer = new ThemeRenderer(this);
345 connect(m_theme_renderer, &ThemeRenderer::rendered, this, &ThemeDialog::renderText);
346 renderPreview();
347
348
349 // Lay out dialog
350 QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
351 m_ok = buttons->button(QDialogButtonBox::Ok);
352 connect(buttons, &QDialogButtonBox::accepted, this, &ThemeDialog::accept);
353 connect(buttons, &QDialogButtonBox::rejected, this, &ThemeDialog::reject);
354
355 QVBoxLayout* groups_layout = new QVBoxLayout(contents);
356 groups_layout->addWidget(text_group);
357 groups_layout->addWidget(background_group);
358 groups_layout->addWidget(foreground_group);
359 groups_layout->addWidget(m_round_corners);
360 groups_layout->addWidget(m_blur);
361 groups_layout->addWidget(m_shadow);
362 groups_layout->addWidget(margins_group);
363 groups_layout->addWidget(line_spacing);
364 groups_layout->addWidget(paragraph_spacing);
365
366 QGridLayout* layout = new QGridLayout(this);
367 layout->setColumnStretch(0, 1);
368 layout->setRowStretch(1, 1);
369 layout->setRowMinimumHeight(2, layout->contentsMargins().top());
370 layout->addLayout(name_layout, 0, 0, 1, 2);
371 layout->addWidget(scroll, 1, 0, 1, 1);
372 layout->addWidget(m_preview, 1, 1, 1, 1, Qt::AlignCenter);
373 layout->addWidget(buttons, 3, 0, 1, 2);
374
375 resize(QSettings().value("ThemeDialog/Size", sizeHint()).toSize());
376 }
377
378 //-----------------------------------------------------------------------------
379
~ThemeDialog()380 ThemeDialog::~ThemeDialog()
381 {
382 m_theme_renderer->wait();
383 }
384
385 //-----------------------------------------------------------------------------
386
accept()387 void ThemeDialog::accept()
388 {
389 m_theme.setName(m_name->text().simplified());
390 setValues(m_theme);
391 if (!m_theme.isDefault()) {
392 m_theme.setLoadColor(m_load_color);
393 }
394 m_theme.saveChanges();
395
396 savePreview();
397
398 QDialog::accept();
399 }
400
401 //-----------------------------------------------------------------------------
402
hideEvent(QHideEvent * event)403 void ThemeDialog::hideEvent(QHideEvent* event)
404 {
405 QSettings().setValue("ThemeDialog/Size", size());
406 QDialog::hideEvent(event);
407 }
408
409 //-----------------------------------------------------------------------------
410
checkNameAvailable()411 void ThemeDialog::checkNameAvailable()
412 {
413 QString name = m_name->text().simplified();
414 bool empty = name.isEmpty();
415 bool changed = (name != m_theme.name());
416 bool exists = Theme::exists(name);
417 m_ok->setEnabled(!changed || (!empty && !exists));
418 }
419
420 //-----------------------------------------------------------------------------
421
fontChanged()422 void ThemeDialog::fontChanged()
423 {
424 QFontDatabase db;
425
426 QFont font = m_font_names->currentFont();
427 QList<int> font_sizes = db.smoothSizes(font.family(), QString());
428 if (font_sizes.isEmpty()) {
429 font_sizes = db.standardSizes();
430 }
431 qreal font_size = m_font_sizes->currentText().toDouble();
432 if (font_size < 0.1) {
433 font_size = std::lround(m_theme.textFont().pointSizeF() * 10.0) * 0.1;
434 }
435
436 m_font_sizes->blockSignals(true);
437 m_font_sizes->clear();
438 int index = 0;
439 for (int i = 0; i < font_sizes.count(); ++i) {
440 int size = font_sizes.at(i);
441 if (size <= font_size) {
442 index = i;
443 }
444 m_font_sizes->addItem(QString::number(size));
445 }
446 m_font_sizes->setCurrentIndex(index);
447 m_font_sizes->setEditText(QString::number(font_size));
448 m_font_sizes->setValidator(new QDoubleValidator(font_sizes.first(), font_sizes.last(), 1, m_font_sizes));
449 m_font_sizes->blockSignals(false);
450 }
451
452 //-----------------------------------------------------------------------------
453
imageChanged()454 void ThemeDialog::imageChanged()
455 {
456 if (!m_background_image->image().isEmpty()) {
457 QSize image = QImageReader(m_background_image->image()).size();
458 QSize desktop = QApplication::desktop()->size();
459 if ((image.width() * image.height() * 4) <= (desktop.width() * desktop.height())) {
460 m_background_type->setCurrentIndex(1);
461 } else if (m_background_type->currentIndex() < 2) {
462 m_background_type->setCurrentIndex(5);
463 }
464 } else {
465 m_background_type->setCurrentIndex(0);
466 }
467 renderPreview();
468 }
469
470 //-----------------------------------------------------------------------------
471
lineSpacingChanged(int index)472 void ThemeDialog::lineSpacingChanged(int index)
473 {
474 switch (index) {
475 case 0:
476 m_line_spacing->setValue(100);
477 m_line_spacing->setEnabled(false);
478 break;
479
480 case 1:
481 m_line_spacing->setValue(150);
482 m_line_spacing->setEnabled(false);
483 break;
484
485 case 2:
486 m_line_spacing->setValue(200);
487 m_line_spacing->setEnabled(false);
488 break;
489
490 default:
491 m_line_spacing->setEnabled(true);
492 break;
493 }
494 }
495
496 //-----------------------------------------------------------------------------
497
positionChanged(int index)498 void ThemeDialog::positionChanged(int index)
499 {
500 m_foreground_width->setEnabled(index != 3);
501 renderPreview();
502 }
503
504 //-----------------------------------------------------------------------------
505
renderPreview()506 void ThemeDialog::renderPreview()
507 {
508 m_clear_image->setEnabled(m_background_image->isEnabled() && !m_background_image->image().isEmpty());
509
510 // Load theme
511 Theme theme;
512 setValues(theme);
513 theme.setBackgroundImage(m_background_image->image());
514
515 // Fetch load color
516 m_load_color = theme.calculateLoadColor();
517
518 // Render theme
519 m_theme_renderer->create(theme, QSize(1920, 1080), 0, devicePixelRatioF());
520 }
521
522 //-----------------------------------------------------------------------------
523
renderText(const QImage & background,const QRect & foreground,const Theme & theme)524 void ThemeDialog::renderText(const QImage& background, const QRect& foreground, const Theme& theme)
525 {
526 QImage preview;
527 theme.renderText(background, foreground, devicePixelRatioF(), &preview, &m_preview_icon);
528 m_preview->setPixmap(QPixmap::fromImage(preview));
529 }
530
531 //-----------------------------------------------------------------------------
532
savePreview()533 void ThemeDialog::savePreview()
534 {
535 Theme::removeIcon(m_theme.id(), m_theme.isDefault());
536 m_preview_icon.save(Theme::iconPath(m_theme.id(), m_theme.isDefault(), devicePixelRatioF()), "", 0);
537 }
538
539 //-----------------------------------------------------------------------------
540
setValues(Theme & theme)541 void ThemeDialog::setValues(Theme& theme)
542 {
543 theme.setBackgroundType(m_background_type->currentIndex());
544 theme.setBackgroundColor(m_background_color->color());
545 theme.setBackgroundImage(m_background_image->toString());
546
547 theme.setForegroundColor(m_foreground_color->color());
548 theme.setForegroundOpacity(m_foreground_opacity->value());
549 theme.setForegroundWidth(m_foreground_width->value());
550 theme.setForegroundMargin(m_foreground_margin->value());
551 theme.setForegroundPadding(m_foreground_padding->value());
552 theme.setForegroundPosition(m_foreground_position->currentIndex());
553
554 theme.setRoundCornersEnabled(m_round_corners->isChecked());
555 theme.setCornerRadius(m_corner_radius->value());
556
557 theme.setBlurEnabled(m_blur->isChecked());
558 theme.setBlurRadius(m_blur_radius->value());
559
560 theme.setShadowEnabled(m_shadow->isChecked());
561 theme.setShadowColor(m_shadow_color->color());
562 theme.setShadowRadius(m_shadow_radius->value());
563 theme.setShadowOffset(m_shadow_offset->value());
564
565 theme.setTextColor(m_text_color->color());
566 QFont font = m_font_names->currentFont();
567 font.setPointSizeF(m_font_sizes->currentText().toDouble());
568 theme.setTextFont(font);
569 theme.setMisspelledColor(m_misspelled_color->color());
570
571 theme.setIndentFirstLine(m_indent_first_line->isChecked());
572 theme.setLineSpacing(m_line_spacing->value());
573 theme.setSpacingAboveParagraph(m_spacing_above_paragraph->value());
574 theme.setSpacingBelowParagraph(m_spacing_below_paragraph->value());
575 theme.setTabWidth(m_tab_width->value());
576 }
577
578 //-----------------------------------------------------------------------------
579