Work around macOS running applications in /.

If an application is launched from the Finder, it appears to get / as
its current directory.  This causes Wireshark open/save dialogs to open
up / if the user hasn't already opened a file in another directory, so
that there's no "last open directory" in the recent file.

Have get_persdatafile_dir(), on UN*X, cache the personal data directory
just as it does on Windows and, if nothing's been cached, have it fetch
the current directory and, if that succeeds *and* it's not the root
directory, use that.  Otherwise, use the user's home directory.

Fixes #9862.

In addition, separate the notion of "last open directory" and "open
dialog initial directory", where the latter is the last open directory
*if* a file has been opened in this session or the recent file has the
last open directory from a previous session, otherwise it's the user's
personal data directory.

Use the latter notion in file open/save dialogs; use the former notion
when reading from and writing to the recent file.

This means we don't need to set the "last open directory" at startup
time.  That way, running Wireshark without opening a file won't cause
the "last open directory" to be set, so that if a user runs it from a
directory, the "open dialog initial directory" won't be the last
directory from which Wireshark was run.
This commit is contained in:
Guy Harris 2023-11-10 00:08:48 -08:00
parent 12b015d1c4
commit 19f7e572a4
36 changed files with 168 additions and 117 deletions

View File

@ -1,6 +1,6 @@
/** @file
*
* Routines to fetch the last directory in which a file was opened;
* Routine to fetch the last directory in which a file was opened;
* its implementation is GUI-dependent, but the API isn't
*
* Wireshark - Network traffic analyzer

View File

@ -716,13 +716,15 @@ int main(int argc, char *qt_argv[])
main_w->connect(&ls_app, &LograyApplication::openCaptureOptions,
main_w, &LograyMainWindow::showCaptureOptionsDialog);
/* Init the "Open file" dialog directory */
/* (do this after the path settings are processed) */
/*
* If we have a saved "last directory in which a file was opened"
* in the recent file, set it as the one for the app.
*
* (do this after the path settings are processed)
*/
if (recent.gui_fileopen_remembered_dir &&
test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
lwApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
} else {
lwApp->setLastOpenDir(get_persdatafile_dir());
set_last_open_dir(recent.gui_fileopen_remembered_dir);
}
#ifdef DEBUG_STARTUP_TIME

View File

@ -1777,7 +1777,7 @@ void LograyMainWindow::exportPacketBytes()
file_name = WiresharkFileDialog::getSaveFileName(this,
mainApp->windowTitleString(tr("Export Selected Packet Bytes")),
mainApp->lastOpenDir().canonicalPath(),
mainApp->openDialogInitialDir().canonicalPath(),
tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD ")")
);

View File

@ -30,7 +30,7 @@
#endif
#include "ui/alert_box.h"
#include "ui/last_open_dir.h"
#include "ui/util.h"
#include "ui/help_url.h"
#include <wsutil/utf8_entities.h>
@ -205,7 +205,7 @@ FolderListModel::FolderListModel(QObject * parent):
AStringListListModel(parent)
{
/* "file open" */
appendRow(QStringList() << tr("\"File\" dialogs") << get_last_open_dir() << tr("capture files"));
appendRow(QStringList() << tr("\"File\" dialogs") << get_open_dialog_initial_dir() << tr("capture files"));
/* temp */
appendRow(QStringList() << tr("Temp") << (global_capture_opts.temp_dir && global_capture_opts.temp_dir[0] ? global_capture_opts.temp_dir : g_get_tmp_dir()) << tr("untitled capture files"));

View File

@ -66,13 +66,14 @@ CaptureFileDialog::CaptureFileDialog(QWidget *parent, capture_file *cf) :
{
switch (prefs.gui_fileopen_style) {
case FO_STYLE_LAST_OPENED:
/* The user has specified that we should start out in the last directory
* we looked in. If we've already opened a file, use its containing
* directory, if we could determine it, as the directory, otherwise
* use the "last opened" directory saved in the preferences file if
* there was one.
/* The user has specified that we should start out in the last
* directory in which we opened a file.
*
* The open dialog initial directory will be that directory
* unless we've never opened a file, in which case it will
* be the user's personal data file directory.
*/
setDirectory(mainApp->lastOpenDir());
setDirectory(mainApp->openDialogInitialDir());
break;
case FO_STYLE_SPECIFIED:

View File

@ -31,7 +31,7 @@
#include "ui/capture_ui_utils.h"
#include "ui/capture_globals.h"
#include "ui/iface_lists.h"
#include "ui/last_open_dir.h"
#include "ui/file_dialog.h"
#include "ui/ws_ui_util.h"
#include "ui/util.h"
@ -366,12 +366,12 @@ void CaptureOptionsDialog::on_capturePromModeCheckBox_toggled(bool checked)
void CaptureOptionsDialog::browseButtonClicked()
{
char *open_dir = NULL;
const char *open_dir = NULL;
switch (prefs.gui_fileopen_style) {
case FO_STYLE_LAST_OPENED:
open_dir = get_last_open_dir();
open_dir = get_open_dialog_initial_dir();
break;
case FO_STYLE_SPECIFIED:

View File

@ -415,7 +415,7 @@ void ColoringRulesDialog::on_buttonBox_clicked(QAbstractButton *button)
if (button == import_button_) {
QString file_name = WiresharkFileDialog::getOpenFileName(this, mainApp->windowTitleString(tr("Import Coloring Rules")),
mainApp->lastOpenDir().path());
mainApp->openDialogInitialDir().path());
if (!file_name.isEmpty()) {
if (!colorRuleModel_.importColors(file_name, err)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err.toUtf8().constData());
@ -433,7 +433,7 @@ void ColoringRulesDialog::on_buttonBox_clicked(QAbstractButton *button)
QString caption = mainApp->windowTitleString(tr("Export %1 Coloring Rules").arg(num_items));
QString file_name = WiresharkFileDialog::getSaveFileName(this, caption,
mainApp->lastOpenDir().path());
mainApp->openDialogInitialDir().path());
if (!file_name.isEmpty()) {
if (!colorRuleModel_.exportColors(file_name, err)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err.toUtf8().constData());

View File

@ -67,7 +67,7 @@ ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *ca
* use the "last opened" directory saved in the preferences file if
* there was one.
*/
setDirectory(mainApp->lastOpenDir());
setDirectory(mainApp->openDialogInitialDir());
break;
case FO_STYLE_SPECIFIED:

View File

@ -244,7 +244,7 @@ void ExportObjectDialog::on_cmbContentType_currentIndexChanged(int index)
void ExportObjectDialog::saveCurrentEntry(QString *tempFile)
{
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QModelIndex proxyIndex = eo_ui_->objectTree->currentIndex();
if (!proxyIndex.isValid())
@ -279,7 +279,7 @@ void ExportObjectDialog::saveCurrentEntry(QString *tempFile)
void ExportObjectDialog::saveAllEntries()
{
QDir save_in_dir(mainApp->lastOpenDir());
QDir save_in_dir(mainApp->openDialogInitialDir());
QString save_in_path;
//

View File

@ -172,7 +172,7 @@ void FirewallRulesDialog::on_buttonBox_clicked(QAbstractButton *button)
.arg(firewall_product_name(prod_));
QByteArray file_name = WiresharkFileDialog::getSaveFileName(this,
save_title,
mainApp->lastOpenDir().canonicalPath(),
mainApp->openDialogInitialDir().canonicalPath(),
tr("Text file (*.txt);;All Files (" ALL_FILES_WILDCARD ")")
).toUtf8();
if (file_name.length() > 0) {

View File

@ -552,7 +552,7 @@ void Iax2AnalysisDialog::on_actionSaveGraph_triggered()
ui->tabWidget->setCurrentWidget(ui->graphTab);
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");
@ -878,7 +878,7 @@ void Iax2AnalysisDialog::saveAudio(Iax2AnalysisDialog::StreamDirection direction
}
QString sel_filter;
QString file_path = WiresharkFileDialog::getSaveFileName(
this, caption, mainApp->lastOpenDir().absoluteFilePath("Saved RTP Audio.au"),
this, caption, mainApp->openDialogInitialDir().absoluteFilePath("Saved RTP Audio.au"),
ext_filter, &sel_filter);
if (file_path.isEmpty()) return;
@ -1148,7 +1148,7 @@ void Iax2AnalysisDialog::saveCsv(Iax2AnalysisDialog::StreamDirection direction)
}
QString file_path = WiresharkFileDialog::getSaveFileName(
this, caption, mainApp->lastOpenDir().absoluteFilePath("RTP Packet Data.csv"),
this, caption, mainApp->openDialogInitialDir().absoluteFilePath("RTP Packet Data.csv"),
tr("Comma-separated values (*.csv)"));
if (file_path.isEmpty()) return;

View File

@ -17,7 +17,7 @@
#include <epan/prefs.h>
#include "ui/text_import_scanner.h"
#include "ui/last_open_dir.h"
#include "ui/util.h"
#include "ui/alert_box.h"
#include "ui/help_url.h"
#include "ui/capture_globals.h"
@ -615,7 +615,7 @@ void ImportTextDialog::on_textFileBrowseButton_clicked()
use the "last opened" directory saved in the preferences file if
there was one. */
/* This is now the default behaviour in file_selection_new() */
open_dir = get_last_open_dir();
open_dir = get_open_dialog_initial_dir();
break;
case FO_STYLE_SPECIFIED:

View File

@ -1598,7 +1598,7 @@ void IOGraphDialog::on_buttonBox_helpRequested()
void IOGraphDialog::on_buttonBox_accepted()
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");

View File

@ -850,7 +850,7 @@ void LteRlcGraphDialog::on_otherDirectionButton_clicked()
void LteRlcGraphDialog::on_buttonBox_accepted()
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");

View File

@ -767,13 +767,15 @@ int main(int argc, char *qt_argv[])
main_w->connect(&ws_app, &WiresharkApplication::openCaptureOptions,
main_w, &WiresharkMainWindow::showCaptureOptionsDialog);
/* Init the "Open file" dialog directory */
/* (do this after the path settings are processed) */
/*
* If we have a saved "last directory in which a file was opened"
* in the recent file, set it as the one for the app.
*
* (do this after the path settings are processed)
*/
if (recent.gui_fileopen_remembered_dir &&
test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
} else {
wsApp->setLastOpenDir(get_persdatafile_dir());
set_last_open_dir(recent.gui_fileopen_remembered_dir);
}
#ifdef DEBUG_STARTUP_TIME

View File

@ -55,7 +55,7 @@
#include "wsutil/filter_files.h"
#include "ui/capture_globals.h"
#include "ui/software_update.h"
#include "ui/last_open_dir.h"
#include "ui/file_dialog.h"
#include "ui/recent_utils.h"
#ifdef HAVE_LIBPCAP
@ -114,8 +114,6 @@ MainApplication *mainApp = NULL;
// XXX - Copied from ui/gtk/file_dlg.c
// MUST be UTF-8
static char *last_open_dir = NULL;
static QList<recent_item_status *> recent_captures_;
static QHash<int, QList<QAction *> > dynamic_menu_groups_;
static QHash<int, QList<QAction *> > added_menu_groups_;
@ -154,18 +152,6 @@ topic_action(topic_action_e action)
if (mainApp) mainApp->helpTopicAction(action);
}
extern "C" char *
get_last_open_dir(void)
{
return last_open_dir;
}
void
set_last_open_dir(const char *dirname)
{
if (mainApp) mainApp->setLastOpenDir(dirname);
}
/*
* Add the capture filename to the application-wide "Recent Files" list.
* Contrary to the name this isn't limited to the "recent" menu.
@ -296,14 +282,15 @@ void MainApplication::updateTaps()
draw_tap_listeners(FALSE);
}
QDir MainApplication::lastOpenDir() {
return QDir(last_open_dir);
QDir MainApplication::openDialogInitialDir() {
return QDir(get_open_dialog_initial_dir());
}
void MainApplication::setLastOpenDirFromFilename(const QString file_name)
{
QString directory = QFileInfo(file_name).absolutePath();
setLastOpenDir(qUtf8Printable(directory));
/* XXX - printable? */
set_last_open_dir(qUtf8Printable(directory));
}
void MainApplication::helpTopicAction(topic_action_e action)
@ -597,28 +584,6 @@ void MainApplication::storeCustomColorsInRecent()
}
}
void MainApplication::setLastOpenDir(const char *dir_name)
{
qint64 len;
gchar *new_last_open_dir;
if (dir_name && dir_name[0]) {
len = strlen(dir_name);
if (dir_name[len-1] == G_DIR_SEPARATOR) {
new_last_open_dir = g_strconcat(dir_name, (char *)NULL);
}
else {
new_last_open_dir = g_strconcat(dir_name,
G_DIR_SEPARATOR_S, (char *)NULL);
}
} else {
new_last_open_dir = NULL;
}
g_free(last_open_dir);
last_open_dir = new_last_open_dir;
}
bool MainApplication::event(QEvent *event)
{
QString display_filter = NULL;

View File

@ -110,8 +110,7 @@ public:
QList<recent_item_status *> recentItems() const;
void addRecentItem(const QString filename, qint64 size, bool accessible);
void removeRecentItem(const QString &filename);
QDir lastOpenDir();
void setLastOpenDir(const char *dir_name);
QDir openDialogInitialDir();
void setLastOpenDirFromFilename(QString file_name);
void helpTopicAction(topic_action_e action);
const QFont monospaceFont(bool zoomed = false) const;

View File

@ -751,7 +751,7 @@ void PacketDiagram::showFieldsToggled(bool checked)
void PacketDiagram::saveAsTriggered()
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");
// Gaze upon my beautiful graph with lossy artifacts!

View File

@ -604,7 +604,7 @@ void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
return;
}
QString zipFile = QFileDialog::getSaveFileName(this, tr("Select zip file for export"), lastOpenDir(), tr("Zip File (*.zip)"));
QString zipFile = QFileDialog::getSaveFileName(this, tr("Select zip file for export"), openDialogInitialDir(), tr("Zip File (*.zip)"));
if (zipFile.length() > 0)
{
@ -635,7 +635,7 @@ void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
void ProfileDialog::importFromZip()
{
QString zipFile = QFileDialog::getOpenFileName(this, tr("Select zip file for import"), lastOpenDir(), tr("Zip File (*.zip)"));
QString zipFile = QFileDialog::getOpenFileName(this, tr("Select zip file for import"), openDialogInitialDir(), tr("Zip File (*.zip)"));
QFileInfo fi(zipFile);
if (! fi.exists())
@ -651,7 +651,7 @@ void ProfileDialog::importFromZip()
void ProfileDialog::importFromDirectory()
{
QString importDir = QFileDialog::getExistingDirectory(this, tr("Select directory for import"), lastOpenDir());
QString importDir = QFileDialog::getExistingDirectory(this, tr("Select directory for import"), openDialogInitialDir());
QFileInfo fi(importDir);
if (! fi.isDir())

View File

@ -621,7 +621,7 @@ void RtpAnalysisDialog::on_actionSaveGraph_triggered()
ui->tabWidget->setCurrentWidget(ui->graphTab);
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");
@ -904,7 +904,7 @@ void RtpAnalysisDialog::saveCsv(RtpAnalysisDialog::StreamDirection direction)
}
QString file_path = WiresharkFileDialog::getSaveFileName(
this, caption, mainApp->lastOpenDir().absoluteFilePath("RTP Packet Data.csv"),
this, caption, mainApp->openDialogInitialDir().absoluteFilePath("RTP Packet Data.csv"),
tr("Comma-separated values (*.csv)"));
if (file_path.isEmpty()) return;

View File

@ -2448,7 +2448,7 @@ save_audio_t RtpPlayerDialog::selectFileAudioFormatAndName(QString *file_path)
QString sel_filter;
*file_path = WiresharkFileDialog::getSaveFileName(
this, tr("Save audio"), mainApp->lastOpenDir().absoluteFilePath(""),
this, tr("Save audio"), mainApp->openDialogInitialDir().absoluteFilePath(""),
ext_filter, &sel_filter);
if (file_path->isEmpty()) return save_audio_none;
@ -2471,7 +2471,7 @@ save_payload_t RtpPlayerDialog::selectFilePayloadFormatAndName(QString *file_pat
QString sel_filter;
*file_path = WiresharkFileDialog::getSaveFileName(
this, tr("Save payload"), mainApp->lastOpenDir().absoluteFilePath(""),
this, tr("Save payload"), mainApp->openDialogInitialDir().absoluteFilePath(""),
ext_filter, &sel_filter);
if (file_path->isEmpty()) return save_payload_none;

View File

@ -790,7 +790,7 @@ void RtpStreamDialog::on_actionExportAsRtpDump_triggered()
rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
QString file_name;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString save_file = path.canonicalPath() + "/" + cap_file_.fileBaseName();
QString extension;
file_name = WiresharkFileDialog::getSaveFileName(this, mainApp->windowTitleString(tr("Save RTPDump As…")),

View File

@ -478,7 +478,7 @@ void SCTPGraphDialog::graphClicked(QCPAbstractPlottable* plottable, int, QMouseE
void SCTPGraphDialog::save_graph(QDialog *dlg, QCustomPlot *plot)
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");

View File

@ -434,7 +434,7 @@ void SequenceDialog::on_buttonBox_clicked(QAbstractButton *button)
void SequenceDialog::exportDiagram()
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");

View File

@ -131,7 +131,7 @@ void SSLKeylogDialog::on_browseKeylogPath()
{
QString caption = mainApp->windowTitleString(tr("TLS Keylog"));
QString file_name = WiresharkFileDialog::getSaveFileName(this, caption,
mainApp->lastOpenDir().path());
mainApp->openDialogInitialDir().path());
if (!file_name.isEmpty()) {
ui->keylogLineEdit->setText(file_name);
}

View File

@ -34,7 +34,7 @@
#include "ui/win32/file_dlg_win32.h"
#endif // Q_OS_WIN
#include "ui/last_open_dir.h"
#include "ui/util.h"
#include <wsutil/utf8_entities.h>
#include "wsutil/file_util.h"
@ -549,7 +549,7 @@ void TapParameterDialog::on_actionSaveAs_triggered()
HANDLE da_ctx = set_thread_per_monitor_v2_awareness();
#endif
QFileDialog SaveAsDialog(this, mainApp->windowTitleString(tr("Save Statistics As…")),
get_last_open_dir());
get_open_dialog_initial_dir());
SaveAsDialog.setNameFilter(tr("Plain text file (*.txt);;"
"Comma separated values (*.csv);;"
"XML document (*.xml);;"

View File

@ -1845,7 +1845,7 @@ void TCPStreamDialog::transformYRange(const QCPRange &y_range1)
void TCPStreamDialog::on_buttonBox_accepted()
{
QString file_name, extension;
QDir path(mainApp->lastOpenDir());
QDir path(mainApp->openDialogInitialDir());
QString pdf_filter = tr("Portable Document Format (*.pdf)");
QString png_filter = tr("Portable Network Graphics (*.png)");
QString bmp_filter = tr("Windows Bitmap (*.bmp)");

View File

@ -20,7 +20,7 @@
#include <epan/prefs.h>
#include <ui/recent.h>
#include <ui/last_open_dir.h>
#include <ui/util.h>
#include "ui/ws_ui_util.h"
#include <wsutil/str_util.h>
@ -306,7 +306,7 @@ QString make_filter_based_on_rtpstream_id(QVector<rtpstream_id_t *> stream_ids)
return filter;
}
QString lastOpenDir()
QString openDialogInitialDir()
{
QString result;
@ -319,7 +319,7 @@ QString lastOpenDir()
use the "last opened" directory saved in the preferences file if
there was one. */
/* This is now the default behaviour in file_selection_new() */
result = QString(get_last_open_dir());
result = QString(get_open_dialog_initial_dir());
break;
case FO_STYLE_SPECIFIED:
@ -340,7 +340,8 @@ QString lastOpenDir()
void storeLastDir(QString dir)
{
if (mainApp && dir.length() > 0)
mainApp->setLastOpenDir(qUtf8Printable(dir));
/* XXX - printable? */
if (dir.length() > 0)
set_last_open_dir(qUtf8Printable(dir));
}

View File

@ -268,7 +268,7 @@ QString make_filter_based_on_rtpstream_id(QVector<rtpstream_id_t *> stream_ids);
*
* @return a reference to that directory.
*/
QString lastOpenDir();
QString openDialogInitialDir();
/**
* @brief Store the directory as last directory being used

View File

@ -11,7 +11,7 @@
#include "config.h"
#include "epan/prefs.h"
#include "ui/last_open_dir.h"
#include "ui/util.h"
#include <ui/qt/widgets/path_selection_edit.h>
#include "ui/qt/widgets/wireshark_file_dialog.h"
@ -76,7 +76,7 @@ void PathSelectionEdit::browseForPath()
if (openDir.isEmpty()) {
if (prefs.gui_fileopen_style == FO_STYLE_LAST_OPENED) {
openDir = QString(get_last_open_dir());
openDir = QString(get_open_dialog_initial_dir());
} else if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED) {
openDir = QString(prefs.gui_fileopen_dir);
}

View File

@ -1895,7 +1895,7 @@ void WiresharkMainWindow::exportPacketBytes()
file_name = WiresharkFileDialog::getSaveFileName(this,
mainApp->windowTitleString(tr("Export Selected Packet Bytes")),
mainApp->lastOpenDir().canonicalPath(),
mainApp->openDialogInitialDir().canonicalPath(),
tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD ")")
);
@ -1968,7 +1968,7 @@ void WiresharkMainWindow::exportTLSSessionKeys()
save_title.append(mainApp->windowTitleString(tr("Export TLS Session Keys (%Ln key(s))", "", keylist_len)));
file_name = WiresharkFileDialog::getSaveFileName(this,
save_title,
mainApp->lastOpenDir().canonicalPath(),
mainApp->openDialogInitialDir().canonicalPath(),
tr("TLS Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD ")")
);
if (file_name.length() > 0) {

View File

@ -25,7 +25,7 @@
#include <epan/column.h>
#include <epan/value_string.h>
#include "ui/last_open_dir.h"
#include "ui/util.h"
#include "ui/recent.h"
#include "ui/recent_utils.h"
#include "ui/packet_list_utils.h"

View File

@ -27,6 +27,8 @@
#include "epan/addr_resolv.h"
#include "epan/strutil.h"
#include <wsutil/filesystem.h>
#include "ui/util.h"
/*
@ -338,3 +340,51 @@ gboolean display_is_remote(void)
}
return is_remote;
}
// MUST be UTF-8
static char *last_open_dir = NULL;
const char *
get_last_open_dir(void)
{
return last_open_dir;
}
void
set_last_open_dir(const char *dirname)
{
size_t len;
gchar *new_last_open_dir;
if (dirname && dirname[0]) {
len = strlen(dirname);
if (dirname[len-1] == G_DIR_SEPARATOR) {
new_last_open_dir = g_strconcat(dirname, (char *)NULL);
}
else {
new_last_open_dir = g_strconcat(dirname,
G_DIR_SEPARATOR_S, (char *)NULL);
}
} else {
new_last_open_dir = NULL;
}
g_free(last_open_dir);
last_open_dir = new_last_open_dir;
}
const char *
get_open_dialog_initial_dir(void)
{
const char *initial_dir;
/*
* If we have a "last directory in which a file was opened", use
* that.
*
* If not, use the user's personal data file directory.
*/
initial_dir = get_last_open_dir();
if (initial_dir == NULL)
initial_dir = get_persdatafile_dir();
return initial_dir;
}

View File

@ -44,13 +44,24 @@ const char *get_conn_cfilter(void);
*/
gboolean display_is_remote(void);
/** Set the latest opened directory.
* Will already be done when using file_selection_new().
/** Get the latest directory in which a file has been opened.
*
* @return the dirname
*/
extern const char *get_last_open_dir(void);
/** Set the latest directory in which a file has been opened.
*
* @param dirname the dirname
*/
extern void set_last_open_dir(const char *dirname);
/** Get the initial directory to use in file open dialogs.
*
* @return the dirname
*/
extern const char *get_open_dialog_initial_dir(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -35,7 +35,7 @@
#include "ui/alert_box.h"
#include "ui/help_url.h"
#include "ui/last_open_dir.h"
#include "ui/file_dialog.h"
#include "ui/simple_dialog.h"
#include "ui/util.h"
#include "ui/ws_ui_util.h"
@ -203,7 +203,7 @@ win32_open_file (HWND h_wnd, const wchar_t *title, GString *file_name, unsigned
if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
ofn->lpstrInitialDir = utf_8to16(prefs.gui_fileopen_dir);
} else {
ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
ofn->lpstrInitialDir = utf_8to16(get_open_dialog_initial_dir());
}
ofn->lpstrTitle = title;
ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
@ -276,7 +276,7 @@ win32_save_as_file(HWND h_wnd, const wchar_t *title, capture_file *cf, GString *
ofn->nMaxFile = MAX_PATH;
ofn->lpstrFileTitle = NULL;
ofn->nMaxFileTitle = 0;
ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
ofn->lpstrInitialDir = utf_8to16(get_open_dialog_initial_dir());
ofn->lpstrTitle = title;
ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
@ -357,7 +357,7 @@ win32_export_specified_packets_file(HWND h_wnd, const wchar_t *title,
ofn->nMaxFile = MAX_PATH;
ofn->lpstrFileTitle = NULL;
ofn->nMaxFileTitle = 0;
ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
ofn->lpstrInitialDir = utf_8to16(get_open_dialog_initial_dir());
ofn->lpstrTitle = title;
ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
@ -435,7 +435,7 @@ win32_merge_file (HWND h_wnd, const wchar_t *title, GString *file_name, GString
if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
ofn->lpstrInitialDir = utf_8to16(prefs.gui_fileopen_dir);
} else {
ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
ofn->lpstrInitialDir = utf_8to16(get_open_dialog_initial_dir());
}
ofn->lpstrTitle = title;
ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
@ -498,7 +498,7 @@ win32_export_file(HWND h_wnd, const wchar_t *title, capture_file *cf, export_typ
ofn->nMaxFile = MAX_PATH;
ofn->lpstrFileTitle = NULL;
ofn->nMaxFileTitle = 0;
ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
ofn->lpstrInitialDir = utf_8to16(get_open_dialog_initial_dir());
ofn->lpstrTitle = title;
ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |

View File

@ -2068,19 +2068,21 @@ copy_persconffile_profile(const char *toname, const char *fromname, bool from_gl
* Get the (default) directory in which personal data is stored.
*
* On Win32, this is the "My Documents" folder in the personal profile.
* On UNIX this is simply the current directory.
* On UNIX this is simply the current directory, unless that's "/",
* which it will be, for example, when Wireshark is run from the
* Finder in macOS, in which case we use the user's home directory.
*/
/* XXX - should this and the get_home_dir() be merged? */
extern const char *
get_persdatafile_dir(void)
{
#ifdef _WIN32
TCHAR tszPath[MAX_PATH];
/* Return the cached value, if available */
if (persdatafile_dir != NULL)
return persdatafile_dir;
#ifdef _WIN32
TCHAR tszPath[MAX_PATH];
/*
* Hint: SHGetFolderPath is not available on MSVC 6 - without
* Platform SDK
@ -2092,7 +2094,25 @@ get_persdatafile_dir(void)
return "";
}
#else
return "";
/*
* Get the current directory.
*/
persdatafile_dir = g_get_current_dir();
if (persdatafile_dir == NULL) {
/* XXX - can this fail? */
/*
* g_get_home_dir() returns a const gchar *; g_strdup() it
* so that it's something that can be freed.
*/
persdatafile_dir = g_strdup(g_get_home_dir());
} else if (strcmp(persdatafile_dir, "/") == 0) {
g_free(persdatafile_dir);
/*
* See above.
*/
persdatafile_dir = g_strdup(g_get_home_dir());
}
return persdatafile_dir;
#endif
}