From 5d3ebf94573e23308a68bae0d476021d52a62755 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 17 Jul 2022 19:23:47 +0100 Subject: [PATCH] Add wxFileDialog::AddShortcut() This allows to add application-specific directories to the file dialog. This commit only contains the implementation for wxMSW and a change showing the new function in the sample. --- include/wx/filedlg.h | 12 +++++++ include/wx/msw/filedlg.h | 1 + include/wx/msw/private/filedialog.h | 3 ++ samples/dialogs/dialogs.cpp | 8 +++++ src/common/fldlgcmn.cpp | 7 ++++ src/msw/dirdlg.cpp | 21 ++++++++++++ src/msw/filedlg.cpp | 53 +++++++++++++++++++++++++++++ 7 files changed, 105 insertions(+) diff --git a/include/wx/filedlg.h b/include/wx/filedlg.h index 06b0259395..318f08bc10 100644 --- a/include/wx/filedlg.h +++ b/include/wx/filedlg.h @@ -56,6 +56,13 @@ enum #define wxFD_DEFAULT_STYLE wxFD_OPEN +// Flags for wxFileDialog::AddShortcut(). +enum +{ + wxFD_SHORTCUT_TOP = 0x0001, + wxFD_SHORTCUT_BOTTOM = 0x0002 +}; + extern WXDLLIMPEXP_DATA_CORE(const char) wxFileDialogNameStr[]; extern WXDLLIMPEXP_DATA_CORE(const char) wxFileSelectorPromptStr[]; extern WXDLLIMPEXP_DATA_CORE(const char) wxFileSelectorDefaultWildcardStr[]; @@ -130,6 +137,11 @@ public: { return m_currentlySelectedFilterIndex; } + // Add a shortcut to the given directory in the sidebar containing such + // shortcuts if supported. + virtual bool AddShortcut(const wxString& directory, int flags = 0); + + // A customize hook methods will be called by wxFileDialog later if this // function returns true, see its documentation for details. // diff --git a/include/wx/msw/filedlg.h b/include/wx/msw/filedlg.h index 8eadbcebd0..b3f798c2b5 100644 --- a/include/wx/msw/filedlg.h +++ b/include/wx/msw/filedlg.h @@ -33,6 +33,7 @@ public: virtual void GetPaths(wxArrayString& paths) const wxOVERRIDE; virtual void GetFilenames(wxArrayString& files) const wxOVERRIDE; + virtual bool AddShortcut(const wxString& directory, int flags = 0) wxOVERRIDE; virtual bool SupportsExtraControl() const wxOVERRIDE { return true; } virtual int ShowModal() wxOVERRIDE; diff --git a/include/wx/msw/private/filedialog.h b/include/wx/msw/private/filedialog.h index d8ed352ebb..72f48a5134 100644 --- a/include/wx/msw/private/filedialog.h +++ b/include/wx/msw/private/filedialog.h @@ -55,6 +55,9 @@ public: // Set the initial path to show in the dialog. void SetInitialPath(const wxString& path); + // Add a shortcut. + void AddPlace(const wxString& path, FDAP fdap); + // Show the file dialog with the given parent window and options. // // Returns the selected path, or paths, in the provided output parameters, diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 581f9428d3..a723414063 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -1824,6 +1824,14 @@ void MyFrame::FileOpen(wxCommandEvent& WXUNUSED(event) ) ) ); + // For demonstration purposes, add wxWidgets directories to the sidebar. + wxString wxdir; + if ( wxGetEnv("WXWIN", &wxdir) ) + { + dialog.AddShortcut(wxdir + "/src", wxFD_SHORTCUT_BOTTOM); + dialog.AddShortcut(wxdir + "/include", wxFD_SHORTCUT_TOP); + } + // Note: this object must remain alive until ShowModal() returns. MyCustomizeHook myCustomizer(dialog); diff --git a/src/common/fldlgcmn.cpp b/src/common/fldlgcmn.cpp index 173d993dc1..8969b54942 100644 --- a/src/common/fldlgcmn.cpp +++ b/src/common/fldlgcmn.cpp @@ -851,6 +851,13 @@ wxString wxFileDialogBase::AppendExtension(const wxString &filePath, return filePath + ext; } +bool wxFileDialogBase::AddShortcut(const wxString& WXUNUSED(directory), + int WXUNUSED(flags)) +{ + // Not implemented by default. + return false; +} + bool wxFileDialogBase::SetCustomizeHook(wxFileDialogCustomizeHook& customizeHook) { if ( !SupportsExtraControl() ) diff --git a/src/msw/dirdlg.cpp b/src/msw/dirdlg.cpp index 3b7064b517..e307b9160b 100644 --- a/src/msw/dirdlg.cpp +++ b/src/msw/dirdlg.cpp @@ -437,6 +437,27 @@ void wxIFileDialog::SetInitialPath(const wxString& defaultPath) } } +void wxIFileDialog::AddPlace(const wxString& path, FDAP fdap) +{ + wxCOMPtr place; + + HRESULT hr = InitShellItemFromPath(place, path); + + // Don't bother with doing anything else if we couldn't parse the path + // (debug message about failing to do it was already logged). + if ( FAILED(hr) ) + return; + + hr = m_fileDialog->AddPlace(place, fdap); + if ( FAILED(hr) ) + { + wxLogApiError + ( + wxString::Format(wxS("IFileDialog::AddPlace(\"%s\")"), path), hr + ); + } +} + } // namespace wxMSWImpl // ---------------------------------------------------------------------------- diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index b0c2c900a9..446979523e 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -714,6 +714,20 @@ public: #if wxUSE_IFILEOPENDIALOG + // Store the extra shortcut directories and their flags. + struct ShortcutData + { + ShortcutData(const wxString& path_, int flags_) + : path(path_), flags(flags_) + { + } + + wxString path; + int flags; + }; + wxVector m_customShortcuts; + + // IUnknown wxSTDMETHODIMP QueryInterface(REFIID iid, void** ppv) @@ -1181,6 +1195,28 @@ void wxFileDialog::MSWOnInitDialogHook(WXHWND hwnd) CreateExtraControl(); } +bool wxFileDialog::AddShortcut(const wxString& directory, int flags) +{ +#if wxUSE_IFILEOPENDIALOG + if ( !HasExtraControlCreator() ) + { + MSWData().m_customShortcuts.push_back( + wxFileDialogMSWData::ShortcutData(directory, flags) + ); + + return true; + } + else + { + // It could be surprising if AddShortcut() silently didn't work, so + // warn the developer about this incompatibility. + wxFAIL_MSG("Can't use both AddShortcut() and SetExtraControlCreator()"); + } +#endif // wxUSE_IFILEOPENDIALOG + + return false; +} + int wxFileDialog::ShowModal() { WX_HOOK_MODAL_DIALOG(); @@ -1576,6 +1612,23 @@ int wxFileDialog::ShowIFileDialog(WXHWND hWndParent) } + for ( wxVector::const_iterator + it = data.m_customShortcuts.begin(); + it != data.m_customShortcuts.end(); + ++it ) + { + FDAP fdap = FDAP_BOTTOM; + if ( it->flags & wxFD_SHORTCUT_TOP ) + { + wxASSERT_MSG( !(it->flags & wxFD_SHORTCUT_BOTTOM), + wxS("Can't use both wxFD_SHORTCUT_TOP and BOTTOM") ); + + fdap = FDAP_TOP; + } + + fileDialog.AddPlace(it->path, fdap); + } + // We never set the following flags currently: // // - FOS_STRICTFILETYPES