File indexing completed on 2024-12-15 04:54:45

0001 /******************************************************************************
0002  *
0003  *  SPDX-FileCopyrightText: 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  *
0007  *******************************************************************************/
0008 
0009 #pragma once
0010 
0011 #include "core/theme.h"
0012 #include "core/themedelegate.h"
0013 #include "utils/optionseteditor.h"
0014 
0015 #include <QLabel>
0016 #include <QRect>
0017 #include <QTreeWidget>
0018 
0019 #include <QDialog>
0020 
0021 class QCheckBox;
0022 
0023 class QComboBox;
0024 class KPluralHandlingSpinBox;
0025 class QLineEdit;
0026 
0027 namespace MessageList
0028 {
0029 namespace Core
0030 {
0031 class Item;
0032 class GroupHeaderItem;
0033 class MessageItem;
0034 class FakeItem;
0035 class ModelInvariantRowMapper;
0036 } // namespace Core
0037 
0038 namespace Utils
0039 {
0040 class ThemeColumnPropertiesDialog : public QDialog
0041 {
0042     Q_OBJECT
0043 public:
0044     explicit ThemeColumnPropertiesDialog(QWidget *parent, Core::Theme::Column *column, const QString &title);
0045 
0046 protected:
0047     Core::Theme::Column *const mColumn;
0048     QLineEdit *mNameEdit = nullptr;
0049     QCheckBox *mVisibleByDefaultCheck = nullptr;
0050     QCheckBox *mIsSenderOrReceiverCheck = nullptr;
0051     QComboBox *mMessageSortingCombo = nullptr;
0052 
0053 protected Q_SLOTS:
0054     void slotOkButtonClicked();
0055 };
0056 
0057 class ThemePreviewDelegate : public Core::ThemeDelegate
0058 {
0059     Q_OBJECT
0060 public:
0061     explicit ThemePreviewDelegate(QAbstractItemView *parent);
0062     ~ThemePreviewDelegate() override;
0063 
0064 private:
0065     Core::GroupHeaderItem *mSampleGroupHeaderItem = nullptr;
0066     Core::FakeItem *mSampleMessageItem = nullptr;
0067     Core::ModelInvariantRowMapper *mRowMapper = nullptr; // needed for the MessageItem above to be valid
0068 public:
0069     Core::Item *itemFromIndex(const QModelIndex &index) const override;
0070 };
0071 
0072 class ThemePreviewWidget : public QTreeWidget
0073 {
0074     Q_OBJECT
0075 public:
0076     explicit ThemePreviewWidget(QWidget *parent);
0077     ~ThemePreviewWidget() override;
0078     void setReadOnly(bool readOnly);
0079 
0080 private:
0081     // DnD insert position stuff
0082 
0083     /**
0084      * The row we'll be inserting the dragged item into
0085      */
0086     enum RowInsertPosition {
0087         AboveRow, ///< We'll insert above the currently hit row in mDelegate
0088         InsideRow, ///< We'll insert inside the currently hit row in mDelegate
0089         BelowRow ///< We'll insert below the currently hit row in mDelegate
0090     };
0091 
0092     /**
0093      * The position in row that we'll be inserting the dragged item
0094      */
0095     enum ItemInsertPosition {
0096         OnLeftOfItem, ///< We'll insert on the left of the selected item
0097         OnRightOfItem, ///< We'll insert on the right of the selected item
0098         AsLastLeftItem, ///< We'll insert as last left item of the row (rightmost left item)
0099         AsLastRightItem, ///< We'll insert as last right item of the row (leftmost right item)
0100         AsFirstLeftItem, ///< We'll insert as first left item of the row (leftmost)
0101         AsFirstRightItem ///< We'll insert as first right item of the row (rightmost)
0102     };
0103 
0104 private:
0105     ThemePreviewDelegate *mDelegate = nullptr;
0106     QTreeWidgetItem *mGroupHeaderSampleItem = nullptr;
0107     QRect mThemeSelectedContentItemRect;
0108     Core::Theme::ContentItem *mSelectedThemeContentItem = nullptr;
0109     Core::Theme::Column *mSelectedThemeColumn = nullptr;
0110     QPoint mMouseDownPoint;
0111     Core::Theme *mTheme = nullptr;
0112     RowInsertPosition mRowInsertPosition;
0113     ItemInsertPosition mItemInsertPosition;
0114     QPoint mDropIndicatorPoint1;
0115     QPoint mDropIndicatorPoint2;
0116     bool mFirstShow;
0117     bool mReadOnly;
0118 
0119 public:
0120     QSize sizeHint() const override;
0121     void setTheme(Core::Theme *theme);
0122 
0123 protected:
0124     void dragMoveEvent(QDragMoveEvent *e) override;
0125     void dragEnterEvent(QDragEnterEvent *e) override;
0126     void dropEvent(QDropEvent *e) override;
0127     void mouseMoveEvent(QMouseEvent *e) override;
0128     void mousePressEvent(QMouseEvent *e) override;
0129     void paintEvent(QPaintEvent *e) override;
0130     void showEvent(QShowEvent *e) override;
0131     void changeEvent(QEvent *event) override;
0132 
0133 private:
0134     void internalHandleDragMoveEvent(QDragMoveEvent *e);
0135     void internalHandleDragEnterEvent(QDragEnterEvent *e);
0136 
0137     /**
0138      * Computes the drop insert position for the dragged item at position pos.
0139      * Returns true if the dragged item can be inserted somewhere and
0140      * false otherwise. Sets mRowInsertPosition, mItemInsertPosition,
0141      * mDropIndicatorPoint1 ,mDropIndicatorPoint2.
0142      */
0143     bool computeContentItemInsertPosition(const QPoint &pos, Core::Theme::ContentItem::Type type);
0144 
0145     void applyThemeColumnWidths();
0146 
0147 protected Q_SLOTS:
0148     void slotHeaderContextMenuRequested(const QPoint &pos);
0149     void slotAddColumn();
0150     void slotColumnProperties();
0151     void slotDeleteColumn();
0152     void slotDisabledFlagsMenuTriggered(QAction *act);
0153     void slotForegroundColorMenuTriggered(QAction *act);
0154     void slotFontMenuTriggered(QAction *act);
0155     void slotSoftenActionTriggered(bool);
0156     void slotGroupHeaderBackgroundModeMenuTriggered(QAction *act);
0157     void slotGroupHeaderBackgroundStyleMenuTriggered(QAction *act);
0158     void slotMoveColumnToLeft();
0159     void slotMoveColumnToRight();
0160 };
0161 
0162 class ThemeContentItemSourceLabel : public QLabel
0163 {
0164     Q_OBJECT
0165 public:
0166     ThemeContentItemSourceLabel(QWidget *parent, Core::Theme::ContentItem::Type type);
0167     ~ThemeContentItemSourceLabel() override;
0168 
0169 public:
0170     Core::Theme::ContentItem::Type type() const;
0171     void startDrag();
0172 
0173 protected:
0174     void mousePressEvent(QMouseEvent *e) override;
0175     void mouseMoveEvent(QMouseEvent *e) override;
0176 
0177 private:
0178     QPoint mMousePressPoint;
0179     Core::Theme::ContentItem::Type mType;
0180 };
0181 
0182 class ThemeEditor : public OptionSetEditor
0183 {
0184     Q_OBJECT
0185 public:
0186     explicit ThemeEditor(QWidget *parent);
0187     ~ThemeEditor() override;
0188 
0189 public:
0190     /**
0191      * Sets the option set to be edited.
0192      * Saves and forgets any previously option set that was being edited.
0193      * The set parameter may be 0: in this case the editor is simply disabled.
0194      */
0195     void editTheme(Core::Theme *set);
0196 
0197     Core::Theme *editedTheme() const;
0198 
0199     void commit();
0200 Q_SIGNALS:
0201     void themeNameChanged();
0202 
0203 private:
0204     void fillViewHeaderPolicyCombo();
0205 
0206 protected Q_SLOTS:
0207     void slotNameEditTextEdited(const QString &newName) override;
0208     void slotIconSizeSpinBoxValueChanged(int val);
0209 
0210 private:
0211     void setReadOnly(bool readOnly);
0212 
0213     Core::Theme *mCurrentTheme = nullptr; // shallow, may be null!
0214 
0215     // Appearance tab
0216     ThemePreviewWidget *mPreviewWidget = nullptr;
0217 
0218     // Advanced tab
0219     QComboBox *mViewHeaderPolicyCombo = nullptr;
0220     KPluralHandlingSpinBox *mIconSizeSpinBox = nullptr;
0221 };
0222 } // namespace Utils
0223 } // namespace MessageList