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