| 1 | // Copyright (C) 2019 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #include "qqmltablemodelcolumn_p.h" |
| 5 | |
| 6 | #include <QtQml/qqmlinfo.h> |
| 7 | |
| 8 | QT_BEGIN_NAMESPACE |
| 9 | |
| 10 | /*! |
| 11 | \qmltype TableModelColumn |
| 12 | //! \nativetype QQmlTableModelColumn |
| 13 | \inqmlmodule Qt.labs.qmlmodels |
| 14 | \brief Represents a column in a model. |
| 15 | \since 5.14 |
| 16 | |
| 17 | The TableModelColumn class represents columns in TableModel. |
| 18 | TableModel supports JavaScript/JSON data where each row is an object, |
| 19 | a list of simple key-value pairs where the keys are unordered. |
| 20 | |
| 21 | \code |
| 22 | { |
| 23 | // Each property is one cell/column. |
| 24 | checked: false, |
| 25 | amount: 1, |
| 26 | fruitType: "Apple", |
| 27 | fruitName: "Granny Smith", |
| 28 | fruitPrice: 1.50 |
| 29 | }, |
| 30 | // ... |
| 31 | \endcode |
| 32 | |
| 33 | However, models in Qt are manipulated via row and column indices. Specifying |
| 34 | the columns with TableModelColumn allows a mapping between Qt's built-in |
| 35 | roles to any property in each row object. |
| 36 | |
| 37 | \snippet qml/tablemodel/fruit-example-simpledelegate.qml file |
| 38 | |
| 39 | TableModelColumn also has basic read-only support for complex rows. For more |
| 40 | information, see \l {Supported Row Data Structures}. |
| 41 | |
| 42 | \note Most of the above concepts also apply to TreeModel, except in |
| 43 | TreeModel each row represents a node of the tree. |
| 44 | |
| 45 | \section1 Supported Roles |
| 46 | |
| 47 | TableModelColumn supports all of \l {Qt::ItemDataRole}{Qt's roles}, |
| 48 | with the exception of \c Qt::InitialSortOrderRole. |
| 49 | Roles can be accessed by as listed below, e.g. |
| 50 | \code |
| 51 | text: display |
| 52 | |
| 53 | required property string display |
| 54 | \endcode |
| 55 | |
| 56 | \table |
| 57 | \row \li Qt::DisplayRole \li display |
| 58 | \row \li Qt::DecorationRole \li decoration |
| 59 | \row \li Qt::EditRole \li edit |
| 60 | \row \li Qt::ToolTipRole \li toolTip |
| 61 | \row \li Qt::StatusTipRole \li statusTip |
| 62 | \row \li Qt::WhatsThisRole \li whatsThis |
| 63 | \row \li Qt::FontRole \li font |
| 64 | \row \li Qt::TextAlignmentRole \li textAlignment |
| 65 | \row \li Qt::BackgroundRole \li background |
| 66 | \row \li Qt::ForegroundRole \li foreground |
| 67 | \row \li Qt::CheckStateRole \li checkState |
| 68 | \row \li Qt::AccessibleTextRole \li accessibleText |
| 69 | \row \li Qt::AccessibleDescriptionRole \li accessibleDescription |
| 70 | \row \li Qt::SizeHintRole \li sizeHintRoleNam |
| 71 | \endtable |
| 72 | |
| 73 | \sa TableModel, TableView |
| 74 | */ |
| 75 | |
| 76 | static constexpr QLatin1StringView displayRoleName("display" ); |
| 77 | static constexpr QLatin1StringView decorationRoleName("decoration" ); |
| 78 | static constexpr QLatin1StringView editRoleName("edit" ); |
| 79 | static constexpr QLatin1StringView toolTipRoleName("toolTip" ); |
| 80 | static constexpr QLatin1StringView statusTipRoleName("statusTip" ); |
| 81 | static constexpr QLatin1StringView whatsThisRoleName("whatsThis" ); |
| 82 | |
| 83 | static constexpr QLatin1StringView fontRoleName("font" ); |
| 84 | static constexpr QLatin1StringView textAlignmentRoleName("textAlignment" ); |
| 85 | static constexpr QLatin1StringView backgroundRoleName("background" ); |
| 86 | static constexpr QLatin1StringView foregroundRoleName("foreground" ); |
| 87 | static constexpr QLatin1StringView checkStateRoleName("checkState" ); |
| 88 | |
| 89 | static constexpr QLatin1StringView accessibleTextRoleName("accessibleText" ); |
| 90 | static constexpr QLatin1StringView accessibleDescriptionRoleName("accessibleDescription" ); |
| 91 | |
| 92 | static constexpr QLatin1StringView sizeHintRoleName("sizeHint" ); |
| 93 | |
| 94 | |
| 95 | QQmlTableModelColumn::QQmlTableModelColumn(QObject *parent) |
| 96 | : QObject(parent) |
| 97 | { |
| 98 | } |
| 99 | |
| 100 | QQmlTableModelColumn::~QQmlTableModelColumn() |
| 101 | { |
| 102 | } |
| 103 | |
| 104 | #define DEFINE_ROLE_PROPERTIES(getterGetterName, getterSetterName, getterSignal, roleName) \ |
| 105 | QJSValue QQmlTableModelColumn::getterGetterName() const \ |
| 106 | { \ |
| 107 | return mGetters.value(roleName); \ |
| 108 | } \ |
| 109 | \ |
| 110 | void QQmlTableModelColumn::getterSetterName(const QJSValue &stringOrFunction) \ |
| 111 | { \ |
| 112 | if (!stringOrFunction.isString() && !stringOrFunction.isCallable()) { \ |
| 113 | qmlWarning(this).quote() << "getter for " << roleName << " must be a function"; \ |
| 114 | return; \ |
| 115 | } \ |
| 116 | if (stringOrFunction.strictlyEquals(decoration())) \ |
| 117 | return; \ |
| 118 | \ |
| 119 | mGetters[roleName] = stringOrFunction; \ |
| 120 | emit decorationChanged(); \ |
| 121 | } |
| 122 | |
| 123 | DEFINE_ROLE_PROPERTIES(display, setDisplay, displayChanged, |
| 124 | displayRoleName) |
| 125 | DEFINE_ROLE_PROPERTIES(decoration, setDecoration, decorationChanged, |
| 126 | decorationRoleName) |
| 127 | DEFINE_ROLE_PROPERTIES(edit, setEdit, editChanged, |
| 128 | editRoleName) |
| 129 | DEFINE_ROLE_PROPERTIES(toolTip, setToolTip, toolTipChanged, |
| 130 | toolTipRoleName) |
| 131 | DEFINE_ROLE_PROPERTIES(statusTip, setStatusTip, statusTipChanged, |
| 132 | statusTipRoleName) |
| 133 | DEFINE_ROLE_PROPERTIES(whatsThis, setWhatsThis, whatsThisChanged, |
| 134 | whatsThisRoleName) |
| 135 | |
| 136 | DEFINE_ROLE_PROPERTIES(font, setFont, fontChanged, |
| 137 | fontRoleName) |
| 138 | DEFINE_ROLE_PROPERTIES(textAlignment, setTextAlignment, textAlignmentChanged, |
| 139 | textAlignmentRoleName) |
| 140 | DEFINE_ROLE_PROPERTIES(background, setBackground, backgroundChanged, |
| 141 | backgroundRoleName) |
| 142 | DEFINE_ROLE_PROPERTIES(foreground, setForeground, foregroundChanged, |
| 143 | foregroundRoleName) |
| 144 | DEFINE_ROLE_PROPERTIES(checkState, setCheckState, checkStateChanged, |
| 145 | checkStateRoleName) |
| 146 | |
| 147 | DEFINE_ROLE_PROPERTIES(accessibleText, setAccessibleText, accessibleTextChanged, |
| 148 | accessibleTextRoleName) |
| 149 | DEFINE_ROLE_PROPERTIES(accessibleDescription, setAccessibleDescription, accessibleDescriptionChanged, |
| 150 | accessibleDescriptionRoleName) |
| 151 | |
| 152 | DEFINE_ROLE_PROPERTIES(sizeHint, setSizeHint, sizeHintChanged, |
| 153 | sizeHintRoleName) |
| 154 | |
| 155 | QJSValue QQmlTableModelColumn::getterAtRole(const QString &roleName) |
| 156 | { |
| 157 | auto it = mGetters.find(key: roleName); |
| 158 | if (it == mGetters.end()) |
| 159 | return QJSValue(); |
| 160 | return *it; |
| 161 | } |
| 162 | |
| 163 | const QHash<QString, QJSValue> QQmlTableModelColumn::getters() const |
| 164 | { |
| 165 | return mGetters; |
| 166 | } |
| 167 | |
| 168 | const QHash<int, QString> QQmlTableModelColumn::supportedRoleNames() |
| 169 | { |
| 170 | static const QHash<int, QString> names { |
| 171 | {Qt::DisplayRole, displayRoleName}, |
| 172 | {Qt::DecorationRole, decorationRoleName}, |
| 173 | {Qt::EditRole, editRoleName}, |
| 174 | {Qt::ToolTipRole, toolTipRoleName}, |
| 175 | {Qt::StatusTipRole, statusTipRoleName}, |
| 176 | {Qt::WhatsThisRole, whatsThisRoleName}, |
| 177 | {Qt::FontRole, fontRoleName}, |
| 178 | {Qt::TextAlignmentRole, textAlignmentRoleName}, |
| 179 | {Qt::BackgroundRole, backgroundRoleName}, |
| 180 | {Qt::ForegroundRole, foregroundRoleName}, |
| 181 | {Qt::CheckStateRole, checkStateRoleName}, |
| 182 | {Qt::AccessibleTextRole, accessibleTextRoleName}, |
| 183 | {Qt::AccessibleDescriptionRole, accessibleDescriptionRoleName}, |
| 184 | {Qt::SizeHintRole, sizeHintRoleName} |
| 185 | }; |
| 186 | return names; |
| 187 | } |
| 188 | |
| 189 | QT_END_NAMESPACE |
| 190 | |
| 191 | #include "moc_qqmltablemodelcolumn_p.cpp" |
| 192 | |