Bug Summary

File:builds/wireshark/wireshark/ui/qt/models/coloring_rules_model.cpp
Warning:line 245, column 5
Potential leak of memory pointed to by 'dst_item'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name coloring_rules_model.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang --driver-mode=g++ -### --analyze -x c++ -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=c++17 -fPIC -fPIC /builds/wireshark/wireshark/ui/qt/models/coloring_rules_model.cpp -o /builds/wireshark/wireshark/sbout/2024-11-18-100252-3912-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-18-100252-3912-1 -x c++ /builds/wireshark/wireshark/ui/qt/models/coloring_rules_model.cpp
1/* coloring_rules_model.cpp
2 * Data model for coloring rules.
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
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
28ColoringRuleItem::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
38ColoringRuleItem::~ColoringRuleItem()
39{
40
41}
42
43ColoringRuleItem::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
53ColoringRuleItem::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
63ColoringRuleItem& 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.
74void
75color_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
85ColoringRulesModel::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
96ColoringRulesModel::~ColoringRulesModel()
97{
98 delete root_;
99 color_filter_list_delete(&conversation_colors_);
100}
101
102GSList *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
122void 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
139void 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
149bool 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
161bool 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
175bool 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
194bool 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
214bool 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
229bool ColoringRulesModel::copyRow(int dst_row, int src_row)
230{
231 if (src_row < 0 || src_row >= rowCount() || dst_row < 0 || dst_row >= rowCount()) {
1
Assuming 'src_row' is >= 0
2
Assuming the condition is false
3
Assuming 'dst_row' is >= 0
4
Assuming the condition is false
5
Taking false branch
232 return false;
233 }
234
235 ColoringRuleItem* src_item = root_->child(src_row);
236 if (src_item == NULL__null)
6
Assuming 'src_item' is not equal to NULL
7
Taking false branch
237 return false;
238
239 ColoringRuleItem* dst_item = new ColoringRuleItem(*src_item);
8
Memory is allocated
240 if (dst_item
8.1
'dst_item' is not equal to NULL
== NULL__null)
9
Taking false branch
241 return false;
242
243 beginInsertRows(QModelIndex(), dst_row, dst_row);
244 root_->insertChild(dst_row, dst_item);
245 endInsertRows();
10
Potential leak of memory pointed to by 'dst_item'
246
247 return true;
248}
249
250Qt::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
272QVariant 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
308bool 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
391QVariant 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
408Qt::DropActions ColoringRulesModel::supportedDropActions() const
409{
410 return Qt::MoveAction | Qt::CopyAction;
411}
412
413QStringList ColoringRulesModel::mimeTypes() const
414{
415 return QStringList() << WiresharkMimeData::ColoringRulesMimeType;
416}
417
418QMimeData* 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
450bool 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
508QModelIndex 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
530QModelIndex 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
549int 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
566int ColoringRulesModel::columnCount(const QModelIndex&) const
567{
568 return colColoringRulesMax;
569}