Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set a default filter in file dialogs #264

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion native-windows-gui/examples/image_decoder_d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct ImageDecoderApp {
#[nwg_resource]
decoder: nwg::ImageDecoder,

#[nwg_resource(title: "Open File", action: nwg::FileDialogAction::Open, filters: "Png(*.png)|Jpeg(*.jpg;*.jpeg)|DDS(*.dds)|TIFF(*.tiff)|BMP(*.bmp)|Any (*.*)")]
#[nwg_resource(title: "Open File", action: nwg::FileDialogAction::Open, filters: "Png(*.png)|Jpeg(*.jpg;*.jpeg)|DDS(*.dds)|TIFF(*.tiff)|BMP(*.bmp)|>Any (*.*)")]
dialog: nwg::FileDialog,

#[nwg_control(text: "Open", focus: true)]
Expand Down
6 changes: 4 additions & 2 deletions native-windows-gui/src/resources/file_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ pub enum FileDialogAction {
* multiselect: Whether the user can select more than one file. Only supported with the Open action
* default_folder: Default folder to show in the dialog.
* filters: If defined, filter the files that the user can select (In a Open dialog) or which extension to add to the saved file (in a Save dialog)
The `filters` value must be a '|' separated string having this format: "Test(*.txt;*.rs)|Any(*.*)"
The `filters` value must be a '|' separated string having this format: "Test(*.txt;*.rs)|Any(*.*)".
If one of the filters has its name prefixed with '>' (like ">Test"), it will become the default filter.

```rust
use native_windows_gui as nwg;
Expand Down Expand Up @@ -168,7 +169,8 @@ impl FileDialog {
This can only be set ONCE (the initialization counts) and won't work if the dialog is `OpenDirectory`.

The `filters` value must be a '|' separated string having this format: "Test(*.txt;*.rs)|Any(*.*)"
Where the fist part is the "human name" and the second part is a filter for the system.
Where the first part is the "human name" and the second part is a filter for the system. If the
human name starts with a '>', the '>' is removed and the filter associated with it becomes the default.
*/
pub fn set_filters<'a>(&self, filters: &'a str) -> Result<(), NwgError> {
unsafe{
Expand Down
21 changes: 19 additions & 2 deletions native-windows-gui/src/win32/resources_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ pub unsafe fn create_file_dialog<'a, 'b>(
match &filters {
&Some(ref f) => match file_dialog_set_filters(file_dialog, f) {
Ok(_) => (),
Err(e) => { println!("set filters"); file_dialog.Release(); return Err(e); }
Err(e) => { file_dialog.Release(); return Err(e); }
},
&None => ()
}
Expand Down Expand Up @@ -456,8 +456,16 @@ pub unsafe fn file_dialog_set_filters<'a>(dialog: &mut IFileDialog, filters: &'a

let mut raw_filters: Vec<COMDLG_FILTERSPEC> = Vec::with_capacity(3);
let mut keep_alive: Vec<(Vec<u16>, Vec<u16>)> = Vec::with_capacity(3);
let mut default_filter = None;

for f in filters.split('|') {
let f = if f.starts_with('>') {
default_filter = Some(raw_filters.len());
f.split_at(1).1
} else {
f
};

let end = f.rfind('(');
if end.is_none() {
let err = format!("Bad extension filter format: {:?}", filters);
Expand All @@ -473,7 +481,16 @@ pub unsafe fn file_dialog_set_filters<'a>(dialog: &mut IFileDialog, filters: &'a

let filters_count = raw_filters.len() as UINT;
if dialog.SetFileTypes(filters_count, raw_filters.as_ptr()) == S_OK {
Ok(())
if let Some(i) = default_filter {
if dialog.SetFileTypeIndex((i + 1) as u32) == S_OK {
Ok(())
} else {
let err = format!("Failed to set the default filter using {:?}", filters);
return Err(NwgError::file_dialog(&err))
}
} else {
Ok(())
}
} else {
let err = format!("Failed to set the filters using {:?}", filters);
return Err(NwgError::file_dialog(&err));
Expand Down