Savepanel - file formats?
-
that would be nice
-
I see no difference in the two methods.. meaning you can use either for browsing for a filename, and it does not matter whether you will be saving nor opening a file.
The method just returns a pathstring IF the user choses a file.On Windows... the file type works correctly if you DO NOT specify a path, and only a "*.ext" as the 2nd argument. Windows will go into the MRU keys in the user's registry hive to get the LAST path where the file of the specified extension was opened/written.
This means only one file extension works.
I do not know what happens on OSX.
-
I'm trying with this
path_to_save_to = UI.savepanel("Save image", ENV["HOME"], "JPG|.jpg|PNG|.png|TIFF|.tif;|GIF|.gif||")
But I can't get the ext..... path_to_save_to contains only the string user input..... Dan Rathbun it's a bug?
-
Tour
path_to_save_to
is the full path to the new file-name
e.g.'C:\Users\TIG\xxx.png'
From that you can parse the file-name:
file_name = File.basename(path_to_save_to)
'
xxx.png
'
You can parse the file-type with:
file_type = File.extname(path_to_save_to)
'.png
'
The user must specify the file-type in the string that they enter, if they don't then you need a fall-back position - either aUI.messagebox
telling them to do so and reopening theUI.savepanel
OR simply assuming it's '.jpg' and appending that to the path -if file_type.empty? || file_type.downcase!='.jpg' || file_type.downcase!='.png' || file_type.downcase!='.gif' || file_type.downcase!='.tif' ||
The final argument for
UI.savepanel
is NOT afile_type
list [that'sUI.opnepanel
's, it's the defaultfile_name
.
So offer 'xxx.jpg
' and then compare the result.Another way would be to get the user to enter a file_name/file_type in an earlier dialog of your own creation, and use that in the
UI.savepanel
so they are then just choosing a folder... OR if you are using a newer SketchUp [>=v2015], first get the file_name/file_type in your own dialog and then useUI.select_directory
to get its destination folder... -
But what's the use of giving a default set of file_types with
UI.savepanel
- they are ignored and NO default name appears at all.
Passing a 'filter' doesn't work anyway, as then entering "xxx
" - with no file_type - it accepts it as being valid.
At least if you pass a file_name, them it'll be displayed, and you are more likely to change the name and retain the file_type...I just retested it [v2016] and if you give the default file_name as ".png" that is is displayed, but it is also accepted when NOT prefixed with a name [plain silly], you cannot offer multiple file_type choices [unlike
UI.openpanel
] - as the "|" is not a valid character in a file_name, and the suggested the option to include a ';' is silly, since the default file_name then starts off as say ".png;.jpg" etc.
Other invalid in a file_name characters become "" so "*.png" or "?.png" >>> ".png"So as I see it, you should pass a valid file_name and the user chooses one [you test their result for compliance]...
But if you are not offering a file_name choice, then you useUI.select_directory
to get the destination folder for the fixed name [perhaps previously having got the file_type in another dialog]...@Dan
Perhaps I am missing something ?
How would you use a file_type filter inUI.savepanel
AND pass a default file_name ?
"JPG|.jpg|PNG|.png||" as the last argument offers a spurious choice.
If not reflected in the return file_path.
Typing 'xxx' returns that as the file's name.
Choosing JPG and typing 'xxx.png' retirns that as the file's name.
So it's pointless filtering this way.
In fact I think it should be ignored inUI.savepanel
, as an invalid argument !
At least if you pass 'xxx.png' as the file's default name, then something is initially displayed, and is acceptable too. -
The main point I am making, is that under the hood, they both call the same Windows API common dialog function.
@tig said:
But what's the use of giving a default set of file_types with
UI.savepanel
- they are ignored ...No they are not,.. not entirely.
They all appear in the filetype dropdown list. AND whichever is selected, serves to filter the directory listing for the current path location. So it partially works.
@tig said:
and NO default name appears at all.
Didn't say it worked perfectly. In fact I consider it bugged.
@tig said:
Passing a 'filter' doesn't work anyway, as then entering "
xxx
" - with no file_type - it accepts it as being valid.Yep,.. the user can override any filename or filetype suggestion, by picking a current file, or by manually typing anything into the filename box.
@tig said:
At least if you pass a file_name, them it'll be displayed, and you are more likely to change the name and retain the file_type...p/quote]
This is more of a "best practices" argument.@tig said:
I just retested it [v2016] and if you give the default file_name as ".png" that is is displayed, but it is also accepted when NOT prefixed with a name [plain silly], ...
Agree, there should be better testing.
@tig said:
... you cannot offer multiple file_type choices [unlike
UI.openpanel
] - as the "|" is not a valid character in a file_name, ...
So as I see it, you should pass a valid file_name and the user chooses one [you test their result for compliance]...Your making an argument of your preferred "best practice". It might apply if the scenario is such that YOU know the filetype would be say SKP.
But in the example we are speaking of, boma gave a scenario where he wants the user to type a filename, and choose one of the image filetypes given in the filter. Then expected the chosen extension to be appended to the filename. (I would also.)
But it is bugged.
@tig said:
@Dan
Perhaps I am missing something ?
How would you use a file_type filter inUI.savepanel
AND pass a default file_name ?Well, as the methods are currently written, you do not. When savepanel gets fixed, You do one or the other, but not both.
-
So we are both "correct"...
You can pass a file_type filter.
But it does nothing useful.You can [I suggest should] pass a default file_name.
But it does nothing useful if the user ignores the file_type.So, as it stands the author is best advised to either preset the file_name [and file_type] and destination folder.
Or at least only ask for the destination folder.
Or failing that, check that the returned value is valid...
i.e.
Not empty?...
Not with no file_type suffix...
Not of an unexpected file_type...
and so on...
On a fail, then the author can choose an error-massage, or to repeat of the dialog until it is satisfactory or canceled etc... -
So, if I want to let the user write only the name and choose the extension - in order to auto append the extension I can't use SU saveFileDialog..... I have to write a dialog by me....
-
You can always check the filename you get back - if it doesn't have an extension, append it.
-
But how to detect the user choice?
-
Going back several posts...
It is a mistake to think that you can use the file-type filter when saving.
UI.openpanel can use it to filter what's shown to choose from - the user then picks a file and it is returned as a string including its path.
But UI.savepanel does not do the same thing - the last argument ought to be a default file name NOT a filter.
If you use a filter it does nothing.
Its returned value is the current_folder/file_nameIf your code allows different file types you probably need to establish that before ever opening the savepanel dialog.
For example, in an earlier dialog.
Then use the savepanel to get the user's desired folder and file_name.
If they enter a file_type use the File & gsub methods to strip it off and add back the file_type suffix they chose earlier.
Alternatively let the user specify the file_type in the savepanel - but if there is not an expected file_type appended you can open a dialog to tell them so, and either default to one of them [e.g. .jpg] OR open a dialog and get them pick one off a dropdown list.Another alternative is to establish the name of the file AND its file-type in an earlier dialog, and then to use UI.select_directory to allow the user to specify the folder for that file.
Or even simpler, have the user specify the file-type from a dialog's dropdown list and then use the model-name as the default file_name [no choice] AND the model's folder as the destination [no choice] - perhaps making a subfolder named Images to keep things tidy ?
You are trying to do something with a UI method that is not possible.
However, there are many alternative ways to do something like this - you are the author, you determine what happens... -
Ok. Sometimes I insist too much in my ideas.....After all my motto is "yes you can" (but I'm realizing that "you" is referred to Dan, Thomthom and TIG, not me..)
-
it's relatively easy to have the user supply all the export setting needed...
the code for that dialog pulled out of one of my plugins...
it's a little untidy because it used @vars that I removed for the example...
I haven't added the menu code as it's buried in another method...but, I also added the ask for directory code first...
It will save an image if you test it...
dir = "" until File.exists?(dir) if UI.respond_to?(;select_directory) # SketchUp 2015 dir = UI.select_directory.to_s else dir = File.dirname(UI.savepanel.to_s) end end view = Sketchup.active_model.active_view.freeze vph = view.vpheight vpw = view.vpwidth height = vph width = vpw title = Sketchup.active_model.title # add a fallback title title = 'Test' if title == "" # Sketchup.active_model.path is empty string and mkdir raises error when # the model has not yet been saved. We could require the user to save, or # guess a default location from ENV (with the risk it also does not exist), # or get the prompt the user later when he actually wants to save an image. path = Sketchup.active_model.path type = '.png' aa = false tran = false image = File.join(title + type) key = 'th' # menu.add_item("Image Settings") do prompts = ["Filename", "Filetype", "Width", "Height", "AA","Quality %", "Transparency", "sytle key", "Save Now"] defaults = [image, type, width, height, aa, 100, tran, key, 'yes'] list = ["", "", "", "", "true|false", "", "true|false", "", "yes|no"] results = UI.inputbox prompts, defaults, list, "Image Out Settings" if results != false # UI.inputbox gives strings. Make sure we immediately cast them into the correct types! image = results[0] type = results[1] width = results[2].to_i # Fixnum height = results[3].to_i # Fixnum aa = results[4] == true # Boolean qual = results[5].to_f/100.0 tran = results[6] == true # Boolean key = results[7] path = File.join(dir,results[0]) # your write code goes here or send to another method... Sketchup.active_model.active_view.write_image( { ;filename=>path, ;width=>width, ;height=>height, ;antialias=>aa, ;transparent=>tran } ) else p 'canceled' end #end
john
-
Oh, I forgot to add that you can use Notepad++ to see how they really should act properly.
Make a junk text file, and play with the SaveAs dialog.
-
That's ok. We have to reinvent the wheel..... but let's admit that this un-natural...the user does expect that once he choose from the combolist the extension and write its own filename and choose the folder where store the file, evrything goes ok whitout any other GUI or other stuff.... AS IN ALL SOFYWARE - SketchUp too.
From my point of view this is a messy behavior of SketchUp APIs...but said that, I'll follow what you had already suggested..... -
The last thing I want to add to the discussion, is that the filetype filtering is always supposed to work to filter the list of files displayed in the dialog's file listing. (That goes for both save and open.)
The save dialog is often used to select an existing file to overwrite with confirmation. (This is why list filtering by filetype is valid.)
My personal rule of thumb is also to always add a "ALL files (.)" filter.EDIT: The user could (whenever they wish) override the chosen filetype by manually adding a file extension.
(WAS: The user should always override the chosen filetype by manually adding a file extension.)If no extension is typed, the chosen file type filter is supposed to be added to the filename. (Which the SketchUp API does NOT currently do.)
But the SketchUp API does not follow standard WinAPI conventions (I think because it was written originally by Mac guys.)
So, the pathstring, the filetype filter and the filename should all be separate parameters for maximum power (flexibility.) Having an either/or filename or filetype parameter takes away flexibility.
So yes, until it is fixed (if ever,) ... using it (3rd param) as a filename might be best for the Save.
This means boma would need to test the result for a "." and an extension, and if not, call a simple
UI.inputbox
to prompt for image type.ftype = UI.inputbox(["choose..."],["PNG"],["JPG|PNG|BMP"],"Image Type").first
-
@tig said:
The final argument for
UI.savepanel
is NOT afile_type
list [that'sUI.openpanel
's, it's the defaultfile_name
.This is NOT true. (EDIT: Well, it's not and it is. Ie, it should be possible according to Microsoft, but isn't because it has never been implemented correctly for the SketchUp API. See rest of discussion.)
UI.openpanel
andUI.savepanel
do the exact same thing, except the window caption and action button text is either, "Open" or "Save".
(With the added feature that if a existing file is chosen in the save dialog, a confirmation to overwrite the file will popup. Choosing "No" returns to the save dialog. A pathstring is not returned until "Yes" is chosen in the confirmation popup.)Yes, the API documentation for
UI.savepanel
is way past need to correction. It has been pointed out to the API team multiple times. -
FYI: Back in Jan, Jim brought up this limitation in the OEM forum, and Thomas responded that neither panels functions are coded correctly (Jim filed a bug,) and cannot take both a filename and a typelist.
http://forums.sketchup.com/t/openpanel-and-savepanel/5489
Advertisement