Sort list of available filetypes when loading a capture

When loading a capture file in the GUI, this change causes the list of
available file types to be sorted alphabetically. "Automatically detect
file type", pcap, and pcapng remain at the top of the list.

Unlike my prior crack at this in change #36862, this is done directly in
the file open dialogs (open_file_hook_proc() for Windows,
CaptureFileDialog::addFormatTypeSelector() and CaptureFileDialog::open()
for Qt). No changes to wiretap.

It's not a huge deal if you folks decide this isn't necessary, I just
think this gives a bit of extra polish to the load-file dialog. It also
makes it easier for the user to spot the format they want if they aren't
aware that the file-format dropdown accepts keyboard input.

Change-Id: Ie81c6d99e83fe862f20b413318ac8ce76463a766
Reviewed-on: https://code.wireshark.org/review/37749
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
David Perry 2020-07-06 16:41:07 -04:00 committed by Gerald Combs
parent d8db04bf5f
commit 00b5c2809a
2 changed files with 50 additions and 3 deletions

View File

@ -626,10 +626,22 @@ void CaptureFileDialog::addDisplayFilterEdit() {
}
void CaptureFileDialog::addFormatTypeSelector(QVBoxLayout &v_box) {
int i;
/* Put Auto, as well as pcap and pcapng (which are the first two entries in
open_routines), at the top of the file type list. */
format_type_.addItem(tr("Automatically detect file type"));
for (int i = 0; open_routines[i].name != NULL; i += 1) {
for (i = 0; i < 2; i += 1) {
format_type_.addItem(open_routines[i].name);
}
/* Generate a sorted list of the remaining file types. */
QStringList routine_names;
for ( /* keep using i */ ; open_routines[i].name != NULL; i += 1) {
routine_names += QString(open_routines[i].name);
}
routine_names.sort(Qt::CaseInsensitive);
for (i = 0; i < routine_names.size(); i += 1) {
format_type_.addItem(routine_names.at(i));
}
v_box.addWidget(&format_type_, 0, Qt::AlignTop);
}
@ -688,7 +700,7 @@ int CaptureFileDialog::open(QString &file_name, unsigned int &type) {
if (WiresharkFileDialog::exec() && selectedFiles().length() > 0) {
file_name = selectedFiles()[0];
type = format_type_.currentIndex();
type = open_info_name_to_type(qPrintable(format_type_.currentText()));
display_filter_.append(display_filter_edit_->text());
return QDialog::Accepted;

View File

@ -916,6 +916,11 @@ filter_tb_syntax_check(HWND hwnd, TCHAR *filter_text) {
g_free(strval);
}
static gint alpha_sort(gconstpointer a, gconstpointer b)
{
return g_ascii_strcasecmp(*(const char **)a, *(const char **)b);
}
static UINT_PTR CALLBACK
open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
HWND cur_ctrl, parent;
@ -931,11 +936,27 @@ open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
SetWindowText(cur_ctrl, utf_8to16(g_dfilter_str));
}
/* Put Auto, as well as pcap and pcapng (which are the first two entries in
open_routines), at the top of the file type list. */
cur_ctrl = GetDlgItem(of_hwnd, EWFD_FORMAT_TYPE);
SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) _T("Automatically detect file type"));
for (i = 0; open_routines[i].name != NULL; i += 1) {
for (i = 0; i < 2; i += 1) {
SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) utf_8to16(open_routines[i].name));
}
/* Generate a sorted list of the remaining file types.
The magic number 60 is a rough starting point for how big the
GPtrArray should start. It'll automatically grow if needed, so
the exact number isn't critical. (This is good, because we don't have
an easy way to get the exact number.) */
GPtrArray *routine_names = g_ptr_array_sized_new(60);
for ( /* keep using i */ ; open_routines[i].name != NULL; i += 1) {
g_ptr_array_add(routine_names, (gpointer)open_routines[i].name);
}
g_ptr_array_sort(routine_names, alpha_sort);
for (guint i = 0; i < routine_names->len; i += 1) {
SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) utf_8to16((const char *)g_ptr_array_index(routine_names, i)));
}
g_ptr_array_free(routine_names, TRUE);
SendMessage(cur_ctrl, CB_SETCURSEL, 0, 0);
preview_set_file_info(of_hwnd, NULL);
@ -951,6 +972,20 @@ open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
cur_ctrl = GetDlgItem(of_hwnd, EWFD_FORMAT_TYPE);
g_format_type = (unsigned int) SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
/* The list of file formats is sorted. Get the format by name. */
guint label_len;
label_len = (guint) SendMessage(cur_ctrl, CB_GETLBTEXTLEN, (WPARAM) g_format_type, 0);
if (label_len != CB_ERR) {
TCHAR *label = g_malloc((label_len+1)*sizeof(TCHAR));
SendMessage(cur_ctrl, CB_GETLBTEXT, (WPARAM) g_format_type, (LPARAM) label);
g_format_type = open_info_name_to_type(utf_16to8(label));
g_free(label);
}
else {
/* Problem, fall back on automatic */
g_format_type = WTAP_TYPE_AUTO;
}
break;
case CDN_SELCHANGE:
/* This _almost_ works correctly. We need to handle directory