Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / qt / profile_dialog.cpp
blobeee9e4b59cf357d79967361dd8a5c7d18cba8c4b
1 /* profile_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 "config.h"
12 #include "wsutil/filesystem.h"
14 #include <ui/qt/utils/qt_ui_utils.h>
16 #include "ui/profile.h"
17 #include "ui/recent.h"
19 #include <ui/qt/utils/variant_pointer.h>
20 #include <ui/qt/models/profile_model.h>
22 #include "profile_dialog.h"
23 #include <ui_profile_dialog.h>
24 #include "main_application.h"
25 #include <ui/qt/utils/color_utils.h>
26 #include <ui/qt/simple_dialog.h>
27 #include <ui/qt/widgets/wireshark_file_dialog.h>
29 #include <QBrush>
30 #include <QDir>
31 #include <QFont>
32 #include <QMessageBox>
33 #include <QPushButton>
34 #include <QTreeWidgetItem>
35 #include <QUrl>
36 #include <QComboBox>
37 #include <QLineEdit>
38 #include <QStandardPaths>
39 #include <QKeyEvent>
40 #include <QMenu>
41 #include <QMessageBox>
43 #define PROFILE_EXPORT_PROPERTY "export"
44 #define PROFILE_EXPORT_ALL "all"
45 #define PROFILE_EXPORT_SELECTED "selected"
47 ProfileDialog::ProfileDialog(QWidget *parent) :
48 GeometryStateDialog(parent),
49 pd_ui_(new Ui::ProfileDialog),
50 ok_button_(Q_NULLPTR),
51 import_button_(Q_NULLPTR),
52 model_(Q_NULLPTR),
53 sort_model_(Q_NULLPTR)
55 pd_ui_->setupUi(this);
56 loadGeometry();
57 setWindowTitle(mainApp->windowTitleString(tr("Configuration Profiles")));
59 ok_button_ = pd_ui_->buttonBox->button(QDialogButtonBox::Ok);
61 // XXX - Use NSImageNameAddTemplate and NSImageNameRemoveTemplate to set stock
62 // icons on macOS.
63 // Are there equivalent stock icons on Windows?
64 pd_ui_->newToolButton->setStockIcon("list-add");
65 pd_ui_->deleteToolButton->setStockIcon("list-remove");
66 pd_ui_->copyToolButton->setStockIcon("list-copy");
67 #ifdef Q_OS_MAC
68 pd_ui_->newToolButton->setAttribute(Qt::WA_MacSmallSize, true);
69 pd_ui_->deleteToolButton->setAttribute(Qt::WA_MacSmallSize, true);
70 pd_ui_->copyToolButton->setAttribute(Qt::WA_MacSmallSize, true);
71 pd_ui_->hintLabel->setAttribute(Qt::WA_MacSmallSize, true);
72 #endif
74 QString as_tooltip = pd_ui_->autoSwitchLimitLabel->toolTip();
75 pd_ui_->autoSwitchSpinBox->setToolTip(as_tooltip);
76 if (!is_packet_configuration_namespace()) {
77 pd_ui_->autoSwitchLimitLabel->setText(tr("Auto switch event limit"));
79 pd_ui_->autoSwitchSpinBox->setValue(recent.gui_profile_switch_check_count);
81 import_button_ = pd_ui_->buttonBox->addButton(tr("Import", "noun"), QDialogButtonBox::ActionRole);
83 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
84 export_button_ = pd_ui_->buttonBox->addButton(tr("Export", "noun"), QDialogButtonBox::ActionRole);
86 QMenu * importMenu = new QMenu(import_button_);
87 QAction * entry = importMenu->addAction(tr("From Zip File..."));
88 connect(entry, &QAction::triggered, this, &ProfileDialog::importFromZip, Qt::QueuedConnection);
89 entry = importMenu->addAction(tr("From Directory..."));
90 connect(entry, &QAction::triggered, this, &ProfileDialog::importFromDirectory, Qt::QueuedConnection);
91 import_button_->setMenu(importMenu);
93 QMenu * exportMenu = new QMenu(export_button_);
94 export_selected_entry_ = exportMenu->addAction(tr("%Ln Selected Personal Profile(s)...", "", 0));
95 export_selected_entry_->setProperty(PROFILE_EXPORT_PROPERTY, PROFILE_EXPORT_SELECTED);
96 connect(export_selected_entry_, &QAction::triggered, this, &ProfileDialog::exportProfiles, Qt::QueuedConnection);
97 entry = exportMenu->addAction(tr("All Personal Profiles..."));
98 entry->setProperty(PROFILE_EXPORT_PROPERTY, PROFILE_EXPORT_ALL);
99 connect(entry, &QAction::triggered, this, &ProfileDialog::exportProfiles, Qt::QueuedConnection);
100 export_button_->setMenu(exportMenu);
101 #else
102 connect(import_button_, &QPushButton::clicked, this, &ProfileDialog::importFromDirectory);
103 #endif
105 resetTreeView();
107 /* Select the row for the currently selected profile or the first row if non is selected*/
108 selectProfile();
110 pd_ui_->cmbProfileTypes->addItems(ProfileSortModel::filterTypes());
112 connect (pd_ui_->cmbProfileTypes, &QComboBox::currentTextChanged,
113 this, &ProfileDialog::filterChanged);
114 connect (pd_ui_->lineProfileFilter, &QLineEdit::textChanged,
115 this, &ProfileDialog::filterChanged);
117 currentItemChanged();
119 connect(pd_ui_->newToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::newToolButtonClicked);
120 connect(pd_ui_->deleteToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::deleteToolButtonClicked);
121 connect(pd_ui_->copyToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::copyToolButtonClicked);
122 connect(pd_ui_->buttonBox, &QDialogButtonBox::accepted, this, &ProfileDialog::buttonBoxAccepted);
123 connect(pd_ui_->buttonBox, &QDialogButtonBox::rejected, this, &ProfileDialog::buttonBoxRejected);
124 connect(pd_ui_->buttonBox, &QDialogButtonBox::helpRequested, this, &ProfileDialog::buttonBoxHelpRequested);
126 pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_NAME);
127 pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_TYPE);
129 pd_ui_->profileTreeView->setFocus();
132 ProfileDialog::~ProfileDialog()
134 delete pd_ui_;
135 empty_profile_list (true);
138 void ProfileDialog::keyPressEvent(QKeyEvent *evt)
140 if (pd_ui_->lineProfileFilter->hasFocus() && (evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return))
141 return;
142 QDialog::keyPressEvent(evt);
145 void ProfileDialog::selectProfile(QString profile)
147 if (profile.isEmpty())
148 profile = QString(get_profile_name());
150 int row = model_->findByName(profile);
151 QModelIndex idx = sort_model_->mapFromSource(model_->index(row, ProfileModel::COL_NAME));
152 if (idx.isValid())
153 pd_ui_->profileTreeView->selectRow(idx.row());
156 int ProfileDialog::execAction(ProfileDialog::ProfileAction profile_action)
158 int ret = QDialog::Accepted;
159 QModelIndex item;
161 switch (profile_action) {
162 case ShowProfiles:
163 ret = exec();
164 break;
165 case NewProfile:
166 newToolButtonClicked();
167 ret = exec();
168 break;
169 case ImportZipProfile:
170 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
171 importFromZip();
172 #endif
173 break;
174 case ImportDirProfile:
175 importFromDirectory();
176 break;
177 case ExportSingleProfile:
178 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
179 exportProfiles();
180 #endif
181 break;
182 case ExportAllProfiles:
183 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
184 exportProfiles(true);
185 #endif
186 break;
187 case EditCurrentProfile:
188 item = pd_ui_->profileTreeView->currentIndex();
189 if (item.isValid()) {
190 pd_ui_->profileTreeView->edit(item);
192 ret = exec();
193 break;
194 case DeleteCurrentProfile:
195 if (delete_current_profile()) {
196 mainApp->setConfigurationProfile (Q_NULLPTR);
198 break;
200 return ret;
203 QModelIndexList ProfileDialog::selectedProfiles()
205 QModelIndexList profiles;
207 foreach (QModelIndex idx, pd_ui_->profileTreeView->selectionModel()->selectedIndexes())
209 QModelIndex temp = sort_model_->mapToSource(idx);
210 if (! temp.isValid() || profiles.contains(temp) || temp.column() != ProfileModel::COL_NAME)
211 continue;
213 profiles << temp;
216 return profiles;
219 void ProfileDialog::selectionChanged()
221 if (selectedProfiles().count() == 0)
222 pd_ui_->profileTreeView->selectRow(0);
224 updateWidgets();
227 void ProfileDialog::updateWidgets()
229 bool enable_del = true;
230 bool enable_ok = true;
231 bool multiple = false;
232 bool enable_import = true;
233 int user_profiles = 0;
235 QString msg;
236 QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
237 QModelIndexList profiles = selectedProfiles();
239 /* Ensure that the index is always the name column */
240 if (index.column() != ProfileModel::COL_NAME)
241 index = index.sibling(index.row(), ProfileModel::COL_NAME);
243 /* check if more than one viable profile is selected, and inform the sorting model */
244 if (profiles.count() > 1)
245 multiple = true;
247 /* Check if user profiles have been selected and allow export if it is so */
248 for (int cnt = 0; cnt < profiles.count(); cnt++)
250 if (! profiles[cnt].data(ProfileModel::DATA_IS_GLOBAL).toBool() && ! profiles[cnt].data(ProfileModel::DATA_IS_DEFAULT).toBool())
251 user_profiles++;
253 if (model_->changesPending())
255 enable_import = false;
256 msg = tr("An import of profiles is not allowed, while changes are pending");
258 else if (model_->importPending())
260 enable_import = false;
261 msg = tr("An import is pending to be saved. Additional imports are not allowed");
263 import_button_->setToolTip(msg);
264 import_button_->setEnabled(enable_import);
266 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
267 bool contains_user = false;
268 bool enable_export = false;
270 if (user_profiles > 0)
271 contains_user = true;
273 /* enable export if no changes are pending */
274 if (! model_->changesPending())
275 enable_export = true;
277 export_button_->setEnabled(enable_export);
278 if (! enable_export)
280 if (! contains_user)
281 export_button_->setToolTip(tr("An export of profiles is only allowed for personal profiles"));
282 else
283 export_button_->setToolTip(tr("An export of profiles is not allowed, while changes are pending"));
285 export_selected_entry_->setVisible(contains_user);
286 #endif
288 /* if the current profile is default with reset pending or a global one, deactivate delete */
289 if (! multiple)
291 if (index.isValid())
293 if (index.data(ProfileModel::DATA_IS_GLOBAL).toBool())
294 enable_del = false;
295 else if (index.data(ProfileModel::DATA_IS_DEFAULT).toBool() && model_->resetDefault())
296 enable_del = false;
298 else if (! index.isValid())
299 enable_del = false;
302 QString hintUrl;
303 msg.clear();
304 if (multiple)
306 /* multiple profiles are being selected, copy is no longer allowed */
307 pd_ui_->copyToolButton->setEnabled(false);
309 msg = tr("%Ln Selected Personal Profile(s)...", "", user_profiles);
310 pd_ui_->hintLabel->setText(msg);
311 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
312 export_selected_entry_->setText(msg);
313 #endif
315 else
317 /* if only one profile is selected, display it's path in the hint label and activate link (if allowed) */
318 if (index.isValid())
320 QString temp = index.data(ProfileModel::DATA_PATH).toString();
321 if (index.data(ProfileModel::DATA_PATH_IS_NOT_DESCRIPTION).toBool() && QFileInfo(temp).isDir())
322 hintUrl = QUrl::fromLocalFile(temp).toString();
323 pd_ui_->hintLabel->setText(temp);
324 pd_ui_->hintLabel->setToolTip(index.data(Qt::ToolTipRole).toString());
326 if (! index.data(ProfileModel::DATA_IS_GLOBAL).toBool() && ! index.data(ProfileModel::DATA_IS_DEFAULT).toBool())
327 msg = tr("%Ln Selected Personal Profile(s)...", "", 1);
330 pd_ui_->copyToolButton->setEnabled(true);
331 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
332 export_selected_entry_->setText(msg);
333 #endif
336 /* Ensure, that the ok button is disabled, if an invalid name is used or if duplicate global profiles exist */
337 if (model_ && model_->rowCount() > 0)
339 msg.clear();
340 for (int row = 0; row < model_->rowCount() && enable_ok; row++)
342 QModelIndex idx = model_->index(row, ProfileModel::COL_NAME);
343 QString name = idx.data().toString();
345 if (! ProfileModel::checkNameValidity(name, &msg))
347 if (idx == index || selectedProfiles().contains(idx))
349 hintUrl.clear();
350 pd_ui_->hintLabel->setText(msg);
353 enable_ok = false;
354 continue;
357 if (model_->checkInvalid(idx) || (! idx.data(ProfileModel::DATA_IS_GLOBAL).toBool() && model_->checkIfDeleted(idx)) )
359 if (idx == index)
360 hintUrl.clear();
361 enable_ok = false;
362 continue;
365 if (idx != index && idx.data().toString().compare(index.data().toString()) == 0)
367 if (idx.data(ProfileModel::DATA_IS_GLOBAL).toBool() == index.data(ProfileModel::DATA_IS_GLOBAL).toBool())
368 enable_ok = false;
371 QList<int> rows = model_->findAllByNameAndVisibility(name, idx.data(ProfileModel::DATA_IS_GLOBAL).toBool());
372 if (rows.count() > 1)
373 enable_ok = false;
376 if (enable_ok && ! model_->checkIfDeleted(index) && index.data(ProfileModel::DATA_STATUS).toInt() == PROF_STAT_CHANGED)
377 hintUrl.clear();
380 pd_ui_->hintLabel->setUrl(hintUrl);
382 pd_ui_->deleteToolButton->setEnabled(enable_del);
383 ok_button_->setEnabled(enable_ok);
386 void ProfileDialog::currentItemChanged(const QModelIndex &, const QModelIndex &)
388 updateWidgets();
391 void ProfileDialog::newToolButtonClicked()
393 pd_ui_->lineProfileFilter->setText("");
394 pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::AllProfiles);
395 sort_model_->setFilterString();
397 QModelIndex ridx = sort_model_->mapFromSource(model_->addNewProfile(tr("New profile")));
398 if (ridx.isValid())
400 pd_ui_->profileTreeView->setCurrentIndex(ridx);
401 pd_ui_->profileTreeView->scrollTo(ridx);
402 pd_ui_->profileTreeView->edit(ridx);
403 currentItemChanged();
405 else
406 updateWidgets();
409 void ProfileDialog::deleteToolButtonClicked()
411 QModelIndexList profiles = selectedProfiles();
412 if (profiles.count() <= 0)
413 return;
415 model_->deleteEntries(profiles);
417 bool isGlobal = model_->activeProfile().data(ProfileModel::DATA_IS_GLOBAL).toBool();
418 int row = model_->findByName(model_->activeProfile().data().toString());
419 /* If the active profile is deleted, the default is selected next */
420 if (row < 0)
421 row = 0;
422 QModelIndex newIdx = sort_model_->mapFromSource(model_->index(row, 0));
423 if (newIdx.data(ProfileModel::DATA_IS_GLOBAL).toBool() != isGlobal)
424 newIdx = sort_model_->mapFromSource(model_->index(0, 0));
426 pd_ui_->profileTreeView->setCurrentIndex(newIdx);
428 updateWidgets();
431 void ProfileDialog::copyToolButtonClicked()
433 QModelIndexList profiles = selectedProfiles();
434 if (profiles.count() > 1)
435 return;
437 pd_ui_->lineProfileFilter->setText("");
438 pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::AllProfiles);
439 sort_model_->setFilterString();
441 QModelIndex current = pd_ui_->profileTreeView->currentIndex();
442 if (current.column() != ProfileModel::COL_NAME)
443 current = current.sibling(current.row(), ProfileModel::COL_NAME);
445 QModelIndex source = sort_model_->mapToSource(current);
446 QModelIndex ridx = model_->duplicateEntry(source);
447 if (ridx.isValid())
449 pd_ui_->profileTreeView->setCurrentIndex(sort_model_->mapFromSource(ridx));
450 pd_ui_->profileTreeView->scrollTo(sort_model_->mapFromSource(ridx));
451 pd_ui_->profileTreeView->edit(sort_model_->mapFromSource(ridx));
452 currentItemChanged();
454 else
455 updateWidgets();
458 void ProfileDialog::buttonBoxAccepted()
460 bool write_recent = true;
461 bool item_data_removed = false;
463 recent.gui_profile_switch_check_count = pd_ui_->autoSwitchSpinBox->value();
465 QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
467 pd_ui_->buttonBox->setFocus();
469 QModelIndexList profiles = selectedProfiles();
470 if (profiles.count() <= 0)
471 index = QModelIndex();
473 QModelIndex default_item = sort_model_->mapFromSource(model_->index(0, ProfileModel::COL_NAME));
474 if (index.isValid() && index.column() != ProfileModel::COL_NAME)
475 index = index.sibling(index.row(), ProfileModel::COL_NAME);
477 if (default_item.data(ProfileModel::DATA_STATUS).toInt() == PROF_STAT_DEFAULT && model_->resetDefault())
479 // Reset Default profile.
480 GList *fl_entry = model_->at(0);
481 remove_from_profile_list(fl_entry);
483 // Don't write recent file if leaving the Default profile after this has been reset.
484 write_recent = !is_default_profile();
486 // Don't fetch profile data if removed.
487 item_data_removed = (index.row() == 0);
490 if (write_recent) {
491 /* Get the current geometry, before writing it to disk */
492 mainApp->emitAppSignal(MainApplication::ProfileChanging);
494 /* Write recent file for current profile now because
495 * the profile may be renamed in apply_profile_changes() */
496 write_profile_recent();
499 char * err_msg = Q_NULLPTR;
500 if ((err_msg = apply_profile_changes()) != Q_NULLPTR) {
501 QMessageBox::critical(this, tr("Profile Error"),
502 err_msg,
503 QMessageBox::Ok);
504 g_free(err_msg);
506 model_->doResetModel();
507 return;
510 model_->doResetModel();
512 QString profileName;
514 if (! index.isValid() && model_->lastSetRow() >= 0)
516 QModelIndex original = model_->index(model_->lastSetRow(), ProfileModel::COL_NAME);
517 index = sort_model_->mapFromSource(original);
520 /* If multiple profiles are selected, do not change the selected profile */
521 if (index.isValid() && ! item_data_removed && profiles.count() <= 1)
523 profileName = model_->data(index).toString();
526 if (profileName.length() > 0 && model_->findByName(profileName) >= 0) {
527 // The new profile exists, change.
528 mainApp->setConfigurationProfile (profileName.toUtf8().constData(), false);
529 } else if (!model_->activeProfile().isValid()) {
530 // The new profile does not exist, and the previous profile has
531 // been deleted. Change to the default profile.
532 mainApp->setConfigurationProfile (Q_NULLPTR, false);
536 void ProfileDialog::buttonBoxRejected()
538 QString msg;
539 if (! model_->clearImported(&msg))
540 QMessageBox::critical(this, tr("Error"), msg);
543 void ProfileDialog::buttonBoxHelpRequested()
545 mainApp->helpTopicAction(HELP_CONFIG_PROFILES_DIALOG);
548 void ProfileDialog::dataChanged(const QModelIndex &)
550 pd_ui_->lineProfileFilter->setText("");
551 pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::AllProfiles);
553 pd_ui_->profileTreeView->setFocus();
554 if (model_->lastSetRow() >= 0)
556 QModelIndex original = model_->index(model_->lastSetRow(), ProfileModel::COL_NAME);
557 pd_ui_->profileTreeView->setCurrentIndex(sort_model_->mapFromSource(original));
558 pd_ui_->profileTreeView->selectRow(sort_model_->mapFromSource(original).row());
561 updateWidgets();
564 void ProfileDialog::filterChanged(const QString &text)
566 if (qobject_cast<QComboBox *>(sender()))
568 QComboBox * cmb = qobject_cast<QComboBox *>(sender());
569 sort_model_->setFilterType(static_cast<ProfileSortModel::FilterType>(cmb->currentIndex()));
571 else if (qobject_cast<QLineEdit *>(sender()))
572 sort_model_->setFilterString(text);
574 QModelIndex active = sort_model_->mapFromSource(model_->activeProfile());
575 if (active.isValid())
576 pd_ui_->profileTreeView->setCurrentIndex(active);
579 #if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
580 void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
582 QAction * action = qobject_cast<QAction *>(sender());
583 if (action && action->property(PROFILE_EXPORT_PROPERTY).isValid())
584 exportAllPersonalProfiles = action->property(PROFILE_EXPORT_PROPERTY).toString().compare(PROFILE_EXPORT_ALL) == 0;
586 QModelIndexList items;
587 int skipped = 0;
589 if (! exportAllPersonalProfiles)
591 foreach (QModelIndex idx, selectedProfiles())
593 QModelIndex baseIdx = sort_model_->index(idx.row(), ProfileModel::COL_NAME);
594 if (! baseIdx.data(ProfileModel::DATA_IS_GLOBAL).toBool() && ! baseIdx.data(ProfileModel::DATA_IS_DEFAULT).toBool())
595 items << sort_model_->mapToSource(baseIdx);
596 else
597 skipped++;
600 else if (exportAllPersonalProfiles)
602 for (int cnt = 0; cnt < sort_model_->rowCount(); cnt++)
604 QModelIndex idx = sort_model_->index(cnt, ProfileModel::COL_NAME);
605 if (! idx.data(ProfileModel::DATA_IS_GLOBAL).toBool() && ! idx.data(ProfileModel::DATA_IS_DEFAULT).toBool())
606 items << sort_model_->mapToSource(idx);
609 if (items.count() == 0)
611 QString msg = tr("No profiles found for export");
612 if (skipped > 0)
613 msg.append(tr(", %Ln profile(s) skipped", "", skipped));
614 QMessageBox::critical(this, tr("Exporting profiles"), msg);
615 return;
618 QString zipFile = WiresharkFileDialog::getSaveFileName(this, tr("Select zip file for export"), openDialogInitialDir(), tr("Zip File (*.zip)"));
620 if (zipFile.length() > 0)
622 QFileInfo fi(zipFile);
623 if (fi.suffix().length() == 0 || fi.suffix().toLower().compare("zip") != 0)
624 zipFile += ".zip";
626 QString err;
627 if (model_->exportProfiles(zipFile, items, &err))
629 QString msg = tr("%Ln profile(s) exported", "", static_cast<int>(items.count()));
630 if (skipped > 0)
631 msg.append(tr(", %Ln profile(s) skipped", "", skipped));
632 QMessageBox::information(this, tr("Exporting profiles"), msg);
634 QFileInfo zip(zipFile);
635 storeLastDir(zip.absolutePath());
637 else
639 QString msg = tr("An error has occurred while exporting profiles");
640 if (err.length() > 0)
641 msg.append(QStringLiteral("\n\n%1: %2").arg(tr("Error"), err));
642 QMessageBox::critical(this, tr("Exporting profiles"), msg);
647 void ProfileDialog::importFromZip()
649 QString zipFile = WiresharkFileDialog::getOpenFileName(this, tr("Select zip file for import"), openDialogInitialDir(), tr("Zip File (*.zip)"));
651 QFileInfo fi(zipFile);
652 if (! fi.exists())
653 return;
655 int skipped = 0;
656 QStringList import;
657 int count = model_->importProfilesFromZip(zipFile, &skipped, &import);
659 finishImport(fi, count, skipped, import);
661 #endif
663 void ProfileDialog::importFromDirectory()
665 QString importDir = WiresharkFileDialog::getExistingDirectory(this, tr("Select directory for import"), openDialogInitialDir());
667 QFileInfo fi(importDir);
668 if (! fi.isDir())
669 return;
671 int skipped = 0;
672 QStringList import;
673 int count = model_->importProfilesFromDir(importDir, &skipped, false, &import);
675 finishImport(fi, count, skipped, import);
678 void ProfileDialog::finishImport(QFileInfo fi, int count, int skipped, QStringList import)
680 QString msg;
681 QMessageBox::Icon icon;
683 if (count == 0 && skipped == 0)
685 icon = QMessageBox::Warning;
686 msg = tr("No profiles found for import in %1").arg(fi.fileName());
688 else
690 icon = QMessageBox::Information;
691 msg = tr("%Ln profile(s) imported", "", count);
692 if (skipped > 0)
693 msg.append(tr(", %Ln profile(s) skipped", "", skipped));
695 QMessageBox msgBox(icon, tr("Importing profiles"), msg, QMessageBox::Ok, this);
696 msgBox.exec();
698 storeLastDir(fi.absolutePath());
700 if (count > 0)
702 import.sort();
703 resetTreeView();
704 model_->markAsImported(import);
705 int rowFirstImported = model_->findByName(import.at(0));
706 QModelIndex idx = sort_model_->mapFromSource(model_->index(rowFirstImported, ProfileModel::COL_NAME));
707 pd_ui_->profileTreeView->selectRow(idx.isValid() ? idx.row() : 0);
710 updateWidgets();
713 void ProfileDialog::resetTreeView()
715 if (model_)
717 pd_ui_->profileTreeView->setModel(Q_NULLPTR);
718 sort_model_->setSourceModel(Q_NULLPTR);
719 model_->disconnect();
720 if (pd_ui_->profileTreeView->selectionModel())
721 pd_ui_->profileTreeView->selectionModel()->disconnect();
722 delete sort_model_;
723 delete model_;
726 model_ = new ProfileModel(pd_ui_->profileTreeView);
727 sort_model_ = new ProfileSortModel(pd_ui_->profileTreeView);
728 sort_model_->setSourceModel(model_);
729 pd_ui_->profileTreeView->setModel(sort_model_);
731 connect(model_, &ProfileModel::itemChanged, this, &ProfileDialog::dataChanged, Qt::QueuedConnection);
732 QItemSelectionModel *selModel = pd_ui_->profileTreeView->selectionModel();
733 connect(selModel, &QItemSelectionModel::currentChanged,
734 this, &ProfileDialog::currentItemChanged, Qt::QueuedConnection);
735 connect(selModel, &QItemSelectionModel::selectionChanged,
736 this, &ProfileDialog::selectionChanged);
738 selectionChanged();
740 if (sort_model_->columnCount() <= 1) {
741 pd_ui_->profileTreeView->header()->hide();