1 | /* |
2 | SPDX-FileCopyrightText: 2001-2003 Christoph Cullmann <cullmann@kde.org> |
3 | SPDX-FileCopyrightText: 2002, 2003 Anders Lund <anders.lund@lund.tdcadsl.dk> |
4 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org> |
5 | SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch> |
6 | |
7 | SPDX-License-Identifier: LGPL-2.0-or-later |
8 | */ |
9 | |
10 | #include "katestyletreewidget.h" |
11 | #include "kateconfig.h" |
12 | #include "kateextendedattribute.h" |
13 | |
14 | #include <KLocalizedString> |
15 | #include <KMessageBox> |
16 | |
17 | #include <QAction> |
18 | #include <QColorDialog> |
19 | #include <QHeaderView> |
20 | #include <QKeyEvent> |
21 | #include <QMenu> |
22 | #include <QPainter> |
23 | #include <QStyledItemDelegate> |
24 | |
25 | // BEGIN KateStyleTreeDelegate |
26 | class KateStyleTreeDelegate : public QStyledItemDelegate |
27 | { |
28 | public: |
29 | KateStyleTreeDelegate(KateStyleTreeWidget *widget); |
30 | |
31 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
32 | |
33 | private: |
34 | static QBrush getBrushForColorColumn(const QModelIndex &index, int column); |
35 | KateStyleTreeWidget *m_widget; |
36 | }; |
37 | // END |
38 | |
39 | // BEGIN KateStyleTreeWidgetItem decl |
40 | /* |
41 | QListViewItem subclass to display/edit a style, bold/italic is check boxes, |
42 | normal and selected colors are boxes, which will display a color chooser when |
43 | activated. |
44 | The context name for the style will be drawn using the editor default font and |
45 | the chosen colors. |
46 | This widget id designed to handle the default as well as the individual hl style |
47 | lists. |
48 | This widget is designed to work with the KateStyleTreeWidget class exclusively. |
49 | Added by anders, jan 23 2002. |
50 | */ |
51 | class KateStyleTreeWidgetItem : public QTreeWidgetItem |
52 | { |
53 | public: |
54 | KateStyleTreeWidgetItem(QTreeWidgetItem *parent, |
55 | const QString &styleName, |
56 | KTextEditor::Attribute::Ptr defaultstyle, |
57 | KTextEditor::Attribute::Ptr data = KTextEditor::Attribute::Ptr()); |
58 | KateStyleTreeWidgetItem(QTreeWidget *parent, |
59 | const QString &styleName, |
60 | KTextEditor::Attribute::Ptr defaultstyle, |
61 | KTextEditor::Attribute::Ptr data = KTextEditor::Attribute::Ptr()); |
62 | ~KateStyleTreeWidgetItem() override |
63 | { |
64 | } |
65 | |
66 | enum columns { |
67 | Context = 0, |
68 | Bold, |
69 | Italic, |
70 | Underline, |
71 | StrikeOut, |
72 | Foreground, |
73 | SelectedForeground, |
74 | Background, |
75 | SelectedBackground, |
76 | UseDefaultStyle, |
77 | NumColumns |
78 | }; |
79 | |
80 | enum { |
81 | Type = ItemType::UserType + 1, |
82 | }; |
83 | |
84 | /* initializes the style from the default and the hldata */ |
85 | void initStyle(); |
86 | /* updates the hldata's style */ |
87 | void updateStyle(); |
88 | /* For bool fields, toggles them, for color fields, display a color chooser */ |
89 | void changeProperty(int p); |
90 | /** unset a color. |
91 | * c is 100 (BGColor) or 101 (SelectedBGColor) for now. |
92 | */ |
93 | void unsetColor(int c); |
94 | /* style context name */ |
95 | QString contextName() const |
96 | { |
97 | return text(column: 0); |
98 | } |
99 | /* only true for a hl mode item using its default style */ |
100 | bool defStyle() const; |
101 | /* true for default styles */ |
102 | bool isDefault() const; |
103 | /* whichever style is active (currentStyle for hl mode styles not using |
104 | the default style, defaultStyle otherwise) */ |
105 | KTextEditor::Attribute::Ptr style() const |
106 | { |
107 | return currentStyle; |
108 | } |
109 | |
110 | QVariant data(int column, int role) const override; |
111 | |
112 | KateStyleTreeWidget *treeWidget() const; |
113 | |
114 | private: |
115 | /* private methods to change properties */ |
116 | void toggleDefStyle(); |
117 | void setColor(int); |
118 | /* helper function to copy the default style into the KateExtendedAttribute, |
119 | when a property is changed and we are using default style. */ |
120 | |
121 | KTextEditor::Attribute::Ptr currentStyle, // the style currently in use (was "is") |
122 | defaultStyle; // default style for hl mode contexts and default styles (was "ds") |
123 | KTextEditor::Attribute::Ptr actualStyle; // itemdata for hl mode contexts (was "st") |
124 | }; |
125 | // END |
126 | |
127 | // BEGIN KateStyleTreeWidget |
128 | KateStyleTreeWidget::KateStyleTreeWidget(QWidget *parent, bool showUseDefaults) |
129 | : QTreeWidget(parent) |
130 | { |
131 | setItemDelegate(new KateStyleTreeDelegate(this)); |
132 | setRootIsDecorated(false); |
133 | |
134 | QStringList ; |
135 | headers << i18nc("@title:column Meaning of text in editor" , "Context" ) << QString() << QString() << QString() << QString() |
136 | << i18nc("@title:column Text style" , "Normal" ) << i18nc("@title:column Text style" , "Selected" ) << i18nc("@title:column Text style" , "Background" ) |
137 | << i18nc("@title:column Text style" , "Background Selected" ); |
138 | if (showUseDefaults) { |
139 | headers << i18n("Use Default Style" ); |
140 | } |
141 | |
142 | setHeaderLabels(headers); |
143 | |
144 | headerItem()->setIcon(column: 1, aicon: QIcon::fromTheme(QStringLiteral("format-text-bold" ))); |
145 | headerItem()->setIcon(column: 2, aicon: QIcon::fromTheme(QStringLiteral("format-text-italic" ))); |
146 | headerItem()->setIcon(column: 3, aicon: QIcon::fromTheme(QStringLiteral("format-text-underline" ))); |
147 | headerItem()->setIcon(column: 4, aicon: QIcon::fromTheme(QStringLiteral("format-text-strikethrough" ))); |
148 | |
149 | // grab the background color and apply it to the palette |
150 | QPalette pal = viewport()->palette(); |
151 | pal.setColor(acr: QPalette::Window, acolor: KateRendererConfig::global()->backgroundColor()); |
152 | viewport()->setPalette(pal); |
153 | } |
154 | |
155 | QIcon brushIcon(const QColor &color) |
156 | { |
157 | QPixmap pm(16, 16); |
158 | QRect all(0, 0, 15, 15); |
159 | { |
160 | QPainter p(&pm); |
161 | p.fillRect(all, color); |
162 | p.setPen(Qt::black); |
163 | p.drawRect(r: all); |
164 | } |
165 | return QIcon(pm); |
166 | } |
167 | |
168 | bool KateStyleTreeWidget::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) |
169 | { |
170 | if (m_readOnly) { |
171 | return false; |
172 | } |
173 | |
174 | if (index.column() == KateStyleTreeWidgetItem::Context) { |
175 | return false; |
176 | } |
177 | |
178 | auto item = itemFromIndex(index); |
179 | if (item->type() != KateStyleTreeWidgetItem::Type) { |
180 | return QTreeWidget::edit(index, trigger, event); |
181 | } |
182 | KateStyleTreeWidgetItem *i = static_cast<KateStyleTreeWidgetItem *>(item); |
183 | |
184 | switch (trigger) { |
185 | case QAbstractItemView::DoubleClicked: |
186 | case QAbstractItemView::SelectedClicked: |
187 | case QAbstractItemView::EditKeyPressed: |
188 | i->changeProperty(p: index.column()); |
189 | update(index); |
190 | update(index: index.sibling(arow: index.row(), acolumn: KateStyleTreeWidgetItem::Context)); |
191 | return false; |
192 | default: |
193 | return QTreeWidget::edit(index, trigger, event); |
194 | } |
195 | } |
196 | |
197 | void KateStyleTreeWidget::resizeColumns() |
198 | { |
199 | for (int i = 0; i < columnCount(); ++i) { |
200 | resizeColumnToContents(column: i); |
201 | } |
202 | } |
203 | |
204 | void KateStyleTreeWidget::showEvent(QShowEvent *event) |
205 | { |
206 | QTreeWidget::showEvent(event); |
207 | |
208 | resizeColumns(); |
209 | } |
210 | |
211 | void KateStyleTreeWidget::(QContextMenuEvent *event) |
212 | { |
213 | if (m_readOnly) { |
214 | return; |
215 | } |
216 | |
217 | auto item = itemAt(p: event->pos()); |
218 | if (item->type() != KateStyleTreeWidgetItem::Type) { |
219 | return; |
220 | } |
221 | KateStyleTreeWidgetItem *i = static_cast<KateStyleTreeWidgetItem *>(item); |
222 | |
223 | QMenu m(this); |
224 | KTextEditor::Attribute::Ptr currentStyle = i->style(); |
225 | // the title is used, because the menu obscures the context name when |
226 | // displayed on behalf of spacePressed(). |
227 | QPainter p; |
228 | p.setPen(Qt::black); |
229 | |
230 | const QIcon emptyColorIcon = brushIcon(color: viewport()->palette().base().color()); |
231 | QIcon cl = brushIcon(color: i->style()->foreground().color()); |
232 | QIcon scl = brushIcon(color: i->style()->selectedForeground().color()); |
233 | QIcon bgcl = i->style()->hasProperty(propertyId: QTextFormat::BackgroundBrush) ? brushIcon(color: i->style()->background().color()) : emptyColorIcon; |
234 | QIcon sbgcl = i->style()->hasProperty(propertyId: CustomProperties::SelectedBackground) ? brushIcon(color: i->style()->selectedBackground().color()) : emptyColorIcon; |
235 | |
236 | m.addSection(text: i->contextName()); |
237 | |
238 | QAction *a = m.addAction(i18n("&Bold" ), receiver: this, SLOT(changeProperty())); |
239 | a->setCheckable(true); |
240 | a->setChecked(currentStyle->fontBold()); |
241 | a->setData(KateStyleTreeWidgetItem::Bold); |
242 | |
243 | a = m.addAction(i18n("&Italic" ), receiver: this, SLOT(changeProperty())); |
244 | a->setCheckable(true); |
245 | a->setChecked(currentStyle->fontItalic()); |
246 | a->setData(KateStyleTreeWidgetItem::Italic); |
247 | |
248 | a = m.addAction(i18n("&Underline" ), receiver: this, SLOT(changeProperty())); |
249 | a->setCheckable(true); |
250 | a->setChecked(currentStyle->fontUnderline()); |
251 | a->setData(KateStyleTreeWidgetItem::Underline); |
252 | |
253 | a = m.addAction(i18n("S&trikeout" ), receiver: this, SLOT(changeProperty())); |
254 | a->setCheckable(true); |
255 | a->setChecked(currentStyle->fontStrikeOut()); |
256 | a->setData(KateStyleTreeWidgetItem::StrikeOut); |
257 | |
258 | m.addSeparator(); |
259 | |
260 | a = m.addAction(icon: cl, i18n("Normal &Color..." ), receiver: this, SLOT(changeProperty())); |
261 | a->setData(KateStyleTreeWidgetItem::Foreground); |
262 | |
263 | a = m.addAction(icon: scl, i18n("&Selected Color..." ), receiver: this, SLOT(changeProperty())); |
264 | a->setData(KateStyleTreeWidgetItem::SelectedForeground); |
265 | |
266 | a = m.addAction(icon: bgcl, i18n("&Background Color..." ), receiver: this, SLOT(changeProperty())); |
267 | a->setData(KateStyleTreeWidgetItem::Background); |
268 | |
269 | a = m.addAction(icon: sbgcl, i18n("S&elected Background Color..." ), receiver: this, SLOT(changeProperty())); |
270 | a->setData(KateStyleTreeWidgetItem::SelectedBackground); |
271 | |
272 | // defaulters |
273 | m.addSeparator(); |
274 | |
275 | a = m.addAction(icon: emptyColorIcon, i18n("Unset Normal Color" ), receiver: this, SLOT(unsetColor())); |
276 | a->setData(1); |
277 | |
278 | a = m.addAction(icon: emptyColorIcon, i18n("Unset Selected Color" ), receiver: this, SLOT(unsetColor())); |
279 | a->setData(2); |
280 | |
281 | // unsetters |
282 | KTextEditor::Attribute::Ptr style = i->style(); |
283 | if (style->hasProperty(propertyId: QTextFormat::BackgroundBrush)) { |
284 | a = m.addAction(icon: emptyColorIcon, i18n("Unset Background Color" ), receiver: this, SLOT(unsetColor())); |
285 | a->setData(3); |
286 | } |
287 | |
288 | if (style->hasProperty(propertyId: CustomProperties::SelectedBackground)) { |
289 | a = m.addAction(icon: emptyColorIcon, i18n("Unset Selected Background Color" ), receiver: this, SLOT(unsetColor())); |
290 | a->setData(4); |
291 | } |
292 | |
293 | if (!i->isDefault() && !i->defStyle()) { |
294 | m.addSeparator(); |
295 | a = m.addAction(i18n("Use &Default Style" ), receiver: this, SLOT(changeProperty())); |
296 | a->setCheckable(true); |
297 | a->setChecked(i->defStyle()); |
298 | a->setData(KateStyleTreeWidgetItem::UseDefaultStyle); |
299 | } |
300 | m.exec(pos: event->globalPos()); |
301 | } |
302 | |
303 | void KateStyleTreeWidget::changeProperty() |
304 | { |
305 | static_cast<KateStyleTreeWidgetItem *>(currentItem())->changeProperty(p: static_cast<QAction *>(sender())->data().toInt()); |
306 | } |
307 | |
308 | void KateStyleTreeWidget::unsetColor() |
309 | { |
310 | static_cast<KateStyleTreeWidgetItem *>(currentItem())->unsetColor(c: static_cast<QAction *>(sender())->data().toInt()); |
311 | } |
312 | |
313 | void KateStyleTreeWidget::updateGroupHeadings() |
314 | { |
315 | for (int i = 0; i < topLevelItemCount(); i++) { |
316 | QTreeWidgetItem *currentTopLevelItem = topLevelItem(index: i); |
317 | QTreeWidgetItem *firstChild = currentTopLevelItem->child(index: 0); |
318 | |
319 | if (firstChild) { |
320 | QColor foregroundColor = firstChild->data(column: KateStyleTreeWidgetItem::Foreground, role: Qt::DisplayRole).value<QColor>(); |
321 | QColor backgroundColor = firstChild->data(column: KateStyleTreeWidgetItem::Background, role: Qt::DisplayRole).value<QColor>(); |
322 | |
323 | currentTopLevelItem->setForeground(column: KateStyleTreeWidgetItem::Context, brush: foregroundColor); |
324 | |
325 | if (backgroundColor.isValid()) { |
326 | currentTopLevelItem->setBackground(column: KateStyleTreeWidgetItem::Context, brush: backgroundColor); |
327 | } |
328 | } |
329 | } |
330 | } |
331 | |
332 | void KateStyleTreeWidget::emitChanged() |
333 | { |
334 | updateGroupHeadings(); |
335 | Q_EMIT changed(); |
336 | } |
337 | |
338 | void KateStyleTreeWidget::addItem(const QString &styleName, KTextEditor::Attribute::Ptr defaultstyle, KTextEditor::Attribute::Ptr data) |
339 | { |
340 | new KateStyleTreeWidgetItem(this, styleName, std::move(defaultstyle), std::move(data)); |
341 | } |
342 | |
343 | void KateStyleTreeWidget::addItem(QTreeWidgetItem *parent, const QString &styleName, KTextEditor::Attribute::Ptr defaultstyle, KTextEditor::Attribute::Ptr data) |
344 | { |
345 | new KateStyleTreeWidgetItem(parent, styleName, std::move(defaultstyle), std::move(data)); |
346 | updateGroupHeadings(); |
347 | } |
348 | // END |
349 | |
350 | // BEGIN KateStyleTreeWidgetItem |
351 | KateStyleTreeDelegate::KateStyleTreeDelegate(KateStyleTreeWidget *widget) |
352 | : QStyledItemDelegate(widget) |
353 | , m_widget(widget) |
354 | { |
355 | } |
356 | |
357 | QBrush KateStyleTreeDelegate::getBrushForColorColumn(const QModelIndex &index, int column) |
358 | { |
359 | QModelIndex colorIndex = index.sibling(arow: index.row(), acolumn: column); |
360 | QVariant displayData = colorIndex.model()->data(index: colorIndex); |
361 | return displayData.value<QBrush>(); |
362 | } |
363 | |
364 | void KateStyleTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const |
365 | { |
366 | static QSet<int> columns; |
367 | if (columns.isEmpty()) { |
368 | columns << KateStyleTreeWidgetItem::Foreground << KateStyleTreeWidgetItem::SelectedForeground << KateStyleTreeWidgetItem::Background |
369 | << KateStyleTreeWidgetItem::SelectedBackground; |
370 | } |
371 | |
372 | if (index.column() == KateStyleTreeWidgetItem::Context) { |
373 | QStyleOptionViewItem styleContextItem(option); |
374 | |
375 | QBrush brush = getBrushForColorColumn(index, column: KateStyleTreeWidgetItem::SelectedBackground); |
376 | if (brush != QBrush()) { |
377 | styleContextItem.palette.setBrush(acr: QPalette::Highlight, abrush: brush); |
378 | } |
379 | |
380 | brush = getBrushForColorColumn(index, column: KateStyleTreeWidgetItem::SelectedForeground); |
381 | if (brush != QBrush()) { |
382 | styleContextItem.palette.setBrush(acr: QPalette::HighlightedText, abrush: brush); |
383 | } |
384 | |
385 | return QStyledItemDelegate::paint(painter, option: styleContextItem, index); |
386 | } |
387 | |
388 | QStyledItemDelegate::paint(painter, option, index); |
389 | |
390 | if (!columns.contains(value: index.column())) { |
391 | return; |
392 | } |
393 | |
394 | QVariant displayData = index.model()->data(index); |
395 | if (displayData.userType() != QMetaType::QBrush) { |
396 | return; |
397 | } |
398 | |
399 | QBrush brush = displayData.value<QBrush>(); |
400 | |
401 | QStyleOptionButton opt; |
402 | opt.rect = option.rect; |
403 | opt.palette = m_widget->palette(); |
404 | |
405 | bool set = brush != QBrush(); |
406 | |
407 | if (!set) { |
408 | opt.text = i18nc("No text or background color set" , "None set" ); |
409 | brush = Qt::white; |
410 | } |
411 | |
412 | m_widget->style()->drawControl(element: QStyle::CE_PushButton, opt: &opt, p: painter, w: m_widget); |
413 | |
414 | if (set) { |
415 | painter->fillRect(m_widget->style()->subElementRect(subElement: QStyle::SE_PushButtonContents, option: &opt, widget: m_widget), brush); |
416 | } |
417 | } |
418 | |
419 | KateStyleTreeWidgetItem::KateStyleTreeWidgetItem(QTreeWidgetItem *parent, |
420 | const QString &stylename, |
421 | KTextEditor::Attribute::Ptr defaultAttribute, |
422 | KTextEditor::Attribute::Ptr actualAttribute) |
423 | : QTreeWidgetItem(parent, KateStyleTreeWidgetItem::Type) |
424 | , currentStyle(nullptr) |
425 | , defaultStyle(std::move(defaultAttribute)) |
426 | , actualStyle(std::move(actualAttribute)) |
427 | { |
428 | initStyle(); |
429 | setText(column: 0, atext: stylename); |
430 | } |
431 | |
432 | KateStyleTreeWidgetItem::KateStyleTreeWidgetItem(QTreeWidget *parent, |
433 | const QString &stylename, |
434 | KTextEditor::Attribute::Ptr defaultAttribute, |
435 | KTextEditor::Attribute::Ptr actualAttribute) |
436 | : QTreeWidgetItem(parent, KateStyleTreeWidgetItem::Type) |
437 | , currentStyle(nullptr) |
438 | , defaultStyle(std::move(defaultAttribute)) |
439 | , actualStyle(std::move(actualAttribute)) |
440 | { |
441 | initStyle(); |
442 | setText(column: 0, atext: stylename); |
443 | } |
444 | |
445 | void KateStyleTreeWidgetItem::initStyle() |
446 | { |
447 | if (!actualStyle) { |
448 | currentStyle = defaultStyle; |
449 | } else { |
450 | currentStyle = new KTextEditor::Attribute(*defaultStyle); |
451 | |
452 | if (actualStyle->hasAnyProperty()) { |
453 | *currentStyle += *actualStyle; |
454 | } |
455 | } |
456 | |
457 | setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); |
458 | } |
459 | |
460 | static Qt::CheckState toCheckState(bool b) |
461 | { |
462 | return b ? Qt::Checked : Qt::Unchecked; |
463 | } |
464 | |
465 | QVariant KateStyleTreeWidgetItem::data(int column, int role) const |
466 | { |
467 | if (column == Context) { |
468 | switch (role) { |
469 | case Qt::ForegroundRole: |
470 | if (style()->hasProperty(propertyId: QTextFormat::ForegroundBrush)) { |
471 | return style()->foreground().color(); |
472 | } |
473 | break; |
474 | |
475 | case Qt::BackgroundRole: |
476 | if (style()->hasProperty(propertyId: QTextFormat::BackgroundBrush)) { |
477 | return style()->background().color(); |
478 | } |
479 | break; |
480 | |
481 | case Qt::FontRole: |
482 | return style()->font(); |
483 | break; |
484 | } |
485 | } |
486 | |
487 | if (role == Qt::CheckStateRole) { |
488 | switch (column) { |
489 | case Bold: |
490 | return toCheckState(b: style()->fontBold()); |
491 | case Italic: |
492 | return toCheckState(b: style()->fontItalic()); |
493 | case Underline: |
494 | return toCheckState(b: style()->fontUnderline()); |
495 | case StrikeOut: |
496 | return toCheckState(b: style()->fontStrikeOut()); |
497 | case UseDefaultStyle: |
498 | /* can't compare all attributes, currentStyle has always more than defaultStyle (e.g. the item's name), |
499 | * so we just compare the important ones:*/ |
500 | return toCheckState(b: currentStyle->foreground() == defaultStyle->foreground() && currentStyle->background() == defaultStyle->background() |
501 | && currentStyle->selectedForeground() == defaultStyle->selectedForeground() |
502 | && currentStyle->selectedBackground() == defaultStyle->selectedBackground() |
503 | && currentStyle->fontBold() == defaultStyle->fontBold() && currentStyle->fontItalic() == defaultStyle->fontItalic() |
504 | && currentStyle->fontUnderline() == defaultStyle->fontUnderline() |
505 | && currentStyle->fontStrikeOut() == defaultStyle->fontStrikeOut()); |
506 | } |
507 | } |
508 | |
509 | if (role == Qt::DisplayRole) { |
510 | switch (column) { |
511 | case Foreground: |
512 | return style()->foreground(); |
513 | case SelectedForeground: |
514 | return style()->selectedForeground(); |
515 | case Background: |
516 | return style()->background(); |
517 | case SelectedBackground: |
518 | return style()->selectedBackground(); |
519 | } |
520 | } |
521 | |
522 | return QTreeWidgetItem::data(column, role); |
523 | } |
524 | |
525 | void KateStyleTreeWidgetItem::updateStyle() |
526 | { |
527 | // nothing there, not update it, will crash |
528 | if (!actualStyle) { |
529 | return; |
530 | } |
531 | |
532 | if (currentStyle->hasProperty(propertyId: QTextFormat::FontWeight)) { |
533 | if (currentStyle->fontWeight() != actualStyle->fontWeight()) { |
534 | actualStyle->setFontWeight(currentStyle->fontWeight()); |
535 | } |
536 | } else { |
537 | actualStyle->clearProperty(propertyId: QTextFormat::FontWeight); |
538 | } |
539 | |
540 | if (currentStyle->hasProperty(propertyId: QTextFormat::FontItalic)) { |
541 | if (currentStyle->fontItalic() != actualStyle->fontItalic()) { |
542 | actualStyle->setFontItalic(currentStyle->fontItalic()); |
543 | } |
544 | } else { |
545 | actualStyle->clearProperty(propertyId: QTextFormat::FontItalic); |
546 | } |
547 | |
548 | if (currentStyle->hasProperty(propertyId: QTextFormat::FontStrikeOut)) { |
549 | if (currentStyle->fontStrikeOut() != actualStyle->fontStrikeOut()) { |
550 | actualStyle->setFontStrikeOut(currentStyle->fontStrikeOut()); |
551 | } |
552 | } else { |
553 | actualStyle->clearProperty(propertyId: QTextFormat::FontStrikeOut); |
554 | } |
555 | |
556 | if (currentStyle->hasProperty(propertyId: QTextFormat::TextUnderlineStyle)) { |
557 | if (currentStyle->fontUnderline() != actualStyle->fontUnderline()) { |
558 | actualStyle->setFontUnderline(currentStyle->fontUnderline()); |
559 | } |
560 | } else { |
561 | actualStyle->clearProperty(propertyId: QTextFormat::TextUnderlineStyle); |
562 | } |
563 | |
564 | if (currentStyle->hasProperty(propertyId: CustomProperties::Outline)) { |
565 | if (currentStyle->outline() != actualStyle->outline()) { |
566 | actualStyle->setOutline(currentStyle->outline()); |
567 | } |
568 | } else { |
569 | actualStyle->clearProperty(propertyId: CustomProperties::Outline); |
570 | } |
571 | |
572 | if (currentStyle->hasProperty(propertyId: QTextFormat::ForegroundBrush)) { |
573 | if (currentStyle->foreground() != actualStyle->foreground()) { |
574 | actualStyle->setForeground(currentStyle->foreground()); |
575 | } |
576 | } else { |
577 | actualStyle->clearProperty(propertyId: QTextFormat::ForegroundBrush); |
578 | } |
579 | |
580 | if (currentStyle->hasProperty(propertyId: CustomProperties::SelectedForeground)) { |
581 | if (currentStyle->selectedForeground() != actualStyle->selectedForeground()) { |
582 | actualStyle->setSelectedForeground(currentStyle->selectedForeground()); |
583 | } |
584 | } else { |
585 | actualStyle->clearProperty(propertyId: CustomProperties::SelectedForeground); |
586 | } |
587 | |
588 | if (currentStyle->hasProperty(propertyId: QTextFormat::BackgroundBrush)) { |
589 | if (currentStyle->background() != actualStyle->background()) { |
590 | actualStyle->setBackground(currentStyle->background()); |
591 | } |
592 | } else { |
593 | actualStyle->clearProperty(propertyId: QTextFormat::BackgroundBrush); |
594 | } |
595 | |
596 | if (currentStyle->hasProperty(propertyId: CustomProperties::SelectedBackground)) { |
597 | if (currentStyle->selectedBackground() != actualStyle->selectedBackground()) { |
598 | actualStyle->setSelectedBackground(currentStyle->selectedBackground()); |
599 | } |
600 | } else { |
601 | actualStyle->clearProperty(propertyId: CustomProperties::SelectedBackground); |
602 | } |
603 | } |
604 | |
605 | /* only true for a hl mode item using its default style */ |
606 | bool KateStyleTreeWidgetItem::defStyle() const |
607 | { |
608 | return actualStyle && actualStyle->properties() != defaultStyle->properties(); |
609 | } |
610 | |
611 | /* true for default styles */ |
612 | bool KateStyleTreeWidgetItem::isDefault() const |
613 | { |
614 | return actualStyle ? false : true; |
615 | } |
616 | |
617 | void KateStyleTreeWidgetItem::changeProperty(int p) |
618 | { |
619 | if (p == Bold) { |
620 | currentStyle->setFontBold(!currentStyle->fontBold()); |
621 | } else if (p == Italic) { |
622 | currentStyle->setFontItalic(!currentStyle->fontItalic()); |
623 | } else if (p == Underline) { |
624 | currentStyle->setFontUnderline(!currentStyle->fontUnderline()); |
625 | } else if (p == StrikeOut) { |
626 | currentStyle->setFontStrikeOut(!currentStyle->fontStrikeOut()); |
627 | } else if (p == UseDefaultStyle) { |
628 | toggleDefStyle(); |
629 | } else { |
630 | setColor(p); |
631 | } |
632 | |
633 | updateStyle(); |
634 | |
635 | treeWidget()->emitChanged(); |
636 | } |
637 | |
638 | void KateStyleTreeWidgetItem::toggleDefStyle() |
639 | { |
640 | if (*currentStyle == *defaultStyle) { |
641 | KMessageBox::information(parent: treeWidget(), |
642 | i18n("\"Use Default Style\" will be automatically unset when you change any style properties." ), |
643 | i18n("Kate Styles" ), |
644 | QStringLiteral("Kate hl config use defaults" )); |
645 | } else { |
646 | currentStyle = KTextEditor::Attribute::Ptr(new KTextEditor::Attribute(*defaultStyle)); |
647 | updateStyle(); |
648 | |
649 | QModelIndex currentIndex = treeWidget()->currentIndex(); |
650 | while (currentIndex.isValid()) { |
651 | treeWidget()->update(index: currentIndex); |
652 | currentIndex = currentIndex.sibling(arow: currentIndex.row(), acolumn: currentIndex.column() - 1); |
653 | } |
654 | } |
655 | } |
656 | |
657 | void KateStyleTreeWidgetItem::setColor(int column) |
658 | { |
659 | QColor c; // use this |
660 | QColor d; // default color |
661 | if (column == Foreground) { |
662 | c = currentStyle->foreground().color(); |
663 | d = defaultStyle->foreground().color(); |
664 | } else if (column == SelectedForeground) { |
665 | c = currentStyle->selectedForeground().color(); |
666 | d = defaultStyle->selectedForeground().color(); |
667 | } else if (column == Background) { |
668 | c = currentStyle->background().color(); |
669 | d = defaultStyle->background().color(); |
670 | } else if (column == SelectedBackground) { |
671 | c = currentStyle->selectedBackground().color(); |
672 | d = defaultStyle->selectedBackground().color(); |
673 | } |
674 | |
675 | if (!c.isValid()) { |
676 | c = d; |
677 | } |
678 | |
679 | const QColor selectedColor = QColorDialog::getColor(initial: c, parent: treeWidget()); |
680 | |
681 | if (!selectedColor.isValid()) { |
682 | return; |
683 | } |
684 | |
685 | // if set default, and the attrib is set in the default style use it |
686 | // else if set default, unset it |
687 | // else set the selected color |
688 | switch (column) { |
689 | case Foreground: |
690 | currentStyle->setForeground(selectedColor); |
691 | break; |
692 | case SelectedForeground: |
693 | currentStyle->setSelectedForeground(selectedColor); |
694 | break; |
695 | case Background: |
696 | currentStyle->setBackground(selectedColor); |
697 | break; |
698 | case SelectedBackground: |
699 | currentStyle->setSelectedBackground(selectedColor); |
700 | break; |
701 | } |
702 | |
703 | // FIXME |
704 | // repaint(); |
705 | } |
706 | |
707 | void KateStyleTreeWidgetItem::unsetColor(int colorId) |
708 | { |
709 | switch (colorId) { |
710 | case 1: |
711 | if (defaultStyle->hasProperty(propertyId: QTextFormat::ForegroundBrush)) { |
712 | currentStyle->setForeground(defaultStyle->foreground()); |
713 | } else { |
714 | currentStyle->clearProperty(propertyId: QTextFormat::ForegroundBrush); |
715 | } |
716 | break; |
717 | case 2: |
718 | if (defaultStyle->hasProperty(propertyId: CustomProperties::SelectedForeground)) { |
719 | currentStyle->setSelectedForeground(defaultStyle->selectedForeground()); |
720 | } else { |
721 | currentStyle->clearProperty(propertyId: CustomProperties::SelectedForeground); |
722 | } |
723 | break; |
724 | case 3: |
725 | if (currentStyle->hasProperty(propertyId: QTextFormat::BackgroundBrush)) { |
726 | currentStyle->clearProperty(propertyId: QTextFormat::BackgroundBrush); |
727 | } |
728 | break; |
729 | case 4: |
730 | if (currentStyle->hasProperty(propertyId: CustomProperties::SelectedBackground)) { |
731 | currentStyle->clearProperty(propertyId: CustomProperties::SelectedBackground); |
732 | } |
733 | break; |
734 | } |
735 | |
736 | updateStyle(); |
737 | |
738 | treeWidget()->emitChanged(); |
739 | } |
740 | |
741 | KateStyleTreeWidget *KateStyleTreeWidgetItem::treeWidget() const |
742 | { |
743 | return static_cast<KateStyleTreeWidget *>(QTreeWidgetItem::treeWidget()); |
744 | } |
745 | |
746 | bool KateStyleTreeWidget::readOnly() const |
747 | { |
748 | return m_readOnly; |
749 | } |
750 | |
751 | void KateStyleTreeWidget::setReadOnly(bool readOnly) |
752 | { |
753 | m_readOnly = readOnly; |
754 | } |
755 | // END |
756 | |
757 | #include "moc_katestyletreewidget.cpp" |
758 | |