Backport wxFileDialog::AddShortcut() changes to 3.2
This is a backport of #22635 with the following changes: - Don't make the new function virtual to avoid changing ABI. - Use wxABI_VERSION checks around the declarations of the new functions (and also constants, for good measure). - Add new symbol to the linker version script (creating a new section for it). - Document the function as being new in 3.2.1, not 3.3.0. See #22543.
This commit is contained in:
parent
973fc9a897
commit
d013367c24
@ -237,6 +237,7 @@ Changes in behaviour which may result in build errors
|
||||
|
||||
All (GUI):
|
||||
|
||||
- Add wxFileDialog::AddShortcut() (#22543).
|
||||
- Fix grid window scrollbars when freezing part of the grid (#22602).
|
||||
- Avoid warnings with wxStaticText flags in C++20 (David Connet, #22656).
|
||||
- Fix AUI floating pane position when dragging (Konstantin S. Matveyev, #22533).
|
||||
|
@ -56,6 +56,17 @@ enum
|
||||
|
||||
#define wxFD_DEFAULT_STYLE wxFD_OPEN
|
||||
|
||||
#if wxABI_VERSION >= 30201
|
||||
|
||||
// Flags for wxFileDialog::AddShortcut().
|
||||
enum
|
||||
{
|
||||
wxFD_SHORTCUT_TOP = 0x0001,
|
||||
wxFD_SHORTCUT_BOTTOM = 0x0002
|
||||
};
|
||||
|
||||
#endif // wxABI_VERSION >= 3.2.1
|
||||
|
||||
extern WXDLLIMPEXP_DATA_CORE(const char) wxFileDialogNameStr[];
|
||||
extern WXDLLIMPEXP_DATA_CORE(const char) wxFileSelectorPromptStr[];
|
||||
extern WXDLLIMPEXP_DATA_CORE(const char) wxFileSelectorDefaultWildcardStr[];
|
||||
@ -130,6 +141,14 @@ public:
|
||||
{ return m_currentlySelectedFilterIndex; }
|
||||
|
||||
|
||||
#if defined(__WXUNIVERSAL__) || !(defined(__WXMSW__) || defined(__WXGTK20__))
|
||||
#if wxABI_VERSION >= 30201
|
||||
// Add a shortcut to the given directory in the sidebar containing such
|
||||
// shortcuts if supported.
|
||||
bool AddShortcut(const wxString& directory, int flags = 0);
|
||||
#endif // wxABI_VERSION >= 3.2.1
|
||||
#endif // Platforms without native implementation.
|
||||
|
||||
// A customize hook methods will be called by wxFileDialog later if this
|
||||
// function returns true, see its documentation for details.
|
||||
//
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
|
||||
virtual int ShowModal() wxOVERRIDE;
|
||||
|
||||
#if wxABI_VERSION >= 30201
|
||||
bool AddShortcut(const wxString& directory, int flags = 0);
|
||||
#endif // wxABI_VERSION >= 3.2.1
|
||||
virtual bool SupportsExtraControl() const wxOVERRIDE { return true; }
|
||||
|
||||
// Implementation only.
|
||||
|
@ -33,6 +33,9 @@ public:
|
||||
|
||||
virtual void GetPaths(wxArrayString& paths) const wxOVERRIDE;
|
||||
virtual void GetFilenames(wxArrayString& files) const wxOVERRIDE;
|
||||
#if wxABI_VERSION >= 30201
|
||||
bool AddShortcut(const wxString& directory, int flags = 0);
|
||||
#endif // wxABI_VERSION >= 3.2.1
|
||||
virtual bool SupportsExtraControl() const wxOVERRIDE { return true; }
|
||||
|
||||
virtual int ShowModal() wxOVERRIDE;
|
||||
|
@ -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,
|
||||
@ -73,6 +76,9 @@ private:
|
||||
wxCOMPtr<IFileDialog> m_fileDialog;
|
||||
};
|
||||
|
||||
// Initialize an IShellItem object with the given path.
|
||||
HRESULT InitShellItemFromPath(wxCOMPtr<IShellItem>& item, const wxString& path);
|
||||
|
||||
// Extract the filesystem path corresponding to the given shell item.
|
||||
HRESULT GetFSPathFromShellItem(const wxCOMPtr<IShellItem>& item, wxString& path);
|
||||
|
||||
|
@ -232,6 +232,46 @@ public:
|
||||
*/
|
||||
virtual ~wxFileDialog();
|
||||
|
||||
/**
|
||||
Add a directory to the list of shortcuts shown in the dialog.
|
||||
|
||||
File dialogs on many platforms display a fixed list of directories
|
||||
which can be easily selected by the user. This function allows to add
|
||||
an application-defined directory to this list, which can be convenient
|
||||
for the programs that use specific directories for their files instead
|
||||
of the default user document directory (see wxStandardPaths).
|
||||
|
||||
Currently this function is only implemented in wxMSW and wxGTK and does
|
||||
nothing under the other platforms. Moreover, in wxMSW this function is
|
||||
incompatible with the use of SetExtraControlCreator(), if you need to
|
||||
use this function and customize the dialog contents, please use the
|
||||
newer SetCustomizeHook() instead.
|
||||
|
||||
The @ref page_samples_dialogs "dialogs sample" shows the use of this
|
||||
function by adding two custom shortcuts corresponding to the
|
||||
subdirectories of @c WXWIN environment variable if it is defined.
|
||||
|
||||
@note In wxMSW, the shortcuts appear in a separate section called
|
||||
"Application Links" by default. To change the title of this
|
||||
section, the application can specify a value of the @c
|
||||
FileDescription field of the version information structure in its
|
||||
resource file -- if present, this string will be used as the
|
||||
section title.
|
||||
|
||||
@param directory The full path to the directory, which should exist.
|
||||
@param flags Can be set to @c wxFD_SHORTCUT_BOTTOM (which is also the
|
||||
default behaviour) to add the shortcut after the existing ones,
|
||||
or @c wxFD_SHORTCUT_TOP to add it before them. Support for the
|
||||
latter flag is only available in wxMSW, in wxGTK the shortcuts are
|
||||
always added to the bottom of the list.
|
||||
@return @true on success or @false if shortcut couldn't be added, e.g.
|
||||
because this functionality is not available on the current
|
||||
platform.
|
||||
|
||||
@since 3.2.1
|
||||
*/
|
||||
bool AddShortcut(const wxString& directory, int flags = 0);
|
||||
|
||||
/**
|
||||
Returns the path of the file currently selected in dialog.
|
||||
|
||||
|
@ -1824,6 +1824,18 @@ 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");
|
||||
|
||||
// By default shortcuts are added at the bottom, but we can override
|
||||
// this in the ports that support it (currently only wxMSW) and add a
|
||||
// shortcut added later at the top instead.
|
||||
dialog.AddShortcut(wxdir + "/include", wxFD_SHORTCUT_TOP);
|
||||
}
|
||||
|
||||
// Note: this object must remain alive until ShowModal() returns.
|
||||
MyCustomizeHook myCustomizer(dialog);
|
||||
|
||||
|
@ -851,6 +851,17 @@ wxString wxFileDialogBase::AppendExtension(const wxString &filePath,
|
||||
return filePath + ext;
|
||||
}
|
||||
|
||||
#if defined(__WXUNIVERSAL__) || !(defined(__WXMSW__) || defined(__WXGTK20__))
|
||||
|
||||
bool wxFileDialogBase::AddShortcut(const wxString& WXUNUSED(directory),
|
||||
int WXUNUSED(flags))
|
||||
{
|
||||
// Not implemented by default.
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // Platforms without native implementation.
|
||||
|
||||
bool wxFileDialogBase::SetCustomizeHook(wxFileDialogCustomizeHook& customizeHook)
|
||||
{
|
||||
if ( !SupportsExtraControl() )
|
||||
|
@ -20,6 +20,7 @@
|
||||
#endif
|
||||
|
||||
#include "wx/gtk/private.h"
|
||||
#include "wx/gtk/private/error.h"
|
||||
#include "wx/gtk/private/mnemonics.h"
|
||||
|
||||
#ifdef __UNIX__
|
||||
@ -499,4 +500,21 @@ void wxFileDialog::GTKSelectionChanged(const wxString& filename)
|
||||
UpdateExtraControlUI();
|
||||
}
|
||||
|
||||
bool wxFileDialog::AddShortcut(const wxString& directory, int WXUNUSED(flags))
|
||||
{
|
||||
wxGtkError error;
|
||||
|
||||
if ( !gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(m_widget),
|
||||
directory.utf8_str(),
|
||||
error.Out()) )
|
||||
{
|
||||
wxLogDebug("Failed to add shortcut \"%s\": %s",
|
||||
directory, error.GetMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // wxUSE_FILEDLG
|
||||
|
@ -352,7 +352,7 @@ void wxIFileDialog::SetTitle(const wxString& message)
|
||||
}
|
||||
}
|
||||
|
||||
void wxIFileDialog::SetInitialPath(const wxString& defaultPath)
|
||||
HRESULT InitShellItemFromPath(wxCOMPtr<IShellItem>& item, const wxString& path)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
@ -383,20 +383,52 @@ void wxIFileDialog::SetInitialPath(const wxString& defaultPath)
|
||||
if ( !s_pfnSHCreateItemFromParsingName )
|
||||
{
|
||||
// There is nothing we can do and the error was already reported.
|
||||
return;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// SHCreateItemFromParsingName() doesn't support slashes, so if the path
|
||||
// uses them, replace them with the backslashes.
|
||||
wxString pathBS;
|
||||
const wxString* pathWithoutSlashes;
|
||||
if ( path.find('/') != wxString::npos )
|
||||
{
|
||||
pathBS = path;
|
||||
pathBS.Replace("/", "\\", true);
|
||||
|
||||
pathWithoutSlashes = &pathBS;
|
||||
}
|
||||
else // Just use the original path without copying.
|
||||
{
|
||||
pathWithoutSlashes = &path;
|
||||
}
|
||||
|
||||
wxCOMPtr<IShellItem> folder;
|
||||
hr = s_pfnSHCreateItemFromParsingName
|
||||
(
|
||||
defaultPath.wc_str(),
|
||||
pathWithoutSlashes->wc_str(),
|
||||
NULL,
|
||||
wxIID_PPV_ARGS(IShellItem, &folder)
|
||||
wxIID_PPV_ARGS(IShellItem, &item)
|
||||
);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError
|
||||
(
|
||||
wxString::Format(wxS("SHCreateItemFromParsingName(\"%s\")"),
|
||||
*pathWithoutSlashes),
|
||||
hr
|
||||
);
|
||||
}
|
||||
|
||||
// Failing to parse the folder name or set it is not really an error,
|
||||
// we'll just ignore the initial directory in this case, but we should
|
||||
// still show the dialog.
|
||||
return hr;
|
||||
}
|
||||
|
||||
void wxIFileDialog::SetInitialPath(const wxString& defaultPath)
|
||||
{
|
||||
wxCOMPtr<IShellItem> folder;
|
||||
|
||||
HRESULT hr = InitShellItemFromPath(folder, defaultPath);
|
||||
|
||||
// Failing to parse the folder name is not really an error, e.g. it might
|
||||
// not exist, so we'll just ignore the initial directory in this case.
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = m_fileDialog->SetFolder(folder);
|
||||
@ -405,6 +437,27 @@ void wxIFileDialog::SetInitialPath(const wxString& defaultPath)
|
||||
}
|
||||
}
|
||||
|
||||
void wxIFileDialog::AddPlace(const wxString& path, FDAP fdap)
|
||||
{
|
||||
wxCOMPtr<IShellItem> 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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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<ShortcutData> 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<wxFileDialogMSWData::ShortcutData>::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
|
||||
|
@ -12,7 +12,9 @@
|
||||
#
|
||||
# # public symbols added in release @WX_VERSION_TAG@.2 (please keep in alphabetical order):
|
||||
# @WX_VERSION_TAG@.2 {
|
||||
# *wxChoice*GetCurrentSelection*;
|
||||
# extern "C++"
|
||||
# "wxChoice::GetCurrentSelection()";
|
||||
# };
|
||||
# };
|
||||
#
|
||||
# If a symbols should have been added in this way, but is forgotten then it
|
||||
@ -21,6 +23,13 @@
|
||||
# and once released its version cannot be changed.
|
||||
|
||||
|
||||
# public symbols added in 3.2.1 (please keep in alphabetical order):
|
||||
@WX_VERSION_TAG@.1 {
|
||||
extern "C++" {
|
||||
"wxFileDialog::AddShortcut(const wxString&, int)";
|
||||
};
|
||||
};
|
||||
|
||||
# symbols available since the beginning of this branch are only given
|
||||
# generic branch tag (don't remove this!):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user