Script won't work properly with FILTERFLAGS=deselect

Hi,

I posted a script here. Please read the script thread to know what it does.

After some test, there is a bug returning no error: If you select only image files, it will work properly as intended. But if among the selected files there are other file types, the script won't apply metadata to the image files. And yet, the script is supposed to handle this case.

Reproduce the "bug" and comments

So select one image file + a text file as an example.

Actually, line 22

cmd.RunCommand("Select """&Filter&""" FILTER FILTERFLAGS=deselect")

works as intended, the text file is deselected.

Line 26, I check that the script registered this new state with

DOpus.Output "Number of selected files that the script will apply GPS : " & ClickData.Func.sourcetab.selected.count
It did since it only report the current number of selected images files. Only 1 in that case.

Line 98, just before applying the metadata, I check again that my variables are OK and the script still works with the selected file

DOpus.Output "Latitude = " & Lat & vbCrLf & "Longitude = " & Lon DOpus.Output "Number of selected files that the script will apply GPS : " & ClickData.Func.sourcetab.selected.count cmd.RunCommand("SetAttr META gpslatitude:"&Lat&"") cmd.RunCommand("SetAttr META gpslongitude:"&Lon&"")
And yet, the metadata won't apply while if you only select image files from the very start, it works.

I'm lost. I really need some enlightenment.

Here is an updated version of the button used as reference for above. Unlike the original button, I just added the option to directly apply the GPS data from clipboard instead of using a prompt dialog as a step to retrieve them.

<?xml version="1.0"?> <button backcol="none" display="both" textcol="none"> <label>Bouton</label> <icon1>#newcommand</icon1> <function type="script"> <instruction>@disablenosel</instruction> <instruction>@filesonly</instruction> <instruction /> <instruction>@script vbscript</instruction> <instruction /> <instruction>&apos; Please select a filter to exclude non images files</instruction> <instruction>&apos; Typacally it should be a filter that actually matches image files you want to apply coordinates to.</instruction> <instruction>Dim Filter</instruction> <instruction>Filter = &quot;Non Image files&quot;</instruction> <instruction /> <instruction>Function OnClick(ByRef ClickData)</instruction> <instruction> &apos; Clear the log output</instruction> <instruction> DOpus.ClearOutput</instruction> <instruction /> <instruction> &apos; INITIATE VARIABLES</instruction> <instruction> UseDialog = False</instruction> <instruction> Match = 0</instruction> <instruction> Set cmd = ClickData.Func.command</instruction> <instruction> Dim GpsInput</instruction> <instruction /> <instruction> &apos; This will deselect all non image files</instruction> <instruction> cmd.RunCommand(&quot;Select &quot;&quot;&quot;&amp;Filter&amp;&quot;&quot;&quot; FILTER FILTERFLAGS=deselect&quot;)</instruction> <instruction /> <instruction> &apos; Number of selected files to check the previous deselect command has run properly</instruction> <instruction> &apos; And YES it is</instruction> <instruction> CountSel = ClickData.Func.sourcetab.selected.count</instruction> <instruction> DOpus.Output &quot;Number of selected files that the script will apply GPS : &quot; &amp; CountSel</instruction> <instruction /> <instruction> &apos; Check if at least 1 file is selected to continue else exit.</instruction> <instruction> If ClickData.Func.sourcetab.selected_files.count &lt; 1 Then</instruction> <instruction> Set dlg = ClickData.Func.Dlg</instruction> <instruction> dlg.Request &quot;No file selected&quot; &amp; vbCrLf &amp; &quot;Please select at least 1 and run the command again&quot;, &quot;OK&quot;</instruction> <instruction> Exit Function</instruction> <instruction> End If</instruction> <instruction /> <instruction> &apos; Ask coordinates until they are valid</instruction> <instruction> Do While Match = 0</instruction> <instruction> &apos; In case prompt dialog is used</instruction> <instruction> If UseDialog = True then</instruction> <instruction> &apos; Create 1st Dialog object.</instruction> <instruction> Set dlg = DOpus.Dlg</instruction> <instruction> &apos; Initialise the object to display a message with 2 buttons and 1 input box</instruction> <instruction> dlg.Window = DOpus.Listers(0)</instruction> <instruction> dlg.title = &quot;GPS coordinates&quot;</instruction> <instruction> dlg.message = &quot;Paste the coordinates you copied from Google Maps.&quot;&amp; vbCrLf &amp; vbCrLf &amp;&quot;Ex: 47.338388, 0.990228&quot;</instruction> <instruction> dlg.buttons = &quot;&amp;OK|&amp;Cancel&quot;</instruction> <instruction> dlg.icon = &quot;question&quot;</instruction> <instruction> dlg.max = 128 &apos; enable the text field</instruction> <instruction> &apos; Show the dialog and print the results to the script log</instruction> <instruction> ret = dlg.Show</instruction> <instruction> &apos; DOpus.Output &quot;Dialog.Show returned &quot; &amp; ret</instruction> <instruction> &apos; DOpus.Output &quot;The string you entered was &quot; &amp; dlg.input</instruction> <instruction /> <instruction> If ret = 0 then &apos; When user cancel action</instruction> <instruction> Exit Function</instruction> <instruction> End If</instruction> <instruction /> <instruction> GpsInput = dlg.input</instruction> <instruction> &apos; DOpus.Output &quot;GpsInput : &quot;&quot;&quot; &amp; GpsInput &amp; &quot;&quot;&quot;&quot;</instruction> <instruction> Set dlg = Nothing &apos; destroy 1st dialog prompt</instruction> <instruction> Else</instruction> <instruction> &apos; In case prompt dialog is not used, just read the clipboard</instruction> <instruction> If DOpus.GetClipFormat = &quot;text&quot; Then</instruction> <instruction> GpsInput = DOpus.GetClip</instruction> <instruction>&apos; DOpus.Output &quot;GpsInput : &quot;&quot;&quot; &amp; GpsInput &amp; &quot;&quot;&quot;&quot;</instruction> <instruction> Else</instruction> <instruction> Set dlg = ClickData.Func.Dlg</instruction> <instruction> dlg.Request &quot;Clipboard content is not as text format&quot; &amp; vbCrLf &amp; &quot;Be sure to copy only coordinates as text and try again&quot;, &quot;OK&quot;</instruction> <instruction> Exit Function</instruction> <instruction> End If</instruction> <instruction /> <instruction> End if</instruction> <instruction /> <instruction> &apos; Check if the input is a valid GPS coordinates</instruction> <instruction> &apos; Create a RegExp object. See http://msdn2.microsoft.com/en-us/library/ms974570.aspx</instruction> <instruction> Set re = New RegExp</instruction> <instruction> re.IgnoreCase = True &apos; Case-sensitive matching.</instruction> <instruction> re.Global = False &apos; All matches will be matched, not just the first match.</instruction> <instruction /> <instruction> re.Pattern = &quot;^(-?[1-8]?\d(?:\.\d{1,18})?|90(?:\.0{1,18})?),\s+?(-?(?:1[0-7]|[1-9])?\d(?:\.\d{1,18})?|180(?:\.0{1,18})?)$&quot;</instruction> <instruction> Set matches = re.Execute(GpsInput)</instruction> <instruction> If matches.Count = 1 Then &apos; Case if pasted values contains valid coordinates</instruction> <instruction> Match = 1</instruction> <instruction>&apos; DOpus.Output &quot;GpsInput is VALID&quot;</instruction> <instruction>&apos; DOpus.Output &quot;Found &quot; &amp; matches.Count &amp; &quot; matches&quot; &amp; vbCRLF &amp; &quot;Match value : &quot; &amp; matches.Item(0).Value</instruction> <instruction> Lat = matches.Item(0).SubMatches(0)</instruction> <instruction> Lon = matches.Item(0).SubMatches(1)</instruction> <instruction>&apos; DOpus.Output &quot;Latitude = &quot; &amp; Lat &amp; vbCrLf &amp; &quot;Longitude = &quot; &amp; Lon</instruction> <instruction> Else &apos; Case if pasted values contains invalid coordinates</instruction> <instruction> Set dlg = ClickData.Func.Dlg</instruction> <instruction> dlg.Request &quot;The format of the coordinates you pasted are wrong&quot; &amp; vbCrLf &amp; &quot;Try again&quot;, &quot;OK&quot;</instruction> <instruction> If UseDialog = False Then Exit Function</instruction> <instruction> &apos; Clear the log output</instruction> <instruction> DOpus.ClearOutput</instruction> <instruction> End If</instruction> <instruction> Loop</instruction> <instruction /> <instruction> &apos; Apply coordinates to files</instruction> <instruction> DOpus.Output &quot;Latitude = &quot; &amp; Lat &amp; vbCrLf &amp; &quot;Longitude = &quot; &amp; Lon</instruction> <instruction> DOpus.Output &quot;Number of selected files that the script will apply GPS : &quot; &amp; ClickData.Func.sourcetab.selected.count</instruction> <instruction> cmd.RunCommand(&quot;SetAttr META gpslatitude:&quot;&amp;Lat&amp;&quot;&quot;)</instruction> <instruction> cmd.RunCommand(&quot;SetAttr META gpslongitude:&quot;&amp;Lon&amp;&quot;&quot;)</instruction> <instruction>End Function</instruction> </function> </button>

Regards

The Command object has methods to change which files it will act on. ClearFiles, AddFile, etc.

Generally, running the Select command in a script won't change anything, except what is selected in the file display.

Also note that you can set both pieces of metdata at once in a single update of the file, which should speed things up and may also make things more reliable, as the file isn't opened, updated and closed twice:

SetAttr META gpslatitude:x gpslongitude:y

Good point about the SetAttr Meta.

I will see how I can handle the file with the methods of command obj. I guess I will need to iterate through selected files and add them to the collection the script apply to.

Selected files are added to the command by default, but you might want to remove the unwanted ones. (Or you can clear the list, then add the wanted ones, if it's easier.)

Thanks. I learn a lot about scripting to handle selected file, filter them, select from script, etc.

Issue is fixed in the last version that work like a charm.

Here is a sample code to show how I handle this. You can test it in a button.

[code]@disablenosel
@filesonly

@script vbscript
' This sample script show you how you can filter selected files by their metadata type
' and handle them to do stuff you need.

Function OnClick(ByRef ClickData)

' ============================================================================
'                         INITIATE VARIABLES & OBJECT
' ============================================================================
Set cmd = ClickData.Func.command
Set srce = ClickData.Func.sourcetab

' ============================================================================
'                         FILTER FILES TO BE PROCESSED
' ============================================================================
DOpus.Output ""
DOpus.Output "============================================================================"
DOpus.Output ""
DOpus.Output "Selected files BEFORE filter : " & srce.selected_files.count
DOpus.Output "Files that will actually be processed BEFORE filter : " & cmd.files.count
cmd.ClearFiles ' All items are removed from the collection so only image files will be added next
DOpus.Output ""
DOpus.Output "FILTERING…"
DOpus.Output ""
n = 1
For Each f In srce.selected_files
    ' If a selected file can handle GPS metadata, it will be added to files to process
    If (f.metadata = "image") then
        cmd.AddFile(f)
        DOpus.Output n & ". """ & f.name & """ will be processed"
    End if
    n = n+1
Next
DOpus.Output ""
' Select files in the active tab that will actually be processed
cmd.RunCommand("Select FROMSCRIPT DESELECTNOMATCH MAKEVISIBLE")
srce.Update ' Synchronize changes made by the previous select command to the sourcetab object. It can be useful if you need to use this object later.
DOpus.Output "Selected files AFTER filter : " & srce.selected_files.count
DOpus.Output "Files that will actually be processed AFTER filter : " & cmd.files.count

' Check if at least 1 file is selected to continue else warn and exit.
If cmd.files.count < 1 Then
    Set dlg = ClickData.Func.Dlg
    dlg.Request "No file selected or no valid file to process."  & vbCrLf & "Please select at least 1 image file and run the command again", "OK"
    Set dlg = Nothing ' destroy dialog
    Exit Function
End If

' Go on with what you need to do with those files next.
' Now any cmd.RunCommand will apply to the files that are actually selected.

End Function
[/code]