Messagelib

theme.h
1/******************************************************************************
2 *
3 * SPDX-FileCopyrightText: 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 *
7 *******************************************************************************/
8
9#pragma once
10
11#include <QColor>
12#include <QList>
13#include <QPair>
14#include <QString>
15
16#include "core/optionset.h"
17#include "core/sortorder.h"
18
19class QPixmap;
20
21namespace MessageList
22{
23namespace Core
24{
25/**
26 * The Theme class defines the visual appearance of the MessageList.
27 *
28 * The core structure of the theme is made up of Column objects which
29 * are mapped to View (QTreeView) columns. Each theme must provide at least one column.
30 *
31 * Each column contains a set of Row objects dedicated to message items
32 * and a set of Row objects dedicated to group header items. There must be at least
33 * one message row and one group header row in each column. Rows are visually
34 * ordered from top to bottom.
35 *
36 * Each Row contains a set of left aligned and a set of right aligned ContentItem objects.
37 * The right aligned items are painted from right to left while the left aligned
38 * ones are painted from left to right. In Right-To-Left mode the ThemeDelegate
39 * follows the exact opposite convention.
40 *
41 * Each ContentItem object specifies a visual element to be displayed in a View
42 * row. The visual elements may be pieces of text (Subject, Date) or icons.
43 *
44 * The Theme is designed to strictly interoperate with the ThemeDelegate class
45 * which takes care of rendering the contents when attached to an QAbstractItemView.
46 */
47class Theme : public OptionSet
48{
49public:
50 /**
51 * The ContentItem class defines a content item inside a Row.
52 * Content items are data items extracted from a message or a group header:
53 * they can be text, spacers, separators or icons.
54 */
56 {
57 private:
58 /**
59 * Bits for composing the Type enumeration members.
60 * We'll be able to test these bits to quickly figure out item properties.
61 */
62 enum TypePropertyBits {
63 /**
64 * Item can use the custom color property
65 */
66 CanUseCustomColor = (1 << 16),
67 /**
68 * Item can be in a disabled state (for example the attachment icon when there is no attachment)
69 */
70 CanBeDisabled = (1 << 17),
71 /**
72 * Item displays some sort of text
73 */
74 DisplaysText = (1 << 18),
75 /**
76 * Item makes sense (and can be applied) for messages
77 */
78 ApplicableToMessageItems = (1 << 19),
79 /**
80 * Item makes sense (and can be applied) for group headers
81 */
82 ApplicableToGroupHeaderItems = (1 << 20),
83 /**
84 * The item takes more horizontal space than the other text items (at the time of writing it's only the subject)
85 */
86 LongText = (1 << 21),
87 /**
88 * The item displays an icon
89 */
90 IsIcon = (1 << 22),
91 /**
92 * The item is a small spacer
93 */
94 IsSpacer = (1 << 23),
95 /**
96 * The item is clickable
97 */
98 IsClickable = (1 << 24)
99 };
100
101 public:
102 /**
103 * The available ContentItem types.
104 * Note that the values in this enum are unique values or'ed with the TypePropertyBits above.
105 */
106 enum Type {
107 /**
108 * Display the subject of the message item. This is a long text.
109 */
110 Subject = 1 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems | LongText,
111 /**
112 * Formatted date time of the message/group
113 */
114 Date = 2 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems | ApplicableToGroupHeaderItems,
115 /**
116 * From: or To: strip, depending on the folder settings
117 */
118 SenderOrReceiver = 3 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems,
119 /**
120 * From: strip, always
121 */
122 Sender = 4 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems,
123 /**
124 * To: strip, always
125 */
126 Receiver = 5 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems,
127 /**
128 * Formatted size of the message
129 */
130 Size = 6 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems,
131 /**
132 * The icon that displays the unread/read state (never disabled)
133 */
134 ReadStateIcon = 7 | ApplicableToMessageItems | IsIcon,
135 /**
136 * The icon that displays the attachment state (may be disabled)
137 */
138 AttachmentStateIcon = 8 | CanBeDisabled | ApplicableToMessageItems | IsIcon,
139 /**
140 * The icon that displays the replied/forwarded state (may be disabled)
141 */
142 RepliedStateIcon = 9 | CanBeDisabled | ApplicableToMessageItems | IsIcon,
143 /**
144 * The group header label
145 */
146 GroupHeaderLabel = 10 | DisplaysText | CanUseCustomColor | ApplicableToGroupHeaderItems,
147 /**
148 * The ActionItem state icon. May be disabled. Clickable (cycles todo->nothing)
149 */
150 ActionItemStateIcon = 11 | CanBeDisabled | ApplicableToMessageItems | IsIcon | IsClickable,
151 /**
152 * The Important tag icon. May be disabled. Clickable (cycles important->nothing)
153 */
154 ImportantStateIcon = 12 | CanBeDisabled | ApplicableToMessageItems | IsIcon | IsClickable,
155 /**
156 * The Spam/Ham state icon. May be disabled. Clickable (cycles spam->ham->nothing)
157 */
158 SpamHamStateIcon = 13 | CanBeDisabled | ApplicableToMessageItems | IsIcon | IsClickable,
159 /**
160 * The Watched/Ignored state icon. May be disabled. Clickable (cycles watched->ignored->nothing)
161 */
162 WatchedIgnoredStateIcon = 14 | CanBeDisabled | ApplicableToMessageItems | IsIcon | IsClickable,
163 /**
164 * The Expanded state icon for group headers. May be disabled. Clickable (expands/collapses the group)
165 */
166 ExpandedStateIcon = 15 | CanBeDisabled | ApplicableToGroupHeaderItems | IsIcon | IsClickable,
167 /**
168 * The Encryption state icon for messages. May be disabled (no encryption).
169 */
170 EncryptionStateIcon = 16 | CanBeDisabled | ApplicableToMessageItems | IsIcon,
171 /**
172 * The Signature state icon for messages. May be disabled (no signature)
173 */
174 SignatureStateIcon = 17 | CanBeDisabled | ApplicableToMessageItems | IsIcon,
175 /**
176 * A vertical separation line.
177 */
178 VerticalLine = 18 | CanUseCustomColor | ApplicableToMessageItems | ApplicableToGroupHeaderItems | IsSpacer,
179 /**
180 * A small empty spacer usable as separator.
181 */
182 HorizontalSpacer = 19 | ApplicableToMessageItems | ApplicableToGroupHeaderItems | IsSpacer,
183 /**
184 * The date of the most recent message in subtree
185 */
186 MostRecentDate = 20 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems | ApplicableToGroupHeaderItems,
187 /**
188 * The combined icon that displays the unread/read/replied/forwarded state (never disabled)
189 */
190 CombinedReadRepliedStateIcon = 21 | ApplicableToMessageItems | IsIcon,
191 /**
192 * The list of MessageItem::Tag entries
193 */
194 TagList = 22 | ApplicableToMessageItems | IsIcon,
195 /**
196 * Whether the message has a annotation/note
197 */
198 AnnotationIcon = 23 | ApplicableToMessageItems | IsIcon | CanBeDisabled | IsClickable,
199
200 /**
201 * Whether the message is an invitation
202 */
203 InvitationIcon = 24 | ApplicableToMessageItems | IsIcon,
204 /**
205 * Folder of the message
206 */
207 Folder = 25 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems
208#if 0
209 TotalMessageCount
210 UnreadMessageCount
211 NewMessageCount
212#endif
213 };
214
215 enum Flags {
216 HideWhenDisabled = 1, ///< In disabled state the icon should take no space (overrides SoftenByBlendingWhenDisabled)
217 SoftenByBlendingWhenDisabled = (1 << 1), ///< In disabled state the icon should be still shown, but made very soft by alpha blending
218 UseCustomColor = (1 << 2), ///< For text and vertical line. If set then always use a custom color, otherwise use default text color
219 IsBold = (1 << 3), ///< For text items. If set then always show as bold, otherwise use the default font weight
220 IsItalic = (1 << 4), ///< Fot text items. If set then always show as italic, otherwise use the default font style
221 SoftenByBlending = (1 << 5) ///< For text items: use 60% opacity.
222 };
223
224 private:
225 Type mType; ///< The type of item
226 unsigned int mFlags; ///< The flags of the item
227
228 QColor mCustomColor; ///< The color to use with this content item, meaningful only if canUseCustomColor() return true.
229
230 public:
231 /**
232 * Creates a ContentItem with the specified type.
233 * A content item must be added to a theme Row.
234 */
235 explicit ContentItem(Type type);
236 /**
237 * Creates a ContentItem that is a copy of the content item src.
238 * A content item must be added to a theme Row.
239 */
240 explicit ContentItem(const ContentItem &src);
241
242 public:
243 /**
244 * Returns the type of this content item
245 */
246 [[nodiscard]] Type type() const;
247
248 /**
249 * Returns true if this ContentItem can be in a "disabled" state.
250 * The attachment state icon, for example, can be disabled when the related
251 * message has no attachments. For such items the HideWhenDisabled
252 * and SoftenByBlendingWhenDisabled flags are meaningful.
253 */
254 [[nodiscard]] bool canBeDisabled() const;
255
256 /**
257 * Returns true if this ContentItem can make use of a custom color.
258 */
259 [[nodiscard]] bool canUseCustomColor() const;
260
261 /**
262 * Returns true if this item displays some kind of text.
263 * Items that display text make use of the customFont() setting.
264 */
265 [[nodiscard]] bool displaysText() const;
266
267 /**
268 * Returns true if this item displays a long text.
269 * The returned value makes sense only if displaysText() returned true.
270 */
271 [[nodiscard]] bool displaysLongText() const;
272
273 /**
274 * Returns true if this item displays an icon.
275 */
276 [[nodiscard]] bool isIcon() const;
277 /**
278 * Returns true if clicking on this kind of item can perform an action
279 */
280 [[nodiscard]] bool isClickable() const;
281
282 /**
283 * Returns true if this item is a small spacer
284 */
285 [[nodiscard]] bool isSpacer() const;
286
287 /**
288 * Static test that returns true if an instance of ContentItem with the
289 * specified type makes sense in a Row for message items.
290 */
291 [[nodiscard]] static bool applicableToMessageItems(Type type);
292
293 /**
294 * Static test that returns true if an instance of ContentItem with the
295 * specified type makes sense in a Row for group header items.
296 */
297 [[nodiscard]] static bool applicableToGroupHeaderItems(Type type);
298
299 /**
300 * Returns a descriptive name for the specified content item type
301 */
302 [[nodiscard]] static QString description(Type type);
303
304 /**
305 * Returns true if this item uses a custom color.
306 * The return value of this function is valid only if canUseCustomColor() returns true.
307 */
308 [[nodiscard]] bool useCustomColor() const;
309
310 /**
311 * Makes this item use the custom color that can be set by setCustomColor().
312 * The custom color is meaningful only if canUseCustomColor() returns true.
313 */
315
316 /**
317 * Returns true if this item uses a bold text.
318 * The return value of this function is valid only if displaysText() returns true.
319 */
320 [[nodiscard]] bool isBold() const;
321
322 /**
323 * Makes this item use a bold font.
324 */
325 void setBold(bool isBold);
326
327 /**
328 * Returns true if this item uses an italic text.
329 * The return value of this function is valid only if displaysText() returns true.
330 */
331 [[nodiscard]] bool isItalic() const;
332
333 /**
334 * Makes this item use italic font.
335 */
336 void setItalic(bool isItalic);
337
338 /**
339 * Returns true if this item should be hidden when in disabled state.
340 * Hidden content items simply aren't painted and take no space.
341 * This flag has meaning only on items for that canBeDisabled() returns true.
342 */
343 [[nodiscard]] bool hideWhenDisabled() const;
344
345 /**
346 * Sets the flag that causes this item to be hidden when disabled.
347 * Hidden content items simply aren't painted and take no space.
348 * This flag overrides the setSoftenByBlendingWhenDisabled() setting.
349 * This flag has meaning only on items for that canBeDisabled() returns true.
350 */
352
353 /**
354 * Returns true if this item should be painted in a "soft" fashion when
355 * in disabled state. Soft icons are painted with very low opacity.
356 * This flag has meaning only on items for that canBeDisabled() returns true.
357 */
358 [[nodiscard]] bool softenByBlendingWhenDisabled() const;
359
360 /**
361 * Sets the flag that causes this item to be painted "softly" when disabled.
362 * Soft icons are painted with very low opacity.
363 * This flag may be overridden by the setHideWhenDisabled() setting.
364 * This flag has meaning only on items for that canBeDisabled() returns true.
365 */
367
368 /**
369 * Returns true if this item should be always painted in a "soft" fashion.
370 * Meaningful only for text items.
371 */
372 [[nodiscard]] bool softenByBlending() const;
373
374 /**
375 * Sets the flag that causes this item to be painted "softly".
376 * Meaningful only for text items.
377 */
379
380 /**
381 * Returns the custom color set for this item.
382 * The return value is meaningful only if canUseCustomColor() returns true
383 * returns true and setUseCustomColor( true ) has been called.
384 */
385 [[nodiscard]] const QColor &customColor() const;
386
387 /**
388 * Sets the custom color for this item. Meaningful only if canUseCustomColor()
389 * returns true and you call setUseCustomColor( true )
390 */
391 void setCustomColor(const QColor &clr);
392
393 // Stuff used by ThemeDelegate. This section should be protected but some gcc
394 // versions seem to get confused with nested class and friend declarations
395 // so for portability we're using a public interface also here.
396
397 /**
398 * Handles content item saving (used by Theme::Row::save())
399 */
400 void save(QDataStream &stream) const;
401
402 /**
403 * Handles content item loading (used by Theme::Row::load())
404 */
405 bool load(QDataStream &stream, int themeVersion);
406 };
407
408 /**
409 * The Row class defines a row of items inside a Column.
410 * The Row has a list of left aligned and a list of right aligned ContentItems.
411 */
412 class Row
413 {
414 public:
415 explicit Row();
416 explicit Row(const Row &src);
417 ~Row();
418
419 private:
420 QList<ContentItem *> mLeftItems; ///< The list of left aligned items
421 QList<ContentItem *> mRightItems; ///< The list of right aligned items
422
423 bool LoadContentItem(int val, QDataStream &stream, int themeVersion, bool leftItem);
424
425 public:
426 /**
427 * Returns the list of left aligned items for this row
428 */
429 const QList<ContentItem *> &leftItems() const;
430
431 /**
432 * Removes all the left items from this row: the items are deleted.
433 */
434 void removeAllLeftItems();
435
436 /**
437 * Adds a left aligned item to this row. The row takes the ownership
438 * of the ContentItem pointer.
439 */
440 void addLeftItem(ContentItem *item);
441
442 /**
443 * Adds a left aligned item at the specified position in this row. The row takes the ownership
444 * of the ContentItem pointer.
445 */
446 void insertLeftItem(int idx, ContentItem *item);
447
448 /**
449 * Removes the specified left aligned content item from this row.
450 * The item is NOT deleted.
451 */
452 void removeLeftItem(ContentItem *item);
453
454 /**
455 * Returns the list of right aligned items for this row
456 */
457 const QList<ContentItem *> &rightItems() const;
458
459 /**
460 * Removes all the right items from this row. The items are deleted.
461 */
462 void removeAllRightItems();
463
464 /**
465 * Adds a right aligned item to this row. The row takes the ownership
466 * of the ContentItem pointer. Please note that the first right aligned item
467 * will start at the right edge, the second right aligned item will come after it etc...
468 */
469 void addRightItem(ContentItem *item);
470
471 /**
472 * Adds a right aligned item at the specified position in this row. The row takes the ownership
473 * of the ContentItem pointer. Remember that right item positions go from right to left.
474 */
475 void insertRightItem(int idx, ContentItem *item);
476
477 /**
478 * Removes the specified right aligned content item from this row.
479 * The item is NOT deleted.
480 */
481 void removeRightItem(ContentItem *item);
482
483 /**
484 * Returns true if this row contains text items.
485 * This is useful if you want to know if the column should just get
486 * its minimum allowable space or it should get more.
487 */
488 [[nodiscard]] bool containsTextItems() const;
489
490 /**
491 * Handles row saving (used by Theme::Column::save())
492 */
493 void save(QDataStream &stream) const;
494
495 /**
496 * Handles row loading (used by Theme::Column::load())
497 */
498 bool load(QDataStream &stream, int themeVersion);
499 };
500
501 /**
502 * The Column class defines a view column available inside this theme.
503 * Each Column has a list of Row items that define the visible rows.
504 */
505 class Column
506 {
507 public:
508 /**
509 * A set of shared runtime data. This is used to store a set of "override" settings
510 * at runtime. For instance, the width of the visible columns of a skin are stored here.
511 */
513 {
514 private:
515 int mReferences; ///< The number of external references to this shared data object
516
517 int mCurrentlyVisible; ///< Is this column currently visible ? always valid (eventually set from default)
518 double mCurrentWidth; ///< The current width of this column, -1 if not valid (never set)
519 public:
520 /**
521 * Create a shared runtime data object
522 */
523 explicit SharedRuntimeData(bool currentlyVisible, double currentWidth);
524
525 /**
526 * Destroy a shared runtime data object
527 */
529
530 public:
531 /**
532 * Increments the reference count for this shared runtime data object.
533 */
534 void addReference();
535
536 /**
537 * Decrements the reference count for this shared runtime data object.
538 * Returns true if there are other references and false otherwise (so the data can be safely deleted)
539 */
540 [[nodiscard]] bool deleteReference();
541
542 /**
543 * Returns the current number of reference counts, that is, the number of
544 * Theme::Column objects that use this SharedRuntimeData instance.
545 */
546 [[nodiscard]] int referenceCount() const;
547
548 /**
549 * Returns the current visibility state
550 */
551 [[nodiscard]] bool currentlyVisible() const;
552
553 /**
554 * Sets the current visibility state
555 */
556 void setCurrentlyVisible(bool visible);
557
558 /**
559 * Returns the current width or -1 if the width is unspecified/invalid
560 */
561 [[nodiscard]] double currentWidth() const;
562
563 /**
564 * Sets the current width of the column
565 */
566 void setCurrentWidth(double currentWidth);
567
568 /**
569 * Saves this runtime data to the specified stream
570 */
571 void save(QDataStream &stream) const;
572
573 /**
574 * Loads the shared runtime data from the specified stream
575 * assuming that it uses the specified theme version.
576 * Returns true on success and false if the data can't be loaded.
577 */
578 bool load(QDataStream &stream, int themeVersion);
579 };
580
581 public:
582 /**
583 * Create an empty column with default settings
584 */
585 explicit Column();
586 /**
587 * Create an exact copy of the column src.
588 * The shared runtime data is not copied (only a reference is added).
589 * If you need to create an independent clone then please use detach()
590 * after the construction.
591 */
592 explicit Column(const Column &src);
593 /**
594 * Kill a column object
595 */
596 ~Column();
597
598 private:
599 QString mLabel; ///< The label visible in the column header
600 QString mPixmapName; ///< The icon's name visible in the column header if it was set
601 bool mVisibleByDefault; ///< Is this column visible by default ?
602 bool mIsSenderOrReceiver; ///< If this column displays the sender/receiver field then we will update its label on the fly
603 SortOrder::MessageSorting mMessageSorting; ///< The message sort order we switch to when clicking on this column
604 QList<Row *> mGroupHeaderRows; ///< The list of rows we display in this column for a GroupHeaderItem
605 QList<Row *> mMessageRows; ///< The list of rows we display in this column for a MessageItem
606
607 SharedRuntimeData *mSharedRuntimeData = nullptr; ///< A pointer to the shared runtime data: shared between all instances of a theme with the same id
608 public:
609 /**
610 * Returns the label set for this column
611 */
612 [[nodiscard]] const QString &label() const;
613
614 /**
615 * Sets the label for this column
616 */
617 void setLabel(const QString &label);
618
619 /**
620 * Returns the icon's name (used in SmallIcon) set for this column
621 */
622 [[nodiscard]] const QString &pixmapName() const;
623
624 /**
625 * Sets the icon's name (used in SmallIcon) for this column
626 */
627 void setPixmapName(const QString &pixmapName);
628
629 /**
630 * Returns true if this column is marked as "sender/receiver" and we should
631 * update its label on-the-fly.
632 */
633 [[nodiscard]] bool isSenderOrReceiver() const;
634
635 /**
636 * Marks this column as containing the "sender/receiver" field.
637 * Such columns will have the label automatically updated.
638 */
639 void setIsSenderOrReceiver(bool sor);
640
641 /**
642 * Returns true if this column has to be shown by default
643 */
644 [[nodiscard]] bool visibleByDefault() const;
645
646 /**
647 * Sets the "visible by default" tag for this column.
648 */
649 void setVisibleByDefault(bool vbd);
650
651 /**
652 * Detaches the shared runtime data object and makes this object
653 * totally independent. The shared runtime data is initialized to default values.
654 */
655 void detach();
656
657 /**
658 * Returns the sort order for messages that we should switch to
659 * when clicking on this column's header (if visible at all).
660 */
661 [[nodiscard]] SortOrder::MessageSorting messageSorting() const;
662
663 /**
664 * Sets the sort order for messages that we should switch to
665 * when clicking on this column's header (if visible at all).
666 */
668
669 /**
670 * Returns the current shared visibility state for this column.
671 * This state is shared between all the instances of this theme.
672 */
673 [[nodiscard]] bool currentlyVisible() const;
674
675 /**
676 * Sets the current shared visibility state for this column.
677 * This state is shared between all the instances of this theme.
678 */
680
681 /**
682 * Returns the current shared width setting for this column
683 * or -1 if the width is not specified and should be auto-determined.
684 * This state is shared between all the instances of this theme.
685 */
686 [[nodiscard]] double currentWidth() const;
687
688 /**
689 * Sets the current shared width setting for this column.
690 * This state is shared between all the instances of this theme.
691 */
692 void setCurrentWidth(double currentWidth);
693
694 /**
695 * Returns the list of rows visible in this column for a MessageItem
696 */
697 [[nodiscard]] const QList<Row *> &messageRows() const;
698
699 /**
700 * Removes all the message rows from this column.
701 */
703
704 /**
705 * Appends a message row to this theme column. The Theme takes
706 * the ownership of the Row pointer.
707 */
708 void addMessageRow(Row *row);
709
710 /**
711 * Inserts a message row to this theme column in the specified position. The Theme takes
712 * the ownership of the Row pointer.
713 */
714 void insertMessageRow(int idx, Row *row);
715
716 /**
717 * Removes the specified message row. The row is NOT deleted.
718 */
719 void removeMessageRow(Row *row);
720
721 /**
722 * Returns the list of rows visible in this column for a GroupHeaderItem
723 */
724 [[nodiscard]] const QList<Row *> &groupHeaderRows() const;
725
726 /**
727 * Removes all the group header rows from this column.
728 */
730
731 /**
732 * Appends a group header row to this theme. The Theme takes
733 * the ownership of the Row pointer.
734 */
735 void addGroupHeaderRow(Row *row);
736
737 /**
738 * Inserts a group header row to this theme column in the specified position. The Theme takes
739 * the ownership of the Row pointer.
740 */
741 void insertGroupHeaderRow(int idx, Row *row);
742
743 /**
744 * Removes the specified group header row. The row is NOT deleted.
745 */
746 void removeGroupHeaderRow(Row *row);
747
748 /**
749 * Returns true if this column contains text items.
750 * This is useful if you want to know if the column should just get
751 * its minimum allowable space or it should get more.
752 */
753 [[nodiscard]] bool containsTextItems() const;
754
755 /**
756 * Handles column saving (used by Theme::save())
757 */
758 void save(QDataStream &stream) const;
759
760 /**
761 * Handles column loading (used by Theme::load())
762 */
763 bool load(QDataStream &stream, int themeVersion);
764 };
765
766public:
767 /**
768 * Creates a totally uninitialized theme object.
769 */
770 explicit Theme();
771
772 /**
773 * Creates a theme object with the specified name and description.
774 */
775 explicit Theme(const QString &name, const QString &description, bool readOnly = false);
776
777 /**
778 * Creates an exact copy of the theme sharing the same runtime data.
779 * If you need an exact clone please use detach() and generateUniqueId() just
780 * after creation.
781 */
782 explicit Theme(const Theme &src);
783
784 /**
785 * Destroys this theme object.
786 */
787 ~Theme() override;
788
789 static bool compareName(Theme *theme1, Theme *theme2)
790 {
791 return theme1->name() < theme2->name();
792 }
793
794public:
795 /**
796 * Which color do we use to paint group header background ?
797 */
799 Transparent, ///< No background at all: use style default
800 AutoColor, ///< Automatically determine the color (somewhere in the middle between background and text)
801 CustomColor, ///< Use a custom color
802 };
803
804 /**
805 * How do we paint group header background ?
806 */
808 PlainRect, ///< One plain rect per column
809 PlainJoinedRect, ///< One big plain rect for all the columns
810 RoundedRect, ///< One rounded rect per column
811 RoundedJoinedRect, ///< One big rounded rect for all the columns
812 GradientRect, ///< One rounded gradient filled rect per column
813 GradientJoinedRect, ///< One big rounded gradient rect for all the columns
814 StyledRect, ///< One styled rect per column
815 StyledJoinedRect, ///< One big styled rect per column
816 };
817
818 /**
819 * How do we manage the QHeaderView attached to our View ?
820 */
822 ShowHeaderAlways,
823 NeverShowHeader,
824 // ShowWhenMoreThanOneColumn, ///< This doesn't work at the moment (since without header we don't have means for showing columns back)
825 };
826
827 enum ThemeIcon {
828 IconNew,
829 IconUnread,
830 IconRead,
831 IconDeleted,
832 IconReplied,
833 IconRepliedAndForwarded,
834 IconQueued,
835 IconActionItem,
836 IconSent,
837 IconForwarded,
838 IconImportant,
839 IconWatched,
840 IconIgnored,
841 IconSpam,
842 IconHam,
843 IconFullySigned,
844 IconPartiallySigned,
845 IconUndefinedSigned,
846 IconNotSigned,
847 IconFullyEncrypted,
848 IconPartiallyEncrypted,
849 IconUndefinedEncrypted,
850 IconNotEncrypted,
851 IconAttachment,
852 IconAnnotation,
853 IconInvitation,
854 IconShowMore,
855 IconShowLess,
856 IconVerticalLine,
857 IconHorizontalSpacer,
858
859 _IconCount
860 };
861
862private:
863 QList<Column *> mColumns; ///< The list of columns available in this theme
864
865 // pixmaps cache. Mutable, so it can be lazily populated from const methods
866 mutable QList<QPixmap *> mPixmaps;
867
868 GroupHeaderBackgroundMode mGroupHeaderBackgroundMode; ///< How do we paint group header background ?
869 QColor mGroupHeaderBackgroundColor; ///< The background color of the message group, used only if CustomColor
870 GroupHeaderBackgroundStyle mGroupHeaderBackgroundStyle; ///< How do we paint group header background ?
871 ViewHeaderPolicy mViewHeaderPolicy; ///< Do we show the header or not ?
872 int mIconSize; ///< The icon size for this theme, 16 is the default
873public:
874 /**
875 * Detaches this object from the shared runtime data for columns.
876 */
877 void detach();
878
879 /**
880 * Resets the column state (visibility and width) to their default values (the "visible by default" ones).
881 */
882 void resetColumnState();
883
884 /**
885 * Resets the column sizes to "default" (subset of resetColumnState() above).
886 */
887 void resetColumnSizes();
888
889 /**
890 * Returns the list of columns available in this theme
891 */
892 [[nodiscard]] const QList<Column *> &columns() const;
893
894 /**
895 * Returns a pointer to the column at the specified index or 0 if there is no such column
896 */
897 Column *column(int idx) const;
898
899 void moveColumn(int idx, int newPosition);
900
901 /**
902 * Removes all columns from this theme
903 */
904 void removeAllColumns();
905
906 /**
907 * Appends a column to this theme
908 */
909 void addColumn(Column *column);
910
911 /**
912 * Inserts a column to this theme at the specified position.
913 */
914 void insertColumn(int idx, Column *column);
915
916 /**
917 * Removes the specified message row. The row is NOT deleted.
918 */
919 void removeColumn(Column *col);
920
921 /**
922 * Returns the group header background mode for this theme.
923 */
924 [[nodiscard]] GroupHeaderBackgroundMode groupHeaderBackgroundMode() const;
925
926 /**
927 * Sets the group header background mode for this theme.
928 * If you set it to CustomColor then please also setGroupHeaderBackgroundColor()
929 */
930 void setGroupHeaderBackgroundMode(GroupHeaderBackgroundMode bm);
931
932 /**
933 * Returns the group header background color for this theme.
934 * This color is used only if groupHeaderBackgroundMode() is set to CustomColor.
935 */
936 const QColor &groupHeaderBackgroundColor() const;
937
938 /**
939 * Sets the group header background color for this theme.
940 * This color is used only if groupHeaderBackgroundMode() is set to CustomColor.
941 */
942 void setGroupHeaderBackgroundColor(const QColor &clr);
943
944 /**
945 * Returns the group header background style for this theme.
946 * The group header background style makes sense only if groupHeaderBackgroundMode() is
947 * set to something different than Transparent.
948 */
949 [[nodiscard]] GroupHeaderBackgroundStyle groupHeaderBackgroundStyle() const;
950
951 /**
952 * Sets the group header background style for this theme.
953 * The group header background style makes sense only if groupHeaderBackgroundMode() is
954 * set to something different than Transparent.
955 */
956 void setGroupHeaderBackgroundStyle(GroupHeaderBackgroundStyle groupHeaderBackgroundStyle);
957
958 /**
959 * Enumerates the available group header background styles.
960 * The returned descriptors are pairs in that the first item is the localized description
961 * of the option value and the second item is the integer option value itself.
962 */
964
965 /**
966 * Returns the currently set ViewHeaderPolicy
967 */
968 [[nodiscard]] ViewHeaderPolicy viewHeaderPolicy() const;
969
970 /**
971 * Sets the ViewHeaderPolicy for this theme
972 */
973 void setViewHeaderPolicy(ViewHeaderPolicy vhp);
974
975 /**
976 * Returns the currently set icon size
977 */
978 [[nodiscard]] int iconSize() const;
979
980 /**
981 * Sets the icon size for this theme.
982 * Please note that the function will not let you set insane values.
983 * The allowable range is [8,64]
984 */
985 void setIconSize(int iconSize);
986
987 /**
988 * Enumerates the available view header policy options.
989 * The returned descriptors are pairs in that the first item is the localized description
990 * of the option value and the second item is the integer option value itself.
991 */
993
994 inline const QPixmap *pixmap(ThemeIcon icon) const
995 {
996 if (Q_UNLIKELY(mPixmaps.isEmpty())) {
997 populatePixmapCache();
998 }
999 return mPixmaps[icon];
1000 }
1001
1002protected:
1003 /**
1004 * Pure virtual reimplemented from OptionSet.
1005 */
1006 void save(QDataStream &stream) const override;
1007
1008 /**
1009 * Pure virtual reimplemented from OptionSet.
1010 */
1011 bool load(QDataStream &stream) override;
1012
1013 void clearPixmapCache() const;
1014 void populatePixmapCache() const;
1015};
1016} // namespace Core
1017} // namespace MessageList
A set of options that can be applied to the MessageList in one shot.
Definition optionset.h:33
const QString & description() const
Returns a description of this option set.
Definition optionset.h:79
const QString & name() const
Returns the name of this OptionSet.
Definition optionset.h:59
MessageSorting
The available message sorting options.
Definition sortorder.h:60
double currentWidth() const
Returns the current width or -1 if the width is unspecified/invalid.
Definition theme.cpp:573
void setCurrentlyVisible(bool visible)
Sets the current visibility state.
Definition theme.cpp:568
void addReference()
Increments the reference count for this shared runtime data object.
Definition theme.cpp:546
int referenceCount() const
Returns the current number of reference counts, that is, the number of Theme::Column objects that use...
Definition theme.cpp:558
bool deleteReference()
Decrements the reference count for this shared runtime data object.
Definition theme.cpp:551
~SharedRuntimeData()
Destroy a shared runtime data object.
bool currentlyVisible() const
Returns the current visibility state.
Definition theme.cpp:563
void setCurrentWidth(double currentWidth)
Sets the current width of the column.
Definition theme.cpp:578
SharedRuntimeData(bool currentlyVisible, double currentWidth)
Create a shared runtime data object.
Definition theme.cpp:537
void save(QDataStream &stream) const
Saves this runtime data to the specified stream.
Definition theme.cpp:583
bool load(QDataStream &stream, int themeVersion)
Loads the shared runtime data from the specified stream assuming that it uses the specified theme ver...
Definition theme.cpp:589
The Column class defines a view column available inside this theme.
Definition theme.h:506
bool isSenderOrReceiver() const
Returns true if this column is marked as "sender/receiver" and we should update its label on-the-fly.
Definition theme.cpp:657
void removeGroupHeaderRow(Row *row)
Removes the specified group header row.
Definition theme.cpp:775
void removeMessageRow(Row *row)
Removes the specified message row.
Definition theme.cpp:756
void setPixmapName(const QString &pixmapName)
Sets the icon's name (used in SmallIcon) for this column.
Definition theme.cpp:652
double currentWidth() const
Returns the current shared width setting for this column or -1 if the width is not specified and shou...
Definition theme.cpp:708
const QList< Row * > & groupHeaderRows() const
Returns the list of rows visible in this column for a GroupHeaderItem.
Definition theme.cpp:761
void save(QDataStream &stream) const
Handles column saving (used by Theme::save())
Definition theme.cpp:795
void detach()
Detaches the shared runtime data object and makes this object totally independent.
Definition theme.cpp:677
void insertMessageRow(int idx, Row *row)
Inserts a message row to this theme column in the specified position.
Definition theme.cpp:747
SortOrder::MessageSorting messageSorting() const
Returns the sort order for messages that we should switch to when clicking on this column's header (i...
Definition theme.cpp:688
bool visibleByDefault() const
Returns true if this column has to be shown by default.
Definition theme.cpp:667
void setMessageSorting(SortOrder::MessageSorting ms)
Sets the sort order for messages that we should switch to when clicking on this column's header (if v...
Definition theme.cpp:693
void setVisibleByDefault(bool vbd)
Sets the "visible by default" tag for this column.
Definition theme.cpp:672
void setIsSenderOrReceiver(bool sor)
Marks this column as containing the "sender/receiver" field.
Definition theme.cpp:662
void addGroupHeaderRow(Row *row)
Appends a group header row to this theme.
Definition theme.cpp:742
void setCurrentWidth(double currentWidth)
Sets the current shared width setting for this column.
Definition theme.cpp:713
Column()
Create an empty column with default settings.
Definition theme.cpp:600
const QList< Row * > & messageRows() const
Returns the list of rows visible in this column for a MessageItem.
Definition theme.cpp:718
bool currentlyVisible() const
Returns the current shared visibility state for this column.
Definition theme.cpp:698
const QString & pixmapName() const
Returns the icon's name (used in SmallIcon) set for this column.
Definition theme.cpp:647
void setLabel(const QString &label)
Sets the label for this column.
Definition theme.cpp:642
void setCurrentlyVisible(bool currentlyVisible)
Sets the current shared visibility state for this column.
Definition theme.cpp:703
void insertGroupHeaderRow(int idx, Row *row)
Inserts a group header row to this theme column in the specified position.
Definition theme.cpp:766
const QString & label() const
Returns the label set for this column.
Definition theme.cpp:637
void removeAllGroupHeaderRows()
Removes all the group header rows from this column.
Definition theme.cpp:735
bool containsTextItems() const
Returns true if this column contains text items.
Definition theme.cpp:780
void removeAllMessageRows()
Removes all the message rows from this column.
Definition theme.cpp:723
~Column()
Kill a column object.
Definition theme.cpp:628
bool load(QDataStream &stream, int themeVersion)
Handles column loading (used by Theme::load())
Definition theme.cpp:824
void addMessageRow(Row *row)
Appends a message row to this theme column.
Definition theme.cpp:730
The ContentItem class defines a content item inside a Row.
Definition theme.h:56
bool displaysText() const
Returns true if this item displays some kind of text.
Definition theme.cpp:78
bool canBeDisabled() const
Returns true if this ContentItem can be in a "disabled" state.
Definition theme.cpp:68
void setSoftenByBlending(bool softenByBlending)
Sets the flag that causes this item to be painted "softly".
Definition theme.cpp:259
bool hideWhenDisabled() const
Returns true if this item should be hidden when in disabled state.
Definition theme.cpp:226
void setBold(bool isBold)
Makes this item use a bold font.
Definition theme.cpp:203
void setUseCustomColor(bool useCustomColor)
Makes this item use the custom color that can be set by setCustomColor().
Definition theme.cpp:189
static bool applicableToMessageItems(Type type)
Static test that returns true if an instance of ContentItem with the specified type makes sense in a ...
Definition theme.cpp:278
bool isSpacer() const
Returns true if this item is a small spacer.
Definition theme.cpp:98
void setSoftenByBlendingWhenDisabled(bool softenByBlendingWhenDisabled)
Sets the flag that causes this item to be painted "softly" when disabled.
Definition theme.cpp:245
bool isBold() const
Returns true if this item uses a bold text.
Definition theme.cpp:198
void setItalic(bool isItalic)
Makes this item use italic font.
Definition theme.cpp:217
void setCustomColor(const QColor &clr)
Sets the custom color for this item.
Definition theme.cpp:273
@ SoftenByBlending
For text items: use 60% opacity.
Definition theme.h:221
@ HideWhenDisabled
In disabled state the icon should take no space (overrides SoftenByBlendingWhenDisabled)
Definition theme.h:216
@ SoftenByBlendingWhenDisabled
In disabled state the icon should be still shown, but made very soft by alpha blending.
Definition theme.h:217
@ UseCustomColor
For text and vertical line. If set then always use a custom color, otherwise use default text color.
Definition theme.h:218
@ IsItalic
Fot text items. If set then always show as italic, otherwise use the default font style.
Definition theme.h:220
@ IsBold
For text items. If set then always show as bold, otherwise use the default font weight.
Definition theme.h:219
Type type() const
Returns the type of this content item.
Definition theme.cpp:63
bool canUseCustomColor() const
Returns true if this ContentItem can make use of a custom color.
Definition theme.cpp:73
bool useCustomColor() const
Returns true if this item uses a custom color.
Definition theme.cpp:184
void save(QDataStream &stream) const
Handles content item saving (used by Theme::Row::save())
Definition theme.cpp:288
bool isIcon() const
Returns true if this item displays an icon.
Definition theme.cpp:88
bool softenByBlending() const
Returns true if this item should be always painted in a "soft" fashion.
Definition theme.cpp:254
bool softenByBlendingWhenDisabled() const
Returns true if this item should be painted in a "soft" fashion when in disabled state.
Definition theme.cpp:240
bool load(QDataStream &stream, int themeVersion)
Handles content item loading (used by Theme::Row::load())
Definition theme.cpp:295
bool isClickable() const
Returns true if clicking on this kind of item can perform an action.
Definition theme.cpp:93
Type
The available ContentItem types.
Definition theme.h:106
@ InvitationIcon
Whether the message is an invitation.
Definition theme.h:203
@ CombinedReadRepliedStateIcon
The combined icon that displays the unread/read/replied/forwarded state (never disabled)
Definition theme.h:190
@ SignatureStateIcon
The Signature state icon for messages.
Definition theme.h:174
@ Date
Formatted date time of the message/group.
Definition theme.h:114
@ MostRecentDate
The date of the most recent message in subtree.
Definition theme.h:186
@ ReadStateIcon
The icon that displays the unread/read state (never disabled)
Definition theme.h:134
@ RepliedStateIcon
The icon that displays the replied/forwarded state (may be disabled)
Definition theme.h:142
@ WatchedIgnoredStateIcon
The Watched/Ignored state icon.
Definition theme.h:162
@ ImportantStateIcon
The Important tag icon.
Definition theme.h:154
@ Folder
Folder of the message.
Definition theme.h:207
@ AttachmentStateIcon
The icon that displays the attachment state (may be disabled)
Definition theme.h:138
@ ExpandedStateIcon
The Expanded state icon for group headers.
Definition theme.h:166
@ SenderOrReceiver
From: or To: strip, depending on the folder settings.
Definition theme.h:118
@ GroupHeaderLabel
The group header label.
Definition theme.h:146
@ Subject
Display the subject of the message item.
Definition theme.h:110
@ VerticalLine
A vertical separation line.
Definition theme.h:178
@ HorizontalSpacer
A small empty spacer usable as separator.
Definition theme.h:182
@ EncryptionStateIcon
The Encryption state icon for messages.
Definition theme.h:170
@ Size
Formatted size of the message.
Definition theme.h:130
@ AnnotationIcon
Whether the message has a annotation/note.
Definition theme.h:198
@ Receiver
To: strip, always.
Definition theme.h:126
@ ActionItemStateIcon
The ActionItem state icon.
Definition theme.h:150
@ Sender
From: strip, always.
Definition theme.h:122
@ SpamHamStateIcon
The Spam/Ham state icon.
Definition theme.h:158
ContentItem(const ContentItem &src)
Creates a ContentItem that is a copy of the content item src.
void setHideWhenDisabled(bool hideWhenDisabled)
Sets the flag that causes this item to be hidden when disabled.
Definition theme.cpp:231
const QColor & customColor() const
Returns the custom color set for this item.
Definition theme.cpp:268
bool displaysLongText() const
Returns true if this item displays a long text.
Definition theme.cpp:83
ContentItem(Type type)
Creates a ContentItem with the specified type.
Definition theme.cpp:53
static bool applicableToGroupHeaderItems(Type type)
Static test that returns true if an instance of ContentItem with the specified type makes sense in a ...
Definition theme.cpp:283
bool isItalic() const
Returns true if this item uses an italic text.
Definition theme.cpp:212
The Row class defines a row of items inside a Column.
Definition theme.h:413
void removeLeftItem(ContentItem *item)
Removes the specified left aligned content item from this row.
Definition theme.cpp:397
void addRightItem(ContentItem *item)
Adds a right aligned item to this row.
Definition theme.cpp:383
void insertRightItem(int idx, ContentItem *item)
Adds a right aligned item at the specified position in this row.
Definition theme.cpp:407
bool containsTextItems() const
Returns true if this row contains text items.
Definition theme.cpp:421
void removeAllLeftItems()
Removes all the left items from this row: the items are deleted.
Definition theme.cpp:364
bool load(QDataStream &stream, int themeVersion)
Handles row loading (used by Theme::Column::load())
Definition theme.cpp:512
void insertLeftItem(int idx, ContentItem *item)
Adds a left aligned item at the specified position in this row.
Definition theme.cpp:388
void removeAllRightItems()
Removes all the right items from this row.
Definition theme.cpp:376
void removeRightItem(ContentItem *item)
Removes the specified right aligned content item from this row.
Definition theme.cpp:416
void save(QDataStream &stream) const
Handles row saving (used by Theme::Column::save())
Definition theme.cpp:436
void addLeftItem(ContentItem *item)
Adds a left aligned item to this row.
Definition theme.cpp:371
const QList< ContentItem * > & rightItems() const
Returns the list of right aligned items for this row.
Definition theme.cpp:402
const QList< ContentItem * > & leftItems() const
Returns the list of left aligned items for this row.
Definition theme.cpp:507
The Theme class defines the visual appearance of the MessageList.
Definition theme.h:48
GroupHeaderBackgroundMode
Which color do we use to paint group header background ?
Definition theme.h:798
@ Transparent
No background at all: use style default.
Definition theme.h:799
@ CustomColor
Use a custom color.
Definition theme.h:801
@ AutoColor
Automatically determine the color (somewhere in the middle between background and text)
Definition theme.h:800
void setGroupHeaderBackgroundStyle(GroupHeaderBackgroundStyle groupHeaderBackgroundStyle)
Sets the group header background style for this theme.
Definition theme.cpp:1040
void setGroupHeaderBackgroundColor(const QColor &clr)
Sets the group header background color for this theme.
Definition theme.cpp:1030
void setViewHeaderPolicy(ViewHeaderPolicy vhp)
Sets the ViewHeaderPolicy for this theme.
Definition theme.cpp:1067
ViewHeaderPolicy
How do we manage the QHeaderView attached to our View ?
Definition theme.h:821
void removeColumn(Column *col)
Removes the specified message row.
Definition theme.cpp:999
void setGroupHeaderBackgroundMode(GroupHeaderBackgroundMode bm)
Sets the group header background mode for this theme.
Definition theme.cpp:1017
void setIconSize(int iconSize)
Sets the icon size for this theme.
Definition theme.cpp:1077
void detach()
Detaches this object from the shared runtime data for columns.
Definition theme.cpp:946
const QColor & groupHeaderBackgroundColor() const
Returns the group header background color for this theme.
Definition theme.cpp:1025
static QList< QPair< QString, int > > enumerateGroupHeaderBackgroundStyles()
Enumerates the available group header background styles.
Definition theme.cpp:1050
~Theme() override
Destroys this theme object.
Definition theme.cpp:940
Theme()
Creates a totally uninitialized theme object.
Definition theme.cpp:909
GroupHeaderBackgroundMode groupHeaderBackgroundMode() const
Returns the group header background mode for this theme.
Definition theme.cpp:1004
void addColumn(Column *column)
Appends a column to this theme.
Definition theme.cpp:985
void insertColumn(int idx, Column *column)
Inserts a column to this theme at the specified position.
Definition theme.cpp:990
ViewHeaderPolicy viewHeaderPolicy() const
Returns the currently set ViewHeaderPolicy.
Definition theme.cpp:1062
void resetColumnSizes()
Resets the column sizes to "default" (subset of resetColumnState() above).
Definition theme.cpp:961
GroupHeaderBackgroundStyle groupHeaderBackgroundStyle() const
Returns the group header background style for this theme.
Definition theme.cpp:1035
static QList< QPair< QString, int > > enumerateViewHeaderPolicyOptions()
Enumerates the available view header policy options.
Definition theme.cpp:1045
bool load(QDataStream &stream) override
Pure virtual reimplemented from OptionSet.
Definition theme.cpp:1089
int iconSize() const
Returns the currently set icon size.
Definition theme.cpp:1072
const QList< Column * > & columns() const
Returns the list of columns available in this theme.
Definition theme.cpp:968
void save(QDataStream &stream) const override
Pure virtual reimplemented from OptionSet.
Definition theme.cpp:1180
void removeAllColumns()
Removes all columns from this theme.
Definition theme.cpp:978
Column * column(int idx) const
Returns a pointer to the column at the specified index or 0 if there is no such column.
Definition theme.cpp:973
void resetColumnState()
Resets the column state (visibility and width) to their default values (the "visible by default" ones...
Definition theme.cpp:953
GroupHeaderBackgroundStyle
How do we paint group header background ?
Definition theme.h:807
@ RoundedJoinedRect
One big rounded rect for all the columns.
Definition theme.h:811
@ PlainRect
One plain rect per column.
Definition theme.h:808
@ GradientRect
One rounded gradient filled rect per column.
Definition theme.h:812
@ StyledRect
One styled rect per column.
Definition theme.h:814
@ RoundedRect
One rounded rect per column.
Definition theme.h:810
@ StyledJoinedRect
One big styled rect per column.
Definition theme.h:815
@ PlainJoinedRect
One big plain rect for all the columns.
Definition theme.h:809
@ GradientJoinedRect
One big rounded gradient rect for all the columns.
Definition theme.h:813
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:12:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.