cade148a2488b7653ae339ba102309f18645593d
[metze/wireshark/wip.git] / ui / qt / models / export_objects_model.cpp
1 /* export_objects_model.cpp
2  * Data model for Export Objects.
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
11 #include "export_objects_model.h"
12
13 #include <ui/qt/utils/qt_ui_utils.h>
14 #include <ui/qt/utils/variant_pointer.h>
15 #include <ui/export_object_ui.h>
16
17 extern "C" {
18
19 static void
20 object_list_add_entry(void *gui_data, export_object_entry_t *entry) {
21     export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
22
23     if (object_list && object_list->model)
24         object_list->model->addObjectEntry(entry);
25 }
26
27 static export_object_entry_t*
28 object_list_get_entry(void *gui_data, int row) {
29     export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
30
31     if (object_list && object_list->model)
32         return object_list->model->objectEntry(row);
33
34     return NULL;
35 }
36
37 } // extern "C"
38
39
40
41
42 ExportObjectModel::ExportObjectModel(register_eo_t* eo, QObject *parent) :
43     QAbstractTableModel(parent),
44     eo_(eo)
45 {
46     eo_gui_data_.model = this;
47
48     export_object_list_.add_entry = object_list_add_entry;
49     export_object_list_.get_entry = object_list_get_entry;
50     export_object_list_.gui_data = (void*)&eo_gui_data_;
51 }
52
53 QVariant ExportObjectModel::data(const QModelIndex &index, int role) const
54 {
55     if ((!index.isValid()) || ((role != Qt::DisplayRole) && (role != Qt::UserRole))) {
56         return QVariant();
57     }
58
59     if (role == Qt::DisplayRole)
60     {
61         export_object_entry_t *entry = VariantPointer<export_object_entry_t>::asPtr(objects_.value(index.row()));
62         if (entry == NULL)
63             return QVariant();
64
65         switch(index.column())
66         {
67         case colPacket:
68             return QString::number(entry->pkt_num);
69         case colHostname:
70             return entry->hostname;
71         case colContent:
72             return entry->content_type;
73         case colSize:
74             return file_size_to_qstring(entry->payload_len);
75         case colFilename:
76             return entry->filename;
77         }
78     }
79     else if (role == Qt::UserRole)
80     {
81         return objects_.value(index.row());
82     }
83
84     return QVariant();
85 }
86
87 QVariant ExportObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
88 {
89     if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
90         return QVariant();
91
92     switch (section) {
93     case colPacket:
94         return tr("Packet");
95     case colHostname:
96         return tr("Hostname");
97     case colContent:
98         return tr("Content Type");
99     case colSize:
100         return tr("Size");
101     case colFilename:
102         return tr("Filename");
103     }
104
105     return QVariant();
106 }
107
108 int ExportObjectModel::rowCount(const QModelIndex &parent) const
109 {
110     // there are no children
111     if (parent.isValid()) {
112         return 0;
113     }
114
115     return objects_.count();
116 }
117
118 int ExportObjectModel::columnCount(const QModelIndex&) const
119 {
120     return colExportObjectMax;
121 }
122
123 void ExportObjectModel::addObjectEntry(export_object_entry_t *entry)
124 {
125     if (entry == NULL)
126         return;
127
128     int count = objects_.count();
129     beginInsertRows(QModelIndex(), count, count);
130     objects_.append(VariantPointer<export_object_entry_t>::asQVariant(entry));
131     endInsertRows();
132 }
133
134 export_object_entry_t* ExportObjectModel::objectEntry(int row)
135 {
136     return VariantPointer<export_object_entry_t>::asPtr(objects_.value(row));
137 }
138
139 bool ExportObjectModel::saveEntry(QModelIndex &index, QString filename)
140 {
141     if (!index.isValid() || filename.isEmpty())
142         return false;
143
144     export_object_entry_t *entry = VariantPointer<export_object_entry_t>::asPtr(objects_.value(index.row()));
145     if (entry == NULL)
146         return false;
147
148     if (filename.length() > 0) {
149         eo_save_entry(filename.toUtf8().constData(), entry, TRUE);
150     }
151
152     return true;
153 }
154
155 bool ExportObjectModel::saveAllEntries(QString path)
156 {
157     if (path.isEmpty())
158         return false;
159
160     bool all_saved = true;
161     export_object_entry_t *entry;
162
163     for (QList<QVariant>::iterator it = objects_.begin(); it != objects_.end(); ++it)
164     {
165         entry = VariantPointer<export_object_entry_t>::asPtr(*it);
166         if (entry == NULL)
167             continue;
168
169         int count = 0;
170         gchar *save_as_fullpath = NULL;
171
172         do {
173             GString *safe_filename;
174
175             g_free(save_as_fullpath);
176             if (entry->filename)
177                 safe_filename = eo_massage_str(entry->filename,
178                     EXPORT_OBJECT_MAXFILELEN - path.length(), count);
179             else {
180                 char generic_name[256];
181                 const char *ext;
182                 ext = eo_ct2ext(entry->content_type);
183                 g_snprintf(generic_name, sizeof(generic_name),
184                     "object%u%s%s", entry->pkt_num, ext ? "." : "",
185                     ext ? ext : "");
186                 safe_filename = eo_massage_str(generic_name,
187                     EXPORT_OBJECT_MAXFILELEN - path.length(), count);
188             }
189             save_as_fullpath = g_build_filename(path.toUtf8().constData(),
190                                                 safe_filename->str, NULL);
191             g_string_free(safe_filename, TRUE);
192         } while (g_file_test(save_as_fullpath, G_FILE_TEST_EXISTS) && ++count < 1000);
193         if (!eo_save_entry(save_as_fullpath, entry, FALSE))
194             all_saved = false;
195         g_free(save_as_fullpath);
196         save_as_fullpath = NULL;
197     }
198
199     return all_saved;
200 }
201
202 void ExportObjectModel::resetObjects()
203 {
204     export_object_gui_reset_cb reset_cb = get_eo_reset_func(eo_);
205
206     emit beginResetModel();
207     objects_.clear();
208     emit endResetModel();
209
210     if (reset_cb)
211         reset_cb();
212 }
213
214 // Called by taps
215 /* Runs at the beginning of tapping only */
216 void ExportObjectModel::resetTap(void *tapdata)
217 {
218     export_object_list_t *tap_object = (export_object_list_t *)tapdata;
219     export_object_list_gui_t *object_list = (export_object_list_gui_t *)tap_object->gui_data;
220     if (object_list && object_list->model)
221         object_list->model->resetObjects();
222 }
223
224 const char* ExportObjectModel::getTapListenerName()
225 {
226     return get_eo_tap_listener_name(eo_);
227 }
228
229 void* ExportObjectModel::getTapData()
230 {
231     return &export_object_list_;
232 }
233
234 tap_packet_cb ExportObjectModel::getTapPacketFunc()
235 {
236     return get_eo_packet_func(eo_);
237 }
238
239 void ExportObjectModel::removeTap()
240 {
241     eo_gui_data_.model = NULL;
242 }
243
244
245
246 ExportObjectProxyModel::ExportObjectProxyModel(QObject * parent)
247     : QSortFilterProxyModel(parent)
248 {
249
250 }
251
252 bool ExportObjectProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
253 {
254     export_object_entry_t *left_entry = VariantPointer<export_object_entry_t>::asPtr(sourceModel()->data(source_left, Qt::UserRole)),
255                           *right_entry = VariantPointer<export_object_entry_t>::asPtr(sourceModel()->data(source_right, Qt::UserRole));
256
257     if ((left_entry != NULL) && (right_entry != NULL))
258     {
259         switch (source_left.column())
260         {
261         case ExportObjectModel::colPacket:
262             return left_entry->pkt_num < right_entry->pkt_num;
263         case ExportObjectModel::colSize:
264             return left_entry->payload_len < right_entry->payload_len;
265         case ExportObjectModel::colFilename:
266             break;
267         }
268     }
269
270     return QSortFilterProxyModel::lessThan(source_left, source_right);
271 }
272
273
274
275 /* * Editor modelines
276  *
277  * Local Variables:
278  * c-basic-offset: 4
279  * tab-width: 8
280  * indent-tabs-mode: nil
281  * End:
282  *
283  * ex: set shiftwidth=4 tabstop=8 expandtab:
284  * :indentSize=4:tabSize=8:noTabs=true:
285  */