summaryrefslogtreecommitdiff
path: root/ui/qt/cache_proxy_model.cpp
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2017-03-17 00:51:08 +0100
committerPeter Wu <peter@lekensteyn.nl>2017-03-24 23:02:43 +0000
commit370f3b358cd9ee7dcd2b7274f7ee6c90d5906c7a (patch)
treef71b56580079e13f017bda7e6c504e30eaa61be8 /ui/qt/cache_proxy_model.cpp
parentb4bc6c72c79fa121753cf94ae179ea73f1e911dd (diff)
downloadwireshark-370f3b358cd9ee7dcd2b7274f7ee6c90d5906c7a.tar.gz
Qt: add cache proxy model for Voip Calls dialog
When a capture file is reloaded, the information stored in VoipCallsInfoModel is invalidated. Add another cache layer to fix this: VoipCallsInfoModel wraps around raw data (invalid on close) CacheProxyModel NEW: use prev. data or cache on close VoipCallsInfoSortedModel provided sorting, etc. VoipCallsDialog actual user of model (callTreeView) This also fixes a UAF after a file was closed, and when a call is selected (that got worse with the last model/view patch and is "fixed" in this patch with the caching layer. Note that the Flow sequence and Play Streams dialog are not that useful when the file is closed). Change-Id: Ib4daff9dc01a54863fe1d943bdbdb876418924ee Reviewed-on: https://code.wireshark.org/review/20574 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'ui/qt/cache_proxy_model.cpp')
-rw-r--r--ui/qt/cache_proxy_model.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/ui/qt/cache_proxy_model.cpp b/ui/qt/cache_proxy_model.cpp
new file mode 100644
index 0000000000..63b1aac70c
--- /dev/null
+++ b/ui/qt/cache_proxy_model.cpp
@@ -0,0 +1,112 @@
+/* cache_proxy_model.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "cache_proxy_model.h"
+
+CacheProxyModel::CacheProxyModel(QObject *parent) : QIdentityProxyModel(parent)
+{
+}
+
+QVariant CacheProxyModel::data(const QModelIndex &index, int role) const
+{
+ QModelIndex dataIndex = cache.index(index.row(), index.column());
+ if (!dataIndex.isValid()) {
+ // index is possibly outside columnCount or rowCount
+ return QVariant();
+ }
+
+ if (hasModel()) {
+ QVariant value = QIdentityProxyModel::data(index, role);
+ cache.setData(dataIndex, value, role);
+ return value;
+ } else {
+ return cache.data(dataIndex, role);
+ }
+}
+
+Qt::ItemFlags CacheProxyModel::flags(const QModelIndex &index) const
+{
+ if (hasModel()) {
+ return QIdentityProxyModel::flags(index);
+ } else {
+ // Override default to prevent editing.
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ }
+}
+
+QVariant CacheProxyModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (hasModel()) {
+ QVariant value = QIdentityProxyModel::headerData(section, orientation, role);
+ cache.setHeaderData(section, orientation, value, role);
+ return value;
+ } else {
+ return cache.headerData(section, orientation, role);
+ }
+}
+
+int CacheProxyModel::rowCount(const QModelIndex &parent) const
+{
+ if (hasModel()) {
+ int count = QIdentityProxyModel::rowCount(parent);
+ cache.setRowCount(count);
+ return count;
+ } else {
+ return cache.rowCount(parent);
+ }
+}
+
+int CacheProxyModel::columnCount(const QModelIndex &parent) const
+{
+ if (hasModel()) {
+ int count = QIdentityProxyModel::columnCount(parent);
+ cache.setColumnCount(count);
+ return count;
+ } else {
+ return cache.columnCount(parent);
+ }
+}
+
+/**
+ * Sets the source model from which data must be pulled. If newSourceModel is
+ * NULL, then the cache will be used.
+ */
+void CacheProxyModel::setSourceModel(QAbstractItemModel *newSourceModel)
+{
+ if (newSourceModel) {
+ cache.clear();
+ QIdentityProxyModel::setSourceModel(newSourceModel);
+ connect(newSourceModel, SIGNAL(modelReset()),
+ this, SLOT(resetCacheModel()));
+ } else {
+ if (sourceModel()) {
+ // Prevent further updates to source model from invalidating cache.
+ disconnect(sourceModel(), SIGNAL(modelReset()),
+ this, SLOT(resetCacheModel()));
+ }
+ QIdentityProxyModel::setSourceModel(&cache);
+ }
+}
+
+void CacheProxyModel::resetCacheModel() {
+ cache.clear();
+}