Application.Open and Application.OpenDocument

I’ve read that when a user opens a document from the finder the app is launched with app.opendocument but I can’t see anything in the documentation about if fires as well, and if it does which one comes first.

I’m trying to set a global variable for the id number of the latest item so that each item entered gets a unique id number that will never repeat or overlap with another. The idea is to set it to -1 on a blank document with, and read it from the document on app.opendocument. That’s where my questions come into play :slight_smile:

Is there a best method for this?

You are correct. Both events fire. As for the order: please verify this yourself.

And don’t depend on the order. We don’t guarantee that events will fire in any particular order… Especially the ones that are close together.

A nice way to handle this is to add the documents that need to be opened to a global array, then start a Timer. After the app has finished opening, the Timer will fire and take care of opening the documents. Each pass of the Timer would handle one document and remove it from the array.

Greg, I understand that I can not have confidence that one event will go before the other (Open, OpenDocument).
But, can I be sure that they will be done in a certain order (one after the other) and not mixed?

Do you have an example. I’ve got zero experience with timers. The code at end of open turns off the timer that was started in OpenDocument?

No example, but I can describe it. Create a subclass of a Timer called DocumentOpenerTimer (or something like that) and add a property Docs() As FolderItem. In your App class, add a property Opener As DocumentOpenerTimer. Before using that property, make sure you set it to a new DocumentOpenerTimer and set it’s period to something low, like 50.

Now in OpenDocument, append your document to Opener.Docs, then set the mode to Multiple. The Timer’s Action will pull an element off of the array and handle opening it. When he array is empty, it will set its own mode to 0.

Does the names you are giving these items cause the docs to open from off of this queue? Just like dragging a doc to the app automagically calls OpenDocument. I feel like I’m missing something.

i.e. the only code is setting up the timer property, instantiating it with the period and then appending docs as they get added.

No. As I said, “The Timer’s Action will pull an element off of the array and handle opening it.” That “handle opening it” is up to you. There is no way Xojo could know what that entails as every app is different, so you’ll have to code it.

But “handle opening it” is that OpenDocument is automatically called???

Yes. Dropping a recognized file onto your app and calling App.Open (I think) maybe the only triggers but check the documentation to be sure.

I really appreciate all of the help.
Several have suggested that I look at the documentation but the documenation on App.OpenDocument is miniscule.

Application.OpenDocument ( item as FolderItem )
The user has double-clicked on a document whose creator matches the application’s creator or the OpenDocument method was called.

This code loads the text of the supplied file into a TextArea on Window1:
If item <> Nil Then
Dim input As TextInputStream
input = TextInputStream.Open(item)

Dim w As New Window1
w.TextArea1.Text = input.ReadAll

End If
----- end -----

App.NewDocument — the entire documentation is this:
Application.NewDocument ( )
The user launched the application by double-clicking the application icon or the NewDocument method was called.
----- end -----

Nothing is said about the order things fire. Nothing is said about where to open your splash screen vs your default app window vs. a document. Nothing about timers and how those play a role. Maybe there is some other documentation somewhere else that I am not finding. I will go read up on Timers and see if that helps clarify.

For OSX you can associate Filetypes in the IDE Build Settings OSX, in Linux the user can do it in a starter or a config file, in Windows ?

Thanks. I have that part working already just fine.

You quoted it yourself,

[quote]Application.NewDocument ( )
The user launched the application by double-clicking the application icon or the NewDocument method was called[/quote]

[quote]Application.OpenDocument ( item as FolderItem )
The user has double-clicked on a document whose creator matches the application’s creator or[/quote]

So either the one or the other event is called

Almost three years ago in this very thread (also the second time I’ve quoted this, specifically)

Additional support time can be purchased.

@Tim Turner
Run this TestProject to see the order things fire on your machine.

Another way to deal with App.OpenDocument, utilizing a timer, is to create a Timer property and a FolderItem array property, and put code similar to this in the OpenDocument event.

[code]Sub OpenDocument(item As FolderItem) Handles OpenDocument
inFiles.Append item

if handleFilesTimer = nil then
handleFilesTimer = new Timer
handleFilesTimer.Period = 1
handleFilesTimer.Mode = Timer.ModeSingle
AddHandler handleFilesTimer.Action, AddressOf HandleFilesTimerAction
End Sub

OpenDocument is called once for each file that is dropped onto the application icon.
This code will append the dropped files to the array “inFiles()” and initialize a timer, or reset its period it the timer already exists.

Once OpenDocument stops being called (meaning that app finished receiving all of the dropped files), the method “HandleFilesTimerAction” will be called since the timer is not longer being reset.

In that method you can process the files however you see fit (and probably ReDim inFiles(-1) to potentially prepare for more files).

[code]Private Sub HandleFilesTimerAction(sender as Timer)
#Pragma Unused sender

// Do whatever you want with the array of FolderItems here
MsgBox "File Count: " + Str(inFiles.Ubound+1)

End Sub

I hope that helps.

On second thought… a timer period of 1 ms is a bit aggressive.

Probably want to up that to 50 or so to be sure that all of the files have been received.

Forget App.Open, do all your work in
OpenDocument - the user double clicked a document associated with your app, or dropped a document on your app
NewDocument - the user opened your app with no document, or selected File -> New

From your original post in 2014, you would set the id number to -1 in NewDocument or read it from the file in OpenDocument.

And while you generally shouldn’t depend on event order, there are some things that are practically guaranteed. App.Open should always be the first event that occurs. (Unless you have some constructors that do bad things, like open windows.)