Skip to content

Commit

Permalink
Merge branch 'dirdialog-multi-hidden'
Browse files Browse the repository at this point in the history
Add wxDD_MULTIPLE and wxDD_SHOW_HIDDEN support to wxDirDialog.

See #1884

Closes #18736.
  • Loading branch information
vadz committed Jul 11, 2020
2 parents 617db49 + a47fd95 commit 0918ab6
Show file tree
Hide file tree
Showing 10 changed files with 365 additions and 183 deletions.
27 changes: 26 additions & 1 deletion include/wx/dirdlg.h
Expand Up @@ -25,8 +25,22 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxDirDialogNameStr[];
extern WXDLLIMPEXP_DATA_CORE(const char) wxDirDialogDefaultFolderStr[];
extern WXDLLIMPEXP_DATA_CORE(const char) wxDirSelectorPromptStr[];


/*
The flags below must coexist with the following flags in m_windowStyle
#define wxCAPTION 0x20000000
#define wxMAXIMIZE 0x00002000
#define wxCLOSE_BOX 0x00001000
#define wxSYSTEM_MENU 0x00000800
wxBORDER_NONE = 0x00200000
#define wxRESIZE_BORDER 0x00000040
#define wxDIALOG_NO_PARENT 0x00000020
*/

#define wxDD_CHANGE_DIR 0x0100
#define wxDD_DIR_MUST_EXIST 0x0200
#define wxDD_MULTIPLE 0x0400
#define wxDD_SHOW_HIDDEN 0x0001

// deprecated, on by default now, use wxDD_DIR_MUST_EXIST to disable it
#define wxDD_NEW_DIR_BUTTON 0
Expand Down Expand Up @@ -74,11 +88,22 @@ class WXDLLIMPEXP_CORE wxDirDialogBase : public wxDialog
virtual void SetPath(const wxString& path) { m_path = path; }

virtual wxString GetMessage() const { return m_message; }
virtual wxString GetPath() const { return m_path; }
virtual wxString GetPath() const
{
wxCHECK_MSG( !HasFlag(wxDD_MULTIPLE), wxString(),
"When using wxDD_MULTIPLE, must call GetPaths() instead" );
return m_path;
}

virtual void GetPaths(wxArrayString& paths) const
{
paths = m_paths;
}

protected:
wxString m_message;
wxString m_path;
wxArrayString m_paths;
};


Expand Down
3 changes: 0 additions & 3 deletions include/wx/gtk/dirdlg.h
Expand Up @@ -37,7 +37,6 @@ class WXDLLIMPEXP_CORE wxDirDialog : public wxDirDialogBase

public: // overrides from wxGenericDirDialog

wxString GetPath() const wxOVERRIDE;
void SetPath(const wxString& path) wxOVERRIDE;


Expand All @@ -55,8 +54,6 @@ class WXDLLIMPEXP_CORE wxDirDialog : public wxDirDialogBase


private:
wxString m_selectedDirectory;

wxDECLARE_DYNAMIC_CLASS(wxDirDialog);
};

Expand Down
2 changes: 1 addition & 1 deletion include/wx/msw/dirdlg.h
Expand Up @@ -30,7 +30,7 @@ class WXDLLIMPEXP_CORE wxDirDialog : public wxDirDialogBase
// The real implementations of ShowModal(), used for Windows versions
// before and since Vista.
int ShowSHBrowseForFolder(WXHWND owner);
int ShowIFileDialog(WXHWND owner);
int ShowIFileOpenDialog(WXHWND owner);

wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDirDialog);
};
Expand Down
6 changes: 6 additions & 0 deletions include/wx/osx/dirdlg.h
Expand Up @@ -47,6 +47,10 @@ class WXDLLIMPEXP_CORE wxDirDialog : public wxDirDialogBase

virtual int ShowModal() wxOVERRIDE;

// MacOS 10.11 has removed the titlebar from the dialog, so this is provided
// only for compatibility with older versions
virtual void SetTitle(const wxString& title) wxOVERRIDE;

#if wxOSX_USE_COCOA
virtual void ShowWindowModal() wxOVERRIDE;
virtual void ModalFinishedCallback(void* panel, int returnCode) wxOVERRIDE;
Expand All @@ -64,6 +68,8 @@ class WXDLLIMPEXP_CORE wxDirDialog : public wxDirDialogBase
// Common part of all ctors.
void Init();

wxString m_title;

wxDECLARE_DYNAMIC_CLASS(wxDirDialog);
};

Expand Down
29 changes: 29 additions & 0 deletions interface/wx/dirdlg.h
Expand Up @@ -5,8 +5,12 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////


#define wxDD_CHANGE_DIR 0x0100
#define wxDD_DIR_MUST_EXIST 0x0200
#define wxDD_MULTIPLE 0x0400
#define wxDD_SHOW_HIDDEN 0x0001

#define wxDD_NEW_DIR_BUTTON 0 // deprecated, on by default now,

#define wxDD_DEFAULT_STYLE (wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
Expand Down Expand Up @@ -43,6 +47,13 @@ const char wxDirDialogNameStr[] = "wxDirCtrl";
@style{wxDD_CHANGE_DIR}
Change the current working directory to the directory chosen by the
user.
@note This flag cannot be used with the @c wxDD_MULTIPLE style.
@style{wxDD_MULTIPLE}
Allow the user to select multiple directories.
This flag is only available since wxWidgets 3.1.4
@style{wxDD_SHOW_HIDDEN}
Show hidden and system folders.
This flag is only available since wxWidgets 3.1.4
@endStyleTable
Notice that @c wxRESIZE_BORDER has special side effect under Windows
Expand All @@ -60,6 +71,11 @@ const char wxDirDialogNameStr[] = "wxDirCtrl";
@endcode
instead of just using @c wxDD_DIR_MUST_EXIST style alone.
@remarks MacOS 10.11+ does not display a title bar on the dialog. Use SetMessage()
to change the string displayed to the user at the top of the dialog after creation.
The SetTitle() method is provided for compatibility with pre-10.11 MacOS versions
that do still support displaying the title bar.
@library{wxcore}
@category{cmndlg}
Expand Down Expand Up @@ -106,9 +122,22 @@ class wxDirDialog : public wxDialog

/**
Returns the default or user-selected path.
@note This function can't be used with dialogs which have the @c wxDD_MULTIPLE style,
use GetPaths() instead.
*/
virtual wxString GetPath() const;

/**
Fills the array @a paths with the full paths of the chosen directories.
@note This function should only be used with the dialogs which have @c wxDD_MULTIPLE style,
use GetPath() for the others.
@since 3.1.4
*/
virtual void GetPaths(wxArrayString& paths) const;

/**
Sets the message that will be displayed on the dialog.
*/
Expand Down
32 changes: 32 additions & 0 deletions samples/dialogs/dialogs.cpp
Expand Up @@ -202,6 +202,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
#if wxUSE_DIRDLG
EVT_MENU(DIALOGS_DIR_CHOOSE, MyFrame::DirChoose)
EVT_MENU(DIALOGS_DIRNEW_CHOOSE, MyFrame::DirChooseNew)
EVT_MENU(DIALOGS_DIRMULTIPLE_CHOOSE, MyFrame::DirChooseMultiple)
#endif // wxUSE_DIRDLG

#if USE_MODAL_PRESENTATION
Expand Down Expand Up @@ -488,6 +489,7 @@ bool MyApp::OnInit()

dir_menu->Append(DIALOGS_DIR_CHOOSE, "&Choose a directory\tCtrl-D");
dir_menu->Append(DIALOGS_DIRNEW_CHOOSE, "Choose a directory (with \"Ne&w\" button)\tShift-Ctrl-D");
dir_menu->Append(DIALOGS_DIRMULTIPLE_CHOOSE, "Choose multiple and hidden directories\tAlt-Ctrl-D");
menuDlg->Append(wxID_ANY,"&Directory operations",dir_menu);

#if USE_DIRDLG_GENERIC
Expand Down Expand Up @@ -1803,6 +1805,36 @@ void MyFrame::DirChooseNew(wxCommandEvent& WXUNUSED(event) )
{
DoDirChoose(wxDD_DEFAULT_STYLE & ~wxDD_DIR_MUST_EXIST);
}

void MyFrame::DirChooseMultiple(wxCommandEvent& WXUNUSED(event))
{
// pass some initial dir and the style to wxDirDialog
int style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST | wxDD_MULTIPLE | wxDD_SHOW_HIDDEN;
wxString dirHome;
wxGetHomeDir(&dirHome);

wxDirDialog dialog(this, "Testing multiple directory picker", dirHome, style);

if ( dialog.ShowModal() == wxID_OK )
{
wxArrayString paths;

dialog.GetPaths(paths);

wxString msg, s;
size_t count = paths.GetCount();
for ( size_t n = 0; n < count; n++ )
{
s.Printf("Directory %d: %s\n",
(int)n, paths[n]);

msg += s;
}

wxMessageDialog dialog2(this, msg, "Selected directories");
dialog2.ShowModal();
}
}
#endif // wxUSE_DIRDLG

#if USE_DIRDLG_GENERIC
Expand Down
2 changes: 2 additions & 0 deletions samples/dialogs/dialogs.h
Expand Up @@ -434,6 +434,7 @@ class MyFrame: public wxFrame
#if wxUSE_DIRDLG
void DirChoose(wxCommandEvent& event);
void DirChooseNew(wxCommandEvent& event);
void DirChooseMultiple(wxCommandEvent& event);
#endif // wxUSE_DIRDLG

#if USE_DIRDLG_GENERIC
Expand Down Expand Up @@ -594,6 +595,7 @@ enum
DIALOGS_FILE_SAVE_GENERIC,
DIALOGS_DIR_CHOOSE,
DIALOGS_DIRNEW_CHOOSE,
DIALOGS_DIRMULTIPLE_CHOOSE,
DIALOGS_GENERIC_DIR_CHOOSE,
DIALOGS_TIP,
DIALOGS_NUM_ENTRY,
Expand Down
40 changes: 31 additions & 9 deletions src/gtk/dirdlg.cpp
Expand Up @@ -71,6 +71,9 @@ bool wxDirDialog::Create(wxWindow* parent,
{
m_message = title;

wxASSERT_MSG( !( (style & wxDD_MULTIPLE) && (style & wxDD_CHANGE_DIR) ),
"wxDD_CHANGE_DIR can't be used together with wxDD_MULTIPLE" );

parent = GetParentForModalDialog(parent, style);

if (!PreCreation(parent, pos, wxDefaultSize) ||
Expand Down Expand Up @@ -110,10 +113,18 @@ bool wxDirDialog::Create(wxWindow* parent,
if (wx_is_at_least_gtk2(18))
{
gtk_file_chooser_set_create_folders(
GTK_FILE_CHOOSER(m_widget), (style & wxDD_DIR_MUST_EXIST) == 0);
GTK_FILE_CHOOSER(m_widget), !HasFlag(wxDD_DIR_MUST_EXIST) );
}
#endif

// Enable multiple selection if desired
gtk_file_chooser_set_select_multiple(
GTK_FILE_CHOOSER(m_widget), HasFlag(wxDD_MULTIPLE) );

// Enable show hidden folders if desired
gtk_file_chooser_set_show_hidden(
GTK_FILE_CHOOSER(m_widget), HasFlag(wxDD_SHOW_HIDDEN) );

// local-only property could be set to false to allow non-local files to be loaded.
// In that case get/set_uri(s) should be used instead of get/set_filename(s) everywhere
// and the GtkFileChooserDialog should probably also be created with a backend,
Expand All @@ -132,13 +143,29 @@ bool wxDirDialog::Create(wxWindow* parent,

void wxDirDialog::GTKOnAccept()
{
wxGtkString str(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(m_widget)));
m_selectedDirectory = wxString::FromUTF8(str);
GSList *fnamesi = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(m_widget));
GSList *fnames = fnamesi;

while ( fnamesi )
{
wxString dir(wxString::FromUTF8(static_cast<gchar *>(fnamesi->data)));
m_paths.Add(dir);

g_free(fnamesi->data);
fnamesi = fnamesi->next;
}

g_slist_free(fnames);

// change to the directory where the user went if asked
if (HasFlag(wxDD_CHANGE_DIR))
{
wxSetWorkingDirectory(m_selectedDirectory);
wxSetWorkingDirectory(m_paths.Last());
}

if (!HasFlag(wxDD_MULTIPLE))
{
m_path = m_paths.Last();
}

EndDialog(wxID_OK);
Expand Down Expand Up @@ -166,9 +193,4 @@ void wxDirDialog::SetPath(const wxString& dir)
}
}

wxString wxDirDialog::GetPath() const
{
return m_selectedDirectory;
}

#endif // wxUSE_DIRDLG

4 comments on commit 0918ab6

@PBfordev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vadz, I noticed that this was not added to changes.txt, while wxFD_SHOW_HIDDEN was back then.

Was this intentional, I remember something that the changes are not tracked with changes.txt but some other way now?

@vadz
Copy link
Contributor Author

@vadz vadz commented on 0918ab6 Jul 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PBfordev yes, this was intentional, as the change log entries are now stored in git notes until the release (it's explained in the 3.1.4 section of docs/changes.txt itself). However thanks for reminding me because I forgot to add a note for this -- done now, thanks again.

@PBfordev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for the quick reply.

@imciner2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I only added the breaking changes to the changes.txt file, so the assertion on the use of GetPath on multiple selection styles is noted in the breaking changes document.

Please sign in to comment.