| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 2005 Joseph Wenninger <jowenn@kde.org> |
| 4 | |
| 5 | SPDX-License-Identifier: LGPL-2.0-or-later |
| 6 | */ |
| 7 | |
| 8 | #ifndef KCHARSELECT_P_H |
| 9 | #define KCHARSELECT_P_H |
| 10 | |
| 11 | #include <QAbstractTableModel> |
| 12 | #include <QFont> |
| 13 | #include <QMimeData> |
| 14 | #include <QTableView> |
| 15 | #include <memory> |
| 16 | |
| 17 | #include "kcharselectdata_p.h" |
| 18 | |
| 19 | class KCharSelectTablePrivate; |
| 20 | |
| 21 | /*! |
| 22 | * \internal |
| 23 | * A table widget which displays the characters of a font. Internally |
| 24 | * used by KCharSelect. See the KCharSelect documentation for further |
| 25 | * details. |
| 26 | */ |
| 27 | class KCharSelectTable : public QTableView |
| 28 | { |
| 29 | Q_OBJECT |
| 30 | |
| 31 | public: |
| 32 | /*! |
| 33 | * Constructor. Using \a _font, draw a table of chars. |
| 34 | * \sa setContents |
| 35 | */ |
| 36 | KCharSelectTable(QWidget *parent, const QFont &_font); |
| 37 | |
| 38 | ~KCharSelectTable() override; |
| 39 | |
| 40 | void resizeEvent(QResizeEvent *) override; |
| 41 | |
| 42 | /*! Set the font to be displayed to \a _font . */ |
| 43 | void setFont(const QFont &_font); |
| 44 | |
| 45 | /*! Set the highlighted character to \a c . */ |
| 46 | void setChar(uint c); |
| 47 | /*! Set the contents of the table to \a chars . */ |
| 48 | void setContents(const QList<uint> &chars); |
| 49 | |
| 50 | /*! Returns Currently highlighted character. */ |
| 51 | uint chr(); |
| 52 | |
| 53 | /*! |
| 54 | * Returns the currently displayed font. |
| 55 | */ |
| 56 | QFont font() const; |
| 57 | |
| 58 | /*! |
| 59 | * Returns a list of currently displayed characters. |
| 60 | */ |
| 61 | QList<uint> displayedChars() const; |
| 62 | |
| 63 | /*! |
| 64 | * Reimplemented. |
| 65 | */ |
| 66 | void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; |
| 67 | |
| 68 | protected: |
| 69 | /*! |
| 70 | * Reimplemented. |
| 71 | */ |
| 72 | void keyPressEvent(QKeyEvent *e) override; |
| 73 | |
| 74 | Q_SIGNALS: |
| 75 | /*! Emitted to indicate that character \a c is activated (such as by double-clicking it). */ |
| 76 | void activated(uint c); |
| 77 | void focusItemChanged(uint c); |
| 78 | void showCharRequested(uint c); |
| 79 | |
| 80 | private: |
| 81 | friend class KCharSelectTablePrivate; |
| 82 | std::unique_ptr<KCharSelectTablePrivate> const d; |
| 83 | |
| 84 | Q_DISABLE_COPY(KCharSelectTable) |
| 85 | }; |
| 86 | |
| 87 | // NO D-Pointer needed, private internal class, no public API |
| 88 | |
| 89 | class KCharSelectItemModel : public QAbstractTableModel |
| 90 | { |
| 91 | Q_OBJECT |
| 92 | public: |
| 93 | KCharSelectItemModel(const QList<uint> &chars, const QFont &font, QObject *parent) |
| 94 | : QAbstractTableModel(parent) |
| 95 | , m_chars(chars) |
| 96 | , m_font(font) |
| 97 | { |
| 98 | if (!chars.isEmpty()) { |
| 99 | m_columns = chars.count(); |
| 100 | } else { |
| 101 | m_columns = 1; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | enum internalRoles { |
| 106 | CharacterRole = Qt::UserRole |
| 107 | }; |
| 108 | int rowCount(const QModelIndex &parent = QModelIndex()) const override |
| 109 | { |
| 110 | if (parent.isValid()) { |
| 111 | return 0; |
| 112 | } |
| 113 | if (m_chars.count() % m_columns == 0) { |
| 114 | return m_chars.count() / m_columns; |
| 115 | } else { |
| 116 | return m_chars.count() / m_columns + 1; |
| 117 | } |
| 118 | } |
| 119 | int columnCount(const QModelIndex & = QModelIndex()) const override |
| 120 | { |
| 121 | return m_columns; |
| 122 | } |
| 123 | |
| 124 | void setFont(const QFont &font) |
| 125 | { |
| 126 | beginResetModel(); |
| 127 | m_font = font; |
| 128 | endResetModel(); |
| 129 | } |
| 130 | Qt::ItemFlags flags(const QModelIndex &index) const override |
| 131 | { |
| 132 | int pos = m_columns * (index.row()) + index.column(); |
| 133 | if (pos >= m_chars.size() || index.row() < 0 || index.column() < 0) { |
| 134 | return Qt::ItemIsDropEnabled; |
| 135 | } |
| 136 | return (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled); |
| 137 | } |
| 138 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; |
| 139 | QMimeData *mimeData(const QModelIndexList &indexes) const override |
| 140 | { |
| 141 | if (indexes.size() != 1) { |
| 142 | return nullptr; |
| 143 | } |
| 144 | QMimeData *mimeData = new QMimeData(); |
| 145 | char32_t character = data(index: indexes[0], role: CharacterRole).toUInt(); |
| 146 | mimeData->setText(QString::fromUcs4(&character, size: 1)); |
| 147 | return mimeData; |
| 148 | } |
| 149 | Qt::DropActions supportedDropActions() const override |
| 150 | { |
| 151 | return Qt::CopyAction; |
| 152 | } |
| 153 | QStringList mimeTypes() const override |
| 154 | { |
| 155 | return {QStringLiteral("text/plain" )}; |
| 156 | } |
| 157 | bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; |
| 158 | |
| 159 | void setColumnCount(int columns); |
| 160 | |
| 161 | QList<uint> chars() const |
| 162 | { |
| 163 | return m_chars; |
| 164 | } |
| 165 | |
| 166 | private: |
| 167 | QList<uint> m_chars; |
| 168 | QFont m_font; |
| 169 | int m_columns; |
| 170 | |
| 171 | Q_SIGNALS: |
| 172 | void showCharRequested(uint c); |
| 173 | }; |
| 174 | #endif // KCHARSELECT_P_H |
| 175 | |