| File: | builds/wireshark/wireshark/ui/qt/models/coloring_rules_model.cpp |
| Warning: | line 495, column 9 Potential leak of memory pointed to by 'item' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* coloring_rules_model.cpp | |||
| 2 | * Data model for coloring rules. | |||
| 3 | * | |||
| 4 | * Wireshark - Network traffic analyzer | |||
| 5 | * By Gerald Combs <gerald@wireshark.org> | |||
| 6 | * Copyright 1998 Gerald Combs | |||
| 7 | * | |||
| 8 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
| 9 | */ | |||
| 10 | #include "config.h" | |||
| 11 | ||||
| 12 | #include "coloring_rules_model.h" | |||
| 13 | ||||
| 14 | #include <errno(*__errno_location ()).h> | |||
| 15 | ||||
| 16 | #include "ui/ws_ui_util.h" //for color_filter_add_cb | |||
| 17 | ||||
| 18 | #include <ui/qt/utils/color_utils.h> | |||
| 19 | #include <ui/qt/utils/qt_ui_utils.h> | |||
| 20 | #include <ui/qt/utils/variant_pointer.h> | |||
| 21 | #include <ui/qt/utils/wireshark_mime_data.h> | |||
| 22 | ||||
| 23 | #include <QMimeData> | |||
| 24 | #include <QJsonDocument> | |||
| 25 | #include <QJsonObject> | |||
| 26 | #include <QJsonArray> | |||
| 27 | ||||
| 28 | ColoringRuleItem::ColoringRuleItem(bool disabled, QString name, QString filter, QColor foreground, QColor background, ColoringRuleItem* parent) | |||
| 29 | : ModelHelperTreeItem<ColoringRuleItem>(parent), | |||
| 30 | disabled_(disabled), | |||
| 31 | name_(name), | |||
| 32 | filter_(filter), | |||
| 33 | foreground_(foreground), | |||
| 34 | background_(background) | |||
| 35 | { | |||
| 36 | } | |||
| 37 | ||||
| 38 | ColoringRuleItem::~ColoringRuleItem() | |||
| 39 | { | |||
| 40 | ||||
| 41 | } | |||
| 42 | ||||
| 43 | ColoringRuleItem::ColoringRuleItem(color_filter_t *colorf, ColoringRuleItem* parent) | |||
| 44 | : ModelHelperTreeItem<ColoringRuleItem>(parent), | |||
| 45 | disabled_(colorf->disabled), | |||
| 46 | name_(colorf->filter_name), | |||
| 47 | filter_(colorf->filter_text), | |||
| 48 | foreground_(ColorUtils::fromColorT(colorf->fg_color)), | |||
| 49 | background_(ColorUtils::fromColorT(colorf->bg_color)) | |||
| 50 | { | |||
| 51 | } | |||
| 52 | ||||
| 53 | ColoringRuleItem::ColoringRuleItem(const ColoringRuleItem& item) | |||
| 54 | : ModelHelperTreeItem<ColoringRuleItem>(item.parent_), | |||
| 55 | disabled_(item.disabled_), | |||
| 56 | name_(item.name_), | |||
| 57 | filter_(item.filter_), | |||
| 58 | foreground_(item.foreground_), | |||
| 59 | background_(item.background_) | |||
| 60 | { | |||
| 61 | } | |||
| 62 | ||||
| 63 | ColoringRuleItem& ColoringRuleItem::operator=(ColoringRuleItem& rhs) | |||
| 64 | { | |||
| 65 | disabled_ = rhs.disabled_; | |||
| 66 | name_ = rhs.name_; | |||
| 67 | filter_ = rhs.filter_; | |||
| 68 | foreground_ = rhs.foreground_; | |||
| 69 | background_ = rhs.background_; | |||
| 70 | return *this; | |||
| 71 | } | |||
| 72 | ||||
| 73 | // Callback for color_filters_clone. | |||
| 74 | void | |||
| 75 | color_filter_add_cb(color_filter_t *colorf, void *user_data) | |||
| 76 | { | |||
| 77 | ColoringRulesModel *model = (ColoringRulesModel*)user_data; | |||
| 78 | ||||
| 79 | if (model == NULL__null) | |||
| 80 | return; | |||
| 81 | ||||
| 82 | model->addColor(colorf); | |||
| 83 | } | |||
| 84 | ||||
| 85 | ColoringRulesModel::ColoringRulesModel(QColor defaultForeground, QColor defaultBackground, QObject *parent) : | |||
| 86 | QAbstractItemModel(parent), | |||
| 87 | root_(new ColoringRuleItem(false, "", "", QColor(), QColor(), NULL__null)), | |||
| 88 | conversation_colors_(NULL__null), | |||
| 89 | defaultForeground_(defaultForeground), | |||
| 90 | defaultBackground_(defaultBackground) | |||
| 91 | ||||
| 92 | { | |||
| 93 | color_filters_clone(this, color_filter_add_cb); | |||
| 94 | } | |||
| 95 | ||||
| 96 | ColoringRulesModel::~ColoringRulesModel() | |||
| 97 | { | |||
| 98 | delete root_; | |||
| 99 | color_filter_list_delete(&conversation_colors_); | |||
| 100 | } | |||
| 101 | ||||
| 102 | GSList *ColoringRulesModel::createColorFilterList() | |||
| 103 | { | |||
| 104 | GSList *cfl = NULL__null; | |||
| 105 | for (int row = 0; row < root_->childCount(); row++) | |||
| 106 | { | |||
| 107 | ColoringRuleItem* rule = root_->child(row); | |||
| 108 | if (rule == NULL__null) | |||
| 109 | continue; | |||
| 110 | ||||
| 111 | color_t fg = ColorUtils::toColorT(rule->foreground_); | |||
| 112 | color_t bg = ColorUtils::toColorT(rule->background_); | |||
| 113 | color_filter_t *colorf = color_filter_new(rule->name_.toUtf8().constData(), | |||
| 114 | rule->filter_.toUtf8().constData(), | |||
| 115 | &bg, &fg, rule->disabled_); | |||
| 116 | cfl = g_slist_append(cfl, colorf); | |||
| 117 | } | |||
| 118 | ||||
| 119 | return cfl; | |||
| 120 | } | |||
| 121 | ||||
| 122 | void ColoringRulesModel::addColor(color_filter_t* colorf) | |||
| 123 | { | |||
| 124 | if (!colorf) return; | |||
| 125 | ||||
| 126 | if (strstr(colorf->filter_name, CONVERSATION_COLOR_PREFIX"___conversation_color_filter___") != NULL__null) { | |||
| 127 | conversation_colors_ = g_slist_append(conversation_colors_, colorf); | |||
| 128 | } else { | |||
| 129 | int count = root_->childCount(); | |||
| 130 | ||||
| 131 | beginInsertRows(QModelIndex(), count, count); | |||
| 132 | ColoringRuleItem* item = new ColoringRuleItem(colorf, root_); | |||
| 133 | color_filter_delete(colorf); | |||
| 134 | root_->appendChild(item); | |||
| 135 | endInsertRows(); | |||
| 136 | } | |||
| 137 | } | |||
| 138 | ||||
| 139 | void ColoringRulesModel::addColor(bool disabled, QString filter, QColor foreground, QColor background) | |||
| 140 | { | |||
| 141 | //add rule to top of the list | |||
| 142 | beginInsertRows(QModelIndex(), 0, 0); | |||
| 143 | ColoringRuleItem* item = new ColoringRuleItem(disabled, tr("New coloring rule"), filter, foreground, background, root_); | |||
| 144 | root_->prependChild(item); | |||
| 145 | endInsertRows(); | |||
| 146 | } | |||
| 147 | ||||
| 148 | ||||
| 149 | bool ColoringRulesModel::importColors(QString filename, QString& err) | |||
| 150 | { | |||
| 151 | bool success = true; | |||
| 152 | char* err_msg = NULL__null; | |||
| 153 | if (!color_filters_import(filename.toUtf8().constData(), this, &err_msg, color_filter_add_cb)) { | |||
| 154 | err = gchar_free_to_qstring(err_msg); | |||
| 155 | success = false; | |||
| 156 | } | |||
| 157 | ||||
| 158 | return success; | |||
| 159 | } | |||
| 160 | ||||
| 161 | bool ColoringRulesModel::exportColors(QString filename, QString& err) | |||
| 162 | { | |||
| 163 | GSList *cfl = createColorFilterList(); | |||
| 164 | bool success = true; | |||
| 165 | char* err_msg = NULL__null; | |||
| 166 | if (!color_filters_export(filename.toUtf8().constData(), cfl, false, &err_msg)) { | |||
| 167 | err = gchar_free_to_qstring(err_msg); | |||
| 168 | success = false; | |||
| 169 | } | |||
| 170 | color_filter_list_delete(&cfl); | |||
| 171 | ||||
| 172 | return success; | |||
| 173 | } | |||
| 174 | ||||
| 175 | bool ColoringRulesModel::writeColors(QString& err) | |||
| 176 | { | |||
| 177 | GSList *cfl = createColorFilterList(); | |||
| 178 | bool success = true; | |||
| 179 | char* err_msg = NULL__null; | |||
| 180 | if (!color_filters_apply(conversation_colors_, cfl, &err_msg)) { | |||
| 181 | err = gchar_free_to_qstring(err_msg); | |||
| 182 | success = false; | |||
| 183 | } | |||
| 184 | if (!color_filters_write(cfl, &err_msg)) { | |||
| 185 | err = tr("Unable to save coloring rules: %1").arg(g_strerror(errno(*__errno_location ()))); | |||
| 186 | success = false; | |||
| 187 | g_free(err_msg); | |||
| 188 | } | |||
| 189 | color_filter_list_delete(&cfl); | |||
| 190 | ||||
| 191 | return success; | |||
| 192 | } | |||
| 193 | ||||
| 194 | bool ColoringRulesModel::insertRows(int row, int count, const QModelIndex& parent) | |||
| 195 | { | |||
| 196 | // sanity check insertion | |||
| 197 | if (row < 0) | |||
| 198 | return false; | |||
| 199 | ||||
| 200 | beginInsertRows(parent, row, row+(count-1)); | |||
| 201 | ||||
| 202 | for (int i = row; i < row + count; i++) | |||
| 203 | { | |||
| 204 | ColoringRuleItem* item = new ColoringRuleItem(true, tr("New coloring rule"), "", defaultForeground_, defaultBackground_, root_); | |||
| 205 | root_->insertChild(i, item); | |||
| 206 | /* Automatically enable the new coloring rule */ | |||
| 207 | setData(index(i, colName, parent), Qt::Checked, Qt::CheckStateRole); | |||
| 208 | } | |||
| 209 | ||||
| 210 | endInsertRows(); | |||
| 211 | return true; | |||
| 212 | } | |||
| 213 | ||||
| 214 | bool ColoringRulesModel::removeRows(int row, int count, const QModelIndex& parent) | |||
| 215 | { | |||
| 216 | if (row < 0) | |||
| 217 | return false; | |||
| 218 | ||||
| 219 | beginRemoveRows(parent, row, row+(count-1)); | |||
| 220 | for (int i = row; i < row + count; i++) | |||
| 221 | { | |||
| 222 | root_->removeChild(row); | |||
| 223 | } | |||
| 224 | endRemoveRows(); | |||
| 225 | ||||
| 226 | return true; | |||
| 227 | } | |||
| 228 | ||||
| 229 | bool ColoringRulesModel::copyRow(int dst_row, int src_row) | |||
| 230 | { | |||
| 231 | if (src_row < 0 || src_row >= rowCount() || dst_row < 0 || dst_row >= rowCount()) { | |||
| 232 | return false; | |||
| 233 | } | |||
| 234 | ||||
| 235 | ColoringRuleItem* src_item = root_->child(src_row); | |||
| 236 | if (src_item == NULL__null) | |||
| 237 | return false; | |||
| 238 | ||||
| 239 | ColoringRuleItem* dst_item = new ColoringRuleItem(*src_item); | |||
| 240 | if (dst_item == NULL__null) | |||
| 241 | return false; | |||
| 242 | ||||
| 243 | beginInsertRows(QModelIndex(), dst_row, dst_row); | |||
| 244 | root_->insertChild(dst_row, dst_item); | |||
| 245 | endInsertRows(); | |||
| 246 | ||||
| 247 | return true; | |||
| 248 | } | |||
| 249 | ||||
| 250 | Qt::ItemFlags ColoringRulesModel::flags(const QModelIndex &index) const | |||
| 251 | { | |||
| 252 | Qt::ItemFlags flags = QAbstractItemModel::flags(index); | |||
| 253 | switch (index.column()) | |||
| 254 | { | |||
| 255 | case colName: | |||
| 256 | flags |= (Qt::ItemIsUserCheckable|Qt::ItemIsEditable); | |||
| 257 | break; | |||
| 258 | case colFilter: | |||
| 259 | flags |= Qt::ItemIsEditable; | |||
| 260 | break; | |||
| 261 | } | |||
| 262 | ||||
| 263 | if (index.isValid()) | |||
| 264 | flags |= (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); | |||
| 265 | else | |||
| 266 | flags |= Qt::ItemIsDropEnabled; | |||
| 267 | ||||
| 268 | return flags; | |||
| 269 | } | |||
| 270 | ||||
| 271 | ||||
| 272 | QVariant ColoringRulesModel::data(const QModelIndex &index, int role) const | |||
| 273 | { | |||
| 274 | if (!index.isValid()) | |||
| 275 | return QVariant(); | |||
| 276 | ||||
| 277 | ColoringRuleItem* rule = root_->child(index.row()); | |||
| 278 | if (rule == NULL__null) | |||
| 279 | return QVariant(); | |||
| 280 | ||||
| 281 | switch (role) | |||
| 282 | { | |||
| 283 | case Qt::DisplayRole: | |||
| 284 | case Qt::EditRole: | |||
| 285 | switch(index.column()) | |||
| 286 | { | |||
| 287 | case colName: | |||
| 288 | return rule->name_; | |||
| 289 | case colFilter: | |||
| 290 | return rule->filter_; | |||
| 291 | } | |||
| 292 | break; | |||
| 293 | case Qt::CheckStateRole: | |||
| 294 | switch(index.column()) | |||
| 295 | { | |||
| 296 | case colName: | |||
| 297 | return rule->disabled_ ? Qt::Unchecked : Qt::Checked; | |||
| 298 | } | |||
| 299 | break; | |||
| 300 | case Qt::BackgroundRole: | |||
| 301 | return rule->background_; | |||
| 302 | case Qt::ForegroundRole: | |||
| 303 | return rule->foreground_; | |||
| 304 | } | |||
| 305 | return QVariant(); | |||
| 306 | } | |||
| 307 | ||||
| 308 | bool ColoringRulesModel::setData(const QModelIndex &dataIndex, const QVariant &value, int role) | |||
| 309 | { | |||
| 310 | if (!dataIndex.isValid()) | |||
| 311 | return false; | |||
| 312 | ||||
| 313 | if (data(dataIndex, role) == value) { | |||
| 314 | // Data appears unchanged, do not do additional checks. | |||
| 315 | return true; | |||
| 316 | } | |||
| 317 | ||||
| 318 | ColoringRuleItem* rule = root_->child(dataIndex.row()); | |||
| 319 | if (rule == NULL__null) | |||
| 320 | return false; | |||
| 321 | ||||
| 322 | QModelIndex topLeft = dataIndex, | |||
| 323 | bottomRight = dataIndex; | |||
| 324 | ||||
| 325 | switch (role) | |||
| 326 | { | |||
| 327 | case Qt::EditRole: | |||
| 328 | switch (dataIndex.column()) | |||
| 329 | { | |||
| 330 | case colName: | |||
| 331 | rule->name_ = value.toString(); | |||
| 332 | break; | |||
| 333 | case colFilter: | |||
| 334 | rule->filter_ = value.toString(); | |||
| 335 | break; | |||
| 336 | default: | |||
| 337 | return false; | |||
| 338 | } | |||
| 339 | break; | |||
| 340 | case Qt::CheckStateRole: | |||
| 341 | switch (dataIndex.column()) | |||
| 342 | { | |||
| 343 | case colName: | |||
| 344 | rule->disabled_ = (value.toInt() == Qt::Checked) ? false : true; | |||
| 345 | break; | |||
| 346 | default: | |||
| 347 | return false; | |||
| 348 | } | |||
| 349 | break; | |||
| 350 | case Qt::BackgroundRole: | |||
| 351 | #if (QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0))) | |||
| 352 | if (!value.canConvert<QColor>()) | |||
| 353 | #else | |||
| 354 | if (!value.canConvert(QVariant::Color)) | |||
| 355 | #endif | |||
| 356 | return false; | |||
| 357 | ||||
| 358 | rule->background_ = QColor(value.toString()); | |||
| 359 | break; | |||
| 360 | case Qt::ForegroundRole: | |||
| 361 | #if (QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0))) | |||
| 362 | if (!value.canConvert<QColor>()) | |||
| 363 | #else | |||
| 364 | if (!value.canConvert(QVariant::Color)) | |||
| 365 | #endif | |||
| 366 | return false; | |||
| 367 | ||||
| 368 | rule->foreground_ = QColor(value.toString()); | |||
| 369 | break; | |||
| 370 | case Qt::UserRole: | |||
| 371 | { | |||
| 372 | ColoringRuleItem* new_rule = VariantPointer<ColoringRuleItem>::asPtr(value); | |||
| 373 | *rule = *new_rule; | |||
| 374 | topLeft = index(dataIndex.row(), colName); | |||
| 375 | bottomRight = index(dataIndex.row(), colFilter); | |||
| 376 | break; | |||
| 377 | } | |||
| 378 | default: | |||
| 379 | return false; | |||
| 380 | } | |||
| 381 | ||||
| 382 | QVector<int> roles; | |||
| 383 | roles << role; | |||
| 384 | ||||
| 385 | emit dataChanged(topLeft, bottomRight, roles); | |||
| 386 | ||||
| 387 | return true; | |||
| 388 | ||||
| 389 | } | |||
| 390 | ||||
| 391 | QVariant ColoringRulesModel::headerData(int section, Qt::Orientation orientation, int role) const | |||
| 392 | { | |||
| 393 | if (role != Qt::DisplayRole || orientation != Qt::Horizontal) | |||
| 394 | return QVariant(); | |||
| 395 | ||||
| 396 | switch ((ColoringRulesColumn)section) { | |||
| 397 | case colName: | |||
| 398 | return tr("Name"); | |||
| 399 | case colFilter: | |||
| 400 | return tr("Filter"); | |||
| 401 | default: | |||
| 402 | break; | |||
| 403 | } | |||
| 404 | ||||
| 405 | return QVariant(); | |||
| 406 | } | |||
| 407 | ||||
| 408 | Qt::DropActions ColoringRulesModel::supportedDropActions() const | |||
| 409 | { | |||
| 410 | return Qt::MoveAction | Qt::CopyAction; | |||
| 411 | } | |||
| 412 | ||||
| 413 | QStringList ColoringRulesModel::mimeTypes() const | |||
| 414 | { | |||
| 415 | return QStringList() << WiresharkMimeData::ColoringRulesMimeType; | |||
| 416 | } | |||
| 417 | ||||
| 418 | QMimeData* ColoringRulesModel::mimeData(const QModelIndexList &indexes) const | |||
| 419 | { | |||
| 420 | //if the list is empty, don't return an empty list | |||
| 421 | if (indexes.count() == 0) | |||
| 422 | return NULL__null; | |||
| 423 | ||||
| 424 | QMimeData *mimeData = new QMimeData(); | |||
| 425 | ||||
| 426 | QJsonArray data; | |||
| 427 | foreach (const QModelIndex & index, indexes)for (auto _container_427 = QtPrivate::qMakeForeachContainer(indexes ); _container_427.i != _container_427.e; ++_container_427.i) if (const QModelIndex & index = *_container_427.i; false) { } else | |||
| 428 | { | |||
| 429 | if (index.column() == 0) | |||
| 430 | { | |||
| 431 | ColoringRuleItem * item = root_->child(index.row()); | |||
| 432 | QJsonObject entry; | |||
| 433 | entry["disabled"] = item->disabled_; | |||
| 434 | entry["name"] = item->name_; | |||
| 435 | entry["filter"] = item->filter_; | |||
| 436 | entry["foreground"] = QVariant::fromValue(item->foreground_).toString(); | |||
| 437 | entry["background"] = QVariant::fromValue(item->background_).toString(); | |||
| 438 | data.append(entry); | |||
| 439 | } | |||
| 440 | } | |||
| 441 | ||||
| 442 | QJsonObject dataSet; | |||
| 443 | dataSet["coloringrules"] = data; | |||
| 444 | QByteArray encodedData = QJsonDocument(dataSet).toJson(); | |||
| 445 | ||||
| 446 | mimeData->setData(WiresharkMimeData::ColoringRulesMimeType, encodedData); | |||
| 447 | return mimeData; | |||
| 448 | } | |||
| 449 | ||||
| 450 | bool ColoringRulesModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) | |||
| 451 | { | |||
| 452 | //clear any previous dragDrop information | |||
| 453 | dragDropRows_.clear(); | |||
| 454 | ||||
| 455 | if (action == Qt::IgnoreAction) | |||
| ||||
| 456 | return true; | |||
| 457 | ||||
| 458 | if (!data->hasFormat(WiresharkMimeData::ColoringRulesMimeType) || column > 0) | |||
| 459 | return false; | |||
| 460 | ||||
| 461 | int beginRow; | |||
| 462 | ||||
| 463 | if (row != -1) | |||
| 464 | beginRow = row; | |||
| 465 | else if (parent.isValid()) | |||
| 466 | beginRow = parent.row(); | |||
| 467 | else | |||
| 468 | beginRow = rowCount(); | |||
| 469 | ||||
| 470 | QList<QVariant> rules; | |||
| 471 | ||||
| 472 | QJsonDocument encodedData = QJsonDocument::fromJson(data->data(WiresharkMimeData::ColoringRulesMimeType)); | |||
| 473 | if (! encodedData.isObject() || ! encodedData.object().contains("coloringrules")) | |||
| 474 | return false; | |||
| 475 | ||||
| 476 | QJsonArray dataArray = encodedData.object()["coloringrules"].toArray(); | |||
| 477 | ||||
| 478 | for (int datarow = 0; datarow < dataArray.count(); datarow++) | |||
| 479 | { | |||
| 480 | QJsonObject entry = dataArray.at(datarow).toObject(); | |||
| 481 | ||||
| 482 | if (! entry.contains("foreground") || ! entry.contains("background") || ! entry.contains("filter")) | |||
| 483 | continue; | |||
| 484 | ||||
| 485 | QColor fgColor = entry["foreground"].toVariant().value<QColor>(); | |||
| 486 | QColor bgColor = entry["background"].toVariant().value<QColor>(); | |||
| 487 | ||||
| 488 | ColoringRuleItem * item = new ColoringRuleItem( | |||
| 489 | entry["disabled"].toVariant().toBool(), | |||
| 490 | entry["name"].toString(), | |||
| 491 | entry["filter"].toString(), | |||
| 492 | fgColor, | |||
| 493 | bgColor, | |||
| 494 | root_); | |||
| 495 | rules.append(VariantPointer<ColoringRuleItem>::asQVariant(item)); | |||
| ||||
| 496 | } | |||
| 497 | ||||
| 498 | insertRows(beginRow, static_cast<int>(rules.count()), QModelIndex()); | |||
| 499 | for (int i = 0; i < rules.count(); i++) { | |||
| 500 | QModelIndex idx = index(beginRow, 0, QModelIndex()); | |||
| 501 | setData(idx, rules[i], Qt::UserRole); | |||
| 502 | beginRow++; | |||
| 503 | } | |||
| 504 | ||||
| 505 | return true; | |||
| 506 | } | |||
| 507 | ||||
| 508 | QModelIndex ColoringRulesModel::index(int row, int column, const QModelIndex &parent) const | |||
| 509 | { | |||
| 510 | if (!hasIndex(row, column, parent)) | |||
| 511 | return QModelIndex(); | |||
| 512 | ||||
| 513 | ColoringRuleItem *parent_item, *child_item; | |||
| 514 | ||||
| 515 | if (!parent.isValid()) | |||
| 516 | parent_item = root_; | |||
| 517 | else | |||
| 518 | parent_item = static_cast<ColoringRuleItem*>(parent.internalPointer()); | |||
| 519 | ||||
| 520 | Q_ASSERT(parent_item)((parent_item) ? static_cast<void>(0) : qt_assert("parent_item" , "ui/qt/models/coloring_rules_model.cpp", 520)); | |||
| 521 | ||||
| 522 | child_item = parent_item->child(row); | |||
| 523 | if (child_item) { | |||
| 524 | return createIndex(row, column, child_item); | |||
| 525 | } | |||
| 526 | ||||
| 527 | return QModelIndex(); | |||
| 528 | } | |||
| 529 | ||||
| 530 | QModelIndex ColoringRulesModel::parent(const QModelIndex& indexItem) const | |||
| 531 | { | |||
| 532 | if (!indexItem.isValid()) | |||
| 533 | return QModelIndex(); | |||
| 534 | ||||
| 535 | ColoringRuleItem* item = static_cast<ColoringRuleItem*>(indexItem.internalPointer()); | |||
| 536 | if (item != NULL__null) { | |||
| 537 | ColoringRuleItem* parent_item = item->parentItem(); | |||
| 538 | if (parent_item != NULL__null) { | |||
| 539 | if (parent_item == root_) | |||
| 540 | return QModelIndex(); | |||
| 541 | ||||
| 542 | return createIndex(parent_item->row(), 0, parent_item); | |||
| 543 | } | |||
| 544 | } | |||
| 545 | ||||
| 546 | return QModelIndex(); | |||
| 547 | } | |||
| 548 | ||||
| 549 | int ColoringRulesModel::rowCount(const QModelIndex& parent) const | |||
| 550 | { | |||
| 551 | ColoringRuleItem *parent_item; | |||
| 552 | if (parent.column() > 0) | |||
| 553 | return 0; | |||
| 554 | ||||
| 555 | if (!parent.isValid()) | |||
| 556 | parent_item = root_; | |||
| 557 | else | |||
| 558 | parent_item = static_cast<ColoringRuleItem*>(parent.internalPointer()); | |||
| 559 | ||||
| 560 | if (parent_item == NULL__null) | |||
| 561 | return 0; | |||
| 562 | ||||
| 563 | return parent_item->childCount(); | |||
| 564 | } | |||
| 565 | ||||
| 566 | int ColoringRulesModel::columnCount(const QModelIndex&) const | |||
| 567 | { | |||
| 568 | return colColoringRulesMax; | |||
| 569 | } |
| 1 | // Copyright (C) 2016 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 | #ifndef QJSONVALUE_H |
| 5 | #define QJSONVALUE_H |
| 6 | |
| 7 | #include <QtCore/qglobal.h> |
| 8 | #include <QtCore/qstring.h> |
| 9 | #include <QtCore/qshareddata.h> |
| 10 | #include <QtCore/qcborvalue.h> |
| 11 | |
| 12 | QT_BEGIN_NAMESPACE |
| 13 | |
| 14 | class QVariant; |
| 15 | class QJsonArray; |
| 16 | class QJsonObject; |
| 17 | class QCborContainerPrivate; |
| 18 | |
| 19 | namespace QJsonPrivate { |
| 20 | class Value; |
| 21 | } |
| 22 | |
| 23 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QJsonValue |
| 24 | { |
| 25 | public: |
| 26 | enum Type { |
| 27 | Null = 0x0, |
| 28 | Bool = 0x1, |
| 29 | Double = 0x2, |
| 30 | String = 0x3, |
| 31 | Array = 0x4, |
| 32 | Object = 0x5, |
| 33 | Undefined = 0x80 |
| 34 | }; |
| 35 | |
| 36 | QJsonValue(Type = Null); |
| 37 | QJsonValue(bool b); |
| 38 | QJsonValue(double n); |
| 39 | QJsonValue(int n); |
| 40 | QJsonValue(qint64 v); |
| 41 | QJsonValue(const QString &s); |
| 42 | QJsonValue(QLatin1StringView s); |
| 43 | #ifndef QT_NO_CAST_FROM_ASCII |
| 44 | QT_ASCII_CAST_WARN inline QJsonValue(const char *s) |
| 45 | : QJsonValue(QString::fromUtf8(s)) {} |
| 46 | #endif |
| 47 | QJsonValue(const QJsonArray &a); |
| 48 | QJsonValue(QJsonArray &&a) noexcept; |
| 49 | QJsonValue(const QJsonObject &o); |
| 50 | QJsonValue(QJsonObject &&o) noexcept; |
| 51 | |
| 52 | ~QJsonValue(); |
| 53 | |
| 54 | QJsonValue(const QJsonValue &other); |
| 55 | QJsonValue &operator =(const QJsonValue &other); |
| 56 | |
| 57 | QJsonValue(QJsonValue &&other) noexcept; |
| 58 | |
| 59 | QJsonValue &operator =(QJsonValue &&other) noexcept |
| 60 | { |
| 61 | swap(other); |
| 62 | return *this; |
| 63 | } |
| 64 | |
| 65 | void swap(QJsonValue &other) noexcept; |
| 66 | |
| 67 | static QJsonValue fromVariant(const QVariant &variant); |
| 68 | QVariant toVariant() const; |
| 69 | |
| 70 | Type type() const; |
| 71 | inline bool isNull() const { return type() == Null; } |
| 72 | inline bool isBool() const { return type() == Bool; } |
| 73 | inline bool isDouble() const { return type() == Double; } |
| 74 | inline bool isString() const { return type() == String; } |
| 75 | inline bool isArray() const { return type() == Array; } |
| 76 | inline bool isObject() const { return type() == Object; } |
| 77 | inline bool isUndefined() const { return type() == Undefined; } |
| 78 | |
| 79 | bool toBool(bool defaultValue = false) const; |
| 80 | int toInt(int defaultValue = 0) const; |
| 81 | qint64 toInteger(qint64 defaultValue = 0) const; |
| 82 | double toDouble(double defaultValue = 0) const; |
| 83 | QString toString() const; |
| 84 | QString toString(const QString &defaultValue) const; |
| 85 | QJsonArray toArray() const; |
| 86 | QJsonArray toArray(const QJsonArray &defaultValue) const; |
| 87 | QJsonObject toObject() const; |
| 88 | QJsonObject toObject(const QJsonObject &defaultValue) const; |
| 89 | |
| 90 | const QJsonValue operator[](const QString &key) const; |
| 91 | const QJsonValue operator[](QStringView key) const; |
| 92 | const QJsonValue operator[](QLatin1StringView key) const; |
| 93 | const QJsonValue operator[](qsizetype i) const; |
| 94 | |
| 95 | bool operator==(const QJsonValue &other) const; |
| 96 | bool operator!=(const QJsonValue &other) const; |
| 97 | |
| 98 | private: |
| 99 | // avoid implicit conversions from char * to bool |
| 100 | QJsonValue(const void *) = delete; |
| 101 | friend class QJsonPrivate::Value; |
| 102 | friend class QJsonArray; |
| 103 | friend class QJsonObject; |
| 104 | friend class QCborValue; |
| 105 | friend Q_CORE_EXPORT__attribute__((visibility("default"))) QDebug operator<<(QDebug, const QJsonValue &); |
| 106 | friend Q_CORE_EXPORT__attribute__((visibility("default"))) QDataStream &operator<<(QDataStream &, const QJsonValue &); |
| 107 | |
| 108 | QCborValue value; |
| 109 | |
| 110 | // Assert binary compatibility with pre-5.15 QJsonValue |
| 111 | static_assert(sizeof(QExplicitlySharedDataPointer<QCborContainerPrivate>) == sizeof(void *)); |
| 112 | static_assert(sizeof(QCborValue::Type) == sizeof(QJsonValue::Type)); |
| 113 | }; |
| 114 | |
| 115 | Q_DECLARE_SHARED(QJsonValue)template<> class QTypeInfo<QJsonValue > { public: enum { isComplex = (((Q_RELOCATABLE_TYPE) & Q_PRIMITIVE_TYPE ) == 0) && !std::is_trivial_v<QJsonValue>, isRelocatable = !isComplex || ((Q_RELOCATABLE_TYPE) & Q_RELOCATABLE_TYPE ) || qIsRelocatable<QJsonValue>, isPointer = false, isIntegral = std::is_integral< QJsonValue >::value, }; }; inline void swap(QJsonValue &value1, QJsonValue &value2) noexcept (noexcept(value1.swap(value2))) { value1.swap(value2); } |
| 116 | |
| 117 | class QJsonValueConstRef |
| 118 | { |
| 119 | public: |
| 120 | QJsonValueConstRef(const QJsonValueConstRef &) = default; |
| 121 | QJsonValueConstRef &operator=(const QJsonValueConstRef &) = delete; |
| 122 | inline operator QJsonValue() const { return concrete(*this); } |
| 123 | |
| 124 | Q_CORE_EXPORT__attribute__((visibility("default"))) QVariant toVariant() const; |
| 125 | QJsonValue::Type type() const { return concreteType(*this); } |
| 126 | bool isNull() const { return type() == QJsonValue::Null; } |
| 127 | bool isBool() const { return type() == QJsonValue::Bool; } |
| 128 | bool isDouble() const { return type() == QJsonValue::Double; } |
| 129 | bool isString() const { return type() == QJsonValue::String; } |
| 130 | bool isArray() const { return type() == QJsonValue::Array; } |
| 131 | bool isObject() const { return type() == QJsonValue::Object; } |
| 132 | bool isUndefined() const { return type() == QJsonValue::Undefined; } |
| 133 | |
| 134 | bool toBool(bool defaultValue = false) const |
| 135 | { return concreteBool(*this, defaultValue); } |
| 136 | int toInt(int defaultValue = 0) const |
| 137 | { return concreteInt(*this, defaultValue, true); } |
| 138 | qint64 toInteger(qint64 defaultValue = 0) const |
| 139 | { return concreteInt(*this, defaultValue, false); } |
| 140 | double toDouble(double defaultValue = 0) const |
| 141 | { return concreteDouble(*this, defaultValue); } |
| 142 | QString toString(const QString &defaultValue = {}) const |
| 143 | { return concreteString(*this, defaultValue); } |
| 144 | Q_CORE_EXPORT__attribute__((visibility("default"))) QJsonArray toArray() const; |
| 145 | Q_CORE_EXPORT__attribute__((visibility("default"))) QJsonObject toObject() const; |
| 146 | |
| 147 | const QJsonValue operator[](QStringView key) const { return concrete(*this)[key]; } |
| 148 | const QJsonValue operator[](QLatin1StringView key) const { return concrete(*this)[key]; } |
| 149 | const QJsonValue operator[](qsizetype i) const { return concrete(*this)[i]; } |
| 150 | |
| 151 | inline bool operator==(const QJsonValue &other) const { return concrete(*this) == other; } |
| 152 | inline bool operator!=(const QJsonValue &other) const { return concrete(*this) != other; } |
| 153 | |
| 154 | protected: |
| 155 | Q_CORE_EXPORT__attribute__((visibility("default"))) static QJsonValue::Type |
| 156 | concreteType(QJsonValueConstRef self) noexcept Q_DECL_PURE_FUNCTION__attribute__((pure)); |
| 157 | Q_CORE_EXPORT__attribute__((visibility("default"))) static bool |
| 158 | concreteBool(QJsonValueConstRef self, bool defaultValue) noexcept Q_DECL_PURE_FUNCTION__attribute__((pure)); |
| 159 | Q_CORE_EXPORT__attribute__((visibility("default"))) static qint64 |
| 160 | concreteInt(QJsonValueConstRef self, qint64 defaultValue, bool clamp) noexcept Q_DECL_PURE_FUNCTION__attribute__((pure)); |
| 161 | Q_CORE_EXPORT__attribute__((visibility("default"))) static double |
| 162 | concreteDouble(QJsonValueConstRef self, double defaultValue) noexcept Q_DECL_PURE_FUNCTION__attribute__((pure)); |
| 163 | Q_CORE_EXPORT__attribute__((visibility("default"))) static QString concreteString(QJsonValueConstRef self, const QString &defaultValue); |
| 164 | Q_CORE_EXPORT__attribute__((visibility("default"))) static QJsonValue concrete(QJsonValueConstRef self) noexcept; |
| 165 | |
| 166 | // for iterators |
| 167 | Q_CORE_EXPORT__attribute__((visibility("default"))) static QString objectKey(QJsonValueConstRef self); |
| 168 | QString objectKey() const { return objectKey(*this); } |
| 169 | |
| 170 | #if QT_VERSION((6<<16)|(4<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0)) && !defined(QT_BOOTSTRAPPED) |
| 171 | QJsonValueConstRef(QJsonArray *array, qsizetype idx) |
| 172 | : a(array), is_object(false), index(static_cast<quint64>(idx)) {} |
| 173 | QJsonValueConstRef(QJsonObject *object, qsizetype idx) |
| 174 | : o(object), is_object(true), index(static_cast<quint64>(idx)) {} |
| 175 | |
| 176 | void rebind(QJsonValueConstRef other) |
| 177 | { |
| 178 | Q_ASSERT(is_object == other.is_object)((is_object == other.is_object) ? static_cast<void>(0) : qt_assert("is_object == other.is_object", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qjsonvalue.h" , 178)); |
| 179 | if (is_object) |
| 180 | o = other.o; |
| 181 | else |
| 182 | a = other.a; |
| 183 | index = other.index; |
| 184 | } |
| 185 | |
| 186 | union { |
| 187 | QJsonArray *a; |
| 188 | QJsonObject *o; |
| 189 | void *d; |
| 190 | }; |
| 191 | quint64 is_object : 1; |
| 192 | quint64 index : 63; |
| 193 | #else |
| 194 | constexpr QJsonValueConstRef(QCborContainerPrivate *d, size_t index, bool is_object) |
| 195 | : d(d), is_object(is_object), index(index) |
| 196 | {} |
| 197 | |
| 198 | // implemented in qjsonarray.h & qjsonobject.h, to get their d |
| 199 | QJsonValueConstRef(QJsonArray *array, qsizetype idx); |
| 200 | QJsonValueConstRef(QJsonObject *object, qsizetype idx); |
| 201 | |
| 202 | void rebind(QJsonValueConstRef other) |
| 203 | { |
| 204 | d = other.d; |
| 205 | index = other.index; |
| 206 | } |
| 207 | |
| 208 | QCborContainerPrivate *d = nullptr; |
| 209 | size_t is_object : 1; |
| 210 | size_t index : std::numeric_limits<size_t>::digits - 1; |
| 211 | #endif |
| 212 | |
| 213 | friend class QJsonArray; |
| 214 | friend class QJsonObject; |
| 215 | friend class QJsonPrivate::Value; |
| 216 | }; |
| 217 | |
| 218 | class QT6_ONLY(Q_CORE_EXPORT)__attribute__((visibility("default"))) QJsonValueRef : public QJsonValueConstRef |
| 219 | { |
| 220 | public: |
| 221 | QJsonValueRef(const QJsonValueRef &) = default; |
| 222 | QT7_ONLY(Q_CORE_EXPORT) QJsonValueRef &operator = (const QJsonValue &val); |
| 223 | QT7_ONLY(Q_CORE_EXPORT) QJsonValueRef &operator = (const QJsonValueRef &val); |
| 224 | |
| 225 | #if QT_VERSION((6<<16)|(4<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0)) && !defined(QT_BOOTSTRAPPED) |
| 226 | // retained for binary compatibility (due to the Q_CORE_EXPORT) because at |
| 227 | // least one compiler emits and exports all inlines in an exported class |
| 228 | |
| 229 | QJsonValueRef(QJsonArray *array, qsizetype idx) |
| 230 | : QJsonValueConstRef(array, idx) {} |
| 231 | QJsonValueRef(QJsonObject *object, qsizetype idx) |
| 232 | : QJsonValueConstRef(object, idx) {} |
| 233 | |
| 234 | operator QJsonValue() const { return toValue(); } |
| 235 | |
| 236 | QVariant toVariant() const; |
| 237 | inline QJsonValue::Type type() const { return QJsonValueConstRef::type(); } |
| 238 | inline bool isNull() const { return type() == QJsonValue::Null; } |
| 239 | inline bool isBool() const { return type() == QJsonValue::Bool; } |
| 240 | inline bool isDouble() const { return type() == QJsonValue::Double; } |
| 241 | inline bool isString() const { return type() == QJsonValue::String; } |
| 242 | inline bool isArray() const { return type() == QJsonValue::Array; } |
| 243 | inline bool isObject() const { return type() == QJsonValue::Object; } |
| 244 | inline bool isUndefined() const { return type() == QJsonValue::Undefined; } |
| 245 | |
| 246 | inline bool toBool(bool defaultValue = false) const { return QJsonValueConstRef::toBool(defaultValue); } |
| 247 | inline int toInt(int defaultValue = 0) const { return QJsonValueConstRef::toInt(defaultValue); } |
| 248 | inline qint64 toInteger(qint64 defaultValue = 0) const { return QJsonValueConstRef::toInteger(defaultValue); } |
| 249 | inline double toDouble(double defaultValue = 0) const { return QJsonValueConstRef::toDouble(defaultValue); } |
| 250 | inline QString toString(const QString &defaultValue = {}) const { return QJsonValueConstRef::toString(defaultValue); } |
| 251 | QJsonArray toArray() const; |
| 252 | QJsonObject toObject() const; |
| 253 | |
| 254 | const QJsonValue operator[](QStringView key) const { return QJsonValueConstRef::operator[](key); } |
| 255 | const QJsonValue operator[](QLatin1StringView key) const { return QJsonValueConstRef::operator[](key); } |
| 256 | const QJsonValue operator[](qsizetype i) const { return QJsonValueConstRef::operator[](i); } |
| 257 | |
| 258 | inline bool operator==(const QJsonValue &other) const { return QJsonValueConstRef::operator==(other); } |
| 259 | inline bool operator!=(const QJsonValue &other) const { return QJsonValueConstRef::operator!=(other); } |
| 260 | |
| 261 | private: |
| 262 | QJsonValue toValue() const; |
| 263 | #else |
| 264 | using QJsonValueConstRef::operator[]; |
| 265 | Q_CORE_EXPORT__attribute__((visibility("default"))) QJsonValueRef operator[](QAnyStringView key); |
| 266 | Q_CORE_EXPORT__attribute__((visibility("default"))) QJsonValueRef operator[](qsizetype i); |
| 267 | |
| 268 | private: |
| 269 | using QJsonValueConstRef::QJsonValueConstRef; |
| 270 | #endif // < Qt 7 |
| 271 | |
| 272 | QT7_ONLY(Q_CORE_EXPORT) void detach(); |
| 273 | friend class QJsonArray; |
| 274 | friend class QJsonObject; |
| 275 | }; |
| 276 | |
| 277 | inline QJsonValue QCborValueConstRef::toJsonValue() const |
| 278 | { |
| 279 | return concrete().toJsonValue(); |
| 280 | } |
| 281 | |
| 282 | inline bool operator==(const QJsonValueConstRef &lhs, const QJsonValueRef &rhs) |
| 283 | { return QJsonValue(lhs) == QJsonValue(rhs); } |
| 284 | inline bool operator!=(const QJsonValueConstRef &lhs, const QJsonValueRef &rhs) |
| 285 | { return !(lhs == rhs); } |
| 286 | |
| 287 | inline bool operator==(const QJsonValueRef &lhs, const QJsonValueConstRef &rhs) |
| 288 | { return QJsonValue(lhs) == QJsonValue(rhs); } |
| 289 | inline bool operator!=(const QJsonValueRef &lhs, const QJsonValueConstRef &rhs) |
| 290 | { return !(lhs == rhs); } |
| 291 | |
| 292 | inline bool operator==(const QJsonValueRef &lhs, const QJsonValueRef &rhs) |
| 293 | { return QJsonValue(lhs) == QJsonValue(rhs); } |
| 294 | inline bool operator!=(const QJsonValueRef &lhs, const QJsonValueRef &rhs) |
| 295 | { return !(lhs == rhs); } |
| 296 | |
| 297 | Q_CORE_EXPORT__attribute__((visibility("default"))) size_t qHash(const QJsonValue &value, size_t seed = 0); |
| 298 | |
| 299 | #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) |
| 300 | Q_CORE_EXPORT__attribute__((visibility("default"))) QDebug operator<<(QDebug, const QJsonValue &); |
| 301 | #endif |
| 302 | |
| 303 | #ifndef QT_NO_DATASTREAM |
| 304 | Q_CORE_EXPORT__attribute__((visibility("default"))) QDataStream &operator<<(QDataStream &, const QJsonValue &); |
| 305 | Q_CORE_EXPORT__attribute__((visibility("default"))) QDataStream &operator>>(QDataStream &, QJsonValue &); |
| 306 | #endif |
| 307 | |
| 308 | QT_END_NAMESPACE |
| 309 | |
| 310 | #endif // QJSONVALUE_H |