TODO netlogon_user_flags_ntlmv2_enabled
[wireshark-sm.git] / ui / qt / capture_comment_dialog.cpp
blobeed09ce096fc029cc0ac83c9f500f1827a8511cc
1 /* packet_comment_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include "capture_comment_dialog.h"
11 #include <ui_capture_comment_dialog.h>
13 #include "file.h"
15 #include "ui/simple_dialog.h"
16 #include "ui/qt/main_window.h"
17 #include "ui/qt/utils/qt_ui_utils.h"
18 #include "main_application.h"
20 #include <QTabBar>
21 #include <QPushButton>
22 #include <QPlainTextEdit>
24 class CaptureCommentTabWidget : public QTabWidget
26 Q_OBJECT
27 public:
28 CaptureCommentTabWidget(QWidget *parent = nullptr) : QTabWidget(parent)
31 setTabsClosable(true);
32 setMovable(true);
33 connect(this, &QTabWidget::tabCloseRequested, this, &CaptureCommentTabWidget::closeTab);
34 connect(tabBar(), &QTabBar::tabMoved, this, &CaptureCommentTabWidget::setTabTitles);
36 int addTab(QWidget *page);
37 void tabRemoved(int index) override;
38 void closeTab(int index);
39 void setReadOnly(bool ro);
40 char** getCommentsText();
42 private:
43 void setTabTitles(int from, int to);
46 int CaptureCommentTabWidget::addTab(QWidget *page)
48 return QTabWidget::addTab(page, tr("Comment %1").arg(count() + 1));
51 void CaptureCommentTabWidget::closeTab(int index)
53 QPlainTextEdit *te;
54 te = qobject_cast<QPlainTextEdit*>(widget(index));
55 if (te != nullptr) {
56 removeTab(index);
57 delete te;
61 void CaptureCommentTabWidget::setReadOnly(bool ro)
63 QPlainTextEdit *commentTextEdit;
64 for (int index = 0; index < count(); index++) {
65 commentTextEdit = qobject_cast<QPlainTextEdit*>(widget(index));
66 if (commentTextEdit != nullptr) {
67 commentTextEdit->setReadOnly(ro);
72 void CaptureCommentTabWidget::tabRemoved(int index)
74 setTabTitles(index, count() - 1);
77 char** CaptureCommentTabWidget::getCommentsText()
79 /* glib 2.68 and later have g_strv_builder which is slightly
80 * more convenient.
82 QPlainTextEdit *te;
83 GPtrArray *ptr_array = g_ptr_array_new_full(count() + 1, g_free);
84 for (int index = 0; index < count(); index++) {
85 te = qobject_cast<QPlainTextEdit*>(widget(index));
86 if (te != nullptr) {
87 char *str = qstring_strdup(te->toPlainText());
90 * Make sure this would fit in a pcapng option.
92 * XXX - 65535 is the maximum size for an option in pcapng;
93 * what if another capture file format supports larger
94 * comments?
96 if (strlen(str) > 65535) {
97 /* It doesn't fit. Give up. */
98 g_ptr_array_free(ptr_array, true);
99 return nullptr;
101 g_ptr_array_add(ptr_array, str);
104 g_ptr_array_add(ptr_array, nullptr);
105 return (char**)g_ptr_array_free(ptr_array, false);
108 void CaptureCommentTabWidget::setTabTitles(int from, int to)
110 if (from < to) {
111 for (; from <= to; from++) {
112 this->setTabText(from, tr("Comment %1").arg(from + 1));
114 } else {
115 for (; from >= to; from--) {
116 this->setTabText(from, tr("Comment %1").arg(from + 1));
121 CaptureCommentDialog::CaptureCommentDialog(QWidget &parent, CaptureFile &capture_file) :
122 WiresharkDialog(parent, capture_file),
123 ui(new Ui::CaptureCommentDialog)
126 ui->setupUi(this);
127 loadGeometry();
128 setWindowSubtitle(tr("Edit Capture Comments"));
130 ui->sectionTabWidget->setTabBarAutoHide(true);
131 this->actionAddButton = ui->buttonBox->addButton(tr("Add Comment"), QDialogButtonBox::ActionRole);
132 connect(this->actionAddButton, &QPushButton::clicked, this, &CaptureCommentDialog::addComment);
134 connect(this, &CaptureCommentDialog::captureCommentChanged, mainApp->mainWindow(), &MainWindow::updateForUnsavedChanges);
135 QTimer::singleShot(0, this, &CaptureCommentDialog::updateWidgets);
138 CaptureCommentDialog::~CaptureCommentDialog()
140 delete ui;
143 void CaptureCommentDialog::addComment()
145 QPlainTextEdit *commentTextEdit;
146 CaptureCommentTabWidget *currentTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->currentWidget());
147 if (currentTW != nullptr) {
148 commentTextEdit = new QPlainTextEdit(currentTW);
150 currentTW->addTab(commentTextEdit);
154 void CaptureCommentDialog::updateWidgets()
156 QPlainTextEdit *commentTextEdit;
157 CaptureCommentTabWidget *shbTW;
158 QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save);
160 if (file_closed_ || !cap_file_.isValid()) {
161 for (int shb = 0; shb < ui->sectionTabWidget->count(); shb++) {
162 shbTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb));
163 shbTW->setReadOnly(true);
165 if (save_bt) {
166 save_bt->setEnabled(false);
168 actionAddButton->setEnabled(false);
169 WiresharkDialog::updateWidgets();
170 return;
173 bool enable = wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION);
174 save_bt->setEnabled(enable);
175 actionAddButton->setEnabled(enable);
177 unsigned num_shbs = wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth);
178 for (unsigned shb_idx = 0; shb_idx < num_shbs; shb_idx++) {
179 shbTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb_idx));
180 if (shbTW == nullptr) {
181 shbTW = new CaptureCommentTabWidget(ui->sectionTabWidget);
182 ui->sectionTabWidget->addTab(shbTW, tr("Section %1").arg(shb_idx + 1));
184 wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, shb_idx);
185 unsigned num_comments = wtap_block_count_option(shb, OPT_COMMENT);
186 char *shb_comment;
187 for (unsigned index = 0; index < num_comments; index++) {
188 commentTextEdit = qobject_cast<QPlainTextEdit*>(shbTW->widget(index));
189 if (commentTextEdit == nullptr) {
190 commentTextEdit = new QPlainTextEdit(shbTW);
191 shbTW->addTab(commentTextEdit);
193 if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, index,
194 &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
195 commentTextEdit->setPlainText(shb_comment);
196 } else {
197 // XXX: Should we warn about this failure?
198 commentTextEdit->setPlainText("");
200 commentTextEdit->setReadOnly(!enable);
202 for (unsigned index = shbTW->count(); index > num_comments; index--) {
203 shbTW->closeTab(index - 1);
207 WiresharkDialog::updateWidgets();
210 void CaptureCommentDialog::on_buttonBox_helpRequested()
212 // mainApp->helpTopicAction(HELP_CAPTURE_COMMENT_DIALOG);
215 void CaptureCommentDialog::on_buttonBox_accepted()
217 int ret = QDialog::Rejected;
219 if (file_closed_ || !cap_file_.capFile()->filename) {
220 done(ret);
221 return;
224 if (wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION))
226 CaptureCommentTabWidget *current;
227 char** comments_text;
228 for (int shb_idx = 0; shb_idx < ui->sectionTabWidget->count(); shb_idx++) {
229 current = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb_idx));
230 comments_text = current->getCommentsText();
231 if (comments_text == nullptr) {
232 /* This is the only error we track currently, so it must be
233 * this. Tell the user and give up. */
234 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
235 "A comment is too large to save in a capture file.");
236 done(ret);
237 return;
239 cf_update_section_comments(cap_file_.capFile(), shb_idx, comments_text);
240 emit captureCommentChanged();
241 ret = QDialog::Accepted;
244 done(ret);
247 void CaptureCommentDialog::on_buttonBox_rejected()
249 reject();
252 #include "capture_comment_dialog.moc"