Copy link to clipboard
Copied
Hello all,
I'm presently mired in my first attmpt at creating a Lr export plugin and, predictably, have hit a wall. As I've not come across example code which does what I'm trying to do, I wonder if someone here may have some pointers.
The goal is to use custom metadata from selected photos to populate an export service provider dialog. This will be used upon export to form appropriate output paths, generate a text file manifest (containing data which will be used by an external workflow) and then copy appropriately-renamed raw files to the output path.
The custom metadata and export dialog creation have worked fine. The snag I'm hitting is I can't seem to get said metadata out of the LrTask which I have to call photo:getPropertyForPlugin() from within. Inside of the calling function, the data is definitely there; logger:trace() prints it to the console. But what is the appropriate way to return the data from within that function into, say, a propertyTable, so that it can be picked up and used elsewhere in the code?
Below is a simplified version of what I'm trying. It would seem that the dialog is creating the static_text before the function running in an AsyncTask() has populated the value for it. Is there a way to force the sequence of events and cause the dialog to wait until there's a value for it to use? What is the obvious thing that I'm doing wrong here?
Thanks very much for any help!
Erik
local photo = catalog:getTargetPhoto()
local function getCustomMetadata( propertyTable )
LrTasks.startAsyncTask( function()
propertyTable.mymetadata = photo:getPropertyForPlugin( 'com.myid.myplugin', 'mymetadata' )
end)
end
function exportDialogSections.startDialog( propertyTable )
getCustomMetadata( propertyTable )
end
function exportDialogSections.sectionsForTopOfDialog( f, propertyTable )
return {
{
title = "Test",
f:row {
f:static_text {
title = propertyTable.mymetadata,
},
},
},
}
end
The typical way plugins handle this is to execute all of their logic within a single asynchronous task. But in your case, I don't see how that approach could be used, since you don't have control over when sectionsForTopOfDialog() is invoked.
You could have sectionsForTopOfDialog() poll politely until the task completes:
...function exportDialogSections.sectionsForTopOfDialog (f, propertyTable)
local done = false
LrTasks.startAsyncTask (function ()
propertyTable.mymetadata =
Copy link to clipboard
Copied
The typical way plugins handle this is to execute all of their logic within a single asynchronous task. But in your case, I don't see how that approach could be used, since you don't have control over when sectionsForTopOfDialog() is invoked.
You could have sectionsForTopOfDialog() poll politely until the task completes:
function exportDialogSections.sectionsForTopOfDialog (f, propertyTable)
local done = false
LrTasks.startAsyncTask (function ()
propertyTable.mymetadata =
photo:getPropertyForPlugin ('com.myid.myplugin', 'mymetadata')
done = true
end)
local delay = 0.01
while not done do
LrTasks.sleep (delay)
delay = math.min (0.1, 2 * delay)
end
return {{title = "Test",
f:row {f:static_text {title = propertyTable.mymetadata}}}}
end
Copy link to clipboard
Copied
"But in your case, I don't see how that approach could be used, since you don't have control over when sectionsForTopOfDialog() is invoked."
Well, good to know I wasn't being a complete idiot.
Your suggestion does the trick. Thanks very much, John!
Cheers,
Erik
Copy link to clipboard
Copied
Another option for future reference:
instead of:
title = propertyTable.mymetadata
have
-- bind_to_object = propertyTable, - not necessary in this context, since propertyTable is the default bound object.
title = LrView.bind( 'mymetadata' ),
width_in_chars = 20, -- or fill_horizontal=1,.. -- assure field width can accomodate maximum title size.
The only down side is that you'll need to make sure the title has enough width (or "fill"), since initial computation will be based on nil data. or initialize propertyTable.mymetadata = string.rep( " ", 20 ), so the title field width is computed based on non-nil data.
In this case, it may make no practical difference, but it's good to understand how to bind to data now, which is or may be changing asynchronously in the future..
Rob
Copy link to clipboard
Copied
That probably won't apply for this particular case (putting the data in a static_text was just to confirm it was working), but it sounds like it will for another feature of the plug-in, so thank you!
Erik
Copy link to clipboard
Copied
I like Rob's solution better than mine.