Copy link to clipboard
Copied
I'm working with file browsing atm using the File objects in JSX and the openDlg -method and quite frankly, this is driving me insane.
Did some crazy person decide that it was a good idea to have the filter-flag on the openDlg -method totally different for Win and OSX? On windows you use a string for the filtering, on OSX it want's a function!
I've checked the documentation and also searched this forum and I can't even find an example of how to set this up so that it works for both Windows and OSX?
Ok so I've found the syntax, but it still doesn't make sense.
fileMask = function(file){file.name.match(/\.psd$/i) ? true:false;}
Here we have the psd-extension hardcoded into the regular extension. But what if we want it to be a variable? And what if t he file doesn't exist yet.
Basically what I want is for the user to:
Browse to a folder
set a file name
save.
The extension type should be locked!
Compared to the windows way of doing things, the OSX way of using a filter function is nonsensical, overly complex and downright annoying!
EDIT: I also discovered that you can't write a file name on OSX unless the file already exists. Come on! Is this the wrong dialog type or something???
Here's my script for prompting a file which handles the Win/Mac differences
...function isWindows() {
return app.systemInformation.indexOf("Operating System: Windows") >= 0
}
function isMac() {
return app.systemInformation.indexOf("Operating System: Mac") >= 0
}
function promptFile(filter_extension) {
var filter = null
if (isMac()) {
if (filter_extension) {
var filter_regex = new RegExp("[^\.]*\."+filter_extension+"$")
filter = function (file_entry) {
retu
Copy link to clipboard
Copied
Here's my script for prompting a file which handles the Win/Mac differences
function isWindows() {
return app.systemInformation.indexOf("Operating System: Windows") >= 0
}
function isMac() {
return app.systemInformation.indexOf("Operating System: Mac") >= 0
}
function promptFile(filter_extension) {
var filter = null
if (isMac()) {
if (filter_extension) {
var filter_regex = new RegExp("[^\.]*\."+filter_extension+"$")
filter = function (file_entry) {
return filter_regex.test(file_entry.name)
}
} else {
filter = function () { return true }
}
} else if (isWindows()) {
if (filter_extension) {
filter = filter_extension.charAt(0).toUpperCase() + filter_extension.slice(1)+"-files:*."+filter_extension
} else {
filter = "All files:*.*"
}
} else {
filter = null
}
var f = File.openDialog("Select your file", filter, false)
if (f) {
return f.fsName.replace(/\\/g, "/") // sanitize to forward slash
}
}
}
Copy link to clipboard
Copied
In xtools, I do it like this:
Stdlib.createFileSelect = function(str) {
if (isWindows()) {
return str;
}if (!str.constructor == String) {
return str;
}var exts = [];
var rex = /\*\.(\*|[\w]+)(.*)/;
var m;
while (m = rex.exec(str)) {
exts.push(m[1].toLowerCase());
str = m[2];
}function macSelect(f) {
var name = decodeURI(f.absoluteURI).toLowerCase();
var _exts = macSelect.exts;// alert(name);
while (f.alias) {
try {
f = f.resolve();
} catch (e) {
f = null;
}if (f == null) {
return false;
}
}if (f instanceof Folder) {
return true;
}
var fext = f.strf("%e").toLowerCase();for (var i = 0; i < _exts.length; i++) {
var ext = _exts;
if (ext == '*') {
return true;
}
if (fext == ext) {
return true;
}
// if (name.match(RegExp("\\." + ext + "$", "i")) != null) {
// return true;
// }
}
return false;
}macSelect.exts = exts;
return macSelect;
};
This way, you can use a Windows file filter and it converts it to a Mac file filter. I've used this for years in multiple projects.
Copy link to clipboard
Copied
Thanks.
That looks overly complicated for something that should be so simple.
I did try your code though Matias and it works. But how can I change it to work with old paths?
This is my current code:
function browser2(objType, ext, fullPath){
if (objType == "file"){
var path = new File(fullPath);
if(File.fs != "Windows") ext = function(){return true}; // OSX wai u do diz?
var dialog = path.openDlg(dialogMessage, ext);
while (dialog.alias){
dialog = dialog.resolve().saveDlg(dialogMessage);
}
}else if (objType == "folder"){
var path = new Folder(fullPath);
var dialog = path.selectDlg(dialogMessage);
while (dialog.alias){
dialog = dialog.resolve.selectDlg(dialogMessage);
}
}
}
On Windows this works exactly as it should. I tell the function if I want to browse for a file or a folder. I can also provide an old path and the dialog will start browsing from that point. The openDlg and selectDlg -methods respects the path to the object.
On OSX the dialog ALWAYS browser for folders ONLY and always from the last browsing point made on the system. The path to the object doesn't even seem to matter for the openDlg and selectDlg methods - Why?
Copy link to clipboard
Copied
In Mac the filter is a function that gets called for every file in a folder and you are supposed to return true/false depending if you are interested of it. That's why if it's null (basically assuming false for every file), you just get the folders. The Win version is simpler (and less powerfull) just specifying a set of file extensions as a specially formatted string.
My script is intended that you can just give the extension you are looking for or null for all files.
Copy link to clipboard
Copied
I see.
Well there seems to be something wrong: I modified your script so that I send in an extra parameter with the old path, and then I use saveDialog. Filter works, but the starting location when browsing is incorrect. Additionally I am unable to actually save the file (error says the file name is not valid!).
// Doesn't work at all. Opens up browsing starting from the user's desktop. Has the filter as a name.
var path = new File(oldPath);
var f = path.saveDialog("Select your file", filter, false);
// Doesn't work at all. Opens up browsing starting from the user's desktop. Has the filter as a name.
var path = new File(oldPath);
var f = path.saveDlg("Select your file", filter, false);
// Opens up the correct file path - but doesn't allow saving
var path = new File(oldPath);
var f = path.openDlg("Select your file", filter, false);
// Doesn't open up dialog
var path = new File(oldPath);
var f = path.openDialog("Select your file", filter, false);
Copy link to clipboard
Copied
Current code - Problems mentioned in the comments
function isWindows(){
return app.systemInformation.indexOf("Operating System: Windows") >= 0
}
function isMac(){
return app.systemInformation.indexOf("Operating System: Mac") >= 0
}
function promptFile(filter_extension, oldPath){
var filter = null
if (isMac()){
if (filter_extension){
var filter_regex = new RegExp("[^\.]*\."+filter_extension+"$")
filter = function (oldPath){
return filter_regex.test(oldPath.name)
}
}else{
filter = function(){ return true }
}
}else if (isWindows()){
if (filter_extension){
filter = filter_extension.charAt(0).toUpperCase() + filter_extension.slice(1)+"-files:*."+filter_extension
}else{
filter = "All files:*.*"
}
}else{
filter = null
}
// alert("oldPath is: " + oldPath);
// Starts browsing where it is supposed to start browsing (oldPath) and allows me to overwrite existing files.
// However, when starting the dialog the file name is always oldFileName.atlas.*.atlas
// Also, when trying to save a new file I get an error saying that the file name is invalid!
var path = new File(oldPath);
var f = path.saveDlg("Select your file", filter, false);
if (f){
return f.fsName.replace(/\\/g, "/") // sanitize to forward slash
}
}
Copy link to clipboard
Copied
To be honest, I've never used saveDlg so not sure if that changes something. But at least one problem, you had replaced "file_entry" with "oldPath" in the filter function. What below means is you create a dynamic function that get's called with every file in the dialog window and it tests if the filename is suitable (has proper prefix). Variable file_entry is the parameter (of type File) of the function, using oldPath might confuse it with the higher level variable.
filter = function (file_entry){
return filter_regex.test(file_entry.name)
}
Also make sure you call the function with extension only, i.e. "atlas", not ".atlas" or "*.atlas". And try debugging with ESTK, very easy to make a small text parsing error
Copy link to clipboard
Copied
I checked the docs (javascript tools guide) and saveDlg takes a filter only in Windows, which allows you to set type like *.*, *.atlas. So you can try leaving it out.
Copy link to clipboard
Copied
Thanks.
I changed back the file_entry variable and also provided promptFile() with a proper extension.
I had given the function an incorrect string - setting it to "atlas" made things working.
File browsing works on Windows but I get some other weird problem on OSX now:
Every single folder is greyed out.
function isWindows(){
return app.systemInformation.indexOf("Operating System: Windows") >= 0
}
function isMac(){
return app.systemInformation.indexOf("Operating System: Mac") >= 0
}
function promptFile(dialogMessage, extFilter, oldPath){
var filter = null
if (isMac()){
if (extFilter){
var filter_regex = new RegExp("[^\.]*\."+extFilter+"$")
filter = function (fileEntry){
return filter_regex.test(fileEntry.name)
}
}else{
filter = function(){ return true }
}
}else if (isWindows()){
if (extFilter){
filter = extFilter.charAt(0).toUpperCase() + extFilter.slice(1)+"-files:*."+extFilter
}else{
filter = "All files:*.*"
}
}else{
filter = null
}
var path = new File(oldPath);
var f = path.saveDlg(dialogMessage, filter, false);
if (f){
return f.fsName.replace(/\\/g, "/")
}
}
// Start browsing:
promptFile(dialogMessage, extension, fullPath)
The weird thing is that even though the documentation says that the second parameter to saveDlg() is only used by windows, it still appears as if the filter function is working. Sure, ALL folders are greyed out and I am unable to browse, but under "Save As" I have proper extension specified!
Another clue: I get the same problem on OSX with greyed out folders when using openDlg()
Copy link to clipboard
Copied
Heh, this is getting confusing
There seems to be _SEVERAL_ versions of the save dialogs
You probably have to just do some trial and error to pick the best one, what rules each has. As far as I see Mac has no option to "create a new file, but only this extension". Extension filter only seems to apply to opening existing and Win (although even there it's just hiding, you can actually set different extension by typing it).
Confusing part is that the "all folders grayed" would implicate it actually wants the filter even though docs say it does not. I.e. youd have to make a filter function that accepts either folders or files with right extension like below (not tested)
filter = function (fileSystemEntry){
if (fileSystemEntry instanceof Folder) {
return true
} else {
return filter_regex.test(fileSystemEntry.name)
}
}
Copy link to clipboard
Copied
I added an extra parameter to promptFile() - sending in the old path to the file (oldPath variable), then
var path = new File(oldPath);
var f = path.openDialog("Select your file", filter)
openDialog doesn't work so I changed it to openDlg. The old path is opened up and the filter is correct (Windows) but I am not able to actually save a new file. Makes sense since it's the openDlg and not the saveDlg.
But when using saveDlg the starting file name is the filter! Also if I specify a name I get an error message saying: "myName. The file name is not valid" - this is regardless of how I write it!
Also tried saveDialog() - which doesn't allow me to specify a path in advance - and I get exactly the same kind of error. The file name is not valid.
Copy link to clipboard
Copied
I'll make a separate thread about the grey-out problem as the original question has been answered already. I marked your response as the correct answer Matias.
Copy link to clipboard
Copied
Here's how I do it in xtools, You can replace f.strf("%e") with whatever function you use to extract a file extension.
This expects a Windows-style file selection string and returns that or a filter function if it's on a Mac.
isWindows = function() {
return $.os.match(/windows/i);
};
Stdlib.createFileSelect = function(str) {
if (isWindows()) {
return str;
}
if (!str.constructor == String) {
return str;
}
var exts = [];
var rex = /\*\.(\*|[\w]+)(.*)/;
var m;
while (m = rex.exec(str)) {
exts.push(m[1].toLowerCase());
str = m[2];
}
function macSelect(f) {
var name = decodeURI(f.absoluteURI).toLowerCase();
var _exts = macSelect.exts;
// alert(name);
while (f.alias) {
try {
f = f.resolve();
} catch (e) {
f = null;
}
if (f == null) {
return false;
}
}
if (f instanceof Folder) {
return true;
}
var fext = f.strf("%e").toLowerCase();
for (var i = 0; i < _exts.length; i++) {
var ext = _exts;
if (ext == '*') {
return true;
}
if (fext == ext) {
return true;
}
}
return false;
}
macSelect.exts = exts;
return macSelect;
};