Added metadata fields to scripts that script_manager can access and

display as a tooltip.

Added script_manager integration to those scripts that didn't have it.
This commit is contained in:
Bill Ferguson
2024-05-15 21:23:13 -04:00
parent ac945b9843
commit 55e68f8cd0
70 changed files with 2311 additions and 1610 deletions

View File

@@ -1,218 +1,225 @@
--[[AutoGrouper plugin for darktable
copyright (c) 2019 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this Plugin
This plugin adds the module "Auto Group" to darktable's lighttable view
----REQUIRED SOFTWARE----
None
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Set a gap amount in second which will be used to determine when images should no
longer be added to a group. If an image is more then the specified amount of time
from the last image in the group it will not be added. Images without timestamps
in exif data will be ignored.
There are two buttons. One allows the grouping to be performed only on the currently
selected images, the other button performs grouping on the entire active collection
]]
local dt = require "darktable"
local du = require "lib/dtutils"
du.check_min_api_version("7.0.0", "AutoGrouper")
local MOD = 'autogrouper'
-- return data structure for script_manager
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local gettext = dt.gettext.gettext
gettext.bindtextdomain(MOD, dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local Ag = {}
Ag.module_installed = false
Ag.event_registered = false
local GUI = {
gap = {},
selected = {},
collection = {}
}
local function InRange(test, low, high) --tests if test value is within range of low and high (inclusive)
if test >= low and test <= high then
return true
else
return false
end
end
local function CompTime(first, second) --compares the timestamps and returns true if first was taken before second
first_time = first.exif_datetime_taken
if string.match(first_time, '[0-9]') == nil then first_time = '9999:99:99 99:99:99' end
first_time = tonumber(string.gsub(first_time, '[^0-9]*',''))
second_time = second.exif_datetime_taken
if string.match(second_time, '[0-9]') == nil then second_time = '9999:99:99 99:99:99' end
second_time = tonumber(string.gsub(second_time, '[^0-9]*',''))
return first_time < second_time
end
local function SeperateTime(str) --seperates the timestamp into individual components for used with OS.time operations
local cleaned = string.gsub(str, '[^%d]',':')
cleaned = string.gsub(cleaned, '::*',':') --YYYY:MM:DD:hh:mm:ss
local year = string.sub(cleaned,1,4)
local month = string.sub(cleaned,6,7)
local day = string.sub(cleaned,9,10)
local hour = string.sub(cleaned,12,13)
local min = string.sub(cleaned,15,16)
local sec = string.sub(cleaned,18,19)
return {year = year, month = month, day = day, hour = hour, min = min, sec = sec}
end
local function GetTimeDiff(curr_image, prev_image) --returns the time difference (in sec.) from current image and the previous image
local curr_time = SeperateTime(curr_image.exif_datetime_taken)
local prev_time = SeperateTime(prev_image.exif_datetime_taken)
return os.time(curr_time)-os.time(prev_time)
end
local function main(on_collection)
local images = {}
if on_collection then
local col_images = dt.collection
for i,image in ipairs(col_images) do --copy images to a standard table, table.sort barfs on type dt_lua_singleton_image_collection
table.insert(images,i,image)
end
else
images = dt.gui.selection()
end
dt.preferences.write(MOD, 'active_gap', 'integer', GUI.gap.value)
if #images < 2 then
dt.print('please select at least 2 images')
return
end
table.sort(images, function(first, second) return CompTime(first,second) end) --sort images by timestamp
for i, image in ipairs(images) do
if i == 1 then
prev_image = image
elseif string.match(image.exif_datetime_taken, '[%d]') ~= nil then --make sure current image has a timestamp, if so check if it is within the user specified gap value and add to group
local curr_image = image
if GetTimeDiff(curr_image, prev_image) <= GUI.gap.value then
images[i]:group_with(images[i-1])
end
prev_image = curr_image
end
end
end
local function install_module()
if not Ag.module_installed then
dt.print_log("installing module")
dt.register_lib(
MOD, -- Module name
_('auto group'), -- name
true, -- expandable
true, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 99}}, -- containers
dt.new_widget("box"){
orientation = "vertical",
GUI.gap,
GUI.selected,
GUI.collection
}
)
Ag.module_installed = true
dt.print_log("module installed")
dt.print_log("styles module visibility is " .. tostring(dt.gui.libs["styles"].visible))
end
end
local function destroy()
dt.gui.libs[MOD].visible = false
end
local function restart()
dt.gui.libs[MOD].visible = true
end
-- GUI --
temp = dt.preferences.read(MOD, 'active_gap', 'integer')
if not InRange(temp, 1, 86400) then temp = 3 end
GUI.gap = dt.new_widget('slider'){
label = _('group gap [sec.]'),
tooltip = _('minimum gap, in seconds, between groups'),
soft_min = 1,
soft_max = 60,
hard_min = 1,
hard_max = 86400,
step = 1,
digits = 0,
value = temp,
reset_callback = function(self)
self.value = 3
end
}
GUI.selected = dt.new_widget("button"){
label = _('auto group: selected'),
tooltip =_('auto group selected images'),
clicked_callback = function() main(false) end
}
GUI.collection = dt.new_widget("button"){
label = _('auto group: collection'),
tooltip =_('auto group the entire collection'),
clicked_callback = function() main(true) end
}
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not Ag.event_registered then
dt.register_event(
"AutoGrouper", "view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
Ag.event_registered = true
end
end
script_data.destroy = destroy
script_data.destroy_method = "hide"
script_data.restart = restart
script_data.show = restart
return script_data
--[[AutoGrouper plugin for darktable
copyright (c) 2019 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this Plugin
This plugin adds the module "Auto Group" to darktable's lighttable view
----REQUIRED SOFTWARE----
None
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Set a gap amount in second which will be used to determine when images should no
longer be added to a group. If an image is more then the specified amount of time
from the last image in the group it will not be added. Images without timestamps
in exif data will be ignored.
There are two buttons. One allows the grouping to be performed only on the currently
selected images, the other button performs grouping on the entire active collection
]]
local dt = require "darktable"
local du = require "lib/dtutils"
du.check_min_api_version("7.0.0", "AutoGrouper")
local MOD = 'autogrouper'
local gettext = dt.gettext
gettext.bindtextdomain(MOD, dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext.gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "AutoGrouper",
purpose = _("automatically group images by time interval"),
author = "Kevin Ertel",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/AutoGrouper/"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local Ag = {}
Ag.module_installed = false
Ag.event_registered = false
local GUI = {
gap = {},
selected = {},
collection = {}
}
local function InRange(test, low, high) --tests if test value is within range of low and high (inclusive)
if test >= low and test <= high then
return true
else
return false
end
end
local function CompTime(first, second) --compares the timestamps and returns true if first was taken before second
first_time = first.exif_datetime_taken
if string.match(first_time, '[0-9]') == nil then first_time = '9999:99:99 99:99:99' end
first_time = tonumber(string.gsub(first_time, '[^0-9]*',''))
second_time = second.exif_datetime_taken
if string.match(second_time, '[0-9]') == nil then second_time = '9999:99:99 99:99:99' end
second_time = tonumber(string.gsub(second_time, '[^0-9]*',''))
return first_time < second_time
end
local function SeperateTime(str) --seperates the timestamp into individual components for used with OS.time operations
local cleaned = string.gsub(str, '[^%d]',':')
cleaned = string.gsub(cleaned, '::*',':') --YYYY:MM:DD:hh:mm:ss
local year = string.sub(cleaned,1,4)
local month = string.sub(cleaned,6,7)
local day = string.sub(cleaned,9,10)
local hour = string.sub(cleaned,12,13)
local min = string.sub(cleaned,15,16)
local sec = string.sub(cleaned,18,19)
return {year = year, month = month, day = day, hour = hour, min = min, sec = sec}
end
local function GetTimeDiff(curr_image, prev_image) --returns the time difference (in sec.) from current image and the previous image
local curr_time = SeperateTime(curr_image.exif_datetime_taken)
local prev_time = SeperateTime(prev_image.exif_datetime_taken)
return os.time(curr_time)-os.time(prev_time)
end
local function main(on_collection)
local images = {}
if on_collection then
local col_images = dt.collection
for i,image in ipairs(col_images) do --copy images to a standard table, table.sort barfs on type dt_lua_singleton_image_collection
table.insert(images,i,image)
end
else
images = dt.gui.selection()
end
dt.preferences.write(MOD, 'active_gap', 'integer', GUI.gap.value)
if #images < 2 then
dt.print('please select at least 2 images')
return
end
table.sort(images, function(first, second) return CompTime(first,second) end) --sort images by timestamp
for i, image in ipairs(images) do
if i == 1 then
prev_image = image
elseif string.match(image.exif_datetime_taken, '[%d]') ~= nil then --make sure current image has a timestamp, if so check if it is within the user specified gap value and add to group
local curr_image = image
if GetTimeDiff(curr_image, prev_image) <= GUI.gap.value then
images[i]:group_with(images[i-1])
end
prev_image = curr_image
end
end
end
local function install_module()
if not Ag.module_installed then
dt.print_log("installing module")
dt.register_lib(
MOD, -- Module name
_('auto group'), -- name
true, -- expandable
true, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 99}}, -- containers
dt.new_widget("box"){
orientation = "vertical",
GUI.gap,
GUI.selected,
GUI.collection
}
)
Ag.module_installed = true
dt.print_log("module installed")
dt.print_log("styles module visibility is " .. tostring(dt.gui.libs["styles"].visible))
end
end
local function destroy()
dt.gui.libs[MOD].visible = false
end
local function restart()
dt.gui.libs[MOD].visible = true
end
-- GUI --
temp = dt.preferences.read(MOD, 'active_gap', 'integer')
if not InRange(temp, 1, 86400) then temp = 3 end
GUI.gap = dt.new_widget('slider'){
label = _('group gap [sec.]'),
tooltip = _('minimum gap, in seconds, between groups'),
soft_min = 1,
soft_max = 60,
hard_min = 1,
hard_max = 86400,
step = 1,
digits = 0,
value = temp,
reset_callback = function(self)
self.value = 3
end
}
GUI.selected = dt.new_widget("button"){
label = _('auto group: selected'),
tooltip =_('auto group selected images'),
clicked_callback = function() main(false) end
}
GUI.collection = dt.new_widget("button"){
label = _('auto group: collection'),
tooltip =_('auto group the entire collection'),
clicked_callback = function() main(true) end
}
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not Ag.event_registered then
dt.register_event(
"AutoGrouper", "view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
Ag.event_registered = true
end
end
script_data.destroy = destroy
script_data.destroy_method = "hide"
script_data.restart = restart
script_data.show = restart
return script_data

View File

@@ -1,253 +1,260 @@
--[[Collect Helper plugin for darktable
copyright (c) 2019 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this plugin
This plugin adds the button(s) to the "Selected Images" module:
1) Return to Previous Collection
2) Collect on image's Folder
3) Collect on image's Color Label(s)
4) Collect on All (AND)
It also adds 3 preferences to the lua options dialog box which allow the user to activate/deactivate the 3 "Collect on" buttons.
Button Behavior:
1) Return to Previous Collection - Will reset the collect parameters to the previously active settings
2) Collect on image's Folder - Will change the collect parameters to be "Folder" with a value of the selected image's folder location
3) Collect on image's Color Label(s) - Will change the collect parameter to be "Color" with a value of the selected images color labels, will apply multiple parameters with AND logic if multiple exist
4) Collect on All (AND) - Will collect on all parameters activated by the preferences dialog, as such this button is redundant if you only have one of the two other options enabled
----REQUIRED SOFTWARE----
NA
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Select the photo you wish to change you collection based on.
In the "Selected Images" module click on "Collect on this Image"
----KNOWN ISSUES----
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local gettext = dt.gettext.gettext
local previous = nil
local all_active = false
du.check_min_api_version("7.0.0", "CollectHelper")
-- return data structure for script_manager
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("CollectHelper", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- FUNCTION --
local function CheckSingleImage(selection)
if #selection ~= 1 then
dt.print(_("please select a single image"))
return true
end
return false
end
local function CheckHasColorLabel(selection)
local ret = false
for _,image in pairs(selection) do
if image.red then ret = true end
if image.blue then ret = true end
if image.green then ret = true end
if image.yellow then ret = true end
if image.purple then ret = true end
end
return ret
end
local function PreviousCollection()
if previous ~= nil then
previous = dt.gui.libs.collect.filter(previous)
end
end
local function CollectOnFolder(all_rules, all_active)
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
local rules = {}
local rule = dt.gui.libs.collect.new_rule()
rule.mode = "DT_LIB_COLLECT_MODE_AND"
rule.data = images[1].path
rule.item = "DT_COLLECTION_PROP_FOLDERS"
table.insert(rules, rule)
if all_active then
for _,active_rule in pairs(rules) do
table.insert(all_rules, active_rule)
end
return all_rules
else
previous = dt.gui.libs.collect.filter(rules)
end
end
local function CollectOnColors(all_rules, all_active)
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
if not CheckHasColorLabel(images) then
dt.print(_('select an image with an active color label'))
return
end
for _,image in pairs(images) do
local rules = {}
if image.red then
local red_rule = dt.gui.libs.collect.new_rule()
red_rule.mode = "DT_LIB_COLLECT_MODE_AND"
red_rule.data = "red"
red_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, red_rule)
end
if image.blue then
local blue_rule = dt.gui.libs.collect.new_rule()
blue_rule.mode = "DT_LIB_COLLECT_MODE_AND"
blue_rule.data = "blue"
blue_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, blue_rule)
end
if image.green then
local green_rule = dt.gui.libs.collect.new_rule()
green_rule.mode = "DT_LIB_COLLECT_MODE_AND"
green_rule.data = "green"
green_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, green_rule)
end
if image.yellow then
local yellow_rule = dt.gui.libs.collect.new_rule()
yellow_rule.mode = "DT_LIB_COLLECT_MODE_AND"
yellow_rule.data = "yellow"
yellow_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, yellow_rule)
end
if image.purple then
local purple_rule = dt.gui.libs.collect.new_rule()
purple_rule.mode = "DT_LIB_COLLECT_MODE_AND"
purple_rule.data = "purple"
purple_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, purple_rule)
end
if all_active then
for _,active_rule in pairs(rules) do
table.insert(all_rules, active_rule)
end
return all_rules
else
previous = dt.gui.libs.collect.filter(rules)
end
end
end
local function CollectOnAll_AND()
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
local rules = {}
if dt.preferences.read('module_CollectHelper','folder','bool') then
rules = CollectOnFolder(rules, true)
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
rules = CollectOnColors(rules, true)
end
previous = dt.gui.libs.collect.filter(rules)
end
local function destroy()
dt.gui.libs.image.destroy_action("CollectHelper_prev")
if dt.preferences.read('module_CollectHelper','folder','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_folder")
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_labels")
end
if dt.preferences.read('module_CollectHelper','all_and','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_and")
end
end
-- GUI --
dt.gui.libs.image.register_action(
"CollectHelper_prev", _("collect: previous"),
function() PreviousCollection() end,
_("sets the collect parameters to be the previously active parameters")
)
if dt.preferences.read('module_CollectHelper','folder','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_folder", _("collect: folder"),
function() CollectOnFolder(_ , false) end,
_("sets the collect parameters to be the selected images's folder")
)
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_labels", _("collect: color label(s)"),
function() CollectOnColors(_ , false) end,
_("sets the collect parameters to be the selected images's color label(s)")
)
end
if dt.preferences.read('module_CollectHelper','all_and','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_and", _("collect: all (AND)"),
function() CollectOnAll_AND() end,
_("sets the collect parameters based on all activated CollectHelper options")
)
end
-- PREFERENCES --
dt.preferences.register("module_CollectHelper", "all_and", -- name
"bool", -- type
_('CollectHelper: all'), -- label
_('will create a collect parameter set that utilizes all enabled CollectHelper types (and)'), -- tooltip
true -- default
)
dt.preferences.register("module_CollectHelper", "colors", -- name
"bool", -- type
_('CollectHelper: color label(s)'), -- label
_('enable the button that allows you to swap to a collection based on selected image\'s color label(s)'), -- tooltip
true -- default
)
dt.preferences.register("module_CollectHelper", "folder", -- name
"bool", -- type
_('CollectHelper: folder'), -- label
_('enable the button that allows you to swap to a collection based on selected image\'s folder location'), -- tooltip
true -- default
)
script_data.destroy = destroy
return script_data
--[[Collect Helper plugin for darktable
copyright (c) 2019 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this plugin
This plugin adds the button(s) to the "Selected Images" module:
1) Return to Previous Collection
2) Collect on image's Folder
3) Collect on image's Color Label(s)
4) Collect on All (AND)
It also adds 3 preferences to the lua options dialog box which allow the user to activate/deactivate the 3 "Collect on" buttons.
Button Behavior:
1) Return to Previous Collection - Will reset the collect parameters to the previously active settings
2) Collect on image's Folder - Will change the collect parameters to be "Folder" with a value of the selected image's folder location
3) Collect on image's Color Label(s) - Will change the collect parameter to be "Color" with a value of the selected images color labels, will apply multiple parameters with AND logic if multiple exist
4) Collect on All (AND) - Will collect on all parameters activated by the preferences dialog, as such this button is redundant if you only have one of the two other options enabled
----REQUIRED SOFTWARE----
NA
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Select the photo you wish to change you collection based on.
In the "Selected Images" module click on "Collect on this Image"
----KNOWN ISSUES----
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local gettext = dt.gettext.gettext
local previous = nil
local all_active = false
du.check_min_api_version("7.0.0", "CollectHelper")
dt.gettext.bindtextdomain("CollectHelper", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "CollectHelper",
purpose = _("add collection helper buttons"),
author = "Kevin Ertel",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/CollectHelper/"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- FUNCTION --
local function CheckSingleImage(selection)
if #selection ~= 1 then
dt.print(_("please select a single image"))
return true
end
return false
end
local function CheckHasColorLabel(selection)
local ret = false
for _,image in pairs(selection) do
if image.red then ret = true end
if image.blue then ret = true end
if image.green then ret = true end
if image.yellow then ret = true end
if image.purple then ret = true end
end
return ret
end
local function PreviousCollection()
if previous ~= nil then
previous = dt.gui.libs.collect.filter(previous)
end
end
local function CollectOnFolder(all_rules, all_active)
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
local rules = {}
local rule = dt.gui.libs.collect.new_rule()
rule.mode = "DT_LIB_COLLECT_MODE_AND"
rule.data = images[1].path
rule.item = "DT_COLLECTION_PROP_FOLDERS"
table.insert(rules, rule)
if all_active then
for _,active_rule in pairs(rules) do
table.insert(all_rules, active_rule)
end
return all_rules
else
previous = dt.gui.libs.collect.filter(rules)
end
end
local function CollectOnColors(all_rules, all_active)
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
if not CheckHasColorLabel(images) then
dt.print(_('select an image with an active color label'))
return
end
for _,image in pairs(images) do
local rules = {}
if image.red then
local red_rule = dt.gui.libs.collect.new_rule()
red_rule.mode = "DT_LIB_COLLECT_MODE_AND"
red_rule.data = "red"
red_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, red_rule)
end
if image.blue then
local blue_rule = dt.gui.libs.collect.new_rule()
blue_rule.mode = "DT_LIB_COLLECT_MODE_AND"
blue_rule.data = "blue"
blue_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, blue_rule)
end
if image.green then
local green_rule = dt.gui.libs.collect.new_rule()
green_rule.mode = "DT_LIB_COLLECT_MODE_AND"
green_rule.data = "green"
green_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, green_rule)
end
if image.yellow then
local yellow_rule = dt.gui.libs.collect.new_rule()
yellow_rule.mode = "DT_LIB_COLLECT_MODE_AND"
yellow_rule.data = "yellow"
yellow_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, yellow_rule)
end
if image.purple then
local purple_rule = dt.gui.libs.collect.new_rule()
purple_rule.mode = "DT_LIB_COLLECT_MODE_AND"
purple_rule.data = "purple"
purple_rule.item = "DT_COLLECTION_PROP_COLORLABEL"
table.insert(rules, purple_rule)
end
if all_active then
for _,active_rule in pairs(rules) do
table.insert(all_rules, active_rule)
end
return all_rules
else
previous = dt.gui.libs.collect.filter(rules)
end
end
end
local function CollectOnAll_AND()
local images = dt.gui.selection()
if CheckSingleImage(images) then
return
end
local rules = {}
if dt.preferences.read('module_CollectHelper','folder','bool') then
rules = CollectOnFolder(rules, true)
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
rules = CollectOnColors(rules, true)
end
previous = dt.gui.libs.collect.filter(rules)
end
local function destroy()
dt.gui.libs.image.destroy_action("CollectHelper_prev")
if dt.preferences.read('module_CollectHelper','folder','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_folder")
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_labels")
end
if dt.preferences.read('module_CollectHelper','all_and','bool') then
dt.gui.libs.image.destroy_action("CollectHelper_and")
end
end
-- GUI --
dt.gui.libs.image.register_action(
"CollectHelper_prev", _("collect: previous"),
function() PreviousCollection() end,
_("sets the collect parameters to be the previously active parameters")
)
if dt.preferences.read('module_CollectHelper','folder','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_folder", _("collect: folder"),
function() CollectOnFolder(_ , false) end,
_("sets the collect parameters to be the selected images's folder")
)
end
if dt.preferences.read('module_CollectHelper','colors','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_labels", _("collect: color label(s)"),
function() CollectOnColors(_ , false) end,
_("sets the collect parameters to be the selected images's color label(s)")
)
end
if dt.preferences.read('module_CollectHelper','all_and','bool') then
dt.gui.libs.image.register_action(
"CollectHelper_and", _("collect: all (AND)"),
function() CollectOnAll_AND() end,
_("sets the collect parameters based on all activated CollectHelper options")
)
end
-- PREFERENCES --
dt.preferences.register("module_CollectHelper", "all_and", -- name
"bool", -- type
_('CollectHelper: all'), -- label
_('will create a collect parameter set that utilizes all enabled CollectHelper types (and)'), -- tooltip
true -- default
)
dt.preferences.register("module_CollectHelper", "colors", -- name
"bool", -- type
_('CollectHelper: color label(s)'), -- label
_('enable the button that allows you to swap to a collection based on selected image\'s color label(s)'), -- tooltip
true -- default
)
dt.preferences.register("module_CollectHelper", "folder", -- name
"bool", -- type
_('CollectHelper: folder'), -- label
_('enable the button that allows you to swap to a collection based on selected image\'s folder location'), -- tooltip
true -- default
)
script_data.destroy = destroy
return script_data

View File

@@ -1,481 +1,488 @@
--[[HDRMerge plugin for darktable
copyright (c) 2018 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this Plugin
This plugin adds the module 'HDRMerge' to darktable's lighttable view
----REQUIRED SOFTWARE----
HDRMerge ver. 4.5 or greater
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your 'lua/contrib' folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
On the initial startup go to darktable settings > lua options and set your executable paths and other preferences, then restart darktable
Select bracketed images and press the Run HDRMerge button. The resulting DNG will be auto-imported into darktable.
Additional tags or style can be applied on auto import as well, if you desire.
Base Options:
Select your desired BPS (bits per sample and Embedded Preview Size.
Batch Options:
Select if you want to run in batch mode or not
Select the gap, in seconds, between images for auto grouping in batch mode
See HDRMerge manual for further detail: http://jcelaya.github.io/hdrmerge/documentation/2014/07/11/user-manual.html
Auto-import Options:
Select a style, whether you want tags to be copied from the original, and any additional tags you desire added when the new image is auto-imported
]]
local dt = require 'darktable'
local du = require "lib/dtutils"
local df = require 'lib/dtutils.file'
local dsys = require 'lib/dtutils.system'
du.check_min_api_version("7.0.0", "HDRmerge")
-- return data structure for script_manager
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local mod = 'module_HDRMerge'
local os_path_seperator = '/'
if dt.configuration.running_os == 'windows' then os_path_seperator = '\\' end
local CURR_API_STRING = dt.configuration.api_version_string
-- Tell gettext where to find the .mo file translating messages for a particular domain
local gettext = dt.gettext.gettext
gettext.bindtextdomain("HDRMerge", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local temp
local HDRM = { --HDRMerge Program Table
name = 'HDRMerge',
bin = '',
first_run = true,
install_error = false,
arg_string = '',
images_string = '',
args = {
bps = {text = '-b ', style = 'integer'},
size = {text = '-p ', style = 'string'},
batch = {text = '-B ', style = 'bool'},
gap = {text = '-g ', style = 'integer'}
}
}
local GUI = { --GUI Elements Table
HDR = {
bps ={},
size ={},
batch ={},
gap ={}
},
Target = {
style ={},
copy_tags ={},
add_tags ={}
},
run = {},
stack = {},
options = {},
exes = {
HDRMerge = {},
update = {},
}
}
HDRM.module_installed = false
HDRM.event_registered = false
--Detect User Styles--
local styles = dt.styles
local styles_count = 1 -- 'none' = 1
for _,i in pairs(dt.styles) do
if type(i) == 'userdata' then styles_count = styles_count + 1 end
end
local function InRange(test, low, high) --tests if test value is within range of low and high (inclusive)
if test >= low and test <= high then
return true
else
return false
end
end
local function GetFileName(full_path) --Parses a full path (path/filename_identifier.extension) into individual parts
--[[Input: Folder1/Folder2/Folder3/Img_0001.CR2
Returns:
path: Folder1/Folder2/Folder3/
filename: Img_0001
identifier: 0001
extension: .CR2
EX:
path_1, file_1, id_1, ext_1 = GetFileName(full_path_1)
]]
local path = string.match(full_path, '.*[\\/]')
local filename = string.gsub(string.match(full_path, '[%w-_]*%.') , '%.' , '' )
local identifier = string.match(filename, '%d*$')
local extension = string.match(full_path, '%.%w*')
return path, filename, identifier, extension
end
local function CleanSpaces(text) --removes spaces from the front and back of passed in text
text = string.gsub(text,'^%s*','')
text = string.gsub(text,'%s*$','')
return text
end
local function BuildExecuteCmd(prog_table) --creates a program command using elements of the passed in program table
local result = CleanSpaces(prog_table.bin)..' '..CleanSpaces(prog_table.arg_string)..' '..CleanSpaces(prog_table.images_string)
return result
end
local function PreCall(prog_tbl) --looks to see if this is the first call, if so checks to see if program is installed properly
for _,prog in pairs(prog_tbl) do
if prog.first_run then
prog.bin = df.check_if_bin_exists(prog.name)
if not prog.bin then
prog.install_error = true
dt.preferences.write(mod, 'bin_exists', 'bool', false)
else
prog.bin = CleanSpaces(prog.bin)
end
prog.first_run = false
end
end
if not dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 2
dt.print(_('please update you binary location'))
end
end
local function ExeUpdate(prog_tbl)
dt.preferences.write(mod, 'bin_exists', 'bool', true)
for _,prog in pairs(prog_tbl) do
dt.preferences.write('executable_paths', prog.name, 'string', GUI.exes[prog.name].value)
prog.bin = df.check_if_bin_exists(prog.name)
if not prog.bin then
prog.install_error = true
dt.preferences.write(mod, 'bin_exists', 'bool', false)
else
prog.bin = CleanSpaces(prog.bin)
end
prog.first_run = false
end
if dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 1
dt.print(_('update successful'))
else
dt.print(_('update unsuccessful, please try again'))
end
end
local function UpdateActivePreference() --sliders & entry boxes do not have a click/changed callback, so their values must be saved to the active preference
temp = GUI.HDR.gap.value
dt.preferences.write(mod, 'active_gap', 'integer', temp)
temp = GUI.Target.add_tags.text
dt.preferences.write(mod, 'active_add_tags', 'string', temp)
end
local function main()
PreCall({HDRM}) --check if furst run then check if install OK
if HDRM.install_error then
dt.print_error('HDRMerge install issue')
dt.print(_('HDRMerge install issue, please ensure the binary path is proper'))
return
end
images = dt.gui.selection() --get selected images
if #images < 2 then --ensure enough images selected
dt.print(_('not enough images selected, select at least 2 images to merge'))
return
end
UpdateActivePreference() --save current gui elements to active preference so those values will be pre-loaded at next startup
--create image string and output path
HDRM.images_string = ''
local out_path = ''
local smallest_id = math.huge
local smallest_name = ''
local largest_id = 0
local source_raw = {}
for _,image in pairs(images) do --loop to concat the images string, also track the image indexes for use in creating the final image name (eg; IMG_1034-1037.dng)
local curr_image = image.path..os_path_seperator..image.filename
HDRM.images_string = HDRM.images_string..df.sanitize_filename(curr_image)..' '
out_path = image.path
_unused, source_name, source_id = GetFileName(image.filename)
source_id = tonumber(source_id) or 0
if source_id < smallest_id then
smallest_id = source_id
smallest_name = source_name
source_raw = image
end
if source_id > largest_id then largest_id = source_id end
end
out_path = out_path..os_path_seperator..smallest_name..'-'..largest_id..'.dng'
out_path = df.create_unique_filename(out_path)
--create argument string
HDRM.arg_string = HDRM.args.bps.text..GUI.HDR.bps.value..' '..HDRM.args.size.text..GUI.HDR.size.value..' '
if GUI.HDR.batch.value then
HDRM.arg_string = HDRM.arg_string..HDRM.args.batch.text..HDRM.args.gap.text..math.floor(GUI.HDR.gap.value)..' -a'
else
HDRM.arg_string = HDRM.arg_string..'-o '..df.sanitize_filename(out_path)
end
-- create run command and execute
local run_cmd = BuildExecuteCmd(HDRM)
resp = dsys.external_command(run_cmd)
if resp == 0 and not GUI.HDR.batch.value then
local imported = dt.database.import(out_path) -- import the new file
if GUI.Target.style.selected > 1 then -- apply selected style
local set_style = styles[GUI.Target.style.selected - 1]
dt.styles.apply(set_style , imported)
end
if GUI.Target.copy_tags.value then -- copy tags from the original file (ignore 'darktable' generated tags)
local all_tags = dt.tags.get_tags(source_raw)
for _,tag in pairs(all_tags) do
if string.match(tag.name, 'darktable|') == nil then dt.tags.attach(tag, imported) end
end
end
local set_tag = GUI.Target.add_tags.text
if set_tag ~= nil then -- add additional user-specified tags
for tag in string.gmatch(set_tag, '[^,]+') do
tag = CleanSpaces(tag)
tag = dt.tags.create(tag)
dt.tags.attach(tag, imported)
end
end
dt.print(_('HDRMerge completed successfully'))
else
dt.print_error('HDRMerge failed')
dt.print(_('HDRMerge failed'))
end
end
local function install_module()
if not HDRM.module_installed then
dt.register_lib( -- register HDRMerge module
'HDRMerge_Lib', -- Module name
_('HDRMerge'), -- name
true, -- expandable
true, -- resetable
{[dt.gui.views.lighttable] = {'DT_UI_CONTAINER_PANEL_RIGHT_CENTER', 99}}, -- containers
dt.new_widget('box'){
orientation = 'vertical',
GUI.stack
}
)
HDRM.module_installed = true
end
end
local function destroy()
dt.gui.libs["HDRMerge_Lib"].visible = false
end
local function restart()
dt.gui.libs["HDRMerge_Lib"].visible = true
end
-- GUI Elements --
local lbl_hdr = dt.new_widget('section_label'){
label = _('HDRMerge options')
}
temp = dt.preferences.read(mod, 'active_bps_ind', 'integer')
if not InRange(temp, 1, 3) then temp = 3 end
GUI.HDR.bps = dt.new_widget('combobox'){
label = _('bits per sample'),
tooltip =_('number of bits per sample in the output image'),
selected = temp,
'16','24','32',
changed_callback = function(self)
dt.preferences.write(mod, 'active_bps', 'integer', self.value)
dt.preferences.write(mod, 'active_bps_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 3
dt.preferences.write(mod, 'active_bps', 'integer', self.value)
dt.preferences.write(mod, 'active_bps_ind', 'integer', self.selected)
end
}
temp = dt.preferences.read(mod, 'active_size_ind', 'integer')
if not InRange(temp, 1, 3) then temp = 2 end
GUI.HDR.size = dt.new_widget('combobox'){
label = _('embedded preview size'),
tooltip =_('size of the embedded preview in output image'),
selected = temp,
_('none'),_('half'),_('full'),
changed_callback = function(self)
dt.preferences.write(mod, 'active_size', 'string', self.value)
dt.preferences.write(mod, 'active_size_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 2
dt.preferences.write(mod, 'active_size', 'string', self.value)
dt.preferences.write(mod, 'active_size_ind', 'integer', self.selected)
end
}
GUI.HDR.batch = dt.new_widget('check_button'){
label = _('batch mode'),
value = dt.preferences.read(mod, 'active_batch', 'bool'),
tooltip = _('enable batch mode operation \nNOTE: resultant files will NOT be auto-imported'),
clicked_callback = function(self)
dt.preferences.write(mod, 'active_batch', 'bool', self.value)
GUI.HDR.gap.sensitive = self.value
end,
reset_callback = function(self) self.value = false end
}
temp = dt.preferences.read(mod, 'active_gap', 'integer')
if not InRange(temp, 1, 3600) then temp = 3 end
GUI.HDR.gap = dt.new_widget('slider'){
label = _('batch gap [sec.]'),
tooltip = _('gap, in seconds, between batch mode groups'),
soft_min = 1,
soft_max = 30,
hard_min = 1,
hard_max = 3600,
step = 1,
digits = 0,
value = temp,
sensitive = GUI.HDR.batch.value,
reset_callback = function(self)
self.value = 3
end
}
local lbl_import = dt.new_widget('section_label'){
label = _('import options')
}
GUI.Target.style = dt.new_widget('combobox'){
label = _('apply style on import'),
tooltip = _('apply selected style on auto-import to newly created image'),
selected = 1,
_('none'),
changed_callback = function(self)
dt.preferences.write(mod, 'active_style', 'string', self.value)
dt.preferences.write(mod, 'active_style_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 1
dt.preferences.write(mod, 'active_style', 'string', self.value)
dt.preferences.write(mod, 'active_style_ind', 'integer', self.selected)
end
}
for k=1, (styles_count-1) do
GUI.Target.style[k+1] = styles[k].name
end
temp = dt.preferences.read(mod, 'active_style_ind', 'integer')
if not InRange(temp, 1, styles_count) then temp = 1 end
GUI.Target.style.selected = temp
GUI.Target.copy_tags = dt.new_widget('check_button'){
label = _('copy tags'),
value = dt.preferences.read(mod, 'active_copy_tags', 'bool'),
tooltip = _('copy tags from first source image'),
clicked_callback = function(self) dt.preferences.write(mod, 'active_copy_tags', 'bool', self.value) end,
reset_callback = function(self) self.value = true end
}
temp = dt.preferences.read(mod, 'active_add_tags', 'string')
if temp == '' then temp = nil end
GUI.Target.add_tags = dt.new_widget('entry'){
tooltip = _('additional tags to be added on import, seperate with commas, all spaces will be removed'),
text = temp,
placeholder = _('enter tags, seperated by commas'),
editable = true
}
GUI.run = dt.new_widget('button'){
label = _('merge'),
tooltip =_('run HDRMerge with the above specified settings'),
clicked_callback = function() main() end
}
GUI.exes.HDRMerge = dt.new_widget('file_chooser_button'){
title = _('select HDRmerge executable'),
value = df.get_executable_path_preference(HDRM.name),
is_directory = false
}
GUI.exes.update = dt.new_widget('button'){
label = _('update'),
tooltip =_('update the binary path with current value'),
clicked_callback = function() ExeUpdate({HDRM}) end
}
GUI.options = dt.new_widget('box'){
orientation = 'vertical',
lbl_hdr,
GUI.HDR.bps,
GUI.HDR.size,
GUI.HDR.batch,
GUI.HDR.gap,
lbl_import,
GUI.Target.style,
GUI.Target.copy_tags,
GUI.Target.add_tags,
GUI.run
}
local exes_box = dt.new_widget('box'){
orientation = 'vertical',
GUI.exes.HDRMerge,
GUI.exes.update
}
GUI.stack = dt.new_widget('stack'){
GUI.options,
exes_box
}
if dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 1
else
GUI.stack.active = 2
end
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not HDRM.event_registered then
dt.register_event(
"HDRmerge", "view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
HDRM.event_registered = true
end
end
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"
script_data.show = restart
--[[HDRMerge plugin for darktable
copyright (c) 2018 Kevin Ertel
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this Plugin
This plugin adds the module 'HDRMerge' to darktable's lighttable view
----REQUIRED SOFTWARE----
HDRMerge ver. 4.5 or greater
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file in to your 'lua/contrib' folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
On the initial startup go to darktable settings > lua options and set your executable paths and other preferences, then restart darktable
Select bracketed images and press the Run HDRMerge button. The resulting DNG will be auto-imported into darktable.
Additional tags or style can be applied on auto import as well, if you desire.
Base Options:
Select your desired BPS (bits per sample and Embedded Preview Size.
Batch Options:
Select if you want to run in batch mode or not
Select the gap, in seconds, between images for auto grouping in batch mode
See HDRMerge manual for further detail: http://jcelaya.github.io/hdrmerge/documentation/2014/07/11/user-manual.html
Auto-import Options:
Select a style, whether you want tags to be copied from the original, and any additional tags you desire added when the new image is auto-imported
]]
local dt = require 'darktable'
local du = require "lib/dtutils"
local df = require 'lib/dtutils.file'
local dsys = require 'lib/dtutils.system'
du.check_min_api_version("7.0.0", "HDRmerge")
-- Tell gettext where to find the .mo file translating messages for a particular domain
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("HDRMerge", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "HDRmerge",
purpose = _("merge bracketed images into an HDR DNG image"),
author = "Kevin Ertel",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/HDRmerge"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local mod = 'module_HDRMerge'
local os_path_seperator = '/'
if dt.configuration.running_os == 'windows' then os_path_seperator = '\\' end
local CURR_API_STRING = dt.configuration.api_version_string
local temp
local HDRM = { --HDRMerge Program Table
name = 'HDRMerge',
bin = '',
first_run = true,
install_error = false,
arg_string = '',
images_string = '',
args = {
bps = {text = '-b ', style = 'integer'},
size = {text = '-p ', style = 'string'},
batch = {text = '-B ', style = 'bool'},
gap = {text = '-g ', style = 'integer'}
}
}
local GUI = { --GUI Elements Table
HDR = {
bps ={},
size ={},
batch ={},
gap ={}
},
Target = {
style ={},
copy_tags ={},
add_tags ={}
},
run = {},
stack = {},
options = {},
exes = {
HDRMerge = {},
update = {},
}
}
HDRM.module_installed = false
HDRM.event_registered = false
--Detect User Styles--
local styles = dt.styles
local styles_count = 1 -- 'none' = 1
for _,i in pairs(dt.styles) do
if type(i) == 'userdata' then styles_count = styles_count + 1 end
end
local function InRange(test, low, high) --tests if test value is within range of low and high (inclusive)
if test >= low and test <= high then
return true
else
return false
end
end
local function GetFileName(full_path) --Parses a full path (path/filename_identifier.extension) into individual parts
--[[Input: Folder1/Folder2/Folder3/Img_0001.CR2
Returns:
path: Folder1/Folder2/Folder3/
filename: Img_0001
identifier: 0001
extension: .CR2
EX:
path_1, file_1, id_1, ext_1 = GetFileName(full_path_1)
]]
local path = string.match(full_path, '.*[\\/]')
local filename = string.gsub(string.match(full_path, '[%w-_]*%.') , '%.' , '' )
local identifier = string.match(filename, '%d*$')
local extension = string.match(full_path, '%.%w*')
return path, filename, identifier, extension
end
local function CleanSpaces(text) --removes spaces from the front and back of passed in text
text = string.gsub(text,'^%s*','')
text = string.gsub(text,'%s*$','')
return text
end
local function BuildExecuteCmd(prog_table) --creates a program command using elements of the passed in program table
local result = CleanSpaces(prog_table.bin)..' '..CleanSpaces(prog_table.arg_string)..' '..CleanSpaces(prog_table.images_string)
return result
end
local function PreCall(prog_tbl) --looks to see if this is the first call, if so checks to see if program is installed properly
for _,prog in pairs(prog_tbl) do
if prog.first_run then
prog.bin = df.check_if_bin_exists(prog.name)
if not prog.bin then
prog.install_error = true
dt.preferences.write(mod, 'bin_exists', 'bool', false)
else
prog.bin = CleanSpaces(prog.bin)
end
prog.first_run = false
end
end
if not dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 2
dt.print(_('please update you binary location'))
end
end
local function ExeUpdate(prog_tbl)
dt.preferences.write(mod, 'bin_exists', 'bool', true)
for _,prog in pairs(prog_tbl) do
dt.preferences.write('executable_paths', prog.name, 'string', GUI.exes[prog.name].value)
prog.bin = df.check_if_bin_exists(prog.name)
if not prog.bin then
prog.install_error = true
dt.preferences.write(mod, 'bin_exists', 'bool', false)
else
prog.bin = CleanSpaces(prog.bin)
end
prog.first_run = false
end
if dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 1
dt.print(_('update successful'))
else
dt.print(_('update unsuccessful, please try again'))
end
end
local function UpdateActivePreference() --sliders & entry boxes do not have a click/changed callback, so their values must be saved to the active preference
temp = GUI.HDR.gap.value
dt.preferences.write(mod, 'active_gap', 'integer', temp)
temp = GUI.Target.add_tags.text
dt.preferences.write(mod, 'active_add_tags', 'string', temp)
end
local function main()
PreCall({HDRM}) --check if furst run then check if install OK
if HDRM.install_error then
dt.print_error('HDRMerge install issue')
dt.print(_('HDRMerge install issue, please ensure the binary path is proper'))
return
end
images = dt.gui.selection() --get selected images
if #images < 2 then --ensure enough images selected
dt.print(_('not enough images selected, select at least 2 images to merge'))
return
end
UpdateActivePreference() --save current gui elements to active preference so those values will be pre-loaded at next startup
--create image string and output path
HDRM.images_string = ''
local out_path = ''
local smallest_id = math.huge
local smallest_name = ''
local largest_id = 0
local source_raw = {}
for _,image in pairs(images) do --loop to concat the images string, also track the image indexes for use in creating the final image name (eg; IMG_1034-1037.dng)
local curr_image = image.path..os_path_seperator..image.filename
HDRM.images_string = HDRM.images_string..df.sanitize_filename(curr_image)..' '
out_path = image.path
_unused, source_name, source_id = GetFileName(image.filename)
source_id = tonumber(source_id) or 0
if source_id < smallest_id then
smallest_id = source_id
smallest_name = source_name
source_raw = image
end
if source_id > largest_id then largest_id = source_id end
end
out_path = out_path..os_path_seperator..smallest_name..'-'..largest_id..'.dng'
out_path = df.create_unique_filename(out_path)
--create argument string
HDRM.arg_string = HDRM.args.bps.text..GUI.HDR.bps.value..' '..HDRM.args.size.text..GUI.HDR.size.value..' '
if GUI.HDR.batch.value then
HDRM.arg_string = HDRM.arg_string..HDRM.args.batch.text..HDRM.args.gap.text..math.floor(GUI.HDR.gap.value)..' -a'
else
HDRM.arg_string = HDRM.arg_string..'-o '..df.sanitize_filename(out_path)
end
-- create run command and execute
local run_cmd = BuildExecuteCmd(HDRM)
resp = dsys.external_command(run_cmd)
if resp == 0 and not GUI.HDR.batch.value then
local imported = dt.database.import(out_path) -- import the new file
if GUI.Target.style.selected > 1 then -- apply selected style
local set_style = styles[GUI.Target.style.selected - 1]
dt.styles.apply(set_style , imported)
end
if GUI.Target.copy_tags.value then -- copy tags from the original file (ignore 'darktable' generated tags)
local all_tags = dt.tags.get_tags(source_raw)
for _,tag in pairs(all_tags) do
if string.match(tag.name, 'darktable|') == nil then dt.tags.attach(tag, imported) end
end
end
local set_tag = GUI.Target.add_tags.text
if set_tag ~= nil then -- add additional user-specified tags
for tag in string.gmatch(set_tag, '[^,]+') do
tag = CleanSpaces(tag)
tag = dt.tags.create(tag)
dt.tags.attach(tag, imported)
end
end
dt.print(_('HDRMerge completed successfully'))
else
dt.print_error('HDRMerge failed')
dt.print(_('HDRMerge failed'))
end
end
local function install_module()
if not HDRM.module_installed then
dt.register_lib( -- register HDRMerge module
'HDRMerge_Lib', -- Module name
_('HDRMerge'), -- name
true, -- expandable
true, -- resetable
{[dt.gui.views.lighttable] = {'DT_UI_CONTAINER_PANEL_RIGHT_CENTER', 99}}, -- containers
dt.new_widget('box'){
orientation = 'vertical',
GUI.stack
}
)
HDRM.module_installed = true
end
end
local function destroy()
dt.gui.libs["HDRMerge_Lib"].visible = false
end
local function restart()
dt.gui.libs["HDRMerge_Lib"].visible = true
end
-- GUI Elements --
local lbl_hdr = dt.new_widget('section_label'){
label = _('HDRMerge options')
}
temp = dt.preferences.read(mod, 'active_bps_ind', 'integer')
if not InRange(temp, 1, 3) then temp = 3 end
GUI.HDR.bps = dt.new_widget('combobox'){
label = _('bits per sample'),
tooltip =_('number of bits per sample in the output image'),
selected = temp,
'16','24','32',
changed_callback = function(self)
dt.preferences.write(mod, 'active_bps', 'integer', self.value)
dt.preferences.write(mod, 'active_bps_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 3
dt.preferences.write(mod, 'active_bps', 'integer', self.value)
dt.preferences.write(mod, 'active_bps_ind', 'integer', self.selected)
end
}
temp = dt.preferences.read(mod, 'active_size_ind', 'integer')
if not InRange(temp, 1, 3) then temp = 2 end
GUI.HDR.size = dt.new_widget('combobox'){
label = _('embedded preview size'),
tooltip =_('size of the embedded preview in output image'),
selected = temp,
_('none'),_('half'),_('full'),
changed_callback = function(self)
dt.preferences.write(mod, 'active_size', 'string', self.value)
dt.preferences.write(mod, 'active_size_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 2
dt.preferences.write(mod, 'active_size', 'string', self.value)
dt.preferences.write(mod, 'active_size_ind', 'integer', self.selected)
end
}
GUI.HDR.batch = dt.new_widget('check_button'){
label = _('batch mode'),
value = dt.preferences.read(mod, 'active_batch', 'bool'),
tooltip = _('enable batch mode operation \nNOTE: resultant files will NOT be auto-imported'),
clicked_callback = function(self)
dt.preferences.write(mod, 'active_batch', 'bool', self.value)
GUI.HDR.gap.sensitive = self.value
end,
reset_callback = function(self) self.value = false end
}
temp = dt.preferences.read(mod, 'active_gap', 'integer')
if not InRange(temp, 1, 3600) then temp = 3 end
GUI.HDR.gap = dt.new_widget('slider'){
label = _('batch gap [sec.]'),
tooltip = _('gap, in seconds, between batch mode groups'),
soft_min = 1,
soft_max = 30,
hard_min = 1,
hard_max = 3600,
step = 1,
digits = 0,
value = temp,
sensitive = GUI.HDR.batch.value,
reset_callback = function(self)
self.value = 3
end
}
local lbl_import = dt.new_widget('section_label'){
label = _('import options')
}
GUI.Target.style = dt.new_widget('combobox'){
label = _('apply style on import'),
tooltip = _('apply selected style on auto-import to newly created image'),
selected = 1,
_('none'),
changed_callback = function(self)
dt.preferences.write(mod, 'active_style', 'string', self.value)
dt.preferences.write(mod, 'active_style_ind', 'integer', self.selected)
end,
reset_callback = function(self)
self.selected = 1
dt.preferences.write(mod, 'active_style', 'string', self.value)
dt.preferences.write(mod, 'active_style_ind', 'integer', self.selected)
end
}
for k=1, (styles_count-1) do
GUI.Target.style[k+1] = styles[k].name
end
temp = dt.preferences.read(mod, 'active_style_ind', 'integer')
if not InRange(temp, 1, styles_count) then temp = 1 end
GUI.Target.style.selected = temp
GUI.Target.copy_tags = dt.new_widget('check_button'){
label = _('copy tags'),
value = dt.preferences.read(mod, 'active_copy_tags', 'bool'),
tooltip = _('copy tags from first source image'),
clicked_callback = function(self) dt.preferences.write(mod, 'active_copy_tags', 'bool', self.value) end,
reset_callback = function(self) self.value = true end
}
temp = dt.preferences.read(mod, 'active_add_tags', 'string')
if temp == '' then temp = nil end
GUI.Target.add_tags = dt.new_widget('entry'){
tooltip = _('additional tags to be added on import, seperate with commas, all spaces will be removed'),
text = temp,
placeholder = _('enter tags, seperated by commas'),
editable = true
}
GUI.run = dt.new_widget('button'){
label = _('merge'),
tooltip =_('run HDRMerge with the above specified settings'),
clicked_callback = function() main() end
}
GUI.exes.HDRMerge = dt.new_widget('file_chooser_button'){
title = _('select HDRmerge executable'),
value = df.get_executable_path_preference(HDRM.name),
is_directory = false
}
GUI.exes.update = dt.new_widget('button'){
label = _('update'),
tooltip =_('update the binary path with current value'),
clicked_callback = function() ExeUpdate({HDRM}) end
}
GUI.options = dt.new_widget('box'){
orientation = 'vertical',
lbl_hdr,
GUI.HDR.bps,
GUI.HDR.size,
GUI.HDR.batch,
GUI.HDR.gap,
lbl_import,
GUI.Target.style,
GUI.Target.copy_tags,
GUI.Target.add_tags,
GUI.run
}
local exes_box = dt.new_widget('box'){
orientation = 'vertical',
GUI.exes.HDRMerge,
GUI.exes.update
}
GUI.stack = dt.new_widget('stack'){
GUI.options,
exes_box
}
if dt.preferences.read(mod, 'bin_exists', 'bool') then
GUI.stack.active = 1
else
GUI.stack.active = 2
end
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not HDRM.event_registered then
dt.register_event(
"HDRmerge", "view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
HDRM.event_registered = true
end
end
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"
script_data.show = restart
return script_data

View File

@@ -52,9 +52,9 @@ local du = require "lib/dtutils"
du.check_min_api_version("7.0.0", "LabelsToTags")
local gettext = dt.gettext.gettext
local gettext = darktable.gettext.gettext
gettext.bindtextdomain("LabelsToTags", dt.configuration.config_dir .."/lua/locale/")
darktable.gettext.bindtextdomain("LabelsToTags", darktable.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -64,6 +64,13 @@ end
local script_data = {}
script_data.metadata = {
name = "LabelsToTags",
purpose = _("allows the mass-application of tags using color labels and ratings as a guide"),
author = "August Schwerdfeger (august@schwerdfeger.name)",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/LabelsToTags"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -1,237 +1,244 @@
--[[
OpenInExplorer plugin for darktable
copyright (c) 2018 Kevin Ertel
Update 2020 and macOS support by Volker Lenhardt
Linux support 2020 by Bill Ferguson
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this plugin
This plugin adds the module "OpenInExplorer" to darktable's lighttable view.
----REQUIRED SOFTWARE----
Apple macOS, Microsoft Windows or Linux
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file into your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Select the photo(s) you wish to find in your operating system's file manager and press "show in file explorer" in the "selected images" section.
- Nautilus (Linux), Explorer (Windows), and Finder (macOS prior to Mojave) will open one window for each selected image at the file's location. The file name will be highlighted.
- On macOS Mojave and Catalina the Finder will open one window for each different directory. In these windows only the last one of the corresponding files will be highlighted (bug or feature?).
- Dolphin (Linux) will open one window with tabs for the different directories. All the selected images' file names are highlighted in their respective directories.
As an alternative option you can choose to show the image file names as symbolic links in an arbitrary directory. Go to preferences|Lua options. This option is not available for Windows users as on Windows solely admins are allowed to create links.
- Pros: You do not clutter up your display with multiple windows. So there is no need to limit the number of selections.
- Cons: If you want to work with the files you are one step behind the original data.
----KNOWN ISSUES----
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
local dsys = require "lib/dtutils.system"
local gettext = dt.gettext.gettext
--Check API version
du.check_min_api_version("7.0.0", "OpenInExplorer")
-- return data structure for script_manager
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("OpenInExplorer", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local act_os = dt.configuration.running_os
local PS = act_os == "windows" and "\\" or "/"
--Detect OS and quit if it is not supported.
if act_os ~= "macos" and act_os ~= "windows" and act_os ~= "linux" then
dt.print(_("OpenInExplorer plug-in only supports linux, macos, and windows at this time"))
dt.print_error("OpenInExplorer plug-in only supports Linux, macOS, and Windows at this time")
return
end
local use_links, links_dir = false, ""
if act_os ~= "windows" then
use_links = dt.preferences.read("OpenInExplorer", "use_links", "bool")
links_dir = dt.preferences.read("OpenInExplorer", "linked_image_files_dir", "string")
end
--Check if the directory exists that was chosen for the file links. Return boolean.
local function check_if_links_dir_exists()
local dir_exists = true
if not links_dir then
--Just for paranoic reasons. I tried, but I couldn't devise a setting for a nil value.
dt.print(_("no links directory selected\nplease check the dt preferences (lua options)"))
dt.print_error("OpenInExplorer: No links directory selected")
dir_exists = false
elseif not df.check_if_file_exists(links_dir) then
dt.print(string.format(_("links directory '%s' not found\nplease check the dt preferences (lua options)"), links_dir))
dt.print_error(string.format("OpenInExplorer: Links directory '%s' not found", links_dir))
dir_exists = false
end
return dir_exists
end
--Format strings for the commands to open the corresponding OS's file manager.
local open_dir = {}
open_dir.windows = "explorer.exe /n, %s"
open_dir.macos = "open %s"
open_dir.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowFolders ass 1 %s ""]]
local open_files = {}
open_files.windows = "explorer.exe /select, %s"
open_files.macos = "open -Rn %s"
open_files.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowItems ass %d %s ""]]
--Call the file mangager for each selected image on Linux.
--There is one call to busctl containing a list of all the image file names.
local function call_list_of_files(selected_images)
local current_image, file_uris, run_cmd = "", "", ""
for _, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
file_uris = file_uris .. df.sanitize_filename("file://" .. current_image) .. " "
dt.print_log("file_uris is " .. file_uris)
end
run_cmd = string.format(open_files.linux, #selected_images, file_uris)
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
--Call the file manager for each selected image on Windows and macOS.
local function call_file_by_file(selected_images)
local current_image, run_cmd = "", ""
for _, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
run_cmd = string.format(open_files[act_os], df.sanitize_filename(current_image))
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
end
--Create a link for each selected image, and finally call the file manager.
local function set_links(selected_images)
local current_image, link_target, run_cmd, k = "", "", "", nil
for k, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
link_target = df.create_unique_filename(links_dir .. PS .. image.filename)
run_cmd = string.format("ln -s %s %s", df.sanitize_filename(current_image), df.sanitize_filename(link_target))
--[[
In case Windows will allow normal users to create soft links:
if act_os == "windows" then
run_cmd = string.format("mklink %s %s", df.sanitize_filename(link_target), df.sanitize_filename(current_image))
end
]]
if dsys.external_command(run_cmd) ~= 0 then
dt.print(_("failed to create links, missing rights?"))
dt.print_error("OpenInExplorer: Failed to create links")
return
end
end
--The URI format is necessary only for the Linux busctl command.
--But it is accepted by the Windows Explorer and macOS's Finder all the same.
run_cmd = string.format(open_dir[act_os], df.sanitize_filename("file://"..links_dir))
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
--The working function that starts the particular task.
local function open_in_fmanager()
local images = dt.gui.selection()
if #images == 0 then
dt.print(_("please select an image"))
else
if use_links and not check_if_links_dir_exists() then
return
end
if #images > 15 and not use_links then
dt.print(_("please select fewer images (max. 15)"))
elseif use_links then
set_links(images)
else
if act_os == "linux" then
call_list_of_files(images)
else
call_file_by_file(images)
end
end
end
end
local function destroy()
dt.gui.libs.image.destroy_action("OpenInExplorer")
dt.destroy_event("OpenInExplorer", "shortcut")
if act_os ~= "windows" then
dt.preferences.destroy("OpenInExplorer", "linked_image_files_dir")
end
dt.preferences.destroy("OpenInExplorer", "use_links")
end
-- GUI --
dt.gui.libs.image.register_action(
"OpenInExplorer", _("show in file explorer"),
function() open_in_fmanager() end,
_("open the file manager at the selected image's location")
)
if act_os ~= "windows" then
dt.preferences.register("OpenInExplorer", "linked_image_files_dir", -- name
"directory", -- type
_("OpenInExplorer: linked files directory"), -- label
_("directory to store the links to the file names, requires restart to take effect"), -- tooltip
"Links to image files", -- default
dt.new_widget("file_chooser_button"){
title = _("select directory"),
is_directory = true,
}
)
dt.preferences.register("OpenInExplorer", "use_links", -- name
"bool", -- type
_("OpenInExplorer: use links"), -- label
_("use links instead of multiple windows, requires restart to take effect"), -- tooltip
false, -- default
""
)
end
dt.register_event(
"OpenInExplorer", "shortcut",
function(event, shortcut) open_in_fmanager() end,
"OpenInExplorer"
)
script_data.destroy = destroy
return script_data
--[[
OpenInExplorer plugin for darktable
copyright (c) 2018 Kevin Ertel
Update 2020 and macOS support by Volker Lenhardt
Linux support 2020 by Bill Ferguson
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[About this plugin
This plugin adds the module "OpenInExplorer" to darktable's lighttable view.
----REQUIRED SOFTWARE----
Apple macOS, Microsoft Windows or Linux
----USAGE----
Install: (see here for more detail: https://github.com/darktable-org/lua-scripts )
1) Copy this file into your "lua/contrib" folder where all other scripts reside.
2) Require this file in your luarc file, as with any other dt plug-in
Select the photo(s) you wish to find in your operating system's file manager and press "show in file explorer" in the "selected images" section.
- Nautilus (Linux), Explorer (Windows), and Finder (macOS prior to Mojave) will open one window for each selected image at the file's location. The file name will be highlighted.
- On macOS Mojave and Catalina the Finder will open one window for each different directory. In these windows only the last one of the corresponding files will be highlighted (bug or feature?).
- Dolphin (Linux) will open one window with tabs for the different directories. All the selected images' file names are highlighted in their respective directories.
As an alternative option you can choose to show the image file names as symbolic links in an arbitrary directory. Go to preferences|Lua options. This option is not available for Windows users as on Windows solely admins are allowed to create links.
- Pros: You do not clutter up your display with multiple windows. So there is no need to limit the number of selections.
- Cons: If you want to work with the files you are one step behind the original data.
----KNOWN ISSUES----
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
local dsys = require "lib/dtutils.system"
local gettext = dt.gettext.gettext
--Check API version
du.check_min_api_version("7.0.0", "OpenInExplorer")
dt.gettext.bindtextdomain("OpenInExplorer", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "OpenInExplorer",
purpose = _("open a selected file in the system file manager"),
author = "Kevin Ertel",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/OpenInExplorer"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local act_os = dt.configuration.running_os
local PS = act_os == "windows" and "\\" or "/"
--Detect OS and quit if it is not supported.
if act_os ~= "macos" and act_os ~= "windows" and act_os ~= "linux" then
dt.print(_("OpenInExplorer plug-in only supports linux, macos, and windows at this time"))
dt.print_error("OpenInExplorer plug-in only supports Linux, macOS, and Windows at this time")
return
end
local use_links, links_dir = false, ""
if act_os ~= "windows" then
use_links = dt.preferences.read("OpenInExplorer", "use_links", "bool")
links_dir = dt.preferences.read("OpenInExplorer", "linked_image_files_dir", "string")
end
--Check if the directory exists that was chosen for the file links. Return boolean.
local function check_if_links_dir_exists()
local dir_exists = true
if not links_dir then
--Just for paranoic reasons. I tried, but I couldn't devise a setting for a nil value.
dt.print(_("no links directory selected\nplease check the dt preferences (lua options)"))
dt.print_error("OpenInExplorer: No links directory selected")
dir_exists = false
elseif not df.check_if_file_exists(links_dir) then
dt.print(string.format(_("links directory '%s' not found\nplease check the dt preferences (lua options)"), links_dir))
dt.print_error(string.format("OpenInExplorer: Links directory '%s' not found", links_dir))
dir_exists = false
end
return dir_exists
end
--Format strings for the commands to open the corresponding OS's file manager.
local open_dir = {}
open_dir.windows = "explorer.exe /n, %s"
open_dir.macos = "open %s"
open_dir.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowFolders ass 1 %s ""]]
local open_files = {}
open_files.windows = "explorer.exe /select, %s"
open_files.macos = "open -Rn %s"
open_files.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowItems ass %d %s ""]]
--Call the file mangager for each selected image on Linux.
--There is one call to busctl containing a list of all the image file names.
local function call_list_of_files(selected_images)
local current_image, file_uris, run_cmd = "", "", ""
for _, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
file_uris = file_uris .. df.sanitize_filename("file://" .. current_image) .. " "
dt.print_log("file_uris is " .. file_uris)
end
run_cmd = string.format(open_files.linux, #selected_images, file_uris)
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
--Call the file manager for each selected image on Windows and macOS.
local function call_file_by_file(selected_images)
local current_image, run_cmd = "", ""
for _, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
run_cmd = string.format(open_files[act_os], df.sanitize_filename(current_image))
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
end
--Create a link for each selected image, and finally call the file manager.
local function set_links(selected_images)
local current_image, link_target, run_cmd, k = "", "", "", nil
for k, image in pairs(selected_images) do
current_image = image.path..PS..image.filename
link_target = df.create_unique_filename(links_dir .. PS .. image.filename)
run_cmd = string.format("ln -s %s %s", df.sanitize_filename(current_image), df.sanitize_filename(link_target))
--[[
In case Windows will allow normal users to create soft links:
if act_os == "windows" then
run_cmd = string.format("mklink %s %s", df.sanitize_filename(link_target), df.sanitize_filename(current_image))
end
]]
if dsys.external_command(run_cmd) ~= 0 then
dt.print(_("failed to create links, missing rights?"))
dt.print_error("OpenInExplorer: Failed to create links")
return
end
end
--The URI format is necessary only for the Linux busctl command.
--But it is accepted by the Windows Explorer and macOS's Finder all the same.
run_cmd = string.format(open_dir[act_os], df.sanitize_filename("file://"..links_dir))
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
dsys.external_command(run_cmd)
end
--The working function that starts the particular task.
local function open_in_fmanager()
local images = dt.gui.selection()
if #images == 0 then
dt.print(_("please select an image"))
else
if use_links and not check_if_links_dir_exists() then
return
end
if #images > 15 and not use_links then
dt.print(_("please select fewer images (max. 15)"))
elseif use_links then
set_links(images)
else
if act_os == "linux" then
call_list_of_files(images)
else
call_file_by_file(images)
end
end
end
end
local function destroy()
dt.gui.libs.image.destroy_action("OpenInExplorer")
dt.destroy_event("OpenInExplorer", "shortcut")
if act_os ~= "windows" then
dt.preferences.destroy("OpenInExplorer", "linked_image_files_dir")
end
dt.preferences.destroy("OpenInExplorer", "use_links")
end
-- GUI --
dt.gui.libs.image.register_action(
"OpenInExplorer", _("show in file explorer"),
function() open_in_fmanager() end,
_("open the file manager at the selected image's location")
)
if act_os ~= "windows" then
dt.preferences.register("OpenInExplorer", "linked_image_files_dir", -- name
"directory", -- type
_("OpenInExplorer: linked files directory"), -- label
_("directory to store the links to the file names, requires restart to take effect"), -- tooltip
"Links to image files", -- default
dt.new_widget("file_chooser_button"){
title = _("select directory"),
is_directory = true,
}
)
dt.preferences.register("OpenInExplorer", "use_links", -- name
"bool", -- type
_("OpenInExplorer: use links"), -- label
_("use links instead of multiple windows, requires restart to take effect"), -- tooltip
false, -- default
""
)
end
dt.register_event(
"OpenInExplorer", "shortcut",
function(event, shortcut) open_in_fmanager() end,
"OpenInExplorer"
)
script_data.destroy = destroy
return script_data

View File

@@ -65,10 +65,26 @@ local MODULE_NAME = "RL_out_sharp"
-- check API version
du.check_min_api_version("7.0.0", MODULE_NAME)
-- translation
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("RL_out_sharp", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "RL_out_sharp",
purpose = _("Richardson-Lucy output sharpening using GMic"),
author = "Marco Carrarini <marco.carrarini@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/RL_out_sharp"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -77,15 +93,6 @@ script_data.show = nil -- only required for libs since the destroy_method only h
-- OS compatibility
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
-- translation
local gettext = dt.gettext.gettext
gettext.bindtextdomain("RL_out_sharp", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- initialize module preferences
if not dt.preferences.read(MODULE_NAME, "initialized", "bool") then
dt.preferences.write(MODULE_NAME, "sigma", "string", "0.7")

View File

@@ -43,7 +43,7 @@ local filelib = require "lib/dtutils.file"
du.check_min_api_version("7.0.0", "autostyle")
local gettext = darktable.gettext.gettext
gettext.bindtextdomain("autostyle", dt.configuration.config_dir .."/lua/locale/")
darktable.gettext.bindtextdomain("autostyle", darktable.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -53,6 +53,13 @@ end
local script_data = {}
script_data.metadata = {
name = "autostyle",
purpose = _("automatically apply a style based on image EXIF tag"),
author = "Marc Cousin <cousinmarc@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/autostyle/"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -40,23 +40,30 @@ local gettext = dt.gettext.gettext
local MODULE = "change_group_leader"
gettext.bindtextdomain(MODULE, dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain(MODULE, dt.configuration.config_dir .."/lua/locale/")
du.check_min_api_version("3.0.0", MODULE)
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "change_group_leader",
purpose = _("automatically change the leader of raw+jpg paired image groups"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/change_group_leader"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local function _(msgid)
return gettext(msgid)
end
-- create a namespace to contain persistent data and widgets
chg_grp_ldr = {}

View File

@@ -39,28 +39,34 @@
local dt = require "darktable"
local du = require "lib/dtutils"
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("clear_GPS", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "clear_GPS",
purpose = _("remove GPS data from selected image(s)"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/clear_gps/"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local gettext = dt.gettext.gettext
gettext.bindtextdomain("clear_GPS", dt.configuration.config_dir .."/lua/locale/")
-- not a number
local NaN = 0/0
du.check_min_api_version("7.0.0", "clear_GPS")
local function _(msgid)
return gettext(msgid)
end
local function clear_GPS(images)
for _, image in ipairs(images) do
-- set the location information to Not a Number (NaN) so it displays correctly

View File

@@ -54,7 +54,7 @@ du.check_min_api_version("7.0.0", "color_profile_manager")
local gettext = dt.gettext.gettext
gettext.bindtextdomain("color_profile_manager", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("color_profile_manager", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -363,6 +363,13 @@ end
local script_data = {}
script_data.metadata = {
name = "color_profile_manager",
purpose = _("manage external darktable color profiles"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/color_profile_manager"
}
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"

View File

@@ -44,21 +44,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "copy_attach_detach_tags")
dt.gettext.bindtextdomain("copy_attach_detach_tags", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "copy_attach_detach_tags",
purpose = _("shortcuts to copy, paste, replace, or remove tags from images"),
author = "Christian Kanzian",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/copy_attach_detach_tags"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("copy_attach_detach_tags", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local cadt = {}
cadt.module_installed = false
cadt.event_registered = false

View File

@@ -37,9 +37,9 @@ local du = require "lib/dtutils"
du.check_min_api_version("7.0.0", "cr2hdr")
local gettext = dt.gettext.gettext
local gettext = darktable.gettext.gettext
gettext.bindtextdomain("cr2hdr", dt.configuration.config_dir .."/lua/locale/")
darktable.gettext.bindtextdomain("cr2hdr", darktable.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -49,6 +49,13 @@ end
local script_data = {}
script_data.metadata = {
name = "cr2hdr",
purpose = _("process Magic Lantern dual ISO images"),
author = "Till Theato <theato@ttill.de>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/cr2hdr"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -1,6 +1,6 @@
--[[
cycle_group_leader.lua - change image grouip leader
cycle_group_leader.lua - change image group leader
Copyright (C) 2024 Bill Ferguson <wpferguson@gmail.com>
@@ -54,29 +54,36 @@ local MODULE = "cycle_group_leader"
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext.gettext
gettext.bindtextdomain("cycle_group_leader", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("cycle_group_leader", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.metadata = {
name = "cycle_group_leader",
purpose = _("change image group leader"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/cycle_group_leader"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -

View File

@@ -67,24 +67,31 @@ if dt.configuration.running_os == 'windows' then os_path_seperator = '\\' end
du.check_min_api_version("7.0.0", "enfuseAdvanced")
-- Tell gettext where to find the .mo file translating messages for a particular domain
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("enfuseAdvanced", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "enfuseAdvanced",
purpose = _("focus stack or exposure blend images"),
author = "Kevin Ertel",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/enfuseAdvanced"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- Tell gettext where to find the .mo file translating messages for a particular domain
local gettext = dt.gettext.gettext
gettext.bindtextdomain("enfuseAdvanced", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- INITS --
local AIS = {
name = 'align_image_stack',

View File

@@ -33,23 +33,30 @@ local ds = require("lib/dtutils.system")
du.check_min_api_version("7.0.0", "exportLUT")
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("exportLUT", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "exportLUT",
purpose = _("export a style as a LUT"),
author = "Noah Clarke",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/exportLUT"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local gettext = dt.gettext.gettext
gettext.bindtextdomain("exportLUT", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
du.check_min_api_version("5.0.0", "exportLUT")
local eL = {}

View File

@@ -75,10 +75,26 @@ local dtsys = require "lib/dtutils.system"
local MODULE_NAME = "ext_editor"
du.check_min_api_version("7.0.0", MODULE_NAME)
-- translation
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("ext_editor", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "ext_editor",
purpose = _("edit images with external editors"),
author = "Marco Carrarini, marco.carrarini@gmail.com",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/ext_editor"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -94,15 +110,6 @@ ee.event_registered = false
ee.widgets = {}
-- translation
local gettext = dt.gettext.gettext
gettext.bindtextdomain("ext_editor", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- maximum number of external programs, can be increased to necessity
local MAX_EDITORS = 9

View File

@@ -54,10 +54,23 @@ local OUTPUT = dt.configuration.tmp_dir .. PS .. "facerecognition.txt"
du.check_min_api_version("7.0.0", MODULE)
dt.gettext.bindtextdomain("face_recognition", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "face_recognition",
purpose = _("use facial recognition to tag images"),
author = "Sebastian Witt",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/face_recognition"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -69,12 +82,6 @@ local fc = {}
fc.module_installed = false
fc.event_registered = false
gettext.bindtextdomain("face_recognition", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function build_image_table(images)
local image_table = {}
local file_extension = ""

View File

@@ -60,13 +60,27 @@ cameras may behave in other ways.
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "fujifilm_dynamic_range")
dt.gettext.bindtextdomain("fujifilm_dynamic_range", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "fujifilm_dynamic_range",
purpose = _("compensate for Fujifilm raw files made using \"dynamic range\""),
author = "Dan Torop <dant@pnym.net>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/fujifilm_dynamic_range"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -30,21 +30,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "fujifilm_ratings")
dt.gettext.bindtextdomain("fujifilm_ratings", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "fujifilm_ratings",
purpose = _("import Fujifilm in-camera ratings"),
author = "Ben Mendis <ben.mendis@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/fujifilm_ratings"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("fujifilm_ratings", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function detect_rating(event, image)
if not df.check_if_bin_exists("exiftool") then
dt.print_error(_("exiftool not found"))

View File

@@ -39,21 +39,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "geoJSON_export")
dt.gettext.bindtextdomain("geoJSON_export", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "geoJSON_export",
purpose = _("export a geoJSON file from geo data"),
author = "Tobias Jakobs",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/geoJSON_export"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("geoJSON_export", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- Sort a table
local function spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua
-- collect the keys

View File

@@ -32,21 +32,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "geoToolbox")
dt.gettext.bindtextdomain("geoToolbox", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "geoToolbox",
purpose = _("geodata tools"),
author = "Tobias Jakobs",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/geoToolbox"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("geoToolbox", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local gT = {}
gT.module_installed = false

View File

@@ -74,21 +74,28 @@ local gimp_widget = nil
du.check_min_api_version("7.0.0", "gimp")
dt.gettext.bindtextdomain("gimp", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "gimp",
purpose = _("export and edit with GIMP"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/gimp"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("gimp", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function group_if_not_member(img, new_img)
local image_table = img:get_group_members()
local is_member = false

View File

@@ -25,25 +25,32 @@ For each source folder, a separate <trk> is generated in the gpx file.
local dt = require "darktable"
local df = require "lib/dtutils.file"
local dl = require "lib/dtutils"
local gettext = dt.gettext.gettext
local gettext = dt.gettext
dl.check_min_api_version("7.0.0", "gpx_export")
-- return data structure for script_manager
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("gpx_export", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext.dgettext("gpx_export", msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "gpx_export",
purpose = _("export gpx information to a file"),
author = "Jannis_V",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/gpx_export"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
local gpx = {}
gpx.module_installed = false
gpx.event_registered = false

View File

@@ -36,12 +36,26 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("2.0.0", "harmonic_armature_guide")
gettext.bindtextdomain("harmonic_armature_guide", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("harmonic_armature_guide", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local script_data = {}
script_data.metadata = {
name = "harmonic_armature_guide",
purpose = _("harmonic artmature guide"),
author = "Hubert Kowalski",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/harmonic_armature_guide"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
dt.guides.register_guide("harmonic armature",
-- draw
function(cairo, x, y, width, height, zoom_scale)
@@ -74,4 +88,12 @@ end,
function()
return dt.new_widget("label"){label = _("harmonic armature"), halign = "start"}
end
)
)
local function destroy()
-- nothing to destroy
end
script_data.destroy = destroy
return script_data

View File

@@ -58,29 +58,36 @@ local MODULE = "hif_group_leader"
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext.gettext
gettext.bindtextdomain("hif_group_leader", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("hif_group_leader", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.metadata = {
name = "hif_group_leader",
purpose = _("make hif image group leader"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/hif_group_leader"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - -
-- P R E F E R E N C E S

View File

@@ -56,21 +56,28 @@ local PQ = dt.configuration.running_os == "windows" and '"' or "'"
-- works with darktable API version from 5.0.0 on
du.check_min_api_version("7.0.0", "hugin")
dt.gettext.bindtextdomain("hugin", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "hugin",
purpose = _("stitch images into a panorama"),
author = "Wolfgang Goetz",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/hugin"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("hugin", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function user_preference_changed(widget)
user_prefer_gui = widget.value
dt.preferences.write(namespace, user_pref_str, "bool", user_prefer_gui)

View File

@@ -73,21 +73,28 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/"
-- works with LUA API version 5.0.0
du.check_min_api_version("7.0.0", "image_stack")
dt.gettext.bindtextdomain("image_stack", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "image_stack",
purpose = _("process a stack of images"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/image_stack"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("image_stack", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- GUI definitions
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@@ -115,10 +115,23 @@ img_time.event_registered = false
du.check_min_api_version("7.0.0", "image_time")
dt.gettext.bindtextdomain("image_time", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "image_time",
purpose = _("synchronize image time for images shot with different cameras or adjust or set image time"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/image_time"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -126,12 +139,6 @@ script_data.show = nil -- only required for libs since the destroy_method only h
gettext.bindtextdomain("image_time", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local PS = dt.configuration.runnin_os == "windows" and "\\" or "/"
local ERROR = -1

View File

@@ -58,29 +58,36 @@ local MODULE = "jpg_group_leader"
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext.gettext
gettext.bindtextdomain("jpg_group_leader", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("jpg_group_leader", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local script_data = {}
script_data.metadata = {
name = "jpg_group_leader",
purpose = _("make jpg image group leader"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/jpg_group_leader"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- - - - - - - - - - - - - - - - - - - - - - - -
-- P R E F E R E N C E S

View File

@@ -45,21 +45,28 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/"
du.check_min_api_version("7.0.0", "kml_export")
dt.gettext.bindtextdomain("kml_export", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "kml_export",
purpose = _("export KML/KMZ data to a file"),
author = "Tobias Jakobs",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/kml_export"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("kml_export", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function show_status(storage, image, format, filename, number, total, high_quality, extra_data)
dt.print(string.format(_("export image %i/%i"), number, total))
end

View File

@@ -41,12 +41,26 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("2.0.0", "passport_guide")
gettext.bindtextdomain("passport_guide", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("passport_guide", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local script_data = {}
script_data.metadata = {
name = "passport_guide",
purpose = _("guides for cropping passport photos"),
author = "Kåre Hampf",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/passport_guide"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
dt.guides.register_guide("passport",
-- draw
function(cairo, x, y, width, height, zoom_scale)
@@ -90,5 +104,13 @@ function()
end
)
local function destroy()
-- nothing to destroy
end
script_data.destroy = destroy
return script_data
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; hl Lua;
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua

View File

@@ -45,12 +45,26 @@ local gettext = dt.gettext
du.check_min_api_version("2.0.0", "passport_guide_germany")
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("passport_guide_germany",dt.configuration.config_dir.."/lua/locale/")
dt.gettext.bindtextdomain("passport_guide_germany",dt.configuration.config_dir.."/lua/locale/")
local function _(msgid)
return gettext.dgettext("passport_guide_germany", msgid)
end
local script_data = {}
script_data.metadata = {
name = "passport_guide_germany",
purpose = _("guides for cropping passport and ID card (\"Personalausweis\") photos based on the \"Passbild-Schablone\" from the German Federal Ministry of the Interior and Community"),
author = "menschmachine",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/passport_guide_germany"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
dt.guides.register_guide("Passport Photo Germany",
-- draw
function(cairo, x, y, width, height, zoom_scale)
@@ -101,5 +115,13 @@ function()
end
)
local function destroy()
-- noting to destroy
end
script_data.destroy = destroy
return script_data
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; hl Lua;
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua

View File

@@ -44,7 +44,7 @@ local df = require "lib/dtutils.file"
local gettext = dt.gettext.gettext
gettext.bindtextdomain("pdf_slideshow", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("pdf_slideshow", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -61,6 +61,13 @@ du.check_min_api_version("7.0.0", "pdf_slideshow")
local script_data = {}
script_data.metadata = {
name = "pdf_slideshow",
purpose = _("generates a PDF slideshow (via Latex) containing all selected images one per slide"),
author = "Pascal Obry",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/pdf_slideshow"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -230,7 +237,7 @@ dt.register_storage("pdf_slideshow",_("pdf slideshow"),
local result = dt.control.execute(command)
if result ~= 0 then
dt.print(_("problem running pdflatex")) -- this one is probably usefull to the user
error("problem running ")..command)
error("problem running "..command)
end
-- open the PDF

View File

@@ -44,10 +44,24 @@ local dtsys = require "lib/dtutils.system"
local MODULE_NAME = "photils"
du.check_min_api_version("7.0.0", MODULE_NAME)
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("photils", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "photils",
purpose = _("suggest tags based on image classification"),
author = "Tobias Scheck",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/photils"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -55,7 +69,6 @@ script_data.show = nil -- only required for libs since the destroy_method only h
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
local gettext = dt.gettext.gettext
local exporter = dt.new_format("jpeg")
exporter.quality = 80
@@ -64,12 +77,6 @@ exporter.max_width = 224
-- helper functions
gettext.bindtextdomain("photils", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function num_keys(tbl)
local num = 0
for _ in pairs(tbl) do num = num + 1 end

View File

@@ -49,10 +49,25 @@ local debug = require "darktable.debug"
du.check_min_api_version("7.0.0", "quicktag")
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain("quicktag", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "quicktag",
purpose = _("use buttons to quickly apply tags assigned to them"),
author = "Christian Kanzian",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/quicktag"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -62,14 +77,6 @@ qt.module_installed = false
qt.event_registered = false
qt.widget_table = {}
local gettext = dt.gettext.gettext
gettext.bindtextdomain("quicktag", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- maximum length of button labels
dt.preferences.register("quickTag",
"labellength",

View File

@@ -46,7 +46,7 @@ du.check_min_api_version("7.0.0", "rate_group")
local gettext = dt.gettext.gettext
gettext.bindtextdomain("rate_group", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("rate_group", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -56,6 +56,13 @@ end
local script_data = {}
script_data.metadata = {
name = "rate_group",
purpose = _("rate all images in a group"),
author = "Dom H (dom@hxy.io)",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/rate_group"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -36,9 +36,9 @@ local debug = require "darktable.debug"
du.check_min_api_version("7.0.0", "rename-tags")
du.deprecated("contrib/rename-tags.lua","darktable release 4.0")
local gettext = dt.gettext.gettext
local gettext = darktable.gettext.gettext
gettext.bindtextdomain("rename-tags", dt.configuration.config_dir .."/lua/locale/")
darktable.gettext.bindtextdomain("rename-tags", darktable.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -48,6 +48,13 @@ end
local script_data = {}
script_data.metadata = {
name = "rename-tags",
purpose = _("rename an existing tag"),
author = "Sebastian Witt (se.witt@gmx.net)",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/rename-tags"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -48,7 +48,7 @@ du.check_min_api_version("7.0.0", "rename_images")
local gettext = dt.gettext.gettext
gettext.bindtextdomain("rename_images", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("rename_images", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -71,6 +71,13 @@ rename.event_registered = false
-- script_manager integration
local script_data = {}
script_data.metadata = {
name = "rename_images",
purpose = _("rename an image file or files"),
author = "Bill Ferguson <wpferguson@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/rename_images"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again

View File

@@ -31,7 +31,7 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/"
local gettext = dt.gettext.gettext
gettext.bindtextdomain("select_non_existing", dt.configuration.config_dir .."/lua/locale/")
dt.gettext.bindtextdomain("select_non_existing", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
@@ -74,5 +74,13 @@ dt.gui.libs.select.register_selection(
_("select all non-existing images in the current images"))
local script_data = {}
script_data.metadata = {
name = "select_non_existing",
purpose = _("enable selection of non-existing images"),
author = "Dirk Dittmar",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/select_non_existing"
}
script_data.destroy = destroy
return script_data

View File

@@ -24,21 +24,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "select_untagged")
dt.gettext.bindtextdomain("select_untagged", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "select_untagged",
purpose = _("enable selection of untagged images"),
author = "Jannis_V",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/select_untagged"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("select_untagged", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function stop_job(job)
job.valid = false
end

View File

@@ -31,21 +31,28 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "slideshowMusic")
dt.gettext.bindtextdomain("slideshowMusic", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "slideshowMusic",
purpose = _("play music during a slideshow"),
author = "Tobias Jakobs",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/slideshowMusic"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
gettext.bindtextdomain("slideshowMusic", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
local function playSlideshowMusic(_, old_view, new_view)
local filename, playMusic

View File

@@ -80,10 +80,23 @@ local dtutils_system = require("lib/dtutils.system")
local LIB_ID = "transfer_hierarchy"
dtutils.check_min_api_version("7.0.0", LIB_ID)
darktable.gettext.bindtextdomain("transfer_hierarchy", darktable.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return darktable.gettext.gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "transfer_hierarchy",
purpose = _("allows the moving or copying of images from one directory tree to another, while preserving the existing hierarchy"),
author = "August Schwerdfeger (august@schwerdfeger.name)",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/transfer_hierarchy"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -96,12 +109,6 @@ local PATH_SEGMENT_REGEX = "(" .. PATH_SEPARATOR .. "?)([^" .. PATH_SEPARATOR ..
unpack = unpack or table.unpack
gmatch = string.gfind or string.gmatch
gettext.bindtextdomain("transfer_hierarchy", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return darktable.gettext.gettext(msgid)
end
-- Header material: END

View File

@@ -41,10 +41,23 @@ local gettext = dt.gettext.gettext
du.check_min_api_version("7.0.0", "video_ffmpeg")
dt.gettext.bindtextdomain("video_ffmpeg", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
script_data.metadata = {
name = "video_ffmpeg",
purpose = _("timelapse video plugin based on ffmpeg"),
author = "Dominik Markiewicz",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contib/video_ffmpeg"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
@@ -54,13 +67,6 @@ local MODULE_NAME = "video_ffmpeg"
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
gettext.bindtextdomain("video_ffmpeg", dt.configuration.config_dir .."/lua/locale/")
local function _(msgid)
return gettext(msgid)
end
---- DECLARATIONS
local resolutions = {
@@ -376,7 +382,7 @@ local module_widget = dt.new_widget("box") {
---- EXPORT & REGISTRATION
local function show_status(enf_storage, image, format, filename, number, total, high_quality, extra_data)
dt.print(string.format(_("export %d / %d"), number), total))
dt.print(string.format(_("export %d / %d", number), total))
end
local function init_export(storage, img_format, images, high_quality, extra_data)