Copy link to clipboard
Copied
For the LrCollection class, the documentation says:
"Retrieve the objects for all the collections by calling LrCatalog.getCollections()."
but there is no other info about it. What does it return?
I have:
local LrApplication = import "LrApplication"
local LrCatalog = LrApplication.activeCatalog()
local collections = LrCatalog:getCollections()
I get:
internal error.... attempt to call method getCollections (a nil value)
What am I doing wrong?
Pete
Oh, silly me, I gave you a code fragment that didn't actually make sense -- very sorry about that.
The problem with this:
local topLevelCollections = LrTasks.startAsyncTask (
function (context)
return catalog:getChildCollections()
end)
is that startAsyncTask does exactly that -- it creates an asynchronous task (i.e. a thread) that executes the function in parallel with the task that called startAsyncTask. It always returns nil, which is why topLevelCollections is always nil.
...
Copy link to clipboard
Copied
That part of the documentation is wrong. Here's a correct code fragment:
local LrApplication = import 'LrApplication'
local catalog = LrApplication.activeCatalog ()
local topLevelCollections = catalog:getChildCollections ()
local topLevelCollectionSets = catalog:getChildCollectionSets ()
The documentation for the two catalog:get* methods is correct.
Copy link to clipboard
Copied
Thanks for the quick reply.
Now I get "We can only wait from within a task", so I changed it to:
local topLevelCollections = LrTasks.startAsyncTask(catalog:getChildCollections(), "getChildCollections")
but I still get the same can only wait from within a task error.
PS: I removed the line for collections sets.
Copy link to clipboard
Copied
local topLevelCollections = LrTasks.startAsyncTask(catalog:getChildCollections(), "getChildCollections")
startAsyncTask requires the first argument to be a function that takes one argument, a function context:
local topLevelCollections = LrTasks.startAsyncTask (
function (context)
return catalog:getChildCollections()
end)
Copy link to clipboard
Copied
Oops, I misspoke slightly. The function passed to startAsyncTask doesn't take any arguments:
local topLevelCollections = LrTasks.startAsyncTask (
function ()
return catalog:getChildCollections()
end)
Copy link to clipboard
Copied
Well, I'm not getting any errors, but topLevelCollections==nil, catalog returns the .lrcat so, I'm confused.
Copy link to clipboard
Copied
OK...that gets me the collections.
The doc says "LrTasks.startAsyncTask( func, optName )",
so thanks for that help too, I never would have guessed it.
Copy link to clipboard
Copied
Some resources I found handy when starting out with the SDK:
- Look at the sample plug-ins. They provide more examples than what's described in the SDK Guide.
- For the Lua lanuage, I found this tutorial quick and easy:
http://lua-users.org/wiki/TutorialDirectory
The Lua language is conceptually simple but much different than the typical scripting languages like Python, Perl, or Visual Basic. (It's most like Scheme, a language that used to be taught in some computer-science departments years ago.)
Copy link to clipboard
Copied
Thanks for the link.
The documentation has other issues w/ consistency too. For example, catalog:getChildCollections says it returns:
(array of LrCollection
) The collection objects.
while catalog:getAllPhotos says it returns:
(table) An array of LrPhoto
objects
I'm assuming that both methods return a table of their respective objects. Now onto ipairs!
Copy link to clipboard
Copied
What you quoted is technically correct, though inconsistent in its use of terminology. In Lua, an "array" is just a table whose keys are numeric. So "(table) An array of LrPhoto
objects" is technically correct.
Copy link to clipboard
Copied
Why don't you post the entire code, and maybe it will be apparent what's going on.
Copy link to clipboard
Copied
Thanks for looking at this:
MyCollections = {}
local LrTasks = import "LrTasks"
local LrApplication = import "LrApplication"
local LrLogger = import "LrLogger"
local myLogger = LrLogger('myLog') -- the log file name
local catalog = LrApplication.activeCatalog()
local topLevelCollections = LrTasks.startAsyncTask (
function ()
return catalog:getChildCollections()
end)
function MyCollections.outputToLog( message )
myLogger:trace( message )
end
myLogger:enable( "logfile" )
MyCollections.outputToLog(topLevelCollections==nil) --<--outputs true
-- this is what I'm working on.. which errors due to topLevelCollections==nil
for _, lrcollection in ipairs( topLevelCollections ) do
collectionNames = collectionNames .. "," .. LrTasks.startAsyncTask (
function()
return lrcollection:getName()
end)
end --for
Copy link to clipboard
Copied
Oh, silly me, I gave you a code fragment that didn't actually make sense -- very sorry about that.
The problem with this:
local topLevelCollections = LrTasks.startAsyncTask (
function (context)
return catalog:getChildCollections()
end)
is that startAsyncTask does exactly that -- it creates an asynchronous task (i.e. a thread) that executes the function in parallel with the task that called startAsyncTask. It always returns nil, which is why topLevelCollections is always nil.
You'll need to put all of the work manipulating collections (and many other methods on catalogs) into a function that's invoked by startAsyncTask. E.g. your plugin could have the structure:
local function main ()
...access the catalog and collections...
...show the main dialog...
end
LrTask.startAsyncTask (main)
Copy link to clipboard
Copied
Got it.
Thanks for getting me started.
Pete