From c9943a206519352b156b7312b22a3707d87cb3dc Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 25 Mar 2023 17:02:48 -0400 Subject: [PATCH 01/40] lib/dtutils/string - Added logging capability with the ability to set library logging level from a user script --- lib/dtutils/string.lua | 117 +++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 29 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index f7159a2..6b71692 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -1,6 +1,12 @@ local dtutils_string = {} local dt = require "darktable" +local du = require "lib/dtutils" +local log = require "lib/dtutils.log" + +local DEFAULT_LOG_LEVEL = log.error + +dtutils_string.log_level = DEFAULT_LOG_LEVEL dtutils_string.libdoc = { Name = [[dtutils.string]], @@ -48,6 +54,8 @@ dtutils_string.libdoc.functions["strip_accents"] = { } function dtutils_string.strip_accents( str ) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) local tableAccents = {} tableAccents["à"] = "a" tableAccents["á"] = "a" @@ -111,6 +119,7 @@ function dtutils_string.strip_accents( str ) end end + log.log_level(old_log_level) return normalizedString end @@ -136,6 +145,8 @@ dtutils_string.libdoc.functions["escape_xml_characters"] = { -- Keep & first, otherwise it will double escape other characters function dtutils_string.escape_xml_characters( str ) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) str = string.gsub(str,"&", "&") str = string.gsub(str,"\"", """) @@ -143,6 +154,7 @@ function dtutils_string.escape_xml_characters( str ) str = string.gsub(str,"<", "<") str = string.gsub(str,">", ">") + log.log_level(old_log_level) return str end @@ -165,11 +177,14 @@ dtutils_string.libdoc.functions["urlencode"] = { } function dtutils_string.urlencode(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) if (str) then str = string.gsub (str, "\n", "\r\n") str = string.gsub (str, "([^%w ])", function (c) return string.format ("%%%02X", string.byte(c)) end) str = string.gsub (str, " ", "+") end + log.log_level(old_log_level) return str end @@ -192,38 +207,52 @@ dtutils_string.libdoc.functions["is_not_sanitized"] = { } local function _is_not_sanitized_posix(str) - -- A sanitized string must be quoted. - if not string.match(str, "^'.*'$") then - return true + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + -- A sanitized string must be quoted. + if not string.match(str, "^'.*'$") then + log.log_level(old_log_level) + return true -- A quoted string containing no quote characters within is sanitized. - elseif string.match(str, "^'[^']*'$") then - return false - end + elseif string.match(str, "^'[^']*'$") then + log.log_level(old_log_level) + return false + end - -- Any quote characters within a sanitized string must be properly - -- escaped. - local quotesStripped = string.sub(str, 2, -2) - local escapedQuotesRemoved = string.gsub(quotesStripped, "'\\''", "") - if string.find(escapedQuotesRemoved, "'") then - return true - else - return false - end + -- Any quote characters within a sanitized string must be properly + -- escaped. + local quotesStripped = string.sub(str, 2, -2) + local escapedQuotesRemoved = string.gsub(quotesStripped, "'\\''", "") + if string.find(escapedQuotesRemoved, "'") then + log.log_level(old_log_level) + return true + else + log.log_level(old_log_level) + return false + end end local function _is_not_sanitized_windows(str) - if not string.match(str, "^\".*\"$") then - return true - else - return false - end + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + if not string.match(str, "^\".*\"$") then + log.log_level(old_log_level) + return true + else + log.log_level(old_log_level) + return false + end end function dtutils_string.is_not_sanitized(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) if dt.configuration.running_os == "windows" then - return _is_not_sanitized_windows(str) + log.log_level(old_log_level) + return _is_not_sanitized_windows(str) else - return _is_not_sanitized_posix(str) + log.log_level(old_log_level) + return _is_not_sanitized_posix(str) end end @@ -246,26 +275,38 @@ dtutils_string.libdoc.functions["sanitize"] = { } local function _sanitize_posix(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) if _is_not_sanitized_posix(str) then - return "'" .. string.gsub(str, "'", "'\\''") .. "'" + log.log_level(old_log_level) + return "'" .. string.gsub(str, "'", "'\\''") .. "'" else - return str + log.log_level(old_log_level) + return str end end local function _sanitize_windows(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) if _is_not_sanitized_windows(str) then - return "\"" .. string.gsub(str, "\"", "\"^\"\"") .. "\"" + log.log_level(old_log_level) + return "\"" .. string.gsub(str, "\"", "\"^\"\"") .. "\"" else - return str + log.log_level(old_log_level) + return str end end function dtutils_string.sanitize(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) if dt.configuration.running_os == "windows" then - return _sanitize_windows(str) + log.log_level(old_log_level) + return _sanitize_windows(str) else - return _sanitize_posix(str) + log.log_level(old_log_level) + return _sanitize_posix(str) end end @@ -288,9 +329,12 @@ dtutils_string.libdoc.functions["sanitize_lua"] = { } function dtutils_string.sanitize_lua(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) str = string.gsub(str, "%-", "%%-") str = string.gsub(str, "%(", "%%(") str = string.gsub(str, "%)", "%%)") + log.log_level(old_log_level) return str end @@ -313,7 +357,9 @@ dtutils_string.libdoc.functions["split_filepath"] = { } function dtutils_string.split_filepath(str) - -- strip out single quotes from quoted pathnames + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + -- strip out single quotes from quoted pathnames str = string.gsub(str, "'", "") str = string.gsub(str, '"', '') local result = {} @@ -323,6 +369,7 @@ function dtutils_string.split_filepath(str) result["basename"] = result["filetype"] result["filetype"] = "" end + log.log_level(old_log_level) return result end @@ -344,7 +391,10 @@ dtutils_string.libdoc.functions["get_path"] = { } function dtutils_string.get_path(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) local parts = dtutils_string.split_filepath(str) + log.log_level(old_log_level) return parts["path"] end @@ -366,7 +416,10 @@ dtutils_string.libdoc.functions["get_filename"] = { } function dtutils_string.get_filename(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) local parts = dtutils_string.split_filepath(str) + log.log_level(old_log_level) return parts["filename"] end @@ -389,7 +442,10 @@ dtutils_string.libdoc.functions["get_basename"] = { } function dtutils_string.get_basename(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) local parts = dtutils_string.split_filepath(str) + log.log_level(old_log_level) return parts["basename"] end @@ -411,7 +467,10 @@ dtutils_string.libdoc.functions["get_filetype"] = { } function dtutils_string.get_filetype(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) local parts = dtutils_string.split_filepath(str) + log.log_level(old_log_level) return parts["filetype"] end From 5331a38f10fdbbd85894ec6b9cd096e242370aa4 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 25 Mar 2023 17:05:11 -0400 Subject: [PATCH 02/40] lib/dtutils/string - added % and + to sanitize_lua() to prevent pattern matching problems --- lib/dtutils/string.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 6b71692..b988731 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -331,9 +331,11 @@ dtutils_string.libdoc.functions["sanitize_lua"] = { function dtutils_string.sanitize_lua(str) local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) + str = string.gsub(str, "%%", "%%%%") str = string.gsub(str, "%-", "%%-") str = string.gsub(str, "%(", "%%(") str = string.gsub(str, "%)", "%%)") + str = string.gsub(str, "+", "%%+") log.log_level(old_log_level) return str end From ad10542b3025a2a4e32d87cc3bd1ca61351a0fdb Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sun, 26 Mar 2023 14:55:40 -0400 Subject: [PATCH 03/40] lib/dtutils/string - Added variable substitution functions that are equivalent to the darktable variable substitution functions. --- lib/dtutils/string.lua | 411 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index b988731..e315eda 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -476,6 +476,417 @@ function dtutils_string.get_filetype(str) return parts["filetype"] end +local substitutes = {} + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local PLACEHOLDERS = {"ROLL.NAME", + "FILE.FOLDER", + "FILE.NAME", + "FILE.EXTENSION", + "ID", + "VERSION", + "VERSION.IF.MULTI", -- Not Implemented + "VERSION.NAME", + "DARKTABLE.VERSION", + "DARKTABLE.NAME", -- Not Implemented + "SEQUENCE", + "WIDTH.SENSOR", + "HEIGHT.SENSOR", + "WIDTH.RAW", + "HEIGHT.RAW", + "WIDTH.CROP", + "HEIGHT.CROP", + "WIDTH.EXPORT", + "HEIGHT.EXPORT", + "WIDTH.MAX", -- Not Implemented + "HEIGHT.MAX", -- Not Implemented + "YEAR", + "MONTH", + "DAY", + "HOUR", + "MINUTE", + "SECOND", + "MSEC", + "EXIF.YEAR", + "EXIF.MONTH", + "EXIF.DAY", + "EXIF.HOUR", + "EXIF.MINUTE", + "EXIF.SECOND", + "EXIF.MSEC", + "EXIF.DATE.REGIONAL", -- Not Implemented + "EXIF.TIME.REGIONAL", -- Not Implemented + "EXIF.ISO", + "EXIF.EXPOSURE", + "EXIF.EXPOSURE.BIAS", + "EXIF.APERTURE", + "EXIF.FOCAL.LENGTH", + "EXIF.FOCUS.DISTANCE", + "LONGITUDE", + "LATITUDE", + "ALTITUDE", + "STARS", + "RATING.ICONS", -- Not Implemented + "LABELS", + "LABELS.ICONS", -- Not Implemented + "MAKER", + "MODEL", + "TITLE", + "DESCRIPTION", + "CREATOR", + "PUBLISHER", + "RIGHTS", + "TAGS", -- Not Implemented + "CATEGORY", -- Not Implemented + "SIDECAR.TXT", -- Not Implemented + "FOLDER.PICTURES", + "FOLDER.HOME", + "FOLDER.DESKTOP", + "OPENCL.ACTIVATED", -- Not Implemented + "USERNAME", + "NL", + "JOBCODE" -- Not Implemented +} + +local PS = dt.configuration.running_os == "windows" and "\\" or "/" +local USER = os.getenv("USERNAME") +local HOME = dt.configuration.running_os == "windows" and os.getenv("HOMEPATH") or os.getenv("HOME") +local PICTURES = HOME .. PS .. (dt.configuration.running_os == "windows" and "My Pictures" or "Pictures") +local DESKTOP = HOME .. PS .. "Desktop" + +local function get_colorlabels(image) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + local colorlabels = {} + if image.red then table.insert(colorlabels, "red") end + if image.yellow then table.insert(colorlabels, "yellow") end + if image.green then table.insert(colorlabels, "green") end + if image.blue then table.insert(colorlabels, "blue") end + if image.purple then table.insert(colorlabels, "purple") end + local labels = #colorlabels == 1 and colorlabels[1] or du.join(colorlabels, ",") + log.log_level(old_log_level) + return labels +end + +dtutils_string.libdoc.functions["build_substitution_list"] = { + Name = [[build_substitution_list]], + Synopsis = [[build a list of variable substitutions]], + Usage = [[local ds = require "lib/dtutils.string" + ds.build_substitution_list(image, sequence, [username], [pic_folder], [home], [desktop]) + image - dt_lua_image_t - the image being processed + sequence - integer - the sequence number of the image + [username] - string - optional - user name. Will be determined if not supplied + [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied + [home] - string - optional - home directory. Will be determined if not supplied + [desktop] - string - optional - desktop directory. Will be determined if not supplied]], + Description = [[build_substitution_list populates variables with values from the arguments + and determined from the system and darktable.]], + Return_Value = [[]], + Limitations = [[If the value for a variable can not be determined, or if it is not supported, + then an empty string is used for the value.]], + Example = [[]], + See_Also = [[https://docs.darktable.org/usermanual/4.2/en/special-topics/variables/]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_string.build_substition_list(image, sequence, username, pic_folder, home, desktop) + -- build the argument substitution list from each image + + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + + local is_api_9_1 = true + if dt.configuration.api_version_string < "9.1.0" then + is_api_9_1 = false + end + + local datetime = os.date("*t") + local user_name = username or USER + local pictures_folder = pic_folder or PICTURES + local home_folder = home or HOME + log.msg(log.info, "home is " .. tostring(home) .. " and HOME is " .. tostring(HOME) .. " and home_folder is " .. tostring(home_folder)) + local desktop_folder = desktop or DESKTOP + + local labels = get_colorlabels(image) + log.msg(log.info, "image date time taken is " .. image.exif_datetime_taken) + local eyear, emon, eday, ehour, emin, esec, emsec + if dt.preferences.read("darktable", "lighttable/ui/milliseconds", "bool") and is_api_9_1 then + eyear, emon, eday, ehour, emin, esec, emsec = + string.match(image.exif_datetime_taken, "(%d+):(%d+):(%d+) (%d+):(%d+):(%d+)%.(%d+)$") + else + emsec = "0" + eyear, emon, eday, ehour, emin, esec = + string.match(image.exif_datetime_taken, "(%d+):(%d+):(%d+) (%d+):(%d+):(%d+)$") + end + local replacements = {image.film, -- ROLL.NAME + image.path, -- FILE.FOLDER + image.filename, -- FILE.NAME + dtutils_string.get_filetype(image.filename),-- FILE.EXTENSION + image.id, -- ID + image.duplicate_index, -- VERSION + "", -- VERSION.IF_MULTI + image.version_name, -- VERSION.NAME + dt.configuration.version, -- DARKTABLE.VERSION + "", -- DARKTABLE.NAME + sequence, -- SEQUENCE + image.width, -- WIDTH.SENSOR + image.height, -- HEIGHT.SENSOR + is_api_9_1 and image.p_width or "", -- WIDTH.RAW + is_api_9_1 and image.p_height or "", -- HEIGHT.RAW + is_api_9_1 and image.final_width or "", -- WIDTH.CROP + is_api_9_1 and image.final_height or "", -- HEIGHT.CROP + is_api_9_1 and image.final_width or "", -- WIDTH.EXPORT + is_api_9_1 and image.final_height or "", -- HEIGHT.EXPORT + "", -- WIDTH.MAX + "", -- HEIGHT.MAX + string.format("%4d", datetime.year), -- YEAR + string.format("%02d", datetime.month), -- MONTH + string.format("%02d", datetime.day), -- DAY + string.format("%02d", datetime.hour), -- HOUR + string.format("%02d", datetime.min), -- MINUTE + string.format("%02d", datetime.sec), -- SECOND + "", -- MSEC + eyear, -- EXIF.YEAR + emon, -- EXIF.MONTH + eday, -- EXIF.DAY + ehour, -- EXIF.HOUR + emin, -- EXIF.MINUTE + esec, -- EXIF.SECOND + emsec, -- EXIF.MSEC + "", -- EXIF.DATE.REGIONAL + "", -- EXIF.TIME.REGIONAL + string.format("%d", image.exif_iso), -- EXIF.ISO + string.format("1/%.0f", 1./image.exif_exposure), -- EXIF.EXPOSURE + image.exif_exposure_bias, -- EXIF.EXPOSURE.BIAS + string.format("%.01f", image.exif_aperture), -- EXIF.APERTURE + string.format("%.0f", image.exif_focal_length), -- EXIF.FOCAL.LENGTH + image.exif_focus_distance, -- EXIF.FOCUS.DISTANCE + image.longitude or "", -- LONGITUDE + image.latitude or "", -- LATITUDE + image.elevation or "", -- ALTITUDE + image.rating, -- STARS + "", -- RATING.ICONS + labels, -- LABELS + "", -- LABELS.ICONS + image.exif_maker, -- MAKER + image.exif_model, -- MODEL + image.title, -- TITLE + image.description, -- DESCRIPTION + image.creator, -- CREATOR + image.publisher, -- PUBLISHER + image.rights, -- RIGHTS + "", -- TAGS + "", -- CATEGORYn + "", -- SIDECAR.TXT + pictures_folder, -- FOLDER.PICTURES + home_folder, -- FOLDER.HOME + desktop_folder, -- FOLDER.DESKTOP + "", -- OPENCL.ACTIVATED + user_name, -- USERNAME + "\n", -- NL + "" -- JOBCODE + } + + for i = 1, #PLACEHOLDERS, 1 do + substitutes[PLACEHOLDERS[i]] = replacements[i] + log.msg(log.info, "setting " .. PLACEHOLDERS[i] .. " to " .. tostring(replacements[i])) + end + log.log_level(old_log_level) +end + +local function check_legacy_vars(var_name) + local var = var_name + if string.match(var, "_") then + var = string.gsub(var, "_", ".") + end + if string.match(var, "^HOME$") then var = "FOLDER.HOME" end + if string.match(var, "^PICTURES.FOLDER$") then var = "FOLDER.PICTURES" end + if string.match(var, "^DESKTOP$") then var = "FOLDER.DESKTOP" end + return var +end + +local function treat(var_string) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + local ret_val = "" + -- remove the var from the string + local var = string.match(var_string, "[%a%._]+") + var = check_legacy_vars(var) + log.msg(log.info, "var_string is " .. tostring(var_string) .. " and var is " .. tostring(var)) + ret_val = substitutes[var] + if not ret_val then + log.msg(log.error, "variable " .. var .. " is not an allowed variable, returning empty value") + log.log_level(old_log_level) + return "" + end + local args = string.gsub(var_string, var, "") + log.msg(log.info, "args is " .. tostring(args)) + if string.len(args) > 0 then + if string.match(args, '^%^%^') then + ret_val = string.upper(ret_val) + elseif string.match(args, "^%^") then + ret_val = string.gsub(ret_val, "^%a", string.upper, 1) + elseif string.match(args, "^,,") then + ret_val = string.lower(ret_val) + elseif string.match(args, "^,") then + ret_val = string.gsub(ret_val, "^%a", string.lower, 1) + elseif string.match(args, "^:%-?%d+:%-?%d+") then + local soffset, slen = string.match(args, ":(%-?%d+):(%-?%d+)") + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + if tonumber(soffset) >= 0 then + soffset = soffset + 1 + end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + if tonumber(soffset) < 0 and tonumber(slen) < 0 then + local temp = soffset + soffset = slen + slen = temp + end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + ret_val = string.sub(ret_val, soffset, slen) + log.msg(log.info, "ret_val is " .. ret_val) + elseif string.match(args, "^:%-?%d+") then + local soffset= string.match(args, ":(%-?%d+)") + if tonumber(soffset) >= 0 then + soffset = soffset + 1 + end + ret_val = string.sub(ret_val, soffset, -1) + elseif string.match(args, "^-%$%(.-%)") then + local replacement = string.match(args, "-%$%(([%a%._]+)%)") + replacement = check_legacy_vars(replacement) + if string.len(ret_val) == 0 then + ret_val = substitutes[replacement] + end + elseif string.match(args, "^-.+$") then + local replacement = string.match(args, "-(.+)$") + if string.len(ret_val) == 0 then + ret_val = replacement + end + elseif string.match(args, "^+.+") then + local replacement = string.match(args, "+(.+)") + if string.len(ret_val) > 0 then + ret_val = replacement + end + elseif string.match(args, "^#.+") then + local pattern = string.match(args, "#(.+)") + log.msg(log.info, "pattern to remove is " .. tostring(pattern)) + ret_val = string.gsub(ret_val, "^" .. dtutils_string.sanitize_lua(pattern), "") + elseif string.match(args, "^%%.+") then + local pattern = string.match(args, "%%(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", "") + elseif string.match(args, "^//.-/.+") then + local pattern, replacement = string.match(args, "//(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement) + elseif string.match(args, "^/#.+/.+") then + local pattern, replacement = string.match(args, "/#(.+)/(.+)") + ret_val = string.gsub(ret_val, "^" .. pattern, replacement, 1) + elseif string.match(args, "^/%%.-/.+") then + local pattern, replacement = string.match(args, "/%%(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", replacement) + elseif string.match(args, "^/.-/.+") then + log.msg(log.info, "took replacement branch") + local pattern, replacement = string.match(args, "/(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement, 1) + end + end + log.log_level(old_log_level) + return ret_val +end + +dtutils_string.libdoc.functions["substitute_list"] = { + Name = [[substitute_list]], + Synopsis = [[Replace variables in a string with their computed values]], + Usage = [[local ds = require "lib/dtutils.string" + local result = ds.substitute_list(str) + str - string - the string containing the variables to be substituted for]], + Description = [[substitute_list replaces the variables in the supplied string with + values computed in build_substitution_list().]], + Return_Value = [[result - string - the input string with values substituted for the variables]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_string.substitute_list(str) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + -- replace the substitution variables in a string + for match in string.gmatch(str, "%$%(.-%)?%)") do + local var = string.match(match, "%$%((.-%)?)%)") + local treated_var = treat(var) + log.msg(log.info, "var is " .. var .. " and treated var is " .. tostring(treated_var)) + str = string.gsub(str, "%$%(".. dtutils_string.sanitize_lua(var) .."%)", tostring(treated_var)) + log.msg(log.info, "str after replacement is " .. str) + end + log.log_level(old_log_level) + return str +end + +dtutils_string.libdoc.functions["clear_substitute_list"] = { + Name = [[clear_substitute_list]], + Synopsis = [[Clear the computed list of variable substitution values]], + Usage = [[local ds = require "lib/dtutils.string" + ds.clear_substitute_list()]], + Description = [[clear_substitute_list resets the list of variable replacement values]], + Return_Value = [[]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_string.clear_substitute_list() + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + for i = 1, #PLACEHOLDERS, 1 do + substitutes[PLACEHOLDERS[i]] = nil + end + log.log_level(old_log_level) +end + +dtutils_string.libdoc.functions["substitute"] = { + Name = [[substitute]], + Synopsis = [[Check if a string has been sanitized]], + Usage = [[local ds = require "lib/dtutils.string" + ds.substitute(image, sequence, [username], [pic_folder], [home], [desktop]) + image - dt_lua_image_t - the image being processed + sequence - integer - the sequence number of the image + [username] - string - optional - user name. Will be determined if not supplied + [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied + [home] - string - optional - home directory. Will be determined if not supplied + [desktop] - string - optional - desktop directory. Will be determined if not supplied]], + Description = [[substitute initializes the substitution list by calling clear_substitute_list(), + then builds the substitutions by calling build_substitution_list() and finally does the + substitution by calling substitute_list(), then returns the result string.]], + Return_Value = [[result - string - the input string with values substituted for the variables]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_string.substitute(image, sequence, variable_string, username, pic_folder, home, desktop) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + dtutils_string.clear_substitute_list() + dtutils_string.build_substition_list(image, sequence, username, pic_folder, home, desktop) + local str = dtutils_string.substitute_list(variable_string) + log.log_level(old_log_level) + return str +end + return dtutils_string From f9fe33f930ccb01fd43edcc4d0c04f880e874910 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 19 Jan 2024 15:24:56 -0500 Subject: [PATCH 04/40] updated script_manager and executable_manager to use darktable translation facilities. Changed translatable messages with arguments to use string.format for one complete string versus snippets. Removed gen_i18n_mo since we will be using darktable's translation facilities and there's no need to generate lua specific mo files. --- tools/executable_manager.lua | 10 ++-- tools/gen_i18n_mo.lua | 108 ----------------------------------- tools/script_manager.lua | 38 ++++++------ 3 files changed, 22 insertions(+), 134 deletions(-) delete mode 100644 tools/gen_i18n_mo.lua diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index a8690ea..75b4a6b 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -45,9 +45,7 @@ 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.bindtextdomain("executable_manager",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local exec_man = {} -- our own namespace exec_man.module_installed = false @@ -58,7 +56,7 @@ exec_man.event_registered = false -- - - - - - - - - - - - - - - - - - - - - - - - - - - - local function _(msg) - return gettext.dgettext("executable_manager", msg) + return gettext(msg) end local function grep(file, pattern) @@ -167,7 +165,7 @@ for i,exec in ipairs(exec_table) do editable = false } executable_path_widgets[exec] = dt.new_widget("file_chooser_button"){ - title = _("select ") .. exec .. _(" executable"), + title = _(string.format("select %s executable", exec)), value = df.get_executable_path_preference(exec), is_directory = false, changed_callback = function(self) @@ -210,7 +208,7 @@ for i,exec in ipairs(exec_table) do dt.new_widget("section_label"){label = _("reset")}, dt.new_widget("button"){ label = _("clear"), - tooltip = _("Clear path for ") .. exec, + tooltip = _(string.format("Clear path for %s", exec)), clicked_callback = function() df.set_executable_path_preference(exec, "") executable_path_widgets[exec].value = "" diff --git a/tools/gen_i18n_mo.lua b/tools/gen_i18n_mo.lua deleted file mode 100644 index 6aa453c..0000000 --- a/tools/gen_i18n_mo.lua +++ /dev/null @@ -1,108 +0,0 @@ ---[[ - gen_18n_mo.lua - generate .mo files from .po files and put them in the correct place - - Copyright (C) 2016,2018 Bill Ferguson - - This program 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. - - This program 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 this program. If not, see . -]] ---[[ - gen_i18n_mo - generate translation files from the source and place them in the appropriate locale directory - - gen_i18n_mo finds all the .po files scattered throughout the script tree, compiles them into - .mo files and places them in the correct locale directory for use by the gettext tools. - -]] - -local dt = require "darktable" -local du = require "lib/dtutils" -local df = require "lib/dtutils.file" -local log = require "lib/dtutils.log" -local dtsys = require "lib/dtutils.system" - -du.check_min_api_version("5.0.0", "gen_I18n_mo") - -local function destroy() - -- nothing to destroy -end - --- figure out the path separator - -local PS = dt.configuration.running_os == "windows" and "\\" or "/" - -local LUA_DIR = dt.configuration.config_dir .. PS .. "lua" .. PS -local LOCALE_DIR = dt.configuration.config_dir .. PS .. "lua" .. PS .. "locale" .. PS - --- check if we have msgfmt - -local msgfmt_executable = df.check_if_bin_exists("msgfmt") - -if msgfmt_executable then - - -- find the .po files - - local find_cmd = "find -L " .. LUA_DIR .. " -name \\*.po -print" - if dt.configuration.running_os == "windows" then - find_cmd = "dir /b/s " .. LUA_DIR .. "\\*.po" - end - - local output = io.popen(find_cmd) - - -- for each .po file.... - - for line in output:lines() do - local fname = df.get_filename(line) - - -- get the language used... this depends on the file being named using - -- the convention /..../lang/LC_MESSAGES/file.po where lang is de_DE, fr_FR, etc. - - local path_parts = du.split(line, PS) - local lang = path_parts[#path_parts - 2] - - -- ensure there is a destination directory for them - - local mkdir_cmd = "mkdir -p " - if dt.configuration.running_os == "windows" then - mkdir_cmd = "mkdir " - end - - if not df.check_if_file_exists(LOCALE_DIR .. lang .. PS .. "LC_MESSAGES") then - log.msg(log.info, "Creating locale", lang) - os.execute(mkdir_cmd .. LOCALE_DIR .. lang .. PS .. "LC_MESSAGES") - end - - -- generate the mo file - - fname = string.gsub(fname, ".po$", ".mo") - log.msg(log.info, "Compiling translation to", fname) - local result = os.execute(msgfmt_executable .. " -o " .. LOCALE_DIR .. lang .. PS .. "LC_MESSAGES" .. PS .. fname .. " " .. line) - end -else - log.msg(log.screen, "ERROR: msgfmt executable not found. Please install or specifiy location in preferences.") -end -dt.preferences.register("executable_paths", "msgfmt", -- name - "file", -- type - 'gen_i18n_mo: msgfmt location', -- label - 'Install location of msgfmt. Requires restart to take effect.', -- tooltip - "msgfmt", -- default - dt.new_widget("file_chooser_button"){ - title = "Select msgfmt[.exe] file", - value = "", - is_directory = false, - } -) - -local script_data = {} -script_data.destroy = destroy - -return script_data diff --git a/tools/script_manager.lua b/tools/script_manager.lua index e65cd20..6a5d2ac 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -56,14 +56,12 @@ local dtsys = require "lib/dtutils.system" local log = require "lib/dtutils.log" local debug = require "darktable.debug" -local gettext = dt.gettext +-- set up translation - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("script_manager",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("script_manager", msgid) + return gettext(msgid) end -- api check @@ -369,7 +367,7 @@ local function get_script_doc(script) -- assume that the second block comment is the documentation description = string.match(content, "%-%-%[%[.-%]%].-%-%-%[%[(.-)%]%]") else - log.msg(log.error, _("Cant read from " .. script)) + log.msg(log.error, "Cant read from " .. script) end if description then restore_log_level(old_log_level) @@ -392,7 +390,7 @@ local function activate(script) script_manager_running_script = nil if status then pref_write(script.script_name, "bool", true) - log.msg(log.screen, _("Loaded ") .. script.script_name) + log.msg(log.screen, string.format(_("Loaded %s"), script.script_name)) script.running = true if err ~= true then log.msg(log.debug, "got lib data") @@ -404,7 +402,7 @@ local function activate(script) script.data = nil end else - log.msg(log.screen, script.script_name .. _(" failed to load")) + log.msg(log.screen, string.format(_("%s failed to load"), script.script_name)) log.msg(log.error, "Error loading " .. script.script_name) log.msg(log.error, "Error message: " .. err) end @@ -443,11 +441,11 @@ local function deactivate(script) script.running = false end log.msg(log.info, "turned off " .. script.script_name) - log.msg(log.screen, script.name .. _(" stopped")) + log.msg(log.screen, string.format(_("%s stopped"), script.name)) else script.running = false log.msg(log.info, "setting " .. script.script_name .. " to not start") - log.msg(log.screen, script.name .. _(" will not start when darktable is restarted")) + log.msg(log.screen, string.format(_("%s will not start when darktable is restarted"), script.name)) end restore_log_level(old_log_level) end @@ -515,7 +513,7 @@ local function scan_scripts(script_dir) if dt.configuration.running_os == "windows" then find_cmd = "dir /b/s \"" .. script_dir .. "\\*.lua\" | sort" end - log.msg(log.debug, _("find command is ") .. find_cmd) + log.msg(log.debug, "find command is " .. find_cmd) -- scan the scripts local output = io.popen(find_cmd) for line in output:lines() do @@ -589,7 +587,7 @@ local function scan_repositories() if dt.configuration.running_os == "windows" then find_cmd = "dir /b/s /a:d " .. LUA_DIR .. PS .. "*.git | sort" end - log.msg(log.debug, _("find command is ") .. find_cmd) + log.msg(log.debug, "find command is " .. find_cmd) local output = io.popen(find_cmd) for line in output:lines() do local l = string.gsub(line, ds.sanitize_lua(LUA_DIR) .. PS, "") -- strip the lua dir off @@ -627,7 +625,7 @@ local function install_scripts() local category = sm.widgets.new_category.text if string.match(du.join(sm.categories, " "), ds.sanitize_lua(category)) then - log.msg(log.screen, _("category ") .. category .. _(" is already in use. Please specify a different category name.")) + log.msg(log.screen, string.format(_("category %s is already in use. Please specify a different category name."), category)) log.msg(log.error, "category " .. category .. " already exists, returning...") restore_log_level(old_log_level) return @@ -658,7 +656,7 @@ local function install_scripts() local count = scan_scripts(LUA_DIR .. PS .. category) if count > 0 then update_combobox_choices(sm.widgets.category_selector, sm.categories, sm.widgets.category_selector.selected) - dt.print(_("scripts successfully installed into category ") .. category) + dt.print(string.format(_("scripts successfully installed into category "), category)) table.insert(sm.installed_repositories, {name = category, directory = LUA_DIR .. PS .. category}) update_script_update_choices() for i = 1, #sm.widgets.category_selector do @@ -719,14 +717,14 @@ local function populate_buttons(category, first, last) button.label = script.name button.name = "sm_started" else - button.label = script.name .. _(" started") + button.label = string.format(_("%s started"), script.name) end else if sm.use_color then button.label = script.name button.name = "sm_stopped" else - button.label = script.name .. _(" stopped") + button.label = string.format(_("%s stopped"), script.name) end end button.ellipsize = "middle" @@ -749,7 +747,7 @@ local function populate_buttons(category, first, last) if sm.use_color then this.name = "sm_stopped" else - this.label = script.name .. _(" stopped") + this.label = string.format(_("%s stopped"), script.name) end else log.msg(log.debug, "activating " .. script.name .. " on " .. script.path .. " for button " .. this.label) @@ -758,7 +756,7 @@ local function populate_buttons(category, first, last) if sm.use_color then this.name = "sm_started" else - this.label = script.name .. " started" + this.label = string.format(_("%s started"), script.name) end end end @@ -826,7 +824,7 @@ local function paginate(direction) else last = first + sm.page_status.num_buttons - 1 end - sm.widgets.page_status.label = _("Page ") .. cur_page .. _(" of ") .. max_pages + sm.widgets.page_status.label = string.format(_("Page %d of %d"), cur_page, max_pages) populate_buttons(category, first, last) restore_log_level(old_log_level) @@ -1125,7 +1123,7 @@ sm.widgets.install_update = dt.new_widget("box"){ sm.widgets.category_selector = dt.new_widget("combobox"){ label = _("category"), - tooltip = _( "select the script category"), + tooltip = _("select the script category"), selected = 1, changed_callback = function(self) if sm.run then From c11845cbf9043e6ab3e0a5bc28bf3ede4eb68882 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 19 Jan 2024 18:57:18 -0500 Subject: [PATCH 05/40] updated example scripts to use darktable translation facilities --- examples/api_version.lua | 11 +++++++++- examples/darkroom_demo.lua | 7 +++---- examples/gettextExample.lua | 16 ++++++--------- examples/hello_world.lua | 10 ++++++++- examples/lighttable_demo.lua | 21 +++++++++---------- examples/moduleExample.lua | 6 ++---- examples/multi_os.lua | 13 +++++------- examples/panels_demo.lua | 5 ++--- examples/preferenceExamples.lua | 36 ++++++++++++++++++++------------- examples/printExamples.lua | 10 ++++++++- examples/running_os.lua | 10 ++++++++- 11 files changed, 87 insertions(+), 58 deletions(-) diff --git a/examples/api_version.lua b/examples/api_version.lua index f2aaff7..1f86f6b 100644 --- a/examples/api_version.lua +++ b/examples/api_version.lua @@ -23,6 +23,14 @@ USAGE ]] local dt = require "darktable" +-- translation facilities + +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- script_manager integration to allow a script to be removed -- without restarting darktable local function destroy() @@ -30,7 +38,8 @@ local function destroy() end local result = dt.configuration.api_version_string -dt.print_error("API Version: "..result) +dt.print_log("API Version: " .. result) +dt.print(string.format(_("API Version: %s"), result)) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to diff --git a/examples/darkroom_demo.lua b/examples/darkroom_demo.lua index b4edcc5..6ca9f89 100644 --- a/examples/darkroom_demo.lua +++ b/examples/darkroom_demo.lua @@ -58,11 +58,10 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - -- T R A N S L A T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - @@ -98,7 +97,7 @@ sleep(1500) -- display first 10 images of collection pausing for a second between each for i, img in ipairs(dt.collection) do - dt.print(_("Displaying image " .. i)) + dt.print(string.format(_("Displaying image "), i)) dt.gui.views.darkroom.display_image(img) sleep(1500) if i == max_images then diff --git a/examples/gettextExample.lua b/examples/gettextExample.lua index 59a676c..f74b503 100644 --- a/examples/gettextExample.lua +++ b/examples/gettextExample.lua @@ -67,22 +67,18 @@ end -- Not translated Text dt.print_error("Hello World!") -local gettext = dt.gettext +local gettext = dt.gettext.gettext + -- Translate a string using the darktable textdomain -dt.print_error(gettext.gettext("image")) - --- Tell gettext where to find the .mo file translating messages for a particular domain - -gettext.bindtextdomain("gettextExample",dt.configuration.config_dir.."/lua/locale/") --- Translate a string using the specified textdomain -dt.print_error(gettext.dgettext("gettextExample", 'Hello World!')) +dt.print_error(gettext("image")) -- Define a local function called _ to make the code more readable and have it call dgettext -- with the proper domain. local function _(msgid) - return gettext.dgettext("gettextExample", msgid) + return gettext(msgid) end -dt.print_error(_('Hello World!')) + +dt.print_error(_("Hello World!")) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to diff --git a/examples/hello_world.lua b/examples/hello_world.lua index f8fba8d..3839ebd 100644 --- a/examples/hello_world.lua +++ b/examples/hello_world.lua @@ -29,15 +29,23 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" +-- translation facilities + du.check_min_api_version("2.0.0", "hello_world") +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- script_manager integration to allow a script to be removed -- without restarting darktable local function destroy() -- nothing to destroy end -dt.print("hello, world") +dt.print(_("hello, world")) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to diff --git a/examples/lighttable_demo.lua b/examples/lighttable_demo.lua index fc07132..768e4ab 100644 --- a/examples/lighttable_demo.lua +++ b/examples/lighttable_demo.lua @@ -59,11 +59,10 @@ end -- - - - - - - - - - - - - - - - - - - - - - - - -- T R A N S L A T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - @@ -145,17 +144,17 @@ sleep(2000) for n, layout in ipairs(layouts) do dt.gui.libs.lighttable_mode.layout(layout) - dt.print(_("set lighttable layout to " .. layout)) - dt.print_log(_("set lighttable layout to " .. layout)) + dt.print(string.format(_("set lighttable layout to %s"), layout)) + dt.print_log("set lighttable layout to " .. layout) sleep(1500) for i = 1, 10 do dt.gui.libs.lighttable_mode.zoom_level(i) - dt.print(_("Set zoom level to " .. i)) + dt.print(string.format(_("Set zoom level to %d"), i)) sleep(1500) end for i = 9, 1, -1 do dt.gui.libs.lighttable_mode.zoom_level(i) - dt.print(_("Set zoom level to " .. i)) + dt.print(string.format(_("Set zoom level to %d"), i)) sleep(1500) end end @@ -174,12 +173,12 @@ dt.print_log("starting sorts") for n, sort in ipairs(sorts) do dt.gui.libs.filter.sort(sort) - dt.print(_("set lighttable sort to " .. sort)) + dt.print(string.format(_("set lighttable sort to %s"), sort)) sleep(1500) for m, sort_order in ipairs(sort_orders) do dt.gui.libs.filter.sort_order(sort_order) - dt.print(_("sort order set to " .. sort_order)) + dt.print(string.format(_("sort order set to %s"), sort_order)) sleep(1500) end end @@ -190,12 +189,12 @@ dt.print(_("lighttable filtering demonstration")) for n, rating in ipairs(ratings) do dt.gui.libs.filter.rating(rating) - dt.print(_("set filter to " .. rating)) + dt.print(string.format(_("set filter to %s"), rating)) sleep(1500) for m, rating_comparator in ipairs(rating_comparators) do dt.gui.libs.filter.rating_comparator(rating_comparator) - dt.print(_("set rating comparator to " .. rating_comparator)) + dt.print(string.format(_("set rating comparator to %s"), rating_comparator)) sleep(1500) end end diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index bf5a325..23184aa 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -47,12 +47,10 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- translation -- https://www.darktable.org/lua-api/index.html#darktable_gettext -local gettext = dt.gettext - -gettext.bindtextdomain("moduleExample", dt.configuration.config_dir .. "/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("moduleExample", msgid) + return gettext(msgid) end -- declare a local namespace and a couple of variables we'll need to install the module diff --git a/examples/multi_os.lua b/examples/multi_os.lua index 4ab650f..7486a25 100644 --- a/examples/multi_os.lua +++ b/examples/multi_os.lua @@ -70,13 +70,10 @@ local dtsys = require "lib/dtutils.system" -- system utilities translations, inserting this lays the groundwork for anyone who wants to translate the strings. ]] -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("multi_os",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("multi_os", msgid) + return gettext(msgid) end --[[ @@ -187,7 +184,7 @@ local function extract_embedded_jpeg(images) end else dt.print_error(image.filename .. " is not a raw file. No image can be extracted") -- print debugging error message - dt.print(image.filename .. " is not a raw file. No image can be extracted") -- print the error to the screen + dt.print(string.format(_("%s is not a raw file. No image can be extracted"), image.filename)) -- print the error to the screen end end else @@ -241,7 +238,7 @@ end dt.gui.libs.image.register_action( "multi_os", _("extract embedded jpeg"), function(event, images) extract_embedded_jpeg(images) end, - "extract embedded jpeg" + _("extract embedded jpeg") ) --[[ @@ -251,7 +248,7 @@ dt.gui.libs.image.register_action( dt.register_event( "multi_os", "shortcut", function(event, shortcut) extract_embedded_jpeg(dt.gui.action_images) end, - "extract embedded jpeg" + _("extract embedded jpeg") ) --[[ diff --git a/examples/panels_demo.lua b/examples/panels_demo.lua index 1f74d71..5938398 100644 --- a/examples/panels_demo.lua +++ b/examples/panels_demo.lua @@ -59,11 +59,10 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - -- T R A N S L A T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/preferenceExamples.lua b/examples/preferenceExamples.lua index 99f8518..74e6152 100644 --- a/examples/preferenceExamples.lua +++ b/examples/preferenceExamples.lua @@ -24,28 +24,36 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" +-- translation facilities + +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + du.check_min_api_version("2.0.1", "preferenceExamples") dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesString", -- name "string", -- type - "Example String", -- label - "Example String Tooltip", -- tooltip + _("Example String"), -- label + _("Example String Tooltip"), -- tooltip "String") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesBool", -- name "bool", -- type - "Example Boolean", -- label - "Example Boolean Tooltip", -- tooltip + _("Example Boolean"), -- label + _("Example Boolean Tooltip"), -- tooltip true) -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesInteger", -- name "integer", -- type - "Example Integer", -- label - "Example Integer Tooltip", -- tooltip + _("Example Integer"), -- label + _("Example Integer Tooltip"), -- tooltip 2, -- default 1, -- min 99) -- max @@ -53,8 +61,8 @@ dt.preferences.register("preferenceExamples", -- script: This is a string dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesFloat", -- name "float", -- type - "Example Float", -- label - "Example Float Tooltip", -- tooltip + _("Example Float"), -- label + _("Example Float Tooltip"), -- tooltip 1.3, -- default 1, -- min 99, -- max @@ -63,22 +71,22 @@ dt.preferences.register("preferenceExamples", -- script: This is a string dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesFile", -- name "file", -- type - "Example File", -- label - "Example File Tooltip", -- tooltip + _("Example File"), -- label + _("Example File Tooltip"), -- tooltip "") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesDirectory", -- name "directory", -- type - "Example Directory", -- label - "Example Directory Tooltip", -- tooltip + _("Example Directory"), -- label + _("Example Directory Tooltip"), -- tooltip "") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesEnum", -- name "enum", -- type - "Example Enum", -- label - "Example Enum Tooltip", -- tooltip + _("Example Enum"), -- label + _("Example Enum Tooltip"), -- tooltip "Enum 1", -- default "Enum 1", "Enum 2") -- values diff --git a/examples/printExamples.lua b/examples/printExamples.lua index b220b7a..b7be20c 100644 --- a/examples/printExamples.lua +++ b/examples/printExamples.lua @@ -24,6 +24,14 @@ local du = require "lib/dtutils" du.check_min_api_version("5.0.0", "printExamples") +-- translation facilities + +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- script_manager integration to allow a script to be removed -- without restarting darktable local function destroy() @@ -32,7 +40,7 @@ end -- Will print a string to the darktable control log (the long -- overlayed window that appears over the main panel). -dt.print("print") +dt.print(_("print")) -- This function will print its parameter if the Lua logdomain is -- activated. Start darktable with the "-d lua" command line option diff --git a/examples/running_os.lua b/examples/running_os.lua index d214b2a..a179e9f 100644 --- a/examples/running_os.lua +++ b/examples/running_os.lua @@ -30,13 +30,21 @@ local du = require "lib/dtutils" du.check_min_api_version("5.0.0", "running_os") +-- translation facilities + +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- script_manager integration to allow a script to be removed -- without restarting darktable local function destroy() -- nothing to destroy end -dt.print("You are running: "..dt.configuration.running_os) +dt.print(string.format(_("You are running: %s"), dt.configuration.running_os)) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to From 37dba718a28b0af9feb27779ec97fc4904452884 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 20 Jan 2024 15:25:16 -0500 Subject: [PATCH 06/40] updated official scripts to use darktable translation facilities --- official/copy_paste_metadata.lua | 11 ++++------- official/delete_long_tags.lua | 2 +- official/delete_unused_tags.lua | 2 +- official/enfuse.lua | 21 +++++++++------------ official/generate_image_txt.lua | 16 +++++++++++----- official/import_filter_manager.lua | 12 +++++++++--- official/import_filters.lua | 2 +- official/save_selection.lua | 12 +++++++++--- official/selection_to_pdf.lua | 26 ++++++++++++++++---------- 9 files changed, 61 insertions(+), 43 deletions(-) diff --git a/official/copy_paste_metadata.lua b/official/copy_paste_metadata.lua index ffd69c8..3afb953 100644 --- a/official/copy_paste_metadata.lua +++ b/official/copy_paste_metadata.lua @@ -27,7 +27,7 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "copy_paste_metadata") @@ -58,11 +58,8 @@ local publisher = "" local rights = "" local tags = {} --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("copy_paste_metadata",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("copy_paste_metadata", msgid) + return gettext(msgid) end local function copy(image) @@ -147,13 +144,13 @@ dt.gui.libs.image.register_action( dt.register_event( "capmd1", "shortcut", function(event, shortcut) copy(dt.gui.action_images[1]) end, - "copy metadata" + _("copy metadata") ) dt.register_event( "capmd2", "shortcut", function(event, shortcut) paste(dt.gui.action_images) end, - "paste metadata" + _("paste metadata") ) script_data.destroy = destroy diff --git a/official/delete_long_tags.lua b/official/delete_long_tags.lua index 31ae799..2c5d0e6 100644 --- a/official/delete_long_tags.lua +++ b/official/delete_long_tags.lua @@ -59,7 +59,7 @@ local long_tags = {} for _,t in ipairs(dt.tags) do local len = #t.name if len > max_length then - print("deleting tag `"..t.name.."' (length: "..len..")") + dt.print_log("deleting tag `"..t.name.."' (length: "..len..")") table.insert(long_tags, t.name) end end diff --git a/official/delete_unused_tags.lua b/official/delete_unused_tags.lua index 0dfab01..e169068 100644 --- a/official/delete_unused_tags.lua +++ b/official/delete_unused_tags.lua @@ -56,7 +56,7 @@ for _, t in ipairs(dt.tags) do end for _,name in pairs(unused_tags) do - print("deleting tag `" .. name .. "'") + dt.print_log("deleting tag `" .. name .. "'") tag = dt.tags.find(name) tag:delete() end diff --git a/official/enfuse.lua b/official/enfuse.lua index 35327cf..fb94229 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -39,7 +39,7 @@ local dtsys = require "lib/dtutils.system" local PS = dt.configuration.running_os == "windows" and "\\" or "/" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "enfuse") @@ -52,16 +52,13 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("enfuse",dt.configuration.config_dir..PS .. "lua" .. PS .. "locale" .. PS) - local enf = {} enf.event_registered = false enf.module_installed = false enf.lib_widgets = {} local function _(msgid) - return gettext.dgettext("enfuse", msgid) + return gettext(msgid) end local function install_module() @@ -132,7 +129,7 @@ if enfuse_installed then exposure_mu = dt.new_widget("slider") { label = "exposure mu", - tooltip = "center also known as MEAN of Gaussian weighting function (0 <= MEAN <= 1); default: 0.5", + tooltip = _("center also known as MEAN of Gaussian weighting function (0 <= MEAN <= 1); default: 0.5"), hard_min = 0, hard_max = 1, value = dt.preferences.read("enfuse", "exposure_mu", "float") @@ -141,7 +138,7 @@ if enfuse_installed then exposure_mu = dt.new_widget("slider") { label = "exposure optimum", - tooltip = "optimum exposure value, usually the maximum of the weighting function (0 <= OPTIMUM <=1); default 0.5", + tooltip = _("optimum exposure value, usually the maximum of the weighting function (0 <= OPTIMUM <=1); default 0.5"), hard_min = 0, hard_max = 1, value = dt.preferences.read("enfuse", "exposure_optimum", "float") @@ -151,7 +148,7 @@ if enfuse_installed then local depth = dt.new_widget("combobox") { label = "depth", - tooltip = "the number of bits per channel of the output image", + tooltip = _("the number of bits per channel of the output image"), value = dt.preferences.read("enfuse", "depth", "integer"), changed_callback = function(w) dt.preferences.write("enfuse", "depth", "integer", w.selected) end, "8", "16", "32" @@ -160,14 +157,14 @@ if enfuse_installed then local blend_colorspace = dt.new_widget("combobox") { label = "blend colorspace", - tooltip = "Force blending in selected colorspace", + tooltip = _("force blending in selected colorspace"), changed_callback = function(w) dt.preferences.write("enfuse", "blend_colorspace", "string", w.selected) end, "", "identity", "ciecam" } local enfuse_button = dt.new_widget("button") { - label = enfuse_installed and "run enfuse" or "enfuse not installed", + label = enfuse_installed and _("run enfuse") or _("enfuse not installed"), clicked_callback = function () -- remember exposure_mu -- TODO: find a way to save it whenever the value changes @@ -185,7 +182,7 @@ if enfuse_installed then end local f = io.open(response_file, "w") if not f then - dt.print(string.format(_("Error writing to `%s`"), response_file)) + dt.print(string.format(_("Error writing to '%s'"), response_file)) os.remove(response_file) return end @@ -251,7 +248,7 @@ if enfuse_installed then ..blend_colorspace_option .." -o \""..output_image.."\" \"@"..response_file.."\"" if dtsys.external_command( command) > 0 then - dt.print(_("Enfuse failed, see terminal output for details")) + dt.print(_("enfuse failed, see terminal output for details")) os.remove(response_file) return end diff --git a/official/generate_image_txt.lua b/official/generate_image_txt.lua index 73b5063..3eeafbe 100644 --- a/official/generate_image_txt.lua +++ b/official/generate_image_txt.lua @@ -38,6 +38,12 @@ local dt = require "darktable" local du = require "lib/dtutils" require "darktable.debug" +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + du.check_min_api_version("7.0.0", "generate_image_txt") -- return data structure for script_manager @@ -52,21 +58,21 @@ script_data.show = nil -- only required for libs since the destroy_method only h dt.preferences.register("generate_image_txt", "enabled", "bool", - "create txt sidecars to display with images", - "the txt files created get shown when the lighttable is zoomed in to one image. also enable the txt overlay setting in the gui tab", + _("create txt sidecars to display with images"), + _("the txt files created get shown when the lighttable is zoomed in to one image. also enable the txt overlay setting in the gui tab"), false) dt.preferences.register("generate_image_txt", "command", "string", - "command to generate the txt sidecar", - "the output of this command gets written to the txt file. use $(FILE_NAME) for the image file", + _("command to generate the txt sidecar"), + _("the output of this command gets written to the txt file. use $(FILE_NAME) for the image file"), "exiv2 $(FILE_NAME)") local check_command = function(command) if not command:find("$(FILE_NAME)", 1, true) then - dt.print("the command for txt sidecars looks bad. better check the preferences") + dt.print(_("the command for txt sidecars looks bad. better check the preferences")) end end diff --git a/official/import_filter_manager.lua b/official/import_filter_manager.lua index c648c1a..7a81f2c 100644 --- a/official/import_filter_manager.lua +++ b/official/import_filter_manager.lua @@ -32,20 +32,26 @@ USAGE local dt = require "darktable" +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + local import_filter_list = {} local n_import_filters = 1 -- allow changing the filter from the preferences dt.preferences.register("import_filter_manager", "active_filter", "string", - "import filter", "the name of the filter used for importing images", "") + _("import filter"), _("the name of the filter used for importing images"), "") -- the dropdown to select the active filter from the import dialog local filter_dropdown = dt.new_widget("combobox") { - label = "import filter", + label = _("import filter"), editable = false, - tooltip = "import filters are applied after completion of the import dialog", + tooltip = _("import filters are applied after completion of the import dialog"), changed_callback = function(widget) dt.preferences.write("import_filter_manager", "active_filter", "string", widget.value) diff --git a/official/import_filters.lua b/official/import_filters.lua index 584a271..807dec6 100644 --- a/official/import_filters.lua +++ b/official/import_filters.lua @@ -34,7 +34,7 @@ local dt = require "darktable" -- ignore jpeg dt.register_import_filter("ignore jpegs", function(event, images) - dt.print_error("ignoring all jpegs") + dt.print_log("ignoring all jpegs") for i, img in ipairs(images) do local extension = img:match("[^.]*$"):upper() if (extension == "JPG") or (extension == "JPEG") then diff --git a/official/save_selection.lua b/official/save_selection.lua index b06f933..22841a9 100644 --- a/official/save_selection.lua +++ b/official/save_selection.lua @@ -38,6 +38,12 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "save_selection") +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- return data structure for script_manager local script_data = {} @@ -61,16 +67,16 @@ for i = 1, buffer_count do local saved_selection dt.register_event("save_selection save " .. i, "shortcut", function() saved_selection = dt.gui.selection() - end, "save to buffer " .. i) + end, string.format(_("save to buffer %d"), i)) dt.register_event("save_selection restore " .. i, "shortcut", function() dt.gui.selection(saved_selection) - end, "restore from buffer " .. i) + end, string.format(_("restore from buffer %d"), i)) end local bounce_buffer = {} dt.register_event("save_selection switch", "shortcut", function() bounce_buffer = dt.gui.selection(bounce_buffer) -end, "switch selection with temporary buffer") +end, _("switch selection with temporary buffer")) script_data.destroy = destroy diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 638ae24..9e1d7b4 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -38,6 +38,12 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "selection_to_pdf") +local gettext = dt.gettext.gettext + +local function _(msg) + return gettext(msg) +end + -- return data structure for script_manager local script_data = {} @@ -49,16 +55,16 @@ script_data.show = nil -- only required for libs since the destroy_method only h dt.preferences.register ("selection_to_pdf","Open with","string", - "a pdf viewer", - "Can be an absolute pathname or the tool may be in the PATH", + _("a pdf viewer"), + _("Can be an absolute pathname or the tool may be in the PATH"), "xdg-open") local title_widget = dt.new_widget("entry") { - placeholder="Title" + placeholder = _("Title") } local no_of_thumbs_widget = dt.new_widget("slider") { - label = "Thumbs per Line", + label = _("Thumbs per Line"), soft_min = 1, -- The soft minimum value for the slider, the slider can't go beyond this point soft_max = 10, -- The soft maximum value for the slider, the slider can't go beyond this point hard_min = 1, -- The hard minimum value for the slider, the user can't manually enter a value beyond this point @@ -66,10 +72,10 @@ local no_of_thumbs_widget = dt.new_widget("slider") value = 4 -- The current value of the slider } local widget = dt.new_widget("box") { - orientation=horizontal, - dt.new_widget("label"){label = "Title:"}, + orientation = horizontal, + dt.new_widget("label"){label = _("Title:")}, title_widget, - dt.new_widget("label"){label = "Thumbnails per row:"}, + dt.new_widget("label"){label = _("Thumbnails per row:")}, no_of_thumbs_widget } @@ -116,7 +122,7 @@ local function destroy() dt.print_log("done destroying") end -dt.register_storage("export_pdf","Export thumbnails to pdf", +dt.register_storage(_("export_pdf"),_("Export thumbnails to pdf"), nil, function(storage,image_table) local my_title = title_widget.text @@ -163,7 +169,7 @@ dt.register_storage("export_pdf","Export thumbnails to pdf", local command = "pdflatex -halt-on-error -output-directory "..dir.." "..locfile local result = dt.control.execute(command) if result ~= 0 then - dt.print("Problem running pdflatex") -- this one is probably usefull to the user + dt.print(_("Problem running pdflatex")) -- this one is probably usefull to the user error("Problem running "..command) end @@ -173,7 +179,7 @@ dt.register_storage("export_pdf","Export thumbnails to pdf", command = command.." "..pdffile local result = dt.control.execute(command) if result ~= 0 then - dt.print("Problem running pdf viewer") -- this one is probably usefull to the user + dt.print(_("Problem running pdf viewer")) -- this one is probably usefull to the user error("Problem running "..command) end From 66b33d6f48c496ce64fe1ef6f835d790b1b7858a Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 20 Jan 2024 20:22:32 -0500 Subject: [PATCH 07/40] updated contrib scripts to use darktable translation facilities --- contrib/AutoGrouper.lua | 6 ++-- contrib/CollectHelper.lua | 7 ++-- contrib/HDRMerge.lua | 10 +++--- contrib/LabelsToTags.lua | 50 ++++++++++++++++------------- contrib/OpenInExplorer.lua | 7 ++-- contrib/RL_out_sharp.lua | 8 ++--- contrib/autostyle.lua | 24 ++++++++------ contrib/change_group_leader.lua | 7 ++-- contrib/clear_GPS.lua | 6 ++-- contrib/color_profile_manager.lua | 11 +++---- contrib/copy_attach_detach_tags.lua | 7 ++-- contrib/cr2hdr.lua | 14 +++++--- contrib/cycle_group_leader.lua | 7 ++-- contrib/enfuseAdvanced.lua | 22 ++++++------- contrib/exportLUT.lua | 8 ++--- contrib/ext_editor.lua | 24 +++++++------- contrib/face_recognition.lua | 13 +++----- contrib/fujifilm_ratings.lua | 10 +++--- contrib/geoJSON_export.lua | 7 ++-- contrib/geoToolbox.lua | 15 ++++----- contrib/gimp.lua | 9 ++---- contrib/gpx_export.lua | 9 ++---- contrib/harmonic_armature_guide.lua | 7 ++-- contrib/hif_group_leader.lua | 7 ++-- contrib/hugin.lua | 11 +++---- contrib/image_stack.lua | 19 +++++------ contrib/image_time.lua | 16 ++++----- contrib/jpg_group_leader.lua | 7 ++-- contrib/kml_export.lua | 7 ++-- contrib/passport_guide.lua | 7 ++-- contrib/pdf_slideshow.lua | 13 +++----- contrib/photils.lua | 8 ++--- contrib/quicktag.lua | 7 ++-- contrib/rate_group.lua | 24 ++++++++------ contrib/rename-tags.lua | 28 +++++++++------- contrib/rename_images.lua | 17 ++++------ contrib/select_non_existing.lua | 5 ++- contrib/select_untagged.lua | 7 ++-- contrib/slideshowMusic.lua | 11 +++---- contrib/transfer_hierarchy.lua | 12 +++---- contrib/video_ffmpeg.lua | 9 +++--- 41 files changed, 224 insertions(+), 279 deletions(-) diff --git a/contrib/AutoGrouper.lua b/contrib/AutoGrouper.lua index 79ded8c..decc9b9 100644 --- a/contrib/AutoGrouper.lua +++ b/contrib/AutoGrouper.lua @@ -52,12 +52,10 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("AutoGrouper",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("AutoGrouper", msgid) + return gettext(msgid) end local Ag = {} diff --git a/contrib/CollectHelper.lua b/contrib/CollectHelper.lua index 7f60935..9e6f12c 100644 --- a/contrib/CollectHelper.lua +++ b/contrib/CollectHelper.lua @@ -47,13 +47,10 @@ In the "Selected Images" module click on "Collect on this Image" local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local previous = nil local all_active = false --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("CollectHelper",dt.configuration.config_dir.."/lua/locale/") - du.check_min_api_version("7.0.0", "CollectHelper") -- return data structure for script_manager @@ -66,7 +63,7 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid script_data.show = nil -- only required for libs since the destroy_method only hides them local function _(msgid) - return gettext.dgettext("CollectHelper", msgid) + return gettext(msgid) end -- FUNCTION -- diff --git a/contrib/HDRMerge.lua b/contrib/HDRMerge.lua index 3e7e29a..a662f21 100644 --- a/contrib/HDRMerge.lua +++ b/contrib/HDRMerge.lua @@ -67,10 +67,10 @@ 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.bindtextdomain('HDRMerge', dt.configuration.config_dir..'/lua/locale/') +local gettext = dt.gettext.gettext + local function _(msgid) - return gettext.dgettext('HDRMerge', msgid) + return gettext(msgid) end local temp @@ -208,7 +208,7 @@ 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_error('HDRMerge install issue') dt.print(_('HDRMerge install issue, please ensure the binary path is proper')) return end @@ -277,7 +277,7 @@ local function main() end dt.print(_('HDRMerge completed successfully')) else - dt.print_error(_('HDRMerge failed')) + dt.print_error('HDRMerge failed') dt.print(_('HDRMerge failed')) end diff --git a/contrib/LabelsToTags.lua b/contrib/LabelsToTags.lua index a89b05d..83feada 100644 --- a/contrib/LabelsToTags.lua +++ b/contrib/LabelsToTags.lua @@ -52,6 +52,12 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "LabelsToTags") +local gettext = dt.gettext.gettext + +local function _(msgid) + return gettext(msgid) +end + -- return data structure for script_manager local script_data = {} @@ -68,7 +74,7 @@ local ltt = {} ltt.module_installed = false ltt.event_registered = false -local LIB_ID = "LabelsToTags" +local LIB_ID = _("LabelsToTags") -- Helper functions: BEGIN @@ -109,23 +115,23 @@ end local initialAvailableMappings = { - ["Colors"] = { ["+*****"] = { "Red" }, - ["*+****"] = { "Yellow" }, - ["**+***"] = { "Green" }, - ["***+**"] = { "Blue" }, - ["****+*"] = { "Purple" } }, - ["Single colors"] = { ["+----*"] = { "Red", "Only red" }, - ["-+---*"] = { "Yellow", "Only yellow" }, - ["--+--*"] = { "Green", "Only green" }, - ["---+-*"] = { "Blue", "Only blue" }, - ["----+*"] = { "Purple", "Only purple" } }, - ["Ratings"] = { ["*****0"] = { "No stars", "Not rejected" }, - ["*****1"] = { "One star", "Not rejected" }, - ["*****2"] = { "Two stars", "Not rejected" }, - ["*****3"] = { "Three stars", "Not rejected" }, - ["*****4"] = { "Four stars", "Not rejected" }, - ["*****5"] = { "Five stars", "Not rejected" }, - ["*****R"] = { "Rejected" } } + [_("Colors")] = { ["+*****"] = { _("Red") }, + ["*+****"] = { _("Yellow") }, + ["**+***"] = { _("Green") }, + ["***+**"] = { _("Blue") }, + ["****+*"] = { _("Purple") } }, + [_("Single colors")] = { ["+----*"] = { _("Red"), _("Only red") }, + ["-+---*"] = { _("Yellow"), _("Only yellow") }, + ["--+--*"] = { _("Green"), _("Only green") }, + ["---+-*"] = { _("Blue"), _("Only blue") }, + ["----+*"] = { _("Purple"), _("Only purple") } }, + [_("Ratings")] = { ["*****0"] = { _("No stars"), _("Not rejected") }, + ["*****1"] = { _("One star"), _("Not rejected") }, + ["*****2"] = { _("Two stars"), _("Not rejected") }, + ["*****3"] = { _("Three stars"), _("Not rejected") }, + ["*****4"] = { _("Four stars"), _("Not rejected") }, + ["*****5"] = { _("Five stars"), _("Not rejected") }, + ["*****R"] = { _("Rejected") } } } local availableMappings = {} @@ -140,14 +146,14 @@ end local function getComboboxTooltip() if availableMappings == nil or next(availableMappings) == nil then - return("No registered mappings -- using defaults") + return(_("No registered mappings -- using defaults")) else - return("Select a label-to-tag mapping") + return(_("Select a label-to-tag mapping")) end end local mappingComboBox = darktable.new_widget("combobox"){ - label = "mapping", + label = _("mapping"), value = 1, tooltip = getComboboxTooltip(), reset_callback = function(selfC) @@ -170,7 +176,7 @@ local mappingComboBox = darktable.new_widget("combobox"){ } local function doTagging(selfC) - local job = darktable.gui.create_job(string.format("labels to tags (%d image" .. (#(darktable.gui.action_images) == 1 and "" or "s") .. ")",#(darktable.gui.action_images)),true) + local job = darktable.gui.create_job(string.format(_("labels to tags (%d image%s)"), #(darktable.gui.action_images), (#(darktable.gui.action_images) == 1 and "" or "s")), true) job.percent = 0.0 local pctIncrement = 1.0 / #(darktable.gui.action_images) diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index 9a8cd65..443a09a 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -51,7 +51,7 @@ 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 +local gettext = dt.gettext.gettext --Check API version du.check_min_api_version("7.0.0", "OpenInExplorer") @@ -65,11 +65,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("OpenInExplorer",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("OpenInExplorer", msgid) + return gettext(msgid) end local act_os = dt.configuration.running_os diff --git a/contrib/RL_out_sharp.lua b/contrib/RL_out_sharp.lua index 2c854e4..44d961e 100644 --- a/contrib/RL_out_sharp.lua +++ b/contrib/RL_out_sharp.lua @@ -78,10 +78,10 @@ script_data.show = nil -- only required for libs since the destroy_method only h local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- translation -local gettext = dt.gettext -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext + local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end -- initialize module preferences @@ -137,7 +137,7 @@ local function export2RL(storage, image_table, extra_data) for image, temp_name in pairs(image_table) do i = i + 1 - dt.print(_("sharpening image ")..i.." ...") + dt.print(string.format(_("sharpening image %d ..."), i)) -- create unique filename new_name = output_folder..PS..df.get_basename(temp_name)..".jpg" new_name = df.create_unique_filename(new_name) diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index 53fc0ab..cf3ebe7 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -42,6 +42,12 @@ local filelib = require "lib/dtutils.file" du.check_min_api_version("7.0.0", "autostyle") +local gettext = darktable.gettext.gettext + +local function _(msgid) + return gettext(msgid) +end + -- return data structure for script_manager local script_data = {} @@ -92,19 +98,19 @@ local function autostyle_apply_one_image (image) -- check they all exist (correct syntax) if (not tag) then - darktable.print("EXIF TAG not found in " .. pref) + darktable.print(string.format(_("EXIF TAG not found in %s"), pref)) return 0 end if (not value) then - darktable.print("value to match not found in " .. pref) + darktable.print(string.format(_("value to match not found in %s"), pref)) return 0 end if (not style_name) then - darktable.print("style name not found in " .. pref) + darktable.print(string.format(_("style name not found in %s"), pref)) return 0 end if not filelib.check_if_bin_exists("exiftool") then - darktable.print("Can't find exiftool") + darktable.print(_("Can't find exiftool")) return 0 end @@ -118,7 +124,7 @@ local function autostyle_apply_one_image (image) end end if (not style) then - darktable.print("style not found for autostyle: " .. style_name) + darktable.print(string.format(_("style not found for autostyle: %s"), style_name)) return 0 end @@ -127,7 +133,7 @@ local function autostyle_apply_one_image (image) --darktable.print_error("dr_attr:" .. auto_dr_attr) -- If the lookup fails, stop here if (not ok) then - darktable.print("Couldn't get attribute " .. auto_dr_attr .. " from exiftool's output") + darktable.print(string.format(_("Couldn't get attribute %s from exiftool's output"), auto_dr_attr)) return 0 end if auto_dr_attr == value then @@ -154,7 +160,7 @@ local function autostyle_apply(shortcut) images_submitted = images_submitted + 1 images_processed = images_processed + autostyle_apply_one_image(image) end - darktable.print("Applied auto style to " .. images_processed .. " out of " .. images_submitted .. " image(s)") + darktable.print(string.format(_("Applied auto style to %d out of %d image(s)"), images_processed, images_submitted)) end local function destroy() @@ -164,9 +170,9 @@ end -- Registering events darktable.register_event("autostyle", "shortcut", autostyle_apply, - "Apply your chosen style from exiftool tags") + _("Apply your chosen style from exiftool tags")) -darktable.preferences.register("autostyle", "exif_tag", "string", "Autostyle: EXIF_tag=value=>style", "apply a style automatically if an EXIF_tag matches value. Find the tag with exiftool", "") +darktable.preferences.register("autostyle", "exif_tag", "string", "Autostyle: EXIF_tag=value=>style", _("apply a style automatically if an EXIF_tag matches value. Find the tag with exiftool"), "") darktable.register_event("autostyle", "post-import-image", autostyle_apply_one_image_event) diff --git a/contrib/change_group_leader.lua b/contrib/change_group_leader.lua index c7fe5c0..786c91e 100644 --- a/contrib/change_group_leader.lua +++ b/contrib/change_group_leader.lua @@ -36,7 +36,7 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local MODULE = "change_group_leader" @@ -51,11 +51,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain(MODULE, dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext(MODULE, msgid) + return gettext(msgid) end -- create a namespace to contain persistent data and widgets diff --git a/contrib/clear_GPS.lua b/contrib/clear_GPS.lua index da4668c..9f21b1e 100644 --- a/contrib/clear_GPS.lua +++ b/contrib/clear_GPS.lua @@ -48,18 +48,16 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 +local gettext = dt.gettext.gettext -- not a number local NaN = 0/0 du.check_min_api_version("7.0.0", "clear_GPS") --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("clear_GPS",dt.configuration.config_dir.."/lua/locale/") local function _(msgid) - return gettext.dgettext("clear_GPS", msgid) + return gettext(msgid) end local function clear_GPS(images) diff --git a/contrib/color_profile_manager.lua b/contrib/color_profile_manager.lua index bd09755..b8ef21f 100644 --- a/contrib/color_profile_manager.lua +++ b/contrib/color_profile_manager.lua @@ -52,13 +52,10 @@ du.check_min_api_version("7.0.0", "color_profile_manager") -- L O C A L I Z A T I O N -- - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("color_profile_manager", dt.configuration.config_dir .. "/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("color_profile_manager", msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - @@ -119,13 +116,13 @@ end local function add_profile(file, dir) df.file_copy(file, dir) - dt.print(_("added color profile " .. file .. " to " .. dir)) + dt.print(string.format(_("added color profile %s to %s"), file, dir)) dt.print_log("color profile " .. file .. " added to " .. dir) end local function remove_profile(file, dir) os.remove(dir .. PS .. file) - dt.print(_("removed color profile " .. file .. " from " .. dir)) + dt.print(string.format(_("removed color profile %s from %s"), file, dir)) dt.print_log("color profile " .. file .. " removed from " .. dir) end diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index 05f6f1f..1de8db2 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -40,7 +40,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local debug = require "darktable.debug" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "copy_attach_detach_tags") @@ -53,11 +53,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("copy_attach_detach_tags",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("copy_attach_detach_tags", msgid) + return gettext(msgid) end local cadt = {} diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua index f4a40c9..53b1e14 100644 --- a/contrib/cr2hdr.lua +++ b/contrib/cr2hdr.lua @@ -37,6 +37,12 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "cr2hdr") +local gettext = dt.gettext.gettext + +local function _(msgid) + return gettext(msgid) +end + -- return data structure for script_manager local script_data = {} @@ -87,7 +93,7 @@ end local function convert_images() if next(queue) == nil then return end - job = darktable.gui.create_job("Dual ISO conversion", true, stop_conversion) + job = darktable.gui.create_job(_("Dual ISO conversion"), true, stop_conversion) for key,image in pairs(queue) do if job.valid then job.percent = (key-1)/#queue @@ -98,7 +104,7 @@ local function convert_images() end local success_count = 0 for _ in pairs(processed_files) do success_count = success_count + 1 end - darktable.print("Dual ISO conversion successful on " .. success_count .. "/" .. #queue .. " images.") + darktable.print(string.format(_("Dual ISO conversion successful on %d/%d images."), success_count, #queue)) job.valid = false processed_files = {} queue = {} @@ -122,13 +128,13 @@ local function destroy() end darktable.register_event("cr2hdr", "shortcut", - convert_action_images, "Run cr2hdr (Magic Lantern DualISO converter) on selected images") + convert_action_images, _("Run cr2hdr (Magic Lantern DualISO converter) on selected images")) darktable.register_event("cr2hdr", "post-import-image", file_imported) darktable.register_event("cr2hdr", "post-import-film", film_imported) -darktable.preferences.register("cr2hdr", "onimport", "bool", "Invoke on import", "If true then cr2hdr will try to proccess every file during importing. Warning: cr2hdr is quite slow even in figuring out on whether the file is Dual ISO or not.", false) +darktable.preferences.register("cr2hdr", "onimport", "bool", _("Invoke on import"), _("If true then cr2hdr will try to proccess every file during importing. Warning: cr2hdr is quite slow even in figuring out on whether the file is Dual ISO or not."), false) script_data.destroy = destroy diff --git a/contrib/cycle_group_leader.lua b/contrib/cycle_group_leader.lua index e4bdd11..dde8546 100644 --- a/contrib/cycle_group_leader.lua +++ b/contrib/cycle_group_leader.lua @@ -69,13 +69,10 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- I 1 8 N -- - - - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE, msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/enfuseAdvanced.lua b/contrib/enfuseAdvanced.lua index 76ffd01..f8aeb9b 100644 --- a/contrib/enfuseAdvanced.lua +++ b/contrib/enfuseAdvanced.lua @@ -77,10 +77,10 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid 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.bindtextdomain('enfuseAdvanced',dt.configuration.config_dir..'/lua/locale/') +local gettext = dt.gettext.gettext + local function _(msgid) - return gettext.dgettext('enfuseAdvanced', msgid) + return gettext(msgid) end -- INITS -- @@ -260,7 +260,7 @@ local function ExeUpdate(prog_tbl) --updates executable paths and verifies them if not prog.bin then prog.install_error = true dt.preferences.write(mod, 'bin_exists', 'bool', false) - dt.print(_('issue with ')..prog.name.._(' executable')) + dt.print(string.format(_("issue with %s executable"), prog.name)) else prog.bin = CleanSpaces(prog.bin) end @@ -377,7 +377,7 @@ local function SaveToPreference(preset) --save the present values of enfuse GUI dt.preferences.write(mod, preset..argument, arg_data.style, temp) end end - dt.print(_('saved to ')..preset) + dt.print(string.format(_("saved to %s"), preset)) end local function LoadFromPreference(preset) --load values from the specified 'preset' into the GUI elements @@ -393,7 +393,7 @@ local function LoadFromPreference(preset) --load values from the specified 'pres dt.preferences.write(mod, 'active_'..argument, arg_data.style, temp) end end - dt.print(_('loaded from ')..preset) + dt.print(string.format(_("loaded from %s"), preset)) end local function remove_temp_files(images_to_remove) --deletes all files specified by the input string @@ -428,7 +428,7 @@ local function support_format(storage, format) --tells dt we only support TIFF e end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) --outputs message to user showing script export status - dt.print(_('export for image fusion ')..tostring(math.floor(number))..' / '..tostring(math.floor(total))) + dt.print(string.format(_("export for image fusion %d / %d"), math.floor(number), math.floor(total))) end local function main(storage, image_table, extra_data) @@ -456,8 +456,8 @@ local function main(storage, image_table, extra_data) job.valid = false if resp ~= 0 then remove_temp_files(images_to_remove) - dt.print_error(AIS.name.._(' failed')) - dt.print(AIS.name.._(' failed')) + dt.print(string.format(_("%s failed"), AIS.name)) + dt.print_error(AIS.name .. ' failed') return end end @@ -483,8 +483,8 @@ local function main(storage, image_table, extra_data) local resp = dsys.external_command(run_cmd) if resp ~= 0 then remove_temp_files(images_to_remove) - dt.print_error(ENF.name.._(' failed')) - dt.print(ENF.name.._(' failed')) + dt.print_error(ENF.name..' failed') + dt.print(string.format(_("%s failed"), ENF.name)) return end diff --git a/contrib/exportLUT.lua b/contrib/exportLUT.lua index fe11960..6a22f83 100644 --- a/contrib/exportLUT.lua +++ b/contrib/exportLUT.lua @@ -42,12 +42,10 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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.bindtextdomain("exportLUT",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("exportLUT", msgid) + return gettext(msgid) end du.check_min_api_version("5.0.0", "exportLUT") @@ -127,7 +125,7 @@ local function export_luts() io_lut:write_image(identity, output_path(style.name, job)) count = count + 1 job.percent = count / size - dt.print(_("Exported: ") .. output_path(style.name, job)) + dt.print(string.format(_("Exported: %s"), output_path(style.name, job))) end dt.print(_("Done exporting haldCLUTs")) job.valid = false diff --git a/contrib/ext_editor.lua b/contrib/ext_editor.lua index 827d527..b28a7f9 100644 --- a/contrib/ext_editor.lua +++ b/contrib/ext_editor.lua @@ -95,10 +95,10 @@ ee.widgets = {} -- translation -local gettext = dt.gettext -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext + local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end -- maximum number of external programs, can be increased to necessity @@ -156,7 +156,7 @@ local function UpdateProgramList(combobox, button_edit, button_edit_copy, update button_edit.sensitive = active button_edit_copy.sensitive = active - if update_button_pressed then dt.print(n_entries.._(" editors configured")) end + if update_button_pressed then dt.print(string.format(_("%d editors configured"), n_entries)) end end @@ -223,17 +223,17 @@ local function OpenWith(images, choice, copy) -- physical copy, check result, return if error local copy_success = df.file_copy(name, new_name) if not copy_success then - dt.print(_("error copying file ")..name) + dt.print(string.format(_("error copying file %s"), name)) return end end -- launch the external editor, check result, return if error local run_cmd = bin.." "..df.sanitize_filename(new_name) - dt.print(_("launching ")..friendly_name.."...") + dt.print(string.format(_("launching %s..."), friendly_name)) local result = dtsys.external_command(run_cmd) if result ~= 0 then - dt.print(_("error launching ")..friendly_name) + dt.print(string.format(_("error launching %s"), friendly_name)) return end @@ -326,7 +326,7 @@ local function export2collection(storage, image_table, extra_data) -- move image to collection folder, check result, return if error move_success = df.file_move(temp_name, new_name) if not move_success then - dt.print(_("error moving file ")..temp_name) + dt.print(string.format(_("error moving file %s"), temp_name)) return end @@ -378,7 +378,7 @@ end local function restart() for i = 1, MAX_EDITORS do dt.register_event(MODULE_NAME .. i, "shortcut", - program_shortcut, _("edit with program ")..string.format("%02d", i)) + program_shortcut, string.format(_("edit with program %02d"), i)) end dt.register_storage("exp2coll", _("collection"), nil, export2collection) dt.gui.libs[MODULE_NAME].visible = true @@ -476,11 +476,11 @@ dt.register_storage("exp2coll", _("collection"), nil, export2collection) -- register the new preferences ----------------------------------------------- for i = MAX_EDITORS, 1, -1 do dt.preferences.register(MODULE_NAME, "program_path_"..i, "file", - _("executable for external editor ")..i, + string.format(_("executable for external editor %d"), i), _("select executable for external editor") , _("(None)")) dt.preferences.register(MODULE_NAME, "program_name_"..i, "string", - _("name of external editor ")..i, + string.format(_("name of external editor %d"), i), _("friendly name of external editor"), "") end dt.preferences.register(MODULE_NAME, "show_in_darkrooom", "bool", @@ -491,7 +491,7 @@ dt.preferences.register(MODULE_NAME, "show_in_darkrooom", "bool", -- register the new shortcuts ------------------------------------------------- for i = 1, MAX_EDITORS do dt.register_event(MODULE_NAME .. i, "shortcut", - program_shortcut, _("edit with program ")..string.format("%02d", i)) + program_shortcut, string.format(_("edit with program %02d"), i)) end diff --git a/contrib/face_recognition.lua b/contrib/face_recognition.lua index 5bd7048..7325d7e 100644 --- a/contrib/face_recognition.lua +++ b/contrib/face_recognition.lua @@ -44,7 +44,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" local dtsys = require "lib/dtutils.system" -local gettext = dt.gettext +local gettext = dt.gettext.gettext -- constants @@ -69,11 +69,8 @@ local fc = {} fc.module_installed = false fc.event_registered = false --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("face_recognition", dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("face_recognition", msgid) + return gettext(msgid) end local function build_image_table(images) @@ -399,7 +396,7 @@ fc.category_tags = dt.new_widget("entry"){ fc.tolerance = dt.new_widget("slider"){ label = _("tolerance"), - tooltip = ("detection tolerance - 0.6 default - lower if too many faces detected"), + tooltip = _("detection tolerance - 0.6 default - lower if too many faces detected"), soft_min = 0.0, hard_min = 0.0, soft_max = 1.0, @@ -482,12 +479,12 @@ table.insert(widgets, fc.num_cores) table.insert(widgets, fc.export_format) table.insert(widgets, dt.new_widget("box"){ orientation = "horizontal", - dt.new_widget("label"){ label = _("width ")}, + dt.new_widget("label"){ label = _("width")}, fc.width, }) table.insert(widgets, dt.new_widget("box"){ orientation = "horizontal", - dt.new_widget("label"){ label = _("height ")}, + dt.new_widget("label"){ label = _("height")}, fc.height, }) table.insert(widgets, fc.execute) diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index c6b8738..c64fffa 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -26,7 +26,7 @@ Dependencies: local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "fujifilm_ratings") @@ -39,10 +39,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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.dgettext("fujifilm_ratings", msgid) + return gettext(msgid) end local function detect_rating(event, image) @@ -60,7 +58,7 @@ local function detect_rating(event, image) if string.len(jpeg_result) > 0 then jpeg_result = string.gsub(jpeg_result, "^Rating.*(%d)", "%1") image.rating = tonumber(jpeg_result) - dt.print_error(_("Using JPEG Rating: ") .. tostring(jpeg_result)) + dt.print_error(string.format(_("Using JPEG Rating: %d"), jpeg_result)) return end command = "exiftool -Rating " .. RAF_filename @@ -71,7 +69,7 @@ local function detect_rating(event, image) if string.len(raf_result) > 0 then raf_result = string.gsub(raf_result, "^Rating.*(%d)", "%1") image.rating = tonumber(raf_result) - dt.print_error(_("Using RAF Rating: ") .. tostring(raf_result)) + dt.print_error(string.format(_("Using RAF Rating: %d"), raf_result)) end end diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index cd748fe..dac5f5f 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -35,7 +35,7 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "geoJSON_export") @@ -48,11 +48,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("geoJSON_export",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("geoJSON_export", msgid) + return gettext(msgid) end -- Sort a table diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index 30f9040..b595015 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -28,7 +28,7 @@ require "geoToolbox" local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "geoToolbox") @@ -41,11 +41,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("geoToolbox",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("geoToolbox", msgid) + return gettext(msgid) end @@ -300,9 +297,9 @@ local function copy_gps() end end - label_copy_gps_lat.label = _("latitude: ") .. copy_gps_latitude - label_copy_gps_lon.label = _("longitude: ") ..copy_gps_longitude - label_copy_gps_ele.label = _("elevation: ") .. copy_gps_elevation + label_copy_gps_lat.label = string.format(_("latitude: "), copy_gps_latitude) + label_copy_gps_lon.label = string.format(_("longitude: "),copy_gps_longitude) + label_copy_gps_ele.label = string.format(_("elevation: "), copy_gps_elevation) return end @@ -582,7 +579,7 @@ local function altitude_profile() file = io.open(exportDirectory.."/"..exportFilename, "w") file:write(csv_file) file:close() - dt.print(_("File created in ")..exportDirectory) + dt.print(string.format(_("File created in %s"), exportDirectory)) end diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 0b235f9..843bbce 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -69,7 +69,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" local dtsys = require "lib/dtutils.system" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local gimp_widget = nil du.check_min_api_version("7.0.0", "gimp") @@ -83,11 +83,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("gimp", msgid) + return gettext(msgid) end local function group_if_not_member(img, new_img) @@ -119,7 +116,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize local gimp_executable = df.check_if_bin_exists("gimp") if not gimp_executable then - dt.print_error(_("GIMP not found")) + dt.print_error("GIMP not found") return end diff --git a/contrib/gpx_export.lua b/contrib/gpx_export.lua index c25028e..6e29c8e 100644 --- a/contrib/gpx_export.lua +++ b/contrib/gpx_export.lua @@ -25,7 +25,7 @@ For each source folder, a separate 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 +local gettext = dt.gettext.gettext dl.check_min_api_version("7.0.0", "gpx_export") @@ -38,9 +38,6 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("gpx_export",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) return gettext.dgettext("gpx_export", msgid) end @@ -132,11 +129,11 @@ local function create_gpx_file() local file = io.open(path, "w") if (file == nil) then - dt.print(_("invalid path: ")..path) + dt.print(string.format(_("invalid path: %s"), path)) else file:write(gpx_file) file:close() - dt.print(_("gpx file created: ")..path) + dt.print(string.format(_("gpx file created: "), path)) end end diff --git a/contrib/harmonic_armature_guide.lua b/contrib/harmonic_armature_guide.lua index e5c23f2..308c5ef 100644 --- a/contrib/harmonic_armature_guide.lua +++ b/contrib/harmonic_armature_guide.lua @@ -32,15 +32,12 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("2.0.0", "harmonic_armature_guide") --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("harmonic_armature_guide",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("harmonic_armature_guide", msgid) + return gettext(msgid) end dt.guides.register_guide("harmonic armature", diff --git a/contrib/hif_group_leader.lua b/contrib/hif_group_leader.lua index 5fa0aa5..14327db 100644 --- a/contrib/hif_group_leader.lua +++ b/contrib/hif_group_leader.lua @@ -73,13 +73,10 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- I 1 8 N -- - - - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE, msgid) + return gettext(msgid) end diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 77ad7cb..6621a18 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -40,7 +40,7 @@ local du = require "lib/dtutils" local df = require "lib/dtutils.file" local log = require "lib/dtutils.log" local dtsys = require "lib/dtutils.system" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local namespace = 'module_hugin' local user_pref_str = 'prefer_gui' @@ -65,11 +65,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("hugin",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("hugin", msgid) + return gettext(msgid) end local function user_preference_changed(widget) @@ -201,7 +198,7 @@ local function create_panorama(storage, image_table, extra_data) --finalize if df.check_if_file_exists(src_path) then log.msg(log.debug, "found ", src_path, " importing to ", dst_path) df.file_move(src_path, dst_path) - dt.print(_("importing file "..dst_path)) + dt.print(string.format(_("importing file %s"), dst_path)) dt.database.import(dst_path) end end @@ -227,7 +224,7 @@ hugin_widget = dt.new_widget("box") { orientation = "vertical", dt.new_widget("check_button") { - label = _(" launch hugin gui"), + label = _("launch hugin gui"), value = user_prefer_gui, tooltip = _('launch hugin in gui mode'), clicked_callback = user_preference_changed diff --git a/contrib/image_stack.lua b/contrib/image_stack.lua index b78b96c..d8abc9a 100644 --- a/contrib/image_stack.lua +++ b/contrib/image_stack.lua @@ -64,7 +64,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" local dtsys = require "lib/dtutils.system" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local job = nil -- path separator constant @@ -82,11 +82,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("image_stack",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("image_stack", msgid) + return gettext(msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -452,7 +449,7 @@ local function copy_image_attributes(from, to, ...) to.rights = from.rights to.description = from.description else - dt.print_error(_("Unrecognized option to copy_image_attributes: " .. arg)) + dt.print_error("Unrecognized option to copy_image_attributes: " .. arg) end end end @@ -496,7 +493,7 @@ local function image_stack(storage, image_table, extra_data) if image_count < 2 then dt.print(_("ERROR: at least 2 images required for image stacking, exiting...")) - dt.print_error(_(image_count .. " image(s) selected, at least 2 required")) + dt.print_error(image_count .. " image(s) selected, at least 2 required") return end @@ -520,13 +517,13 @@ local function image_stack(storage, image_table, extra_data) job.percent = job.percent + percent_step else dt.print(_("ERROR: image alignment failed")) - dt.print_error(_("image alignment failed")) + dt.print_error("image alignment failed") cleanup(img_list) return end else dt.print(_("ERROR: align_image_stack not found")) - dt.print_error(_("align_image_stack not found")) + dt.print_error("align_image_stack not found") cleanup(img_list) return end @@ -540,7 +537,7 @@ local function image_stack(storage, image_table, extra_data) local ignore_tif_tags = " -quiet -define tiff:ignore-tags=40965,42032,42033,42034,42036,18246,18249,36867,34864,34866 " if convert_executable then local convert_command = convert_executable .. ignore_tif_tags .. convert_arguments - dt.print_log(_("convert command is " .. convert_command)) + dt.print_log("convert command is " .. convert_command) dt.print(_("processing image stack")) local result = dtsys.external_command(convert_command) if result == 0 then @@ -580,7 +577,7 @@ local function image_stack(storage, image_table, extra_data) end else dt.print(_("ERROR: convert executable not found")) - dt.print_error(_("convert executable not found")) + dt.print_error("convert executable not found") cleanup(img_list) end job.valid = false diff --git a/contrib/image_time.lua b/contrib/image_time.lua index 17d5481..1655a12 100644 --- a/contrib/image_time.lua +++ b/contrib/image_time.lua @@ -107,7 +107,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" local ds = require "lib/dtutils.string" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local img_time = {} img_time.module_installed = false @@ -125,11 +125,9 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid 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 -gettext.bindtextdomain("image_time",dt.configuration.config_dir.."/lua/locale/") local function _(msgid) - return gettext.dgettext("image_time", msgid) + return gettext(msgid) end local PS = dt.configuration.runnin_os == "windows" and "\\" or "/" @@ -249,7 +247,7 @@ local function _get_windows_image_file_creation_time(image) end p:close() else - dt.print(_("unable to get information for ") .. image.filename) + dt.print(string.format(_("unable to get information for "), image.filename)) datetime = ERROR end return datetime @@ -266,7 +264,7 @@ local function _get_nix_image_file_creation_time(image) end p:close() else - dt.print(_("unable to get information for ") .. image.filename) + dt.print(string.format(_("unable to get information for "), image.filename)) datetime = ERROR end return datetime @@ -314,7 +312,7 @@ local function reset_time(images) image.exif_datetime_taken = get_original_image_time(image) end else - dt.print_error(_("reset time: no images selected")) + dt.print_error("reset time: no images selected") dt.print(_("please select the images that need their time reset")) end end @@ -430,8 +428,8 @@ end img_time.widgets = { -- name, type, tooltip, placeholder, {"ayr", "combobox", _("years"), _("years to adjust by, 0 - ?"), {seq(0,20)}, 1}, - {"amo", "combobox", _("months"), ("months to adjust by, 0-12"), {seq(0,12)}, 1}, - {"ady", "combobox", _("days"), ("days to adjust by, 0-31"), {seq(0,31)}, 1}, + {"amo", "combobox", _("months"), _("months to adjust by, 0-12"), {seq(0,12)}, 1}, + {"ady", "combobox", _("days"), _("days to adjust by, 0-31"), {seq(0,31)}, 1}, {"ahr", "combobox", _("hours"), _("hours to adjust by, 0-23"), {seq(0,23)}, 1}, {"amn", "combobox", _("minutes"), _("minutes to adjust by, 0-59"), {seq(0,59)}, 1}, {"asc", "combobox", _("seconds"), _("seconds to adjust by, 0-59"), {seq(0,59)}, 1}, diff --git a/contrib/jpg_group_leader.lua b/contrib/jpg_group_leader.lua index ab97588..e30afb8 100644 --- a/contrib/jpg_group_leader.lua +++ b/contrib/jpg_group_leader.lua @@ -73,13 +73,10 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- I 1 8 N -- - - - - - - - - - - - - - - - - - - - - - - - - - -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE, msgid) + return gettext(msgid) end diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index f772fb7..0729309 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -39,7 +39,7 @@ local df = require "lib/dtutils.file" local ds = require "lib/dtutils.string" local dsys = require "lib/dtutils.system" -local gettext = dt.gettext +local gettext = dt.gettext.gettext local PS = dt.configuration.running_os == "windows" and "\\" or "/" @@ -54,11 +54,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("kml_export",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("kml_export", msgid) + return gettext(msgid) end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index 0b61728..6e10183 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -37,15 +37,12 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("2.0.0", "passport_guide") --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("passport_guide",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("passport_guide", msgid) + return gettext(msgid) end dt.guides.register_guide("passport", diff --git a/contrib/pdf_slideshow.lua b/contrib/pdf_slideshow.lua index 1194884..adffffe 100644 --- a/contrib/pdf_slideshow.lua +++ b/contrib/pdf_slideshow.lua @@ -42,17 +42,14 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("pdf_slideshow",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("pdf_slideshow", msgid) + return gettext(msgid) end if not df.check_if_bin_exists("pdflatex") then - dt.print_error(_("pdflatex not found")) + dt.print_error("pdflatex not found") return end @@ -231,7 +228,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 @@ -241,7 +238,7 @@ dt.register_storage("pdf_slideshow",_("pdf slideshow"), local result = dt.control.execute(command) if result ~= 0 then dt.print(_("problem running pdf viewer")) -- this one is probably usefull to the user - error(_("problem running ")..command) + error("problem running "..command) end -- finally do some clean-up diff --git a/contrib/photils.lua b/contrib/photils.lua index b5e99bd..0e6662f 100644 --- a/contrib/photils.lua +++ b/contrib/photils.lua @@ -55,9 +55,7 @@ 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.bindtextdomain(MODULE_NAME, - dt.configuration.config_dir .. PS .. "lua" .. PS .. "locale" .. PS) +local gettext = dt.gettext.gettext local exporter = dt.new_format("jpeg") exporter.quality = 80 @@ -67,7 +65,7 @@ exporter.max_width = 224 -- helper functions local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end local function num_keys(tbl) @@ -428,7 +426,7 @@ end if not photils_installed then GUI.warning_label.label = _("photils-cli not found") - dt.print_log(_("photils-cli not found")) + dt.print_log("photils-cli not found") else GUI.warning_label.label = _("Select an image, click \"get tags\" and get \nsuggestions for tags.") end diff --git a/contrib/quicktag.lua b/contrib/quicktag.lua index 15f1d8d..82ccb53 100644 --- a/contrib/quicktag.lua +++ b/contrib/quicktag.lua @@ -62,13 +62,10 @@ qt.module_installed = false qt.event_registered = false qt.widget_table = {} -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("quicktag",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("quicktag", msgid) + return gettext(msgid) end -- maximum length of button labels diff --git a/contrib/rate_group.lua b/contrib/rate_group.lua index 9a790f8..ca85b26 100644 --- a/contrib/rate_group.lua +++ b/contrib/rate_group.lua @@ -44,6 +44,12 @@ local du = require "lib/dtutils" -- added version check du.check_min_api_version("7.0.0", "rate_group") +local gettext = dt.gettext.gettext + +local function _(msgid) + return gettext(msgid) +end + -- return data structure for script_manager local script_data = {} @@ -62,9 +68,9 @@ local function apply_rating(rating) end end if rating < 0 then - dt.print("rejecting group(s)") + dt.print(_("rejecting group(s)")) else - dt.print("applying rating " ..rating.. " to group(s)") + dt.print(string.format(_("applying rating %d to group(s)"), rating)) end end @@ -81,37 +87,37 @@ end dt.register_event("rg_reject", "shortcut", function(event, shortcut) apply_rating(-1) -end, "Reject group") +end, _("Reject group")) dt.register_event("rg0", "shortcut", function(event, shortcut) apply_rating(0) -end, "Rate group 0") +end, _("Rate group 0")) dt.register_event("rg1", "shortcut", function(event, shortcut) apply_rating(1) -end, "Rate group 1") +end, _("Rate group 1")) dt.register_event("rg2", "shortcut", function(event, shortcut) apply_rating(2) -end, "Rate group 2") +end, _("Rate group 2")) dt.register_event("rg3", "shortcut", function(event, shortcut) apply_rating(3) -end, "Rate group 3") +end, _("Rate group 3")) dt.register_event("rg4", "shortcut", function(event, shortcut) apply_rating(4) -end, "Rate group 4") +end, _("Rate group 4")) dt.register_event("rg5", "shortcut", function(event, shortcut) apply_rating(5) -end, "Rate group 5") +end, _("Rate group 5")) script_data.destroy = destroy diff --git a/contrib/rename-tags.lua b/contrib/rename-tags.lua index 2213b92..4e03af7 100644 --- a/contrib/rename-tags.lua +++ b/contrib/rename-tags.lua @@ -36,6 +36,12 @@ 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 function _(msgid) + return gettext(msgid) +end + -- return data structure for script_manager local script_data = {} @@ -50,8 +56,8 @@ rt.module_installed = false rt.event_registered = false -- GUI entries -local old_tag = darktable.new_widget("entry") { tooltip = "Enter old tag" } -local new_tag = darktable.new_widget("entry") { tooltip = "Enter new tag" } +local old_tag = darktable.new_widget("entry") { tooltip = _("Enter old tag") } +local new_tag = darktable.new_widget("entry") { tooltip = _("Enter new tag") } local function rename_reset() old_tag.text = '' @@ -62,11 +68,11 @@ end local function rename_tags() -- If entries are empty, return if old_tag.text == '' then - darktable.print ("Old tag can't be empty") + darktable.print (_("Old tag can't be empty")) return end if new_tag.text == '' then - darktable.print ("New tag can't be empty") + darktable.print (_("New tag can't be empty")) return end @@ -76,12 +82,12 @@ local function rename_tags() local ot = darktable.tags.find (old_tag.text) if not ot then - darktable.print ("Old tag does not exist") + darktable.print (_("Old tag does not exist")) return end -- Show job - local job = darktable.gui.create_job ("Renaming tag", true) + local job = darktable.gui.create_job (_("Renaming tag"), true) old_tag.editable = false new_tag.editable = false @@ -104,7 +110,7 @@ local function rename_tags() darktable.tags.delete (ot) job.valid = false - darktable.print ("Renamed tags for " .. count .. " images") + darktable.print (string.format(_("Renamed tags for %d images"), count)) old_tag.editable = true new_tag.editable = true @@ -115,7 +121,7 @@ end local function install_module() if not rt.module_installed then - darktable.register_lib ("rename_tags", "rename tag", true, true, {[darktable.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 20},}, rt.rename_widget, nil, nil) + darktable.register_lib ("rename_tags", _("rename tag"), true, true, {[darktable.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 20},}, rt.rename_widget, nil, nil) rt.module_installed = true end end @@ -131,13 +137,13 @@ end -- GUI local old_widget = darktable.new_widget ("box") { orientation = "horizontal", - darktable.new_widget("label") { label = "Old tag" }, + darktable.new_widget("label") { label = _("Old tag") }, old_tag } local new_widget = darktable.new_widget ("box") { orientation = "horizontal", - darktable.new_widget("label") { label = "New tag" }, + darktable.new_widget("label") { label = _("New tag") }, new_tag } @@ -146,7 +152,7 @@ rt.rename_widget = darktable.new_widget ("box") { reset_callback = rename_reset, old_widget, new_widget, - darktable.new_widget("button") { label = "Go", clicked_callback = rename_tags } + darktable.new_widget("button") { label = _("Go"), clicked_callback = rename_tags } } if darktable.gui.current_view().id == "lighttable" then diff --git a/contrib/rename_images.lua b/contrib/rename_images.lua index e8e013d..cf133cf 100644 --- a/contrib/rename_images.lua +++ b/contrib/rename_images.lua @@ -46,13 +46,10 @@ local df = require "lib/dtutils.file" du.check_min_api_version("7.0.0", "rename_images") -local gettext = dt.gettext - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("rename_images",dt.configuration.config_dir.."/lua/locale/") +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext("rename_images", msgid) + return gettext(msgid) end -- namespace variable @@ -86,7 +83,7 @@ local MODULE_NAME = "rename_images" local PS = dt.configuration.running_os == "windows" and "\\" or "/" local USER = os.getenv("USERNAME") local HOME = os.getenv(dt.configuration.running_os == "windows" and "HOMEPATH" or "HOME") -local PICTURES = HOME .. PS .. dt.configuration.running_os == "windows" and "My Pictures" or "Pictures" +local PICTURES = HOME .. PS .. dt.configuration.running_os == "windows" and _("My Pictures") or _("Pictures") local DESKTOP = HOME .. PS .. "Desktop" -- - - - - - - - - - - - - - - - - - - - - - - - @@ -158,8 +155,8 @@ local function substitute_list(str) if rename.substitutes[var] then str = string.gsub(str, "%$%("..var.."%)", rename.substitutes[var]) else - dt.print_error(_("unrecognized variable " .. var)) - dt.print(_("unknown variable " .. var .. ", aborting...")) + dt.print_error("unrecognized variable " .. var) + dt.print(string.format(_("unknown variable %s, aborting..."), var)) return -1 end end @@ -210,7 +207,7 @@ local function do_rename(images) if #images > 0 then local pattern = rename.widgets.pattern.text dt.preferences.write(MODULE_NAME, "pattern", "string", pattern) - dt.print_log(_("pattern is " .. pattern)) + dt.print_log("pattern is " .. pattern) if string.len(pattern) > 0 then local datetime = os.date("*t") @@ -250,7 +247,7 @@ local function do_rename(images) stop_job(job) local collect_rules = dt.gui.libs.collect.filter() dt.gui.libs.collect.filter(collect_rules) - dt.print(_("renamed " .. #images .. " images")) + dt.print(string.format(_("renamed %d images"), #images)) else -- pattern length dt.print_error("no pattern supplied, returning...") dt.print(_("please enter the new name or pattern")) diff --git a/contrib/select_non_existing.lua b/contrib/select_non_existing.lua index 9baef66..9536f03 100644 --- a/contrib/select_non_existing.lua +++ b/contrib/select_non_existing.lua @@ -29,11 +29,10 @@ du.check_min_api_version("9.1.0", MODULE) -- figure out the path separator local PS = dt.configuration.running_os == "windows" and "\\" or "/" -local gettext = dt.gettext -gettext.bindtextdomain(MODULE, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) +local gettext = dt.gettext.gettext local function _(msgid) - return gettext.dgettext(MODULE, msgid) + return gettext(msgid) end local function stop_job(job) diff --git a/contrib/select_untagged.lua b/contrib/select_untagged.lua index d15941b..bb887f2 100644 --- a/contrib/select_untagged.lua +++ b/contrib/select_untagged.lua @@ -20,7 +20,7 @@ Enable selection of untagged images (darktable|* tags are ignored) local dt = require "darktable" local du = require "lib/dtutils" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "select_untagged") @@ -33,11 +33,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("select_untagged",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("select_untagged", msgid) + return gettext(msgid) end local function stop_job(job) diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index cf62aa6..71bae54 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -27,7 +27,7 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" -local gettext = dt.gettext +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "slideshowMusic") @@ -40,11 +40,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 -gettext.bindtextdomain("slideshowMusic",dt.configuration.config_dir.."/lua/locale/") - local function _(msgid) - return gettext.dgettext("slideshowMusic", msgid) + return gettext(msgid) end local function playSlideshowMusic(_, old_view, new_view) @@ -54,7 +51,7 @@ local function playSlideshowMusic(_, old_view, new_view) playMusic = dt.preferences.read("slideshowMusic","PlaySlideshowMusic","bool") if not df.check_if_bin_exists("rhythmbox-client") then - dt.print_error(_("rhythmbox-client not found")) + dt.print_error("rhythmbox-client not found") return end @@ -70,7 +67,7 @@ local function playSlideshowMusic(_, old_view, new_view) if (old_view and old_view.id == "slideshow") then stopCommand = "rhythmbox-client --pause" --dt.print_error(stopCommand) - dt.control.execute( stopCommand) + dt.control.execute(stopCommand) end end end diff --git a/contrib/transfer_hierarchy.lua b/contrib/transfer_hierarchy.lua index 10c5f0d..15bea2a 100755 --- a/contrib/transfer_hierarchy.lua +++ b/contrib/transfer_hierarchy.lua @@ -96,10 +96,8 @@ local PATH_SEGMENT_REGEX = "(" .. PATH_SEPARATOR .. "?)([^" .. PATH_SEPARATOR .. unpack = unpack or table.unpack gmatch = string.gfind or string.gmatch -darktable.gettext.bindtextdomain(LIB_ID, darktable.configuration.config_dir .. PATH_SEPARATOR .. "lua" .. PATH_SEPARATOR .. "locale" .. PATH_SEPARATOR) - local function _(msgid) - return darktable.gettext.dgettext(LIB_ID, msgid) + return darktable.gettext.gettext(msgid) end -- Header material: END @@ -268,17 +266,17 @@ local function doTransfer(transferFunc) films[film] = destBase .. string.sub(film.path, #sourceBase+1) if not pathExists(films[film]) then if createDirectory(films[film]) == nil then - darktable.print(_("transfer hierarchy: ERROR: could not create directory: " .. films[film])) + darktable.print(string.format(_("transfer hierarchy: ERROR: could not create directory: %s"), films[film])) return end end if not pathIsDirectory(films[film]) then - darktable.print(_("transfer hierarchy: ERROR: not a directory: " .. films[film])) + darktable.print(string.format(_("transfer hierarchy: ERROR: not a directory: %s"), films[film])) return end destFilms[film] = darktable.films.new(films[film]) if destFilms[film] == nil then - darktable.print(_("transfer hierarchy: ERROR: could not create film: " .. film.path)) + darktable.print(string.format(_("transfer hierarchy: ERROR: could not create film: %s"), film.path)) end end @@ -287,7 +285,7 @@ local function doTransfer(transferFunc) srcFilms[img] = img.film end - local job = darktable.gui.create_job(string.format(_("transfer hierarchy") .. " (%d image" .. (#(darktable.gui.action_images) == 1 and "" or "s") .. ")", #(darktable.gui.action_images)), true, stopTransfer) + local job = darktable.gui.create_job(string.format(_("transfer hierarchy (%d image%s)"), #(darktable.gui.action_images), (#(darktable.gui.action_images) == 1 and "" or "s")), true, stopTransfer) job.percent = 0.0 local pctIncrement = 1.0 / #(darktable.gui.action_images) for _,img in ipairs(darktable.gui.action_images) do diff --git a/contrib/video_ffmpeg.lua b/contrib/video_ffmpeg.lua index 165b577..7c902ed 100644 --- a/contrib/video_ffmpeg.lua +++ b/contrib/video_ffmpeg.lua @@ -37,7 +37,7 @@ 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 +local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "video_ffmpeg") @@ -53,10 +53,9 @@ script_data.show = nil -- only required for libs since the destroy_method only h local MODULE_NAME = "video_ffmpeg" local PS = dt.configuration.running_os == "windows" and "\\" or "/" -gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) local function _(msgid) - return gettext.dgettext(MODULE_NAME, msgid) + return gettext(msgid) end @@ -375,7 +374,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(_("export ")..tostring(number).." / "..tostring(total)) + dt.print(string.format(_("export %d / %d"), number), total)) end local function init_export(storage, img_format, images, high_quality, extra_data) @@ -465,7 +464,7 @@ end dt.register_storage( "module_video_ffmpeg", - _(MODULE_NAME), + _("video ffmpeg"), show_status, finalize_export, nil, From 05a73d8810667664325fd3430c18f4dd875b9758 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 29 Mar 2024 12:45:28 -0400 Subject: [PATCH 08/40] changed translatable strings to lower case --- official/enfuse.lua | 16 ++++++++-------- official/selection_to_pdf.lua | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/official/enfuse.lua b/official/enfuse.lua index fb94229..74999ad 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -129,7 +129,7 @@ if enfuse_installed then exposure_mu = dt.new_widget("slider") { label = "exposure mu", - tooltip = _("center also known as MEAN of Gaussian weighting function (0 <= MEAN <= 1); default: 0.5"), + tooltip = _("center also known as mean of gaussian weighting function (0 <= mean <= 1); default: 0.5"), hard_min = 0, hard_max = 1, value = dt.preferences.read("enfuse", "exposure_mu", "float") @@ -138,7 +138,7 @@ if enfuse_installed then exposure_mu = dt.new_widget("slider") { label = "exposure optimum", - tooltip = _("optimum exposure value, usually the maximum of the weighting function (0 <= OPTIMUM <=1); default 0.5"), + tooltip = _("optimum exposure value, usually the maximum of the weighting function (0 <= optimum <=1); default 0.5"), hard_min = 0, hard_max = 1, value = dt.preferences.read("enfuse", "exposure_optimum", "float") @@ -182,7 +182,7 @@ if enfuse_installed then end local f = io.open(response_file, "w") if not f then - dt.print(string.format(_("Error writing to '%s'"), response_file)) + dt.print(string.format(_("error writing to '%s'"), response_file)) os.remove(response_file) return end @@ -205,9 +205,9 @@ if enfuse_installed then if dt.configuration.running_os == "windows" then tmp_exported = dt.configuration.tmp_dir .. tmp_exported -- windows os.tmpname() defaults to root directory end - dt.print(string.format(_("Converting raw file '%s' to tiff..."), i.filename)) + dt.print(string.format(_("converting raw file '%s' to tiff..."), i.filename)) tiff_exporter:write_image(i, tmp_exported, false) - dt.print_log(string.format("Raw file '%s' converted to '%s'", i.filename, tmp_exported)) + dt.print_log(string.format("raw file '%s' converted to '%s'", i.filename, tmp_exported)) cnt = cnt + 1 f:write(tmp_exported.."\n") @@ -215,14 +215,14 @@ if enfuse_installed then -- other images will be skipped else - dt.print(string.format(_("Skipping %s..."), i.filename)) + dt.print(string.format(_("skipping %s..."), i.filename)) n_skipped = n_skipped + 1 end end f:close() -- bail out if there is nothing to do if cnt == 0 then - dt.print(_("No suitable images selected, nothing to do for enfuse")) + dt.print(_("no suitable images selected, nothing to do for enfuse")) os.remove(response_file) return end @@ -296,7 +296,7 @@ if enfuse_installed then else dt.print_error("enfuse executable not found") error("enfuse executable not found") - dt.print(_("Could not find enfuse executable. Not loading enfuse exporter...")) + dt.print(_("could not find enfuse executable, not loading enfuse exporter...")) end script_data.destroy = destroy diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 9e1d7b4..6806313 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -56,15 +56,15 @@ script_data.show = nil -- only required for libs since the destroy_method only h dt.preferences.register ("selection_to_pdf","Open with","string", _("a pdf viewer"), - _("Can be an absolute pathname or the tool may be in the PATH"), + _("can be an absolute pathname or the tool may be in the PATH"), "xdg-open") local title_widget = dt.new_widget("entry") { - placeholder = _("Title") + placeholder = _("title") } local no_of_thumbs_widget = dt.new_widget("slider") { - label = _("Thumbs per Line"), + label = _("thumbs per line"), soft_min = 1, -- The soft minimum value for the slider, the slider can't go beyond this point soft_max = 10, -- The soft maximum value for the slider, the slider can't go beyond this point hard_min = 1, -- The hard minimum value for the slider, the user can't manually enter a value beyond this point @@ -73,9 +73,9 @@ local no_of_thumbs_widget = dt.new_widget("slider") } local widget = dt.new_widget("box") { orientation = horizontal, - dt.new_widget("label"){label = _("Title:")}, + dt.new_widget("label"){label = _("title:")}, title_widget, - dt.new_widget("label"){label = _("Thumbnails per row:")}, + dt.new_widget("label"){label = _("thumbnails per row:")}, no_of_thumbs_widget } @@ -122,7 +122,7 @@ local function destroy() dt.print_log("done destroying") end -dt.register_storage(_("export_pdf"),_("Export thumbnails to pdf"), +dt.register_storage(_("export_pdf"),_("export thumbnails to pdf"), nil, function(storage,image_table) local my_title = title_widget.text @@ -169,7 +169,7 @@ dt.register_storage(_("export_pdf"),_("Export thumbnails to pdf"), local command = "pdflatex -halt-on-error -output-directory "..dir.." "..locfile local result = dt.control.execute(command) if result ~= 0 then - dt.print(_("Problem running pdflatex")) -- this one is probably usefull to the user + dt.print(_("problem running pdflatex")) -- this one is probably usefull to the user error("Problem running "..command) end @@ -179,7 +179,7 @@ dt.register_storage(_("export_pdf"),_("Export thumbnails to pdf"), command = command.." "..pdffile local result = dt.control.execute(command) if result ~= 0 then - dt.print(_("Problem running pdf viewer")) -- this one is probably usefull to the user + dt.print(_("problem running pdf viewer")) -- this one is probably usefull to the user error("Problem running "..command) end From 1fd2ca20aba1814bf787f2c4917e0c29d900cb8b Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 29 Mar 2024 12:55:08 -0400 Subject: [PATCH 09/40] changed translatable strings to lower case --- tools/executable_manager.lua | 4 ++-- tools/script_manager.lua | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index 75b4a6b..7055741 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -140,7 +140,7 @@ local matches = grep(DARKTABLERC, "executable_paths") -- check if we have something to manage and exit if not if #matches == 0 then - dt.print(_("No executable paths found, exiting...")) + dt.print(_("no executable paths found, exiting...")) return end @@ -208,7 +208,7 @@ for i,exec in ipairs(exec_table) do dt.new_widget("section_label"){label = _("reset")}, dt.new_widget("button"){ label = _("clear"), - tooltip = _(string.format("Clear path for %s", exec)), + tooltip = string.format(_("clear path for %s"), exec), clicked_callback = function() df.set_executable_path_preference(exec, "") executable_path_widgets[exec].value = "" diff --git a/tools/script_manager.lua b/tools/script_manager.lua index 6a5d2ac..a7a5683 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -390,7 +390,7 @@ local function activate(script) script_manager_running_script = nil if status then pref_write(script.script_name, "bool", true) - log.msg(log.screen, string.format(_("Loaded %s"), script.script_name)) + log.msg(log.screen, string.format(_("loaded %s"), script.script_name)) script.running = true if err ~= true then log.msg(log.debug, "got lib data") @@ -541,7 +541,7 @@ local function update_scripts() local git = sm.executables.git if not git then - dt.print(_("ERROR: git not found. Install or specify the location of the git executable.")) + dt.print(_("ERROR: git not found, install or specify the location of the git executable.")) return end @@ -625,7 +625,7 @@ local function install_scripts() local category = sm.widgets.new_category.text if string.match(du.join(sm.categories, " "), ds.sanitize_lua(category)) then - log.msg(log.screen, string.format(_("category %s is already in use. Please specify a different category name."), category)) + log.msg(log.screen, string.format(_("category %s is already in use, please specify a different category name."), category)) log.msg(log.error, "category " .. category .. " already exists, returning...") restore_log_level(old_log_level) return @@ -636,7 +636,7 @@ local function install_scripts() local git = sm.executables.git if not git then - dt.print(_("ERROR: git not found. Install or specify the location of the git executable.")) + dt.print(_("ERROR: git not found, install or specify the location of the git executable.")) restore_log_level(old_log_level) return end @@ -672,7 +672,7 @@ local function install_scripts() sm.widgets.new_category.text = "" sm.widgets.main_menu.selected = 3 else - dt.print(_("No scripts found to install")) + dt.print(_("no scripts found to install")) log.msg(log.error, "scan_scripts returned " .. count .. " scripts found. Not adding to category_selector") end else @@ -824,7 +824,7 @@ local function paginate(direction) else last = first + sm.page_status.num_buttons - 1 end - sm.widgets.page_status.label = string.format(_("Page %d of %d"), cur_page, max_pages) + sm.widgets.page_status.label = string.format(_("page %d of %d"), cur_page, max_pages) populate_buttons(category, first, last) restore_log_level(old_log_level) @@ -1087,7 +1087,7 @@ sm.widgets.add_scripts = dt.new_widget("box"){ } sm.widgets.allow_disable = dt.new_widget("check_button"){ - label = _('Enable "Disable Scripts" button'), + label = _('enable "disable scripts" button'), value = false, clicked_callback = function(this) if this.value == true then @@ -1097,7 +1097,7 @@ sm.widgets.allow_disable = dt.new_widget("check_button"){ } sm.widgets.disable_scripts = dt.new_widget("button"){ - label = _("Disable Scripts"), + label = _("disable scripts"), sensitive = false, clicked_callback = function(this) local LUARC = dt.configuration.config_dir .. PS .. "luarc" @@ -1143,7 +1143,7 @@ end local page_back = "<" local page_forward = ">" -sm.widgets.page_status = dt.new_widget("label"){label = _("Page:")} +sm.widgets.page_status = dt.new_widget("label"){label = _("page:")} sm.widgets.page_back = dt.new_widget("button"){ label = page_back, clicked_callback = function(this) @@ -1171,7 +1171,7 @@ sm.widgets.page_control = dt.new_widget("box"){ sm.widgets.scripts = dt.new_widget("box"){ orientation = vertical, - dt.new_widget("label"){label = _("Scripts")}, + dt.new_widget("label"){label = _("scripts")}, sm.widgets.category_selector, sm.widgets.page_control, table.unpack(sm.widgets.buttons) @@ -1200,7 +1200,7 @@ sm.widgets.change_buttons = dt.new_widget("button"){ sm.widgets.configure = dt.new_widget("box"){ orientation = "vertical", - dt.new_widget("label"){label = _("Configuration")}, + dt.new_widget("label"){label = _("configuration")}, sm.widgets.num_buttons, sm.widgets.change_buttons, } From e47ab3474556b58025e38983c3b0729cb849b4c5 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 29 Mar 2024 13:10:41 -0400 Subject: [PATCH 10/40] changed translatable strings to lower case --- examples/api_version.lua | 2 +- examples/darkroom_demo.lua | 6 +++--- examples/gettextExample.lua | 2 +- examples/lighttable_demo.lua | 4 ++-- examples/moduleExample.lua | 16 ++++++++-------- examples/multi_os.lua | 8 ++++---- examples/panels_demo.lua | 14 +++++++------- examples/preferenceExamples.lua | 28 ++++++++++++++-------------- examples/running_os.lua | 2 +- 9 files changed, 41 insertions(+), 41 deletions(-) diff --git a/examples/api_version.lua b/examples/api_version.lua index 1f86f6b..49dc62a 100644 --- a/examples/api_version.lua +++ b/examples/api_version.lua @@ -39,7 +39,7 @@ end local result = dt.configuration.api_version_string dt.print_log("API Version: " .. result) -dt.print(string.format(_("API Version: %s"), result)) +dt.print(string.format(_("API version: %s"), result)) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to diff --git a/examples/darkroom_demo.lua b/examples/darkroom_demo.lua index 6ca9f89..bdd7f84 100644 --- a/examples/darkroom_demo.lua +++ b/examples/darkroom_demo.lua @@ -91,13 +91,13 @@ dt.gui.current_view(dt.gui.views.darkroom) local max_images = 10 -dt.print(_("Showing images, with a pause in between each")) +dt.print(_("showing images, with a pause in between each")) sleep(1500) -- display first 10 images of collection pausing for a second between each for i, img in ipairs(dt.collection) do - dt.print(string.format(_("Displaying image "), i)) + dt.print(string.format(_("displaying image "), i)) dt.gui.views.darkroom.display_image(img) sleep(1500) if i == max_images then @@ -107,7 +107,7 @@ end -- return to lighttable view -dt.print(_("Restoring view")) +dt.print(_("restoring view")) sleep(1500) dt.gui.current_view(current_view) diff --git a/examples/gettextExample.lua b/examples/gettextExample.lua index f74b503..f0f51e9 100644 --- a/examples/gettextExample.lua +++ b/examples/gettextExample.lua @@ -78,7 +78,7 @@ local function _(msgid) return gettext(msgid) end -dt.print_error(_("Hello World!")) +dt.print_error(_("hello world!")) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to diff --git a/examples/lighttable_demo.lua b/examples/lighttable_demo.lua index 768e4ab..e1e0732 100644 --- a/examples/lighttable_demo.lua +++ b/examples/lighttable_demo.lua @@ -149,12 +149,12 @@ for n, layout in ipairs(layouts) do sleep(1500) for i = 1, 10 do dt.gui.libs.lighttable_mode.zoom_level(i) - dt.print(string.format(_("Set zoom level to %d"), i)) + dt.print(string.format(_("set zoom level to %d"), i)) sleep(1500) end for i = 9, 1, -1 do dt.gui.libs.lighttable_mode.zoom_level(i) - dt.print(string.format(_("Set zoom level to %d"), i)) + dt.print(string.format(_("set zoom level to %d"), i)) sleep(1500) end end diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index 23184aa..5674132 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -78,9 +78,9 @@ local function install_module() orientation = "vertical", dt.new_widget("button") { - label = _("MyButton"), + label = _("my button"), clicked_callback = function (_) - dt.print(_("Button clicked")) + dt.print(_("button clicked")) end }, table.unpack(mE.widgets), @@ -103,10 +103,10 @@ local function restart() end -- https://www.darktable.org/lua-api/types_lua_check_button.html -local check_button = dt.new_widget("check_button"){label = _("MyCheck_button"), value = true} +local check_button = dt.new_widget("check_button"){label = _("my check_button"), value = true} -- https://www.darktable.org/lua-api/types_lua_combobox.html -local combobox = dt.new_widget("combobox"){label = _("MyCombobox"), value = 2, "8", "16", "32"} +local combobox = dt.new_widget("combobox"){label = _("my combobox"), value = 2, "8", "16", "32"} -- https://www.darktable.org/lua-api/types_lua_entry.html local entry = dt.new_widget("entry") @@ -115,21 +115,21 @@ local entry = dt.new_widget("entry") placeholder = _("placeholder"), is_password = false, editable = true, - tooltip = _("Tooltip Text"), + tooltip = _("tooltip text"), reset_callback = function(self) self.text = "text" end } -- https://www.darktable.org/lua-api/types_lua_file_chooser_button.html local file_chooser_button = dt.new_widget("file_chooser_button") { - title = _("MyFile_chooser_button"), -- The title of the window when choosing a file + title = _("my file_chooser_button"), -- The title of the window when choosing a file value = "", -- The currently selected file is_directory = false -- True if the file chooser button only allows directories to be selecte } -- https://www.darktable.org/lua-api/types_lua_label.html local label = dt.new_widget("label") -label.label = _("MyLabel") -- This is an alternative way to the "{}" syntax to set a property +label.label = _("my label") -- This is an alternative way to the "{}" syntax to set a property -- https://www.darktable.org/lua-api/types_lua_separator.html local separator = dt.new_widget("separator"){} @@ -137,7 +137,7 @@ local separator = dt.new_widget("separator"){} -- https://www.darktable.org/lua-api/types_lua_slider.html local slider = dt.new_widget("slider") { - label = _("MySlider"), + label = _("my slider"), soft_min = 10, -- The soft minimum value for the slider, the slider can't go beyond this point soft_max = 100, -- The soft maximum value for the slider, the slider can't go beyond this point hard_min = 0, -- The hard minimum value for the slider, the user can't manually enter a value beyond this point diff --git a/examples/multi_os.lua b/examples/multi_os.lua index 7486a25..5c084cf 100644 --- a/examples/multi_os.lua +++ b/examples/multi_os.lua @@ -184,12 +184,12 @@ local function extract_embedded_jpeg(images) end else dt.print_error(image.filename .. " is not a raw file. No image can be extracted") -- print debugging error message - dt.print(string.format(_("%s is not a raw file. No image can be extracted"), image.filename)) -- print the error to the screen + dt.print(string.format(_("%s is not a raw file, no image can be extracted"), image.filename)) -- print the error to the screen end end else dt.print_error("ufraw-batch not found. Exiting...") -- print debugging error message - dt.print("ufraw-batch not found. Exiting...") -- print the error to the screen + dt.print("ufraw-batch not found, exiting...") -- print the error to the screen end end @@ -213,7 +213,7 @@ end if dt.configuration.running_os ~= "linux" then local executable = "ufraw-batch" local ufraw_batch_path_widget = dt.new_widget("file_chooser_button"){ - title = _("Select ufraw-batch[.exe] executable"), + title = _("select ufraw-batch[.exe] executable"), value = df.get_executable_path_preference(executable), is_directory = false, changed_callback = function(self) @@ -225,7 +225,7 @@ if dt.configuration.running_os ~= "linux" then dt.preferences.register("executable_paths", "ufraw-batch", -- name "file", -- type _('multi_os: ufraw-batch location'), -- label - _('Installed location of ufraw-batch. Requires restart to take effect.'), -- tooltip + _('Installed location of ufraw-batch, requires restart to take effect.'), -- tooltip "ufraw-batch", -- default ufraw_batch_path_widget ) diff --git a/examples/panels_demo.lua b/examples/panels_demo.lua index 5938398..971d69b 100644 --- a/examples/panels_demo.lua +++ b/examples/panels_demo.lua @@ -93,29 +93,29 @@ dt.gui.panel_show_all() -- hide center_top, center_bottom, left, top, right, bottom in order -dt.print(_("Hiding all panels, one at a tme")) +dt.print(_("hiding all panels, one at a tme")) sleep(1500) for i = 1, #panels do - dt.print(_("Hiding " .. panels[i])) + dt.print(_("hiding " .. panels[i])) dt.gui.panel_hide(panels[i]) sleep(1500) end -- display left, then top, then right, then bottom - dt.print(_("Make panels visible, one at a time")) + dt.print(_("make panels visible, one at a time")) sleep(1500) for i = #panels, 1, -1 do - dt.print(_("Showing " .. panels[i])) + dt.print(_("showing " .. panels[i])) dt.gui.panel_show(panels[i]) sleep(1500) end -- hide all -dt.print(_("Hiding all panels")) +dt.print(_("hiding all panels")) sleep(1500) dt.gui.panel_hide_all() @@ -123,7 +123,7 @@ sleep(1500) -- show all -dt.print(_("Showing all panels")) +dt.print(_("showing all panels")) sleep(1500) dt.gui.panel_show_all() @@ -131,7 +131,7 @@ sleep(1500) -- restore -dt.print(_("Restoring panels to starting configuration")) +dt.print(_("restoring panels to starting configuration")) for i = 1, #panels do if panel_status[i] then dt.gui.panel_show(panels[i]) diff --git a/examples/preferenceExamples.lua b/examples/preferenceExamples.lua index 74e6152..aa8eae2 100644 --- a/examples/preferenceExamples.lua +++ b/examples/preferenceExamples.lua @@ -38,22 +38,22 @@ du.check_min_api_version("2.0.1", "preferenceExamples") dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesString", -- name "string", -- type - _("Example String"), -- label - _("Example String Tooltip"), -- tooltip + _("example string"), -- label + _("example string tooltip"), -- tooltip "String") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesBool", -- name "bool", -- type - _("Example Boolean"), -- label - _("Example Boolean Tooltip"), -- tooltip + _("example boolean"), -- label + _("example boolean tooltip"), -- tooltip true) -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesInteger", -- name "integer", -- type - _("Example Integer"), -- label - _("Example Integer Tooltip"), -- tooltip + _("example integer"), -- label + _("example integer tooltip"), -- tooltip 2, -- default 1, -- min 99) -- max @@ -61,8 +61,8 @@ dt.preferences.register("preferenceExamples", -- script: This is a string dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesFloat", -- name "float", -- type - _("Example Float"), -- label - _("Example Float Tooltip"), -- tooltip + _("example float"), -- label + _("example float tooltip"), -- tooltip 1.3, -- default 1, -- min 99, -- max @@ -71,22 +71,22 @@ dt.preferences.register("preferenceExamples", -- script: This is a string dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesFile", -- name "file", -- type - _("Example File"), -- label - _("Example File Tooltip"), -- tooltip + _("example file"), -- label + _("example file tooltip"), -- tooltip "") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesDirectory", -- name "directory", -- type - _("Example Directory"), -- label - _("Example Directory Tooltip"), -- tooltip + _("example directory"), -- label + _("example directory tooltip"), -- tooltip "") -- default dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesEnum", -- name "enum", -- type - _("Example Enum"), -- label - _("Example Enum Tooltip"), -- tooltip + _("example enum"), -- label + _("example enum tooltip"), -- tooltip "Enum 1", -- default "Enum 1", "Enum 2") -- values diff --git a/examples/running_os.lua b/examples/running_os.lua index a179e9f..2c68bf0 100644 --- a/examples/running_os.lua +++ b/examples/running_os.lua @@ -44,7 +44,7 @@ local function destroy() -- nothing to destroy end -dt.print(string.format(_("You are running: %s"), dt.configuration.running_os)) +dt.print(string.format(_("you are running: %s"), dt.configuration.running_os)) -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to From 231e9b352bb560fb0e7c0c36eccc88770eb988e5 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 29 Mar 2024 14:17:19 -0400 Subject: [PATCH 11/40] changed translatable strings to lower case --- contrib/CollectHelper.lua | 22 ++++++++--------- contrib/HDRMerge.lua | 8 +++--- contrib/LabelsToTags.lua | 38 ++++++++++++++--------------- contrib/OpenInExplorer.lua | 20 +++++++-------- contrib/autostyle.lua | 12 ++++----- contrib/change_group_leader.lua | 4 +-- contrib/clear_GPS.lua | 4 +-- contrib/copy_attach_detach_tags.lua | 10 ++++---- contrib/cr2hdr.lua | 8 +++--- contrib/cycle_group_leader.lua | 4 +-- contrib/enfuseAdvanced.lua | 14 +++++------ contrib/exportLUT.lua | 12 ++++----- contrib/ext_editor.lua | 2 +- contrib/face_recognition.lua | 10 ++++---- contrib/fujifilm_ratings.lua | 4 +-- contrib/geoJSON_export.lua | 14 +++++------ contrib/geoToolbox.lua | 36 +++++++++++++-------------- contrib/gimp.lua | 6 ++--- contrib/hif_group_leader.lua | 4 +-- contrib/image_stack.lua | 8 +++--- contrib/image_time.lua | 12 ++++----- contrib/jpg_group_leader.lua | 4 +-- contrib/kml_export.lua | 26 ++++++++++---------- contrib/photils.lua | 18 +++++++------- contrib/rate_group.lua | 14 +++++------ contrib/rename-tags.lua | 20 +++++++-------- contrib/slideshowMusic.lua | 6 ++--- contrib/transfer_hierarchy.lua | 2 +- contrib/video_ffmpeg.lua | 2 +- 29 files changed, 172 insertions(+), 172 deletions(-) diff --git a/contrib/CollectHelper.lua b/contrib/CollectHelper.lua index 9e6f12c..7e72d55 100644 --- a/contrib/CollectHelper.lua +++ b/contrib/CollectHelper.lua @@ -69,7 +69,7 @@ end -- FUNCTION -- local function CheckSingleImage(selection) if #selection ~= 1 then - dt.print(_("Please select a single image")) + dt.print(_("please select a single image")) return true end return false @@ -202,47 +202,47 @@ end dt.gui.libs.image.register_action( "CollectHelper_prev", _("collect: previous"), function() PreviousCollection() end, - _("Sets the Collect parameters to be the previously active parameters") + _("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") + _("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)") + _("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") + _("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 + _('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 + _('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 + _('CollectHelper: folder'), -- label + _('enable the button that allows you to swap to a collection based on selected image\'s folder location'), -- tooltip true -- default ) diff --git a/contrib/HDRMerge.lua b/contrib/HDRMerge.lua index a662f21..c4fd75b 100644 --- a/contrib/HDRMerge.lua +++ b/contrib/HDRMerge.lua @@ -378,7 +378,7 @@ local lbl_import = dt.new_widget('section_label'){ } GUI.Target.style = dt.new_widget('combobox'){ label = _('apply style on import'), - tooltip = _('Apply selected style on auto-import to newly created image'), + tooltip = _('apply selected style on auto-import to newly created image'), selected = 1, _('none'), changed_callback = function(self) @@ -407,9 +407,9 @@ GUI.Target.copy_tags = dt.new_widget('check_button'){ 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'), + tooltip = _('additional tags to be added on import, seperate with commas, all spaces will be removed'), text = temp, - placeholder = _('Enter tags, seperated by commas'), + placeholder = _('enter tags, seperated by commas'), editable = true } GUI.run = dt.new_widget('button'){ @@ -418,7 +418,7 @@ GUI.run = dt.new_widget('button'){ clicked_callback = function() main() end } GUI.exes.HDRMerge = dt.new_widget('file_chooser_button'){ - title = _('Select HDRmerge executable'), + title = _('select HDRmerge executable'), value = df.get_executable_path_preference(HDRM.name), is_directory = false } diff --git a/contrib/LabelsToTags.lua b/contrib/LabelsToTags.lua index 83feada..bc3a212 100644 --- a/contrib/LabelsToTags.lua +++ b/contrib/LabelsToTags.lua @@ -115,23 +115,23 @@ end local initialAvailableMappings = { - [_("Colors")] = { ["+*****"] = { _("Red") }, - ["*+****"] = { _("Yellow") }, - ["**+***"] = { _("Green") }, - ["***+**"] = { _("Blue") }, - ["****+*"] = { _("Purple") } }, - [_("Single colors")] = { ["+----*"] = { _("Red"), _("Only red") }, - ["-+---*"] = { _("Yellow"), _("Only yellow") }, - ["--+--*"] = { _("Green"), _("Only green") }, - ["---+-*"] = { _("Blue"), _("Only blue") }, - ["----+*"] = { _("Purple"), _("Only purple") } }, - [_("Ratings")] = { ["*****0"] = { _("No stars"), _("Not rejected") }, - ["*****1"] = { _("One star"), _("Not rejected") }, - ["*****2"] = { _("Two stars"), _("Not rejected") }, - ["*****3"] = { _("Three stars"), _("Not rejected") }, - ["*****4"] = { _("Four stars"), _("Not rejected") }, - ["*****5"] = { _("Five stars"), _("Not rejected") }, - ["*****R"] = { _("Rejected") } } + [_("colors")] = { ["+*****"] = { _("red") }, + ["*+****"] = { _("yellow") }, + ["**+***"] = { _("green") }, + ["***+**"] = { _("blue") }, + ["****+*"] = { _("purple") } }, + [_("single colors")] = { ["+----*"] = { _("red"), _("only red") }, + ["-+---*"] = { _("Yellow"), _("only yellow") }, + ["--+--*"] = { _("Green"), _("only green") }, + ["---+-*"] = { _("Blue"), _("only blue") }, + ["----+*"] = { _("Purple"), _("only purple") } }, + [_("ratings")] = { ["*****0"] = { _("no stars"), _("not rejected") }, + ["*****1"] = { _("one star"), _("not rejected") }, + ["*****2"] = { _("two stars"), _("not rejected") }, + ["*****3"] = { _("three stars"), _("not rejected") }, + ["*****4"] = { _("four stars"), _("not rejected") }, + ["*****5"] = { _("five stars"), _("not rejected") }, + ["*****R"] = { _("rejected") } } } local availableMappings = {} @@ -146,9 +146,9 @@ end local function getComboboxTooltip() if availableMappings == nil or next(availableMappings) == nil then - return(_("No registered mappings -- using defaults")) + return(_("no registered mappings -- using defaults")) else - return(_("Select a label-to-tag mapping")) + return(_("select a label-to-tag mapping")) end end diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index 443a09a..522e92b 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -74,7 +74,7 @@ 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(_("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 @@ -90,11 +90,11 @@ 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(_("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(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 @@ -151,7 +151,7 @@ local function set_links(selected_images) end ]] if dsys.external_command(run_cmd) ~= 0 then - dt.print(_("Failed to create links. Missing rights?")) + dt.print(_("failed to create links, missing rights?")) dt.print_error("OpenInExplorer: Failed to create links") return end @@ -167,13 +167,13 @@ end local function open_in_fmanager() local images = dt.gui.selection() if #images == 0 then - dt.print(_("Please select an image")) + 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)")) + dt.print(_("please select fewer images (max. 15)")) elseif use_links then set_links(images) else @@ -200,7 +200,7 @@ end 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") + _("open the file manager at the selected image's location") ) @@ -208,17 +208,17 @@ 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 + _("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"), + 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 + _("use links instead of multiple windows, requires restart to take effect"), -- tooltip false, -- default "" ) diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index cf3ebe7..4c1284e 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -98,7 +98,7 @@ local function autostyle_apply_one_image (image) -- check they all exist (correct syntax) if (not tag) then - darktable.print(string.format(_("EXIF TAG not found in %s"), pref)) + darktable.print(string.format(_("EXIF tag not found in %s"), pref)) return 0 end if (not value) then @@ -110,7 +110,7 @@ local function autostyle_apply_one_image (image) return 0 end if not filelib.check_if_bin_exists("exiftool") then - darktable.print(_("Can't find exiftool")) + darktable.print(_("can't find exiftool")) return 0 end @@ -133,7 +133,7 @@ local function autostyle_apply_one_image (image) --darktable.print_error("dr_attr:" .. auto_dr_attr) -- If the lookup fails, stop here if (not ok) then - darktable.print(string.format(_("Couldn't get attribute %s from exiftool's output"), auto_dr_attr)) + darktable.print(string.format(_("couldn't get attribute %s from exiftool's output"), auto_dr_attr)) return 0 end if auto_dr_attr == value then @@ -160,7 +160,7 @@ local function autostyle_apply(shortcut) images_submitted = images_submitted + 1 images_processed = images_processed + autostyle_apply_one_image(image) end - darktable.print(string.format(_("Applied auto style to %d out of %d image(s)"), images_processed, images_submitted)) + darktable.print(string.format(_("applied auto style to %d out of %d image(s)"), images_processed, images_submitted)) end local function destroy() @@ -170,9 +170,9 @@ end -- Registering events darktable.register_event("autostyle", "shortcut", autostyle_apply, - _("Apply your chosen style from exiftool tags")) + _("apply your chosen style from exiftool tags")) -darktable.preferences.register("autostyle", "exif_tag", "string", "Autostyle: EXIF_tag=value=>style", _("apply a style automatically if an EXIF_tag matches value. Find the tag with exiftool"), "") +darktable.preferences.register("autostyle", "exif_tag", "string", "Autostyle: EXIF_tag=value=>style", _("apply a style automatically if an EXIF tag matches value, find the tag with exiftool"), "") darktable.register_event("autostyle", "post-import-image", autostyle_apply_one_image_event) diff --git a/contrib/change_group_leader.lua b/contrib/change_group_leader.lua index 786c91e..0c70ac3 100644 --- a/contrib/change_group_leader.lua +++ b/contrib/change_group_leader.lua @@ -118,7 +118,7 @@ end local function process_image_groups(images) if #images < 1 then - dt.print(_("No images selected.")) + dt.print(_("o images selected")) dt.print_log(MODULE .. "no images seletected, returning...") else local mode = cgl.widgets.mode.value @@ -158,7 +158,7 @@ cgl.widgets.mode = dt.new_widget("combobox"){ } cgl.widgets.execute = dt.new_widget("button"){ - label = _("Execute"), + label = _("execute"), clicked_callback = function() process_image_groups(dt.gui.action_images) end diff --git a/contrib/clear_GPS.lua b/contrib/clear_GPS.lua index 9f21b1e..7e12e09 100644 --- a/contrib/clear_GPS.lua +++ b/contrib/clear_GPS.lua @@ -79,13 +79,13 @@ script_data.destroy = destroy dt.gui.libs.image.register_action( "clear_GPS", _("clear GPS data"), function(event, images) clear_GPS(images) end, - _("Clear GPS data from selected images") + _("clear GPS data from selected images") ) dt.register_event( "clear_GPS", "shortcut", function(event, shortcut) clear_GPS(dt.gui.action_images) end, - _("Clear GPS data") + _("clear GPS data") ) return script_data diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index 1de8db2..de78f13 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -96,7 +96,7 @@ local function mcopy_tags() end end - dt.print(_('Image tags copied ...')) + dt.print(_('image tags copied ...')) --create UI tag list local taglist = "" @@ -118,7 +118,7 @@ local function mcopy_tags() local function attach_tags() if next(image_tags) == nil then - dt.print(_('No tag to attach, please copy tags first.')) + dt.print(_('no tag to attach, please copy tags first.')) return true end @@ -142,7 +142,7 @@ local function attach_tags() end end end - dt.print(_('Tags attached ...')) + dt.print(_('tags attached ...')) end local function detach_tags() @@ -158,13 +158,13 @@ local function detach_tags() end end end - dt.print(_('Tags removed from image(s).')) + dt.print(_('tags removed from image(s).')) end local function replace_tags() detach_tags() attach_tags() - dt.print(_('Tags replaced')) + dt.print(_('tags replaced')) end local function install_module() diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua index 53b1e14..8b6f54d 100644 --- a/contrib/cr2hdr.lua +++ b/contrib/cr2hdr.lua @@ -93,7 +93,7 @@ end local function convert_images() if next(queue) == nil then return end - job = darktable.gui.create_job(_("Dual ISO conversion"), true, stop_conversion) + job = darktable.gui.create_job(_("dual ISO conversion"), true, stop_conversion) for key,image in pairs(queue) do if job.valid then job.percent = (key-1)/#queue @@ -104,7 +104,7 @@ local function convert_images() end local success_count = 0 for _ in pairs(processed_files) do success_count = success_count + 1 end - darktable.print(string.format(_("Dual ISO conversion successful on %d/%d images."), success_count, #queue)) + darktable.print(string.format(_("dual ISO conversion successful on %d/%d images."), success_count, #queue)) job.valid = false processed_files = {} queue = {} @@ -128,13 +128,13 @@ local function destroy() end darktable.register_event("cr2hdr", "shortcut", - convert_action_images, _("Run cr2hdr (Magic Lantern DualISO converter) on selected images")) + convert_action_images, _("run cr2hdr (Magic Lantern DualISO converter) on selected images")) darktable.register_event("cr2hdr", "post-import-image", file_imported) darktable.register_event("cr2hdr", "post-import-film", film_imported) -darktable.preferences.register("cr2hdr", "onimport", "bool", _("Invoke on import"), _("If true then cr2hdr will try to proccess every file during importing. Warning: cr2hdr is quite slow even in figuring out on whether the file is Dual ISO or not."), false) +darktable.preferences.register("cr2hdr", "onimport", "bool", _("invoke on import"), _("if true then cr2hdr will try to proccess every file during importing\nwarning: cr2hdr is quite slow even in figuring out on whether the file is dual ISO or not."), false) script_data.destroy = destroy diff --git a/contrib/cycle_group_leader.lua b/contrib/cycle_group_leader.lua index dde8546..d2bf3da 100644 --- a/contrib/cycle_group_leader.lua +++ b/contrib/cycle_group_leader.lua @@ -97,7 +97,7 @@ end local function cycle_group_leader(image) local group_images = image:get_group_members() if #group_images < 2 then - hinter_msg(_("No images to cycle to in group")) + hinter_msg(_("no images to cycle to in group")) return else local position = nil @@ -144,7 +144,7 @@ dt.register_event(MODULE, "shortcut", -- ignore the film roll, it contains all the images, not just the imported local images = dt.gui.selection() if #images < 1 then - dt.print(_("No image selected. Please select an image and try again")) + dt.print(_("no image selected, please select an image and try again")) else cycle_group_leader(images[1]) end diff --git a/contrib/enfuseAdvanced.lua b/contrib/enfuseAdvanced.lua index f8aeb9b..8698f47 100644 --- a/contrib/enfuseAdvanced.lua +++ b/contrib/enfuseAdvanced.lua @@ -729,7 +729,7 @@ GUI.ENF.hard_masks = dt.new_widget('check_button'){ GUI.ENF.save_masks = dt.new_widget('check_button'){ label = _('save masks'), value = dt.preferences.read(mod, 'active_save_masks', 'bool'), - tooltip = _('Save the generated weight masks to your home directory,\nenblend saves masks as 8 bit grayscale, \ni.e. single channel images. \nfor accuracy we recommend to choose a lossless format.'), + tooltip = _('save the generated weight masks to your home directory,\nenblend saves masks as 8 bit grayscale, \ni.e. single channel images. \nfor accuracy we recommend to choose a lossless format.'), clicked_callback = function(self) dt.preferences.write(mod, 'active_save_masks', 'bool', self.value) end, reset_callback = function(self) self.value = false end } @@ -882,7 +882,7 @@ GUI.Target.output_directory = dt.new_widget('file_chooser_button'){ GUI.Target.source_location = dt.new_widget('check_button'){ label = _('save to source image location'), value = dt.preferences.read(mod, 'active_source_location', 'bool'), - tooltip = _('If checked ignores the location above and saves output image(s) to the same location as the source images.'), + tooltip = _('if checked ignores the location above and saves output image(s) to the same location as the source images.'), clicked_callback = function(self) dt.preferences.write(mod, 'active_source_location', 'bool', self.value) end, reset_callback = function(self) self.value = true end } @@ -916,8 +916,8 @@ GUI.Target.auto_import = dt.new_widget('check_button'){ } temp = dt.preferences.read(mod, 'active_apply_style_ind', 'integer') GUI.Target.apply_style = dt.new_widget('combobox'){ - label = _('Apply Style on Import'), - tooltip = _('Apply selected style on auto-import to newly created blended image'), + label = _('apply style on Import'), + tooltip = _('apply selected style on auto-import to newly created blended image'), selected = 1, 'none', changed_callback = function(self) @@ -938,16 +938,16 @@ GUI.Target.apply_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 image.'), + tooltip = _('copy tags from first 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'), + tooltip = _('additional tags to be added on import, seperate with commas, all spaces will be removed'), text = temp, - placeholder = 'Enter tags, seperated by commas', + placeholder = _('enter tags, seperated by commas'), editable = true } temp = dt.preferences.read(mod, 'active_current_preset_ind', 'integer') diff --git a/contrib/exportLUT.lua b/contrib/exportLUT.lua index 6a22f83..7cc5b63 100644 --- a/contrib/exportLUT.lua +++ b/contrib/exportLUT.lua @@ -62,13 +62,13 @@ local mkdir_command = 'mkdir -p ' if dt.configuration.running_os == 'windows' then mkdir_command = 'mkdir ' end local file_chooser_button = dt.new_widget("file_chooser_button"){ - title = _("Identity_file_chooser"), + title = _("identity_file_chooser"), value = "", is_directory = false } local export_chooser_button = dt.new_widget("file_chooser_button"){ - title = _("Export_location_chooser"), + title = _("export_location_chooser"), value = "", is_directory = true } @@ -104,9 +104,9 @@ end local function export_luts() local identity = dt.database.import(file_chooser_button.value) if(type(identity) ~= "userdata") then - dt.print(_("Invalid identity lut file")) + dt.print(_("invalid identity lut file")) else - local job = dt.gui.create_job(_('Exporting styles as haldCLUTs'), true, end_job) + local job = dt.gui.create_job(_('exporting styles as haldCLUTs'), true, end_job) local size = 1 @@ -125,9 +125,9 @@ local function export_luts() io_lut:write_image(identity, output_path(style.name, job)) count = count + 1 job.percent = count / size - dt.print(string.format(_("Exported: %s"), output_path(style.name, job))) + dt.print(string.format(_("exported: %s"), output_path(style.name, job))) end - dt.print(_("Done exporting haldCLUTs")) + dt.print(_("done exporting haldCLUTs")) job.valid = false identity:reset() end diff --git a/contrib/ext_editor.lua b/contrib/ext_editor.lua index b28a7f9..a6485d4 100644 --- a/contrib/ext_editor.lua +++ b/contrib/ext_editor.lua @@ -477,7 +477,7 @@ dt.register_storage("exp2coll", _("collection"), nil, export2collection) for i = MAX_EDITORS, 1, -1 do dt.preferences.register(MODULE_NAME, "program_path_"..i, "file", string.format(_("executable for external editor %d"), i), - _("select executable for external editor") , _("(None)")) + _("select executable for external editor") , _("(none)")) dt.preferences.register(MODULE_NAME, "program_name_"..i, "string", string.format(_("name of external editor %d"), i), diff --git a/contrib/face_recognition.lua b/contrib/face_recognition.lua index 7325d7e..8c23fa7 100644 --- a/contrib/face_recognition.lua +++ b/contrib/face_recognition.lua @@ -132,7 +132,7 @@ local function do_export(img_tbl, images) job.percent = 0.0 for export,img in pairs(img_tbl) do exp_cnt = exp_cnt + 1 - dt.print(string.format(_("Exporting image %i of %i images"), exp_cnt, images)) + dt.print(string.format(_("exporting image %i of %i images"), exp_cnt, images)) exporter:write_image(img, export, upsize) job.percent = job.percent + percent_step end @@ -202,7 +202,7 @@ local function face_recognition () local bin_path = df.check_if_bin_exists("face_recognition") if not bin_path then - dt.print(_("Face recognition not found")) + dt.print(_("face recognition not found")) return end @@ -254,7 +254,7 @@ local function face_recognition () local command = bin_path .. " --cpus " .. nrCores .. " --tolerance " .. tolerance .. " " .. knownPath .. " " .. path .. " > " .. OUTPUT os.setlocale() dt.print_log("Face recognition: Running command: " .. command) - dt.print(_("Starting face recognition...")) + dt.print(_("starting face recognition...")) dtsys.external_command(command) @@ -262,9 +262,9 @@ local function face_recognition () local f = io.open(OUTPUT, "rb") if not f then - dt.print(_("Face recognition failed")) + dt.print(_("face recognition failed")) else - dt.print(_("Face recognition finished")) + dt.print(_("face recognition finished")) f:close () end diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index c64fffa..8e19648 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -58,7 +58,7 @@ local function detect_rating(event, image) if string.len(jpeg_result) > 0 then jpeg_result = string.gsub(jpeg_result, "^Rating.*(%d)", "%1") image.rating = tonumber(jpeg_result) - dt.print_error(string.format(_("Using JPEG Rating: %d"), jpeg_result)) + dt.print_error(string.format(_("using JPEG rating: %d"), jpeg_result)) return end command = "exiftool -Rating " .. RAF_filename @@ -69,7 +69,7 @@ local function detect_rating(event, image) if string.len(raf_result) > 0 then raf_result = string.gsub(raf_result, "^Rating.*(%d)", "%1") image.rating = tonumber(raf_result) - dt.print_error(string.format(_("Using RAF Rating: %d"), raf_result)) + dt.print_error(string.format(_("using RAF rating: %d"), raf_result)) end end diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index dac5f5f..a6dfc51 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -77,7 +77,7 @@ local function spairs(_table, order) -- Code copied from http://stackoverflow.co 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)) + dt.print(string.format(_("export image %i/%i"), number, total)) end local function create_geoJSON_file(storage, image_table, extra_data) @@ -306,19 +306,19 @@ dt.preferences.register("geoJSON_export", "CreateMapBoxHTMLFile", "bool", _("geoJSON export: Create an additional HTML file"), - _("Creates a HTML file, that loads the geoJASON file. (Needs a MapBox key"), + _("creates an HTML file that loads the geoJSON file. (needs a MapBox key"), false ) dt.preferences.register("geoJSON_export", "mapBoxKey", "string", - _("geoJSON export: MapBox Key"), + _("geoJSON export: MapBox key"), _("https://www.mapbox.com/studio/account/tokens"), '' ) dt.preferences.register("geoJSON_export", "OpengeoJSONFile", "bool", - _("geoJSON export: Open geoJSON file after export"), - _("Opens the geoJSON file after the export with the standard program for geoJSON files"), + _("geoJSON export: open geoJSON file after export"), + _("opens the geoJSON file after the export with the standard program for geoJSON files"), false ) local handle = io.popen("xdg-user-dir DESKTOP") @@ -330,8 +330,8 @@ end dt.preferences.register("geoJSON_export", "ExportDirectory", "directory", - _("geoJSON export: Export directory"), - _("A directory that will be used to export the geoJSON files"), + _("geoJSON export: export directory"), + _("a directory that will be used to export the geoJSON files"), result ) -- Register diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index b595015..ee895ca 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -53,7 +53,7 @@ gT.event_registered = false -- local labelDistance = dt.new_widget("label") -labelDistance.label = _("Distance:") +labelDistance.label = _("distance:") local label_copy_gps_lat = dt.new_widget("check_button") { @@ -490,7 +490,7 @@ local function calc_distance() distanceUnit = _("km") end - return string.format(_("Distance: %.2f %s"), distance, distanceUnit) + return string.format(_("distance: %.2f %s"), distance, distanceUnit) end local function print_calc_distance() @@ -513,12 +513,12 @@ local altitude_filename = dt.new_widget("entry") text = "altitude.csv", placeholder = "altitude.csv", editable = true, - tooltip = _("Name of the exported file"), + tooltip = _("name of the exported file"), reset_callback = function(self) self.text = "text" end } local function altitude_profile() - dt.print(_("Start export")) + dt.print(_("start export")) local sel_images = dt.gui.action_images local lat1 = 0; @@ -579,7 +579,7 @@ local function altitude_profile() file = io.open(exportDirectory.."/"..exportFilename, "w") file:write(csv_file) file:close() - dt.print(string.format(_("File created in %s"), exportDirectory)) + dt.print(string.format(_("file created in %s"), exportDirectory)) end @@ -609,14 +609,14 @@ end local function restart() dt.register_event("geoToolbox_cd", "shortcut", - print_calc_distance, _("Calculate the distance from latitude and longitude in km")) + print_calc_distance, _("calculate the distance from latitude and longitude in km")) dt.register_event("geoToolbox", "mouse-over-image-changed", toolbox_calc_distance) dt.register_event("geoToolbox_wg", "shortcut", - select_with_gps, _("Select all images with GPS information")) + select_with_gps, _("select all images with GPS information")) dt.register_event("geoToolbox_ng", "shortcut", - select_without_gps, _("Select all images without GPS information")) + select_without_gps, _("select all images without GPS information")) dt.gui.libs["geoToolbox"].visible = true end @@ -639,20 +639,20 @@ gT.widget = dt.new_widget("box") dt.new_widget("button") { label = _("select geo images"), - tooltip = _("Select all images with GPS information"), + tooltip = _("select all images with GPS information"), clicked_callback = select_with_gps }, dt.new_widget("button") { label = _("select non-geo images"), - tooltip = _("Select all images without GPS information"), + tooltip = _("select all images without GPS information"), clicked_callback = select_without_gps }, separator,-------------------------------------------------------- dt.new_widget("button") { label = _("copy GPS data"), - tooltip = _("Copy GPS data"), + tooltip = _("copy GPS data"), clicked_callback = copy_gps }, label_copy_gps_lat, @@ -661,7 +661,7 @@ gT.widget = dt.new_widget("box") dt.new_widget("button") { label = _("paste GPS data"), - tooltip = _("Paste GPS data"), + tooltip = _("paste GPS data"), clicked_callback = paste_gps }, separator2,-------------------------------------------------------- @@ -691,14 +691,14 @@ gT.widget = dt.new_widget("box") dt.new_widget("button") { label = _("open in Gnome Maps"), - tooltip = _("Open location in Gnome Maps"), + tooltip = _("open location in Gnome Maps"), clicked_callback = open_location_in_gnome_maps }, separator4,-------------------------------------------------------- dt.new_widget("button") { label = _("reverse geocode"), - tooltip = _("This just shows the name of the location, but doesn't add it as tag"), + tooltip = _("this just shows the name of the location, but doesn't add it as tag"), clicked_callback = reverse_geocode }, separator5,-------------------------------------------------------- @@ -708,7 +708,7 @@ gT.widget = dt.new_widget("box") dt.new_widget("button") { label = _("export altitude CSV file"), - tooltip = _("Create an altitude profile using the GPS data in the metadata"), + tooltip = _("create an altitude profile using the GPS data in the metadata"), clicked_callback = altitude_profile }, labelDistance @@ -741,14 +741,14 @@ dt.preferences.register("geoToolbox", -- Register dt.register_event("geoToolbox_cd", "shortcut", - print_calc_distance, _("Calculate the distance from latitude and longitude in km")) + print_calc_distance, _("calculate the distance from latitude and longitude in km")) dt.register_event("geoToolbox", "mouse-over-image-changed", toolbox_calc_distance) dt.register_event("geoToolbox_wg", "shortcut", - select_with_gps, _("Select all images with GPS information")) + select_with_gps, _("select all images with GPS information")) dt.register_event("geoToolbox_ng", "shortcut", - select_without_gps, _("Select all images without GPS information")) + select_without_gps, _("select all images without GPS information")) script_data.destroy = destroy script_data.restart = restart diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 843bbce..db1e48f 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -106,7 +106,7 @@ 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)) + dt.print(string.format(_("export image %i/%i"), number, total)) end local function gimp_edit(storage, image_table, extra_data) --finalize @@ -139,7 +139,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize img_list = img_list ..exp_img.. " " end - dt.print(_("Launching GIMP...")) + dt.print(_("launching GIMP...")) local gimpStartCommand gimpStartCommand = gimp_executable .. " " .. img_list @@ -210,7 +210,7 @@ gimp_widget = dt.new_widget("check_button"){ end } -dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit, nil, nil, gimp_widget) +dt.register_storage("module_gimp", _("edit with GIMP"), show_status, gimp_edit, nil, nil, gimp_widget) -- script_data.destroy = destroy diff --git a/contrib/hif_group_leader.lua b/contrib/hif_group_leader.lua index 14327db..c50d8b2 100644 --- a/contrib/hif_group_leader.lua +++ b/contrib/hif_group_leader.lua @@ -179,7 +179,7 @@ dt.register_event(MODULE .. "_collect", "shortcut", local images = dt.collection make_existing_hif_group_leader(images) end, - _("Make hif group leader for collection") + _("make hif group leader for collection") ) dt.register_event(MODULE .. "_select", "shortcut", @@ -187,7 +187,7 @@ dt.register_event(MODULE .. "_select", "shortcut", local images = dt.gui.selection() make_existing_hif_group_leader(images) end, - _("Make hif group leader for selection") + _("make hif group leader for selection") ) return script_data \ No newline at end of file diff --git a/contrib/image_stack.lua b/contrib/image_stack.lua index d8abc9a..f6aad52 100644 --- a/contrib/image_stack.lua +++ b/contrib/image_stack.lua @@ -256,7 +256,7 @@ 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)) + dt.print(string.format(_("export image %i/%i"), number, total)) end -- read the gui and populate the align_image_stack arguments @@ -551,7 +551,7 @@ local function image_stack(storage, image_table, extra_data) local import_filename = df.create_unique_filename(film_roll_path .. PS .. df.get_filename(output_filename)) df.file_move(output_filename, import_filename) imported_image = dt.database.import(import_filename) - local created_tag = dt.tags.create(_("Created with|image_stack")) + local created_tag = dt.tags.create(_("created with|image_stack")) dt.tags.attach(created_tag, imported_image) -- all the images are the same except for time, so just copy the attributes -- from the first @@ -565,7 +565,7 @@ local function image_stack(storage, image_table, extra_data) if tag_source then dt.print(_("tagging source images")) - local source_tag = dt.tags.create(_("Source file|" .. imported_image.filename)) + local source_tag = dt.tags.create(_("source file|" .. imported_image.filename)) for img, _ in pairs(image_table) do dt.tags.attach(source_tag, img) end @@ -589,7 +589,7 @@ end dt.preferences.register("align_image_stack", "align_use_gpu", -- name "bool", -- type - _('align image stack: use GPU for remaping'), -- label + _('align image stack: use GPU for remapping'), -- label _('set the GPU remapping for image align'), -- tooltip false) diff --git a/contrib/image_time.lua b/contrib/image_time.lua index 1655a12..1f0a7d2 100644 --- a/contrib/image_time.lua +++ b/contrib/image_time.lua @@ -173,7 +173,7 @@ local function calculate_difference(images) img_time.diff_entry.text = calc_time_difference(images[1], images[2]) img_time.btn.sensitive = true else - dt.print(_("Error: 2 images must be selected")) + dt.print(_("ERROR: 2 images must be selected")) end end @@ -247,7 +247,7 @@ local function _get_windows_image_file_creation_time(image) end p:close() else - dt.print(string.format(_("unable to get information for "), image.filename)) + dt.print(string.format(_("unable to get information for $s"), image.filename)) datetime = ERROR end return datetime @@ -264,7 +264,7 @@ local function _get_nix_image_file_creation_time(image) end p:close() else - dt.print(string.format(_("unable to get information for "), image.filename)) + dt.print(string.format(_("unable to get information for %s"), image.filename)) datetime = ERROR end return datetime @@ -455,13 +455,13 @@ end img_time.syr.selected = #img_time.syr img_time.diff_entry = dt.new_widget("entry"){ - tooltip = _("Time difference between images in seconds"), - placeholder = _("Select 2 images and use the calculate button"), + tooltip = _("time difference between images in seconds"), + placeholder = _("select 2 images and use the calculate button"), text = "", } img_time.calc_btn = dt.new_widget("button"){ - label = _("Calculate"), + label = _("calculate"), tooltip = _("calculate time difference between 2 images"), clicked_callback = function() calculate_difference(dt.gui.action_images) diff --git a/contrib/jpg_group_leader.lua b/contrib/jpg_group_leader.lua index e30afb8..63d9801 100644 --- a/contrib/jpg_group_leader.lua +++ b/contrib/jpg_group_leader.lua @@ -179,7 +179,7 @@ dt.register_event(MODULE .. "_collect", "shortcut", local images = dt.collection make_existing_jpg_group_leader(images) end, - _("Make jpg group leader for collection") + _("make jpg group leader for collection") ) dt.register_event(MODULE .. "_select", "shortcut", @@ -187,7 +187,7 @@ dt.register_event(MODULE .. "_select", "shortcut", local images = dt.gui.selection() make_existing_jpg_group_leader(images) end, - _("Make jpg group leader for selection") + _("make jpg group leader for selection") ) return script_data \ No newline at end of file diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 0729309..79ac384 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -59,7 +59,7 @@ local function _(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)) + dt.print(string.format(_("export image %i/%i"), number, total)) end -- Add duplicate index to filename @@ -317,14 +317,14 @@ if dt.configuration.running_os == "windows" then "OpenKmlFile", "bool", _("KML export: Open KML file after export"), - _("Opens the KML file after the export with the standard program for KML files"), + _("opens the KML file after the export with the standard program for KML files"), false ) else dt.preferences.register("kml_export", "OpenKmlFile", "bool", - _("KML export: Open KML/KMZ file after export"), - _("Opens the KML file after the export with the standard program for KML files"), + _("KML export: open KML/KMZ file after export"), + _("opens the KML file after the export with the standard program for KML files"), false ) end @@ -343,23 +343,23 @@ end dt.preferences.register("kml_export", "ExportDirectory", "directory", - _("KML export: Export directory"), - _("A directory that will be used to export the KML/KMZ files"), + _("KML export: export directory"), + _("a directory that will be used to export the KML/KMZ files"), defaultDir ) if dt.configuration.running_os ~= "linux" then dt.preferences.register("kml_export", "magickPath", -- name "file", -- type - _("KML export: ImageMagick binary Location"), -- label - _("Install location of magick[.exe]. Requires restart to take effect."), -- tooltip + _("KML export: ImageMagick binary location"), -- label + _("install location of magick[.exe], requires restart to take effect"), -- tooltip "magick") -- default end dt.preferences.register("kml_export", "CreatePath", "bool", - _("KML export: Connect images with path"), + _("KML export: connect images with path"), _("connect all images with a path"), false ) @@ -367,16 +367,16 @@ if dt.configuration.running_os == "linux" then dt.preferences.register("kml_export", "CreateKMZ", "bool", - _("KML export: Create KMZ file"), - _("Compress all imeges to one KMZ file"), + _("KML export: create KMZ file"), + _("compress all imeges to one KMZ file"), true ) end -- Register if dt.configuration.running_os == "windows" then - dt.register_storage("kml_export", _("KML Export"), nil, create_kml_file) + dt.register_storage("kml_export", _("KML export"), nil, create_kml_file) else - dt.register_storage("kml_export", _("KML/KMZ Export"), nil, create_kml_file) + dt.register_storage("kml_export", _("KML/KMZ export"), nil, create_kml_file) end script_data.destroy = destroy diff --git a/contrib/photils.lua b/contrib/photils.lua index 0e6662f..f26998f 100644 --- a/contrib/photils.lua +++ b/contrib/photils.lua @@ -176,7 +176,7 @@ function PHOTILS.image_changed() end function PHOTILS.tagged_image_has_changed() - GUI.warning.label = _("The suggested tags were not generated\n for the currently selected image!") + GUI.warning.label = _("the suggested tags were not generated\n for the currently selected image!") end function PHOTILS.paginate() @@ -233,7 +233,7 @@ end function PHOTILS.attach_tags() local num_selected = #dt.gui.selection() - local job = dt.gui.create_job(_("Apply tag to image"), true) + local job = dt.gui.create_job(_("apply tag to image"), true) for i = 1, num_selected, 1 do local image = dt.gui.selection()[i] @@ -245,7 +245,7 @@ function PHOTILS.attach_tags() job.percent = i / num_selected end - dt.print(_("Tags successfully attached to image")) + dt.print(_("tags successfully attached to image")) job.valid = false end @@ -311,11 +311,11 @@ function PHOTILS.on_tags_clicked() local images = dt.gui.selection() if #images == 0 then - dt.print(_("No image selected.")) + dt.print(_("no image selected.")) dt.control.sleep(2000) else if #images > 1 then - dt.print(_("This plugin can only handle a single image.")) + dt.print(_("this plugin can only handle a single image.")) dt.gui.selection({images[1]}) dt.control.sleep(2000) end @@ -428,7 +428,7 @@ if not photils_installed then GUI.warning_label.label = _("photils-cli not found") dt.print_log("photils-cli not found") else - GUI.warning_label.label = _("Select an image, click \"get tags\" and get \nsuggestions for tags.") + GUI.warning_label.label = _("select an image, click \"get tags\" and get \nsuggestions for tags.") end GUI.pagination = dt.new_widget("box") { @@ -471,9 +471,9 @@ dt.preferences.register(MODULE_NAME, "export_image_before_for_tags", "bool", _("photils: use exported image for tag request"), - _("If enabled, the image passed to photils for tag suggestion is based on the exported, already edited image. " .. - "Otherwise, the embedded thumbnail of the RAW file will be used for tag suggestion." .. - "The embedded thumbnail could speedup the tag suggestion but can fail if the RAW file is not supported."), + _("if enabled, the image passed to photils for tag suggestion is based on the exported, already edited image. " .. + "otherwise, the embedded thumbnail of the RAW file will be used for tag suggestion." .. + "the embedded thumbnail could speedup the tag suggestion but can fail if the RAW file is not supported."), true) dt.register_event("photils", "mouse-over-image-changed", diff --git a/contrib/rate_group.lua b/contrib/rate_group.lua index ca85b26..4b02d5e 100644 --- a/contrib/rate_group.lua +++ b/contrib/rate_group.lua @@ -87,37 +87,37 @@ end dt.register_event("rg_reject", "shortcut", function(event, shortcut) apply_rating(-1) -end, _("Reject group")) +end, _("reject group")) dt.register_event("rg0", "shortcut", function(event, shortcut) apply_rating(0) -end, _("Rate group 0")) +end, _("rate group 0")) dt.register_event("rg1", "shortcut", function(event, shortcut) apply_rating(1) -end, _("Rate group 1")) +end, _("rate group 1")) dt.register_event("rg2", "shortcut", function(event, shortcut) apply_rating(2) -end, _("Rate group 2")) +end, _("rate group 2")) dt.register_event("rg3", "shortcut", function(event, shortcut) apply_rating(3) -end, _("Rate group 3")) +end, _("rate group 3")) dt.register_event("rg4", "shortcut", function(event, shortcut) apply_rating(4) -end, _("Rate group 4")) +end, _("rate group 4")) dt.register_event("rg5", "shortcut", function(event, shortcut) apply_rating(5) -end, _("Rate group 5")) +end, _("rate group 5")) script_data.destroy = destroy diff --git a/contrib/rename-tags.lua b/contrib/rename-tags.lua index 4e03af7..05d9491 100644 --- a/contrib/rename-tags.lua +++ b/contrib/rename-tags.lua @@ -56,8 +56,8 @@ rt.module_installed = false rt.event_registered = false -- GUI entries -local old_tag = darktable.new_widget("entry") { tooltip = _("Enter old tag") } -local new_tag = darktable.new_widget("entry") { tooltip = _("Enter new tag") } +local old_tag = darktable.new_widget("entry") { tooltip = _("enter old tag") } +local new_tag = darktable.new_widget("entry") { tooltip = _("enter new tag") } local function rename_reset() old_tag.text = '' @@ -68,11 +68,11 @@ end local function rename_tags() -- If entries are empty, return if old_tag.text == '' then - darktable.print (_("Old tag can't be empty")) + darktable.print (_("old tag can't be empty")) return end if new_tag.text == '' then - darktable.print (_("New tag can't be empty")) + darktable.print (_("new tag can't be empty")) return end @@ -82,12 +82,12 @@ local function rename_tags() local ot = darktable.tags.find (old_tag.text) if not ot then - darktable.print (_("Old tag does not exist")) + darktable.print (_("old tag does not exist")) return end -- Show job - local job = darktable.gui.create_job (_("Renaming tag"), true) + local job = darktable.gui.create_job (_("renaming tag"), true) old_tag.editable = false new_tag.editable = false @@ -110,7 +110,7 @@ local function rename_tags() darktable.tags.delete (ot) job.valid = false - darktable.print (string.format(_("Renamed tags for %d images"), count)) + darktable.print (string.format(_("renamed tags for %d images"), count)) old_tag.editable = true new_tag.editable = true @@ -137,13 +137,13 @@ end -- GUI local old_widget = darktable.new_widget ("box") { orientation = "horizontal", - darktable.new_widget("label") { label = _("Old tag") }, + darktable.new_widget("label") { label = _("old tag") }, old_tag } local new_widget = darktable.new_widget ("box") { orientation = "horizontal", - darktable.new_widget("label") { label = _("New tag") }, + darktable.new_widget("label") { label = _("new tag") }, new_tag } @@ -152,7 +152,7 @@ rt.rename_widget = darktable.new_widget ("box") { reset_callback = rename_reset, old_widget, new_widget, - darktable.new_widget("button") { label = _("Go"), clicked_callback = rename_tags } + darktable.new_widget("button") { label = _("go"), clicked_callback = rename_tags } } if darktable.gui.current_view().id == "lighttable" then diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index 71bae54..abb7213 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -80,12 +80,12 @@ function destroy() end -- Preferences -dt.preferences.register("slideshowMusic", "SlideshowMusic", "file", _("Slideshow background music file"), "", "") +dt.preferences.register("slideshowMusic", "SlideshowMusic", "file", _("slideshow background music file"), "", "") dt.preferences.register("slideshowMusic", "PlaySlideshowMusic", "bool", - _("Play slideshow background music"), - _("Plays music with rhythmbox if a slideshow starts"), + _("play slideshow background music"), + _("plays music with rhythmbox if a slideshow starts"), true) -- Register dt.register_event("slideshow_music", "view-changed", diff --git a/contrib/transfer_hierarchy.lua b/contrib/transfer_hierarchy.lua index 15bea2a..6fdb2dc 100755 --- a/contrib/transfer_hierarchy.lua +++ b/contrib/transfer_hierarchy.lua @@ -149,7 +149,7 @@ end -- Widgets and business logic: BEGIN local sourceTextBox = darktable.new_widget("entry") { - tooltip = _("Lowest directory containing all selected images"), + tooltip = _("lowest directory containing all selected images"), editable = false } sourceTextBox.reset_callback = function() sourceTextBox.text = "" end diff --git a/contrib/video_ffmpeg.lua b/contrib/video_ffmpeg.lua index 7c902ed..63f40b5 100644 --- a/contrib/video_ffmpeg.lua +++ b/contrib/video_ffmpeg.lua @@ -293,7 +293,7 @@ else end local output_directory_chooser = dt.new_widget("file_chooser_button"){ - title = _("Select export path"), + title = _("select export path"), is_directory = true, tooltip =_("select the target directory for the timelapse. \nthe filename is created automatically."), value = string_pref_read("export_path", defaultVideoDir), From 06ab263e7494e46e54c015eff4434e5e6a57234e Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 29 Mar 2024 16:04:07 -0400 Subject: [PATCH 12/40] examples/gui_action.lua - changed nan to NaN --- examples/gui_action.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gui_action.lua b/examples/gui_action.lua index cbf33a4..205366e 100644 --- a/examples/gui_action.lua +++ b/examples/gui_action.lua @@ -90,7 +90,7 @@ dt.register_lib( label = "execute action", tooltip = "execute the action specified in the fields above", clicked_callback = function(_) - local sp = nan + local sp = NaN if wg.check.value then sp = wg.speed.text end wg.return_value.text = dt.gui.action(wg.action.text, wg.instance.value, wg.element.text, wg.effect.text, sp) end @@ -102,4 +102,4 @@ dt.register_lib( wg.return_value }, } - ) \ No newline at end of file + ) From e78e718769d1f290bc59e26143a0c5c2d5b98090 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Tue, 2 Apr 2024 17:54:10 -0400 Subject: [PATCH 13/40] tools/script_manager - allow for inclusion of directory/package specific libraries by adding "local" libraries to the search path to ensure they are found when needed. --- tools/script_manager.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/script_manager.lua b/tools/script_manager.lua index 7376ed4..bb96401 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -509,6 +509,25 @@ local function process_script_data(script_file) restore_log_level(old_log_level) end +local function ensure_lib_in_search_path(line) + local old_log_level = set_log_level(sm.log_level) + set_log_level(log.debug) + log.msg(log.debug, "line is " .. line) + if string.match(line, ds.sanitize_lua(dt.configuration.config_dir .. PS .. "lua/lib")) then + log.msg(log.debug, line .. " is already in search path, returning...") + return + end + local path = string.match(line, "(.+)/lib/.+lua") + log.msg(log.debug, "extracted path is " .. path) + log.msg(log.debug, "package.path is " .. package.path) + if not string.match(package.path, ds.sanitize_lua(path)) then + log.msg(log.debug, "path isn't in package.path, adding...") + package.path = package.path .. ";" .. path .. "/?.lua" + log.msg(log.debug, "new package.path is " .. package.path) + end + restore_log_level(old_log_level) +end + local function scan_scripts(script_dir) local old_log_level = set_log_level(sm.log_level) local script_count = 0 @@ -529,6 +548,8 @@ local function scan_scripts(script_dir) process_script_data(script_file) script_count = script_count + 1 end + else + ensure_lib_in_search_path(line) -- but let's make sure libraries can be found end end end From 125af63bda044b4b72625d2c35ade9634f95d037 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 6 Apr 2024 21:48:51 -0400 Subject: [PATCH 14/40] tools/script_manager - revert ensure_lib_in_path because of windows problems. --- tools/script_manager.lua | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tools/script_manager.lua b/tools/script_manager.lua index bb96401..31a7228 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -509,25 +509,6 @@ local function process_script_data(script_file) restore_log_level(old_log_level) end -local function ensure_lib_in_search_path(line) - local old_log_level = set_log_level(sm.log_level) - set_log_level(log.debug) - log.msg(log.debug, "line is " .. line) - if string.match(line, ds.sanitize_lua(dt.configuration.config_dir .. PS .. "lua/lib")) then - log.msg(log.debug, line .. " is already in search path, returning...") - return - end - local path = string.match(line, "(.+)/lib/.+lua") - log.msg(log.debug, "extracted path is " .. path) - log.msg(log.debug, "package.path is " .. package.path) - if not string.match(package.path, ds.sanitize_lua(path)) then - log.msg(log.debug, "path isn't in package.path, adding...") - package.path = package.path .. ";" .. path .. "/?.lua" - log.msg(log.debug, "new package.path is " .. package.path) - end - restore_log_level(old_log_level) -end - local function scan_scripts(script_dir) local old_log_level = set_log_level(sm.log_level) local script_count = 0 @@ -549,7 +530,7 @@ local function scan_scripts(script_dir) script_count = script_count + 1 end else - ensure_lib_in_search_path(line) -- but let's make sure libraries can be found + -- ensure_lib_in_search_path(line) -- but let's make sure libraries can be found end end end From 63d5aad465b6d1c537c48e73013c900805fff00e Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 8 Apr 2024 23:30:30 -0400 Subject: [PATCH 15/40] tools/script_manager reimplemented ensure_lib_in_path with a windows aware path specification --- tools/script_manager.lua | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/script_manager.lua b/tools/script_manager.lua index 31a7228..6dcd6b6 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -509,6 +509,35 @@ local function process_script_data(script_file) restore_log_level(old_log_level) end +local function ensure_lib_in_search_path(line) + local old_log_level = set_log_level(sm.log_level) + set_log_level(log.debug) + + log.msg(log.debug, "line is " .. line) + + if string.match(line, ds.sanitize_lua(dt.configuration.config_dir .. PS .. "lua" .. PS .. "lib")) then + log.msg(log.debug, line .. " is already in search path, returning...") + return + end + + local pattern = dt.configuration.running_os == "windows" and "(.+)\\lib\\.+lua" or "(.+)/lib/.+lua" + local path = string.match(line, pattern) + + log.msg(log.debug, "extracted path is " .. path) + log.msg(log.debug, "package.path is " .. package.path) + + if not string.match(package.path, ds.sanitize_lua(path)) then + + log.msg(log.debug, "path isn't in package.path, adding...") + + package.path = package.path .. ";" .. path .. "/?.lua" + + log.msg(log.debug, "new package.path is " .. package.path) + end + + restore_log_level(old_log_level) +end + local function scan_scripts(script_dir) local old_log_level = set_log_level(sm.log_level) local script_count = 0 @@ -530,7 +559,7 @@ local function scan_scripts(script_dir) script_count = script_count + 1 end else - -- ensure_lib_in_search_path(line) -- but let's make sure libraries can be found + ensure_lib_in_search_path(line) -- but let's make sure libraries can be found end end end From 52b4508e08474163c6e3f99ff8e5aa490f4d71b9 Mon Sep 17 00:00:00 2001 From: Christian Sueltrop Date: Mon, 6 May 2024 21:53:46 +0200 Subject: [PATCH 16/40] Added LUA script "passport_guide_germany.lua", which implements a cropping guide for passport photos according to the standards for German passport and ID card photos. --- contrib/passport_guide_germany.lua | 105 +++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 contrib/passport_guide_germany.lua diff --git a/contrib/passport_guide_germany.lua b/contrib/passport_guide_germany.lua new file mode 100644 index 0000000..f020ae7 --- /dev/null +++ b/contrib/passport_guide_germany.lua @@ -0,0 +1,105 @@ +--[[ + German passport photo cropping guide for darktable. + Derived from the passport cropping guide by Kåre Hampf. + + copyright (c) 2017 Kåre Hampf + copyright (c) 2024 Christian Sültrop + + 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 . +]] + +--[[ +PASSPORT CROPPING GUIDE +Guides for cropping passport and ID card ("Personalausweis") photos based on the "Passbild-Schablone" +from the German Federal Ministry of the Interior and Community. +(https://www.bmi.bund.de/SharedDocs/downloads/DE/veroeffentlichungen/themen/moderne-verwaltung/ausweise/passbild-schablone-erwachsene.pdf?__blob=publicationFile&v=3) + +INSTALLATION +* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory +* add the following line in the file $CONFIGDIR/luarc + require "passport_guide_germany" +* (optional) add the line: + "plugins/darkroom/clipping/extra_aspect_ratios/passport 35x45mm=45:35" + to $CONFIGDIR/darktablerc + +USAGE +* when using the cropping tool, select "Passport Photo Germany" as guide and if you added the line in yout rc + select "passport 35x45mm" as aspect +]] + +local dt = require "darktable" +local du = require "lib/dtutils" +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/") + +local function _(msgid) + return gettext.dgettext("passport_guide_germany", msgid) +end + +dt.guides.register_guide("Passport Photo Germany", +-- draw +function(cairo, x, y, width, height, zoom_scale) + local _width, _height + + -- get the max 35x45 rectangle + local aspect_ratio = 45 / 35 + if width * aspect_ratio > height then + _width = height / aspect_ratio + _height = height + else + _width = width + _height = width * aspect_ratio + end + + cairo:save() + + cairo:translate(x + (width - _width) / 2, y + (height - _height) / 2) + cairo:scale(_width / 35, _height / 45) + + -- the outer rectangle + cairo:rectangle( 0, 0, 35, 45) + + -- Nose position: The nose tip must be between these lines + cairo:draw_line(15.5, 45, 15.5, 13) + cairo:draw_line(35-15.5, 45, 35-15.5, 13) + + -- Face height + -- optimum face height: The upper end of the head should be between these lines + cairo:draw_line(0, 4, 35, 4) + cairo:draw_line(0, 8, 35, 8) + + -- tolerated face height: The upper end of the head must not be below this line + cairo:draw_line(6, 13, 30, 13) + + -- Eye area: The eyes must be between these lines + cairo:draw_line(0, 13, 35, 13) + cairo:draw_line(0, 23, 35, 23) + + -- Cheek line: The cheek must lie on this line + cairo:draw_line(9, 45-5, 27, 45-5) + + cairo:restore() +end, +-- gui +function() + return dt.new_widget("label"){label = _("Passport Photo Germany"), halign = "start"} +end +) + +-- 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 From cd3788f0129f0704e1191dc9667dc4e3333061e3 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Tue, 14 May 2024 22:39:22 -0400 Subject: [PATCH 17/40] all scripts - added bindtextdomain back in because 4.8 isn't ready to handle the translations yet. In 5.0 this will be removed and darktable will handle translating the strings. --- contrib/AutoGrouper.lua | 1 + contrib/CollectHelper.lua | 2 ++ contrib/HDRMerge.lua | 2 ++ contrib/LabelsToTags.lua | 2 ++ contrib/OpenInExplorer.lua | 2 ++ contrib/RL_out_sharp.lua | 2 ++ contrib/autostyle.lua | 1 + contrib/change_group_leader.lua | 2 ++ contrib/clear_GPS.lua | 1 + contrib/color_profile_manager.lua | 2 ++ contrib/copy_attach_detach_tags.lua | 2 ++ contrib/cr2hdr.lua | 2 ++ contrib/cycle_group_leader.lua | 2 ++ contrib/enfuseAdvanced.lua | 2 ++ contrib/exportLUT.lua | 2 ++ contrib/ext_editor.lua | 2 ++ contrib/face_recognition.lua | 2 ++ contrib/fujifilm_ratings.lua | 2 ++ contrib/geoJSON_export.lua | 2 ++ contrib/geoToolbox.lua | 2 ++ contrib/gimp.lua | 2 ++ contrib/gpx_export.lua | 2 ++ contrib/harmonic_armature_guide.lua | 2 ++ contrib/hif_group_leader.lua | 2 ++ contrib/hugin.lua | 2 ++ contrib/image_stack.lua | 2 ++ contrib/image_time.lua | 2 ++ contrib/jpg_group_leader.lua | 2 ++ contrib/kml_export.lua | 2 ++ contrib/passport_guide.lua | 2 ++ contrib/pdf_slideshow.lua | 2 ++ contrib/photils.lua | 2 ++ contrib/quicktag.lua | 2 ++ contrib/rate_group.lua | 2 ++ contrib/rename-tags.lua | 2 ++ contrib/rename_images.lua | 2 ++ contrib/select_non_existing.lua | 2 ++ contrib/select_untagged.lua | 2 ++ contrib/slideshowMusic.lua | 2 ++ contrib/transfer_hierarchy.lua | 2 ++ contrib/video_ffmpeg.lua | 2 ++ examples/api_version.lua | 2 ++ examples/darkroom_demo.lua | 6 ++++-- examples/gettextExample.lua | 2 ++ examples/hello_world.lua | 2 ++ examples/lighttable_demo.lua | 2 ++ examples/moduleExample.lua | 2 ++ examples/multi_os.lua | 2 ++ examples/panels_demo.lua | 4 +++- examples/preferenceExamples.lua | 2 ++ examples/printExamples.lua | 2 ++ examples/running_os.lua | 2 ++ official/copy_paste_metadata.lua | 2 ++ official/enfuse.lua | 2 ++ official/generate_image_txt.lua | 2 ++ official/import_filter_manager.lua | 2 ++ official/save_selection.lua | 2 ++ official/selection_to_pdf.lua | 2 ++ tools/executable_manager.lua | 2 ++ tools/script_manager.lua | 2 ++ 60 files changed, 120 insertions(+), 3 deletions(-) diff --git a/contrib/AutoGrouper.lua b/contrib/AutoGrouper.lua index decc9b9..4d8ced3 100644 --- a/contrib/AutoGrouper.lua +++ b/contrib/AutoGrouper.lua @@ -53,6 +53,7 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid 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) diff --git a/contrib/CollectHelper.lua b/contrib/CollectHelper.lua index 7e72d55..4e37f06 100644 --- a/contrib/CollectHelper.lua +++ b/contrib/CollectHelper.lua @@ -62,6 +62,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/HDRMerge.lua b/contrib/HDRMerge.lua index c4fd75b..f365ec4 100644 --- a/contrib/HDRMerge.lua +++ b/contrib/HDRMerge.lua @@ -69,6 +69,8 @@ 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 diff --git a/contrib/LabelsToTags.lua b/contrib/LabelsToTags.lua index bc3a212..c41c6ad 100644 --- a/contrib/LabelsToTags.lua +++ b/contrib/LabelsToTags.lua @@ -54,6 +54,8 @@ du.check_min_api_version("7.0.0", "LabelsToTags") local gettext = dt.gettext.gettext +gettext.bindtextdomain("LabelsToTags", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index 522e92b..d375af7 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -65,6 +65,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/RL_out_sharp.lua b/contrib/RL_out_sharp.lua index 44d961e..fcbfb5c 100644 --- a/contrib/RL_out_sharp.lua +++ b/contrib/RL_out_sharp.lua @@ -80,6 +80,8 @@ 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 diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index 4c1284e..426b76f 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -43,6 +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/") local function _(msgid) return gettext(msgid) diff --git a/contrib/change_group_leader.lua b/contrib/change_group_leader.lua index 0c70ac3..b70310d 100644 --- a/contrib/change_group_leader.lua +++ b/contrib/change_group_leader.lua @@ -40,6 +40,8 @@ local gettext = dt.gettext.gettext local MODULE = "change_group_leader" +gettext.bindtextdomain(MODULE, dt.configuration.config_dir .."/lua/locale/") + du.check_min_api_version("3.0.0", MODULE) -- return data structure for script_manager diff --git a/contrib/clear_GPS.lua b/contrib/clear_GPS.lua index 7e12e09..da91502 100644 --- a/contrib/clear_GPS.lua +++ b/contrib/clear_GPS.lua @@ -49,6 +49,7 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid 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 diff --git a/contrib/color_profile_manager.lua b/contrib/color_profile_manager.lua index b8ef21f..61b4028 100644 --- a/contrib/color_profile_manager.lua +++ b/contrib/color_profile_manager.lua @@ -54,6 +54,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index de78f13..fb9f487 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -53,6 +53,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua index 8b6f54d..04232c2 100644 --- a/contrib/cr2hdr.lua +++ b/contrib/cr2hdr.lua @@ -39,6 +39,8 @@ du.check_min_api_version("7.0.0", "cr2hdr") local gettext = dt.gettext.gettext +gettext.bindtextdomain("cr2hdr", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/cycle_group_leader.lua b/contrib/cycle_group_leader.lua index d2bf3da..1b8d684 100644 --- a/contrib/cycle_group_leader.lua +++ b/contrib/cycle_group_leader.lua @@ -71,6 +71,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h local gettext = dt.gettext.gettext +gettext.bindtextdomain("cycle_group_leader", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/enfuseAdvanced.lua b/contrib/enfuseAdvanced.lua index 8698f47..42b62b1 100644 --- a/contrib/enfuseAdvanced.lua +++ b/contrib/enfuseAdvanced.lua @@ -79,6 +79,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- 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 diff --git a/contrib/exportLUT.lua b/contrib/exportLUT.lua index 7cc5b63..4b04455 100644 --- a/contrib/exportLUT.lua +++ b/contrib/exportLUT.lua @@ -44,6 +44,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h local gettext = dt.gettext.gettext +gettext.bindtextdomain("exportLUT", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/ext_editor.lua b/contrib/ext_editor.lua index a6485d4..0650cd7 100644 --- a/contrib/ext_editor.lua +++ b/contrib/ext_editor.lua @@ -97,6 +97,8 @@ 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 diff --git a/contrib/face_recognition.lua b/contrib/face_recognition.lua index 8c23fa7..233b4b7 100644 --- a/contrib/face_recognition.lua +++ b/contrib/face_recognition.lua @@ -69,6 +69,8 @@ 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 diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index 8e19648..df73b46 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -39,6 +39,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index a6dfc51..18247ee 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -48,6 +48,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index ee895ca..33a6736 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -41,6 +41,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/gimp.lua b/contrib/gimp.lua index db1e48f..e8d2a4e 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -83,6 +83,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/gpx_export.lua b/contrib/gpx_export.lua index 6e29c8e..39bb519 100644 --- a/contrib/gpx_export.lua +++ b/contrib/gpx_export.lua @@ -38,6 +38,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/harmonic_armature_guide.lua b/contrib/harmonic_armature_guide.lua index 308c5ef..2e8afd8 100644 --- a/contrib/harmonic_armature_guide.lua +++ b/contrib/harmonic_armature_guide.lua @@ -36,6 +36,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/hif_group_leader.lua b/contrib/hif_group_leader.lua index c50d8b2..4c7fb61 100644 --- a/contrib/hif_group_leader.lua +++ b/contrib/hif_group_leader.lua @@ -75,6 +75,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h local gettext = dt.gettext.gettext +gettext.bindtextdomain("hif_group_leader", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 6621a18..451eb95 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -65,6 +65,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/image_stack.lua b/contrib/image_stack.lua index f6aad52..424b2fc 100644 --- a/contrib/image_stack.lua +++ b/contrib/image_stack.lua @@ -82,6 +82,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/image_time.lua b/contrib/image_time.lua index 1f0a7d2..81bce25 100644 --- a/contrib/image_time.lua +++ b/contrib/image_time.lua @@ -126,6 +126,8 @@ 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 diff --git a/contrib/jpg_group_leader.lua b/contrib/jpg_group_leader.lua index 63d9801..d8fd728 100644 --- a/contrib/jpg_group_leader.lua +++ b/contrib/jpg_group_leader.lua @@ -75,6 +75,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h local gettext = dt.gettext.gettext +gettext.bindtextdomain("jpg_group_leader", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 79ac384..25eb5d2 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -54,6 +54,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index 6e10183..0b233c6 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -41,6 +41,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/pdf_slideshow.lua b/contrib/pdf_slideshow.lua index adffffe..b6fb180 100644 --- a/contrib/pdf_slideshow.lua +++ b/contrib/pdf_slideshow.lua @@ -44,6 +44,8 @@ local df = require "lib/dtutils.file" local gettext = dt.gettext.gettext +gettext.bindtextdomain("pdf_slideshow", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/photils.lua b/contrib/photils.lua index f26998f..250915e 100644 --- a/contrib/photils.lua +++ b/contrib/photils.lua @@ -64,6 +64,8 @@ exporter.max_width = 224 -- helper functions +gettext.bindtextdomain("photils", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/quicktag.lua b/contrib/quicktag.lua index 82ccb53..1ab5f3f 100644 --- a/contrib/quicktag.lua +++ b/contrib/quicktag.lua @@ -64,6 +64,8 @@ qt.widget_table = {} local gettext = dt.gettext.gettext +gettext.bindtextdomain("quicktag", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/rate_group.lua b/contrib/rate_group.lua index 4b02d5e..d8e7130 100644 --- a/contrib/rate_group.lua +++ b/contrib/rate_group.lua @@ -46,6 +46,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/rename-tags.lua b/contrib/rename-tags.lua index 05d9491..90597bb 100644 --- a/contrib/rename-tags.lua +++ b/contrib/rename-tags.lua @@ -38,6 +38,8 @@ du.deprecated("contrib/rename-tags.lua","darktable release 4.0") local gettext = dt.gettext.gettext +gettext.bindtextdomain("rename-tags", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/rename_images.lua b/contrib/rename_images.lua index cf133cf..e63a1ab 100644 --- a/contrib/rename_images.lua +++ b/contrib/rename_images.lua @@ -48,6 +48,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/select_non_existing.lua b/contrib/select_non_existing.lua index 9536f03..a8225b1 100644 --- a/contrib/select_non_existing.lua +++ b/contrib/select_non_existing.lua @@ -31,6 +31,8 @@ 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/") + local function _(msgid) return gettext(msgid) end diff --git a/contrib/select_untagged.lua b/contrib/select_untagged.lua index bb887f2..97bf338 100644 --- a/contrib/select_untagged.lua +++ b/contrib/select_untagged.lua @@ -33,6 +33,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index abb7213..666402e 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -40,6 +40,8 @@ script_data.destroy_method = nil -- set to hide for libs since we can't destroy 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 diff --git a/contrib/transfer_hierarchy.lua b/contrib/transfer_hierarchy.lua index 6fdb2dc..574ef4b 100755 --- a/contrib/transfer_hierarchy.lua +++ b/contrib/transfer_hierarchy.lua @@ -96,6 +96,8 @@ 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 diff --git a/contrib/video_ffmpeg.lua b/contrib/video_ffmpeg.lua index 63f40b5..5c4369c 100644 --- a/contrib/video_ffmpeg.lua +++ b/contrib/video_ffmpeg.lua @@ -54,6 +54,8 @@ 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 diff --git a/examples/api_version.lua b/examples/api_version.lua index 49dc62a..d89416c 100644 --- a/examples/api_version.lua +++ b/examples/api_version.lua @@ -27,6 +27,8 @@ local dt = require "darktable" local gettext = dt.gettext.gettext +gettext.bindtextdomain("api_version", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/examples/darkroom_demo.lua b/examples/darkroom_demo.lua index bdd7f84..2a52888 100644 --- a/examples/darkroom_demo.lua +++ b/examples/darkroom_demo.lua @@ -40,7 +40,7 @@ local du = require "lib/dtutils" -- V E R S I O N C H E C K -- - - - - - - - - - - - - - - - - - - - - - - - -du.check_min_api_version("5.0.2", "darkroom_mode") -- darktable 3.0 +du.check_min_api_version("5.0.2", "darkroom_demo") -- darktable 3.0 -- script_manager integration to allow a script to be removed -- without restarting darktable @@ -52,7 +52,7 @@ end -- C O N S T A N T S -- - - - - - - - - - - - - - - - - - - - - - - - -local MODULE_NAME = "darkroom" +local MODULE_NAME = "darkroom_demo" local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - @@ -60,6 +60,8 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext +gettext.bindtextdomain("darkroom_demo", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/examples/gettextExample.lua b/examples/gettextExample.lua index f0f51e9..7c1e241 100644 --- a/examples/gettextExample.lua +++ b/examples/gettextExample.lua @@ -69,6 +69,8 @@ dt.print_error("Hello World!") local gettext = dt.gettext.gettext +gettext.bindtextdomain("gettextExample", dt.configuration.config_dir .."/lua/locale/") + -- Translate a string using the darktable textdomain dt.print_error(gettext("image")) diff --git a/examples/hello_world.lua b/examples/hello_world.lua index 3839ebd..75e52ca 100644 --- a/examples/hello_world.lua +++ b/examples/hello_world.lua @@ -35,6 +35,8 @@ du.check_min_api_version("2.0.0", "hello_world") local gettext = dt.gettext.gettext +gettext.bindtextdomain("hello_world", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/examples/lighttable_demo.lua b/examples/lighttable_demo.lua index e1e0732..6047e88 100644 --- a/examples/lighttable_demo.lua +++ b/examples/lighttable_demo.lua @@ -61,6 +61,8 @@ end -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext +gettext.bindtextdomain("lighttable_demo", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index 5674132..06ba003 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -49,6 +49,8 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- https://www.darktable.org/lua-api/index.html#darktable_gettext local gettext = dt.gettext.gettext +gettext.bindtextdomain("moduleExample", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/examples/multi_os.lua b/examples/multi_os.lua index 5c084cf..8d8758a 100644 --- a/examples/multi_os.lua +++ b/examples/multi_os.lua @@ -72,6 +72,8 @@ local dtsys = require "lib/dtutils.system" -- system utilities local gettext = dt.gettext.gettext +gettext.bindtextdomain("multi_os", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/examples/panels_demo.lua b/examples/panels_demo.lua index 971d69b..ad7c924 100644 --- a/examples/panels_demo.lua +++ b/examples/panels_demo.lua @@ -53,7 +53,7 @@ end -- C O N S T A N T S -- - - - - - - - - - - - - - - - - - - - - - - - -local MODULE_NAME = "panels" +local MODULE_NAME = "panels_demo" local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - @@ -61,6 +61,8 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext +gettext.bindtextdomain("panels_demo", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/examples/preferenceExamples.lua b/examples/preferenceExamples.lua index aa8eae2..c9040d8 100644 --- a/examples/preferenceExamples.lua +++ b/examples/preferenceExamples.lua @@ -28,6 +28,8 @@ local du = require "lib/dtutils" local gettext = dt.gettext.gettext +gettext.bindtextdomain("preferenceExamples", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/examples/printExamples.lua b/examples/printExamples.lua index b7be20c..c68ddd5 100644 --- a/examples/printExamples.lua +++ b/examples/printExamples.lua @@ -28,6 +28,8 @@ du.check_min_api_version("5.0.0", "printExamples") local gettext = dt.gettext.gettext +gettext.bindtextdomain("printExamples", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/examples/running_os.lua b/examples/running_os.lua index 2c68bf0..6a71095 100644 --- a/examples/running_os.lua +++ b/examples/running_os.lua @@ -34,6 +34,8 @@ du.check_min_api_version("5.0.0", "running_os") local gettext = dt.gettext.gettext +gettext.bindtextdomain("running_os", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/official/copy_paste_metadata.lua b/official/copy_paste_metadata.lua index 3afb953..a44270e 100644 --- a/official/copy_paste_metadata.lua +++ b/official/copy_paste_metadata.lua @@ -58,6 +58,8 @@ local publisher = "" local rights = "" local tags = {} +gettext.bindtextdomain("copy_paste_metadata", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/official/enfuse.lua b/official/enfuse.lua index 74999ad..9aa5815 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -57,6 +57,8 @@ enf.event_registered = false enf.module_installed = false enf.lib_widgets = {} +gettext.bindtextdomain("enfuse", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end diff --git a/official/generate_image_txt.lua b/official/generate_image_txt.lua index 3eeafbe..c955988 100644 --- a/official/generate_image_txt.lua +++ b/official/generate_image_txt.lua @@ -40,6 +40,8 @@ require "darktable.debug" local gettext = dt.gettext.gettext +gettext.bindtextdomain("generate_image_txt", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/official/import_filter_manager.lua b/official/import_filter_manager.lua index 7a81f2c..05bc45d 100644 --- a/official/import_filter_manager.lua +++ b/official/import_filter_manager.lua @@ -34,6 +34,8 @@ local dt = require "darktable" local gettext = dt.gettext.gettext +gettext.bindtextdomain("import_filter_manager", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/official/save_selection.lua b/official/save_selection.lua index 22841a9..f37ad0b 100644 --- a/official/save_selection.lua +++ b/official/save_selection.lua @@ -40,6 +40,8 @@ du.check_min_api_version("7.0.0", "save_selection") local gettext = dt.gettext.gettext +gettext.bindtextdomain("save_selection", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 6806313..116f0d7 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -40,6 +40,8 @@ du.check_min_api_version("7.0.0", "selection_to_pdf") local gettext = dt.gettext.gettext +gettext.bindtextdomain("selection_to_pdf", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index 7055741..4865974 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -55,6 +55,8 @@ exec_man.event_registered = false -- F U N C T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - - - - - +gettext.bindtextdomain("executable_manager", dt.configuration.config_dir .."/lua/locale/") + local function _(msg) return gettext(msg) end diff --git a/tools/script_manager.lua b/tools/script_manager.lua index a7a5683..22997dd 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -60,6 +60,8 @@ local debug = require "darktable.debug" local gettext = dt.gettext.gettext +gettext.bindtextdomain("script_manager", dt.configuration.config_dir .."/lua/locale/") + local function _(msgid) return gettext(msgid) end From 55e68f8cd0a4378c5814b988a3d533a1dc548dcf Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 15 May 2024 21:23:13 -0400 Subject: [PATCH 18/40] 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. --- contrib/AutoGrouper.lua | 443 ++++++------- contrib/CollectHelper.lua | 513 +++++++-------- contrib/HDRMerge.lua | 967 ++++++++++++++-------------- contrib/LabelsToTags.lua | 11 +- contrib/OpenInExplorer.lua | 481 +++++++------- contrib/RL_out_sharp.lua | 25 +- contrib/autostyle.lua | 9 +- contrib/change_group_leader.lua | 17 +- contrib/clear_GPS.lua | 22 +- contrib/color_profile_manager.lua | 9 +- contrib/copy_attach_detach_tags.lua | 19 +- contrib/cr2hdr.lua | 11 +- contrib/cycle_group_leader.lua | 33 +- contrib/enfuseAdvanced.lua | 25 +- contrib/exportLUT.lua | 23 +- contrib/ext_editor.lua | 25 +- contrib/face_recognition.lua | 19 +- contrib/fujifilm_dynamic_range.lua | 14 + contrib/fujifilm_ratings.lua | 19 +- contrib/geoJSON_export.lua | 19 +- contrib/geoToolbox.lua | 19 +- contrib/gimp.lua | 19 +- contrib/gpx_export.lua | 27 +- contrib/harmonic_armature_guide.lua | 26 +- contrib/hif_group_leader.lua | 31 +- contrib/hugin.lua | 19 +- contrib/image_stack.lua | 19 +- contrib/image_time.lua | 19 +- contrib/jpg_group_leader.lua | 31 +- contrib/kml_export.lua | 19 +- contrib/passport_guide.lua | 24 +- contrib/passport_guide_germany.lua | 24 +- contrib/pdf_slideshow.lua | 11 +- contrib/photils.lua | 21 +- contrib/quicktag.lua | 23 +- contrib/rate_group.lua | 9 +- contrib/rename-tags.lua | 11 +- contrib/rename_images.lua | 9 +- contrib/select_non_existing.lua | 10 +- contrib/select_untagged.lua | 19 +- contrib/slideshowMusic.lua | 19 +- contrib/transfer_hierarchy.lua | 19 +- contrib/video_ffmpeg.lua | 22 +- examples/api_version.lua | 10 +- examples/darkroom_demo.lua | 10 +- examples/gettextExample.lua | 10 +- examples/gui_action.lua | 38 ++ examples/hello_world.lua | 10 +- examples/lighttable_demo.lua | 10 +- examples/moduleExample.lua | 25 +- examples/multi_os.lua | 10 +- examples/panels_demo.lua | 10 +- examples/preferenceExamples.lua | 19 +- examples/printExamples.lua | 10 +- examples/running_os.lua | 10 +- examples/x-touch.lua | 357 +++++----- official/check_for_updates.lua | 15 + official/copy_paste_metadata.lua | 19 +- official/delete_long_tags.lua | 15 + official/delete_unused_tags.lua | 15 + official/enfuse.lua | 19 +- official/generate_image_txt.lua | 9 +- official/image_path_in_ui.lua | 15 + official/import_filter_manager.lua | 24 +- official/import_filters.lua | 30 + official/save_selection.lua | 11 +- official/selection_to_pdf.lua | 11 +- tools/executable_manager.lua | 23 +- tools/get_lib_manpages.lua | 16 + tools/get_libdoc.lua | 16 + 70 files changed, 2311 insertions(+), 1610 deletions(-) diff --git a/contrib/AutoGrouper.lua b/contrib/AutoGrouper.lua index 4d8ced3..90f65db 100644 --- a/contrib/AutoGrouper.lua +++ b/contrib/AutoGrouper.lua @@ -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 . -]] - ---[[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 . +]] + +--[[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 diff --git a/contrib/CollectHelper.lua b/contrib/CollectHelper.lua index 4e37f06..ca76d85 100644 --- a/contrib/CollectHelper.lua +++ b/contrib/CollectHelper.lua @@ -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 . -]] - ---[[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 . +]] + +--[[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 diff --git a/contrib/HDRMerge.lua b/contrib/HDRMerge.lua index f365ec4..5ab1bee 100644 --- a/contrib/HDRMerge.lua +++ b/contrib/HDRMerge.lua @@ -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 . -]] - ---[[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 . +]] + +--[[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 \ No newline at end of file diff --git a/contrib/LabelsToTags.lua b/contrib/LabelsToTags.lua index c41c6ad..6046f9c 100644 --- a/contrib/LabelsToTags.lua +++ b/contrib/LabelsToTags.lua @@ -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 diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index d375af7..dba04d0 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -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 . -]] - ---[[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 . +]] + +--[[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 diff --git a/contrib/RL_out_sharp.lua b/contrib/RL_out_sharp.lua index fcbfb5c..aa64b3f 100644 --- a/contrib/RL_out_sharp.lua +++ b/contrib/RL_out_sharp.lua @@ -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 ", + 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") diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index 426b76f..a12cd0a 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -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 ", + 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 diff --git a/contrib/change_group_leader.lua b/contrib/change_group_leader.lua index b70310d..202f3f6 100644 --- a/contrib/change_group_leader.lua +++ b/contrib/change_group_leader.lua @@ -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 ", + 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 = {} diff --git a/contrib/clear_GPS.lua b/contrib/clear_GPS.lua index da91502..f90d8b8 100644 --- a/contrib/clear_GPS.lua +++ b/contrib/clear_GPS.lua @@ -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 ", + 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 diff --git a/contrib/color_profile_manager.lua b/contrib/color_profile_manager.lua index 61b4028..ed08317 100644 --- a/contrib/color_profile_manager.lua +++ b/contrib/color_profile_manager.lua @@ -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 ", + 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" diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index fb9f487..6d6c470 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -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 diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua index 04232c2..a091a8f 100644 --- a/contrib/cr2hdr.lua +++ b/contrib/cr2hdr.lua @@ -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 ", + 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 diff --git a/contrib/cycle_group_leader.lua b/contrib/cycle_group_leader.lua index 1b8d684..30ed0b8 100644 --- a/contrib/cycle_group_leader.lua +++ b/contrib/cycle_group_leader.lua @@ -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 @@ -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 ", + 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 -- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/enfuseAdvanced.lua b/contrib/enfuseAdvanced.lua index 42b62b1..b5ec586 100644 --- a/contrib/enfuseAdvanced.lua +++ b/contrib/enfuseAdvanced.lua @@ -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', diff --git a/contrib/exportLUT.lua b/contrib/exportLUT.lua index 4b04455..0a578a2 100644 --- a/contrib/exportLUT.lua +++ b/contrib/exportLUT.lua @@ -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 = {} diff --git a/contrib/ext_editor.lua b/contrib/ext_editor.lua index 0650cd7..592550b 100644 --- a/contrib/ext_editor.lua +++ b/contrib/ext_editor.lua @@ -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 diff --git a/contrib/face_recognition.lua b/contrib/face_recognition.lua index 233b4b7..0f6183b 100644 --- a/contrib/face_recognition.lua +++ b/contrib/face_recognition.lua @@ -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 = "" diff --git a/contrib/fujifilm_dynamic_range.lua b/contrib/fujifilm_dynamic_range.lua index a6d8087..d373d13 100644 --- a/contrib/fujifilm_dynamic_range.lua +++ b/contrib/fujifilm_dynamic_range.lua @@ -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 ", + 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 diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index df73b46..f9bb1c8 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -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 ", + 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")) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 18247ee..695976a 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -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 diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index 33a6736..83caa13 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -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 diff --git a/contrib/gimp.lua b/contrib/gimp.lua index e8d2a4e..9a60cad 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -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 ", + 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 diff --git a/contrib/gpx_export.lua b/contrib/gpx_export.lua index 39bb519..b3d9301 100644 --- a/contrib/gpx_export.lua +++ b/contrib/gpx_export.lua @@ -25,25 +25,32 @@ For each source folder, a separate 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 diff --git a/contrib/harmonic_armature_guide.lua b/contrib/harmonic_armature_guide.lua index 2e8afd8..fd16f2b 100644 --- a/contrib/harmonic_armature_guide.lua +++ b/contrib/harmonic_armature_guide.lua @@ -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 -) \ No newline at end of file +) + +local function destroy() + -- nothing to destroy +end + +script_data.destroy = destroy + +return script_data diff --git a/contrib/hif_group_leader.lua b/contrib/hif_group_leader.lua index 4c7fb61..26eaf48 100644 --- a/contrib/hif_group_leader.lua +++ b/contrib/hif_group_leader.lua @@ -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 ", + 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 diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 451eb95..f209c0c 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -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) diff --git a/contrib/image_stack.lua b/contrib/image_stack.lua index 424b2fc..c63ff16 100644 --- a/contrib/image_stack.lua +++ b/contrib/image_stack.lua @@ -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 ", + 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 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/image_time.lua b/contrib/image_time.lua index 81bce25..f20e500 100644 --- a/contrib/image_time.lua +++ b/contrib/image_time.lua @@ -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 ", + 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 diff --git a/contrib/jpg_group_leader.lua b/contrib/jpg_group_leader.lua index d8fd728..6201b39 100644 --- a/contrib/jpg_group_leader.lua +++ b/contrib/jpg_group_leader.lua @@ -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 ", + 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 diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 25eb5d2..ec1aa04 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -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 diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index 0b233c6..246e737 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -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 diff --git a/contrib/passport_guide_germany.lua b/contrib/passport_guide_germany.lua index f020ae7..735c092 100644 --- a/contrib/passport_guide_germany.lua +++ b/contrib/passport_guide_germany.lua @@ -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 diff --git a/contrib/pdf_slideshow.lua b/contrib/pdf_slideshow.lua index b6fb180..911493f 100644 --- a/contrib/pdf_slideshow.lua +++ b/contrib/pdf_slideshow.lua @@ -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 diff --git a/contrib/photils.lua b/contrib/photils.lua index 250915e..b06dc6e 100644 --- a/contrib/photils.lua +++ b/contrib/photils.lua @@ -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 diff --git a/contrib/quicktag.lua b/contrib/quicktag.lua index 1ab5f3f..7a17fa1 100644 --- a/contrib/quicktag.lua +++ b/contrib/quicktag.lua @@ -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", diff --git a/contrib/rate_group.lua b/contrib/rate_group.lua index d8e7130..6455f6d 100644 --- a/contrib/rate_group.lua +++ b/contrib/rate_group.lua @@ -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 diff --git a/contrib/rename-tags.lua b/contrib/rename-tags.lua index 90597bb..3b84eba 100644 --- a/contrib/rename-tags.lua +++ b/contrib/rename-tags.lua @@ -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 diff --git a/contrib/rename_images.lua b/contrib/rename_images.lua index e63a1ab..d3ed982 100644 --- a/contrib/rename_images.lua +++ b/contrib/rename_images.lua @@ -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 ", + 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 diff --git a/contrib/select_non_existing.lua b/contrib/select_non_existing.lua index a8225b1..f691589 100644 --- a/contrib/select_non_existing.lua +++ b/contrib/select_non_existing.lua @@ -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 \ No newline at end of file diff --git a/contrib/select_untagged.lua b/contrib/select_untagged.lua index 97bf338..2aef97e 100644 --- a/contrib/select_untagged.lua +++ b/contrib/select_untagged.lua @@ -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 diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index 666402e..c5b9d8c 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -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 diff --git a/contrib/transfer_hierarchy.lua b/contrib/transfer_hierarchy.lua index 574ef4b..96b18e4 100755 --- a/contrib/transfer_hierarchy.lua +++ b/contrib/transfer_hierarchy.lua @@ -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 diff --git a/contrib/video_ffmpeg.lua b/contrib/video_ffmpeg.lua index 5c4369c..4203188 100644 --- a/contrib/video_ffmpeg.lua +++ b/contrib/video_ffmpeg.lua @@ -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) diff --git a/examples/api_version.lua b/examples/api_version.lua index d89416c..d54b788 100644 --- a/examples/api_version.lua +++ b/examples/api_version.lua @@ -27,7 +27,7 @@ local dt = require "darktable" local gettext = dt.gettext.gettext -gettext.bindtextdomain("api_version", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("api_version", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -47,6 +47,14 @@ dt.print(string.format(_("API version: %s"), result)) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "api_version", + purpose = _("display api_version example"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/api_version" +} + script_data.destroy = destroy return script_data diff --git a/examples/darkroom_demo.lua b/examples/darkroom_demo.lua index 2a52888..802df74 100644 --- a/examples/darkroom_demo.lua +++ b/examples/darkroom_demo.lua @@ -60,7 +60,7 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext -gettext.bindtextdomain("darkroom_demo", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("darkroom_demo", dt.configuration.config_dir .."/lua/locale/") local function _(msgid) return gettext(msgid) @@ -117,6 +117,14 @@ dt.gui.current_view(current_view) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "darkroom_demo", + purpose = _("example demonstrating how to control image display in darkroom mode"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/darkroom_demo" +} + script_data.destroy = destroy return script_data diff --git a/examples/gettextExample.lua b/examples/gettextExample.lua index 7c1e241..20d5db4 100644 --- a/examples/gettextExample.lua +++ b/examples/gettextExample.lua @@ -69,7 +69,7 @@ dt.print_error("Hello World!") local gettext = dt.gettext.gettext -gettext.bindtextdomain("gettextExample", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("gettextExample", dt.configuration.config_dir .."/lua/locale/") -- Translate a string using the darktable textdomain dt.print_error(gettext("image")) @@ -86,6 +86,14 @@ dt.print_error(_("hello world!")) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "gettextExample", + purpose = _("example of how translations works"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/gettextExample" +} + script_data.destroy = destroy return script_data diff --git a/examples/gui_action.lua b/examples/gui_action.lua index 205366e..3bff94b 100644 --- a/examples/gui_action.lua +++ b/examples/gui_action.lua @@ -4,6 +4,29 @@ local NaN = 0/0 local wg = {} +local gettext = dt.gettext.gettext +dt.gettext.bindtextdomain("gui_action", 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 = "gui_action", + purpose = _("example of how to use darktable.gui.action() calls"), + author = "Diederik ter Rahe", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/gui_action" +} + +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 + wg.action = dt.new_widget("entry"){ text = "lib/filter/view", placeholder = "action path", @@ -103,3 +126,18 @@ dt.register_lib( }, } ) + +local function restart() + dt.gui.libs["execute_action"].visible = true +end + +local function destroy() + dt.gui.libs["execute_action"].visible = false +end + +script_data.destroy = destroy +script_data.destroy_method = "hide" +script_data.restart = restart +script_data.show = restart + +return script_data diff --git a/examples/hello_world.lua b/examples/hello_world.lua index 75e52ca..e64c4f9 100644 --- a/examples/hello_world.lua +++ b/examples/hello_world.lua @@ -35,7 +35,7 @@ du.check_min_api_version("2.0.0", "hello_world") local gettext = dt.gettext.gettext -gettext.bindtextdomain("hello_world", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("hello_world", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -53,6 +53,14 @@ dt.print(_("hello, world")) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "hello_world", + purpose = _("example of how to print a message to the screen"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/hello_world" +} + script_data.destroy = destroy return script_data diff --git a/examples/lighttable_demo.lua b/examples/lighttable_demo.lua index 6047e88..d897ff8 100644 --- a/examples/lighttable_demo.lua +++ b/examples/lighttable_demo.lua @@ -61,7 +61,7 @@ end -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext -gettext.bindtextdomain("lighttable_demo", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("lighttable_demo", dt.configuration.config_dir .."/lua/locale/") local function _(msgid) return gettext(msgid) @@ -216,6 +216,14 @@ current_sort_order = dt.gui.libs.filter.sort_order(current_sort_order) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "lighttable_demo", + purpose = _("example demonstrating how to control lighttable display modes"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/lighttable_demo" +} + script_data.destroy = destroy return script_data diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index 06ba003..edf4815 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -35,10 +35,26 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "moduleExample") +-- https://www.darktable.org/lua-api/index.html#darktable_gettext +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("moduleExample", 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 = "moduleExample", + purpose = _("example of how to create a lighttable module"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/moduleExample" +} + 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 @@ -46,15 +62,6 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- translation --- https://www.darktable.org/lua-api/index.html#darktable_gettext -local gettext = dt.gettext.gettext - -gettext.bindtextdomain("moduleExample", dt.configuration.config_dir .."/lua/locale/") - -local function _(msgid) - return gettext(msgid) -end - -- declare a local namespace and a couple of variables we'll need to install the module local mE = {} mE.widgets = {} diff --git a/examples/multi_os.lua b/examples/multi_os.lua index 8d8758a..f27cc9e 100644 --- a/examples/multi_os.lua +++ b/examples/multi_os.lua @@ -72,7 +72,7 @@ local dtsys = require "lib/dtutils.system" -- system utilities local gettext = dt.gettext.gettext -gettext.bindtextdomain("multi_os", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("multi_os", dt.configuration.config_dir .."/lua/locale/") local function _(msgid) return gettext(msgid) @@ -260,6 +260,14 @@ dt.register_event( ]] local script_data = {} + +script_data.metadata = { + name = "multi_os", + purpose = _("example module thet runs on different operating systems"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/multi_os" +} + script_data.destroy = destroy return script_data diff --git a/examples/panels_demo.lua b/examples/panels_demo.lua index ad7c924..36e31e3 100644 --- a/examples/panels_demo.lua +++ b/examples/panels_demo.lua @@ -61,7 +61,7 @@ local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext.gettext -gettext.bindtextdomain("panels_demo", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("panels_demo", dt.configuration.config_dir .."/lua/locale/") local function _(msgid) return gettext(msgid) @@ -146,6 +146,14 @@ end -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "panels_demo", + purpose = _("example demonstrating how to contol panel visibility"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/panels_demo" +} + script_data.destroy = destroy return script_data diff --git a/examples/preferenceExamples.lua b/examples/preferenceExamples.lua index c9040d8..e3721ca 100644 --- a/examples/preferenceExamples.lua +++ b/examples/preferenceExamples.lua @@ -28,12 +28,21 @@ local du = require "lib/dtutils" local gettext = dt.gettext.gettext -gettext.bindtextdomain("preferenceExamples", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("preferenceExamples", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) end +local script_data = {} + +script_data.metadata = { + name = "preferenceExamples", + purpose = _("example to show the different preference types that are possible"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/preferenceExamples" +} + du.check_min_api_version("2.0.1", "preferenceExamples") @@ -92,3 +101,11 @@ dt.preferences.register("preferenceExamples", -- script: This is a string "Enum 1", -- default "Enum 1", "Enum 2") -- values + +local function destroy() + -- nothing to destroy +end + +script_data.destroy = destroy + +return script_data diff --git a/examples/printExamples.lua b/examples/printExamples.lua index c68ddd5..23614c5 100644 --- a/examples/printExamples.lua +++ b/examples/printExamples.lua @@ -28,7 +28,7 @@ du.check_min_api_version("5.0.0", "printExamples") local gettext = dt.gettext.gettext -gettext.bindtextdomain("printExamples", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("printExamples", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -58,6 +58,14 @@ dt.print_log("print log") -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "printExamples", + purpose = _("example showing the different types of printing messages"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/printExamples" +} + script_data.destroy = destroy return script_data diff --git a/examples/running_os.lua b/examples/running_os.lua index 6a71095..1e61cb8 100644 --- a/examples/running_os.lua +++ b/examples/running_os.lua @@ -34,7 +34,7 @@ du.check_min_api_version("5.0.0", "running_os") local gettext = dt.gettext.gettext -gettext.bindtextdomain("running_os", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("running_os", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -52,6 +52,14 @@ dt.print(string.format(_("you are running: %s"), dt.configuration.running_os)) -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} + +script_data.metadata = { + name = "running_os", + purpose = _("example of how to determine the operating system being used"), + author = "Tobias Jakobs", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/running_os" +} + script_data.destroy = destroy return script_data diff --git a/examples/x-touch.lua b/examples/x-touch.lua index 73ed112..dd8dd2e 100644 --- a/examples/x-touch.lua +++ b/examples/x-touch.lua @@ -1,163 +1,194 @@ ---[[ - This file is part of darktable, - copyright (c) 2023 Diederik ter Rahe - - 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 . -]] ---[[ -X-Touch Mini flexible encoder shortcuts - -This script will create virtual sliders that are mapped dynamically to -the most relevant sliders for the currently focused processing module. -Tailored modules are color zones, tone equalizer, color calibration and -mask manager properties. The script can easily be amended for other -devices or personal preferences. Virtual "toggle" buttons can be created -as well, that dynamically change meaning depending on current status. - -USAGE -* require this script from your main lua file -* restart darktable -* create shortcuts for each of the encoders on the x-touch mini - to a virtual slider under lua/x-touch - or import the following shortcutsrc file in the shortcuts dialog/preferences tab: - -None;midi:CC1=lua/x-touch/knob 1 -None;midi:CC2=lua/x-touch/knob 2 -None;midi:CC3=lua/x-touch/knob 3 -None;midi:CC4=lua/x-touch/knob 4 -None;midi:CC5=lua/x-touch/knob 5 -None;midi:CC6=lua/x-touch/knob 6 -None;midi:CC7=lua/x-touch/knob 7 -None;midi:CC8=lua/x-touch/knob 8 -midi:E0=global/modifiers -midi:F0=global/modifiers;ctrl -midi:F#0=global/modifiers;alt -midi:G#-1=iop/blend/tools/show and edit mask elements -midi:A-1=iop/colorzones;focus -midi:A#-1=iop/toneequal;focus -midi:B-1=iop/colorbalancergb;focus -midi:C0=iop/channelmixerrgb;focus -]] - -local dt = require "darktable" -local du = require "lib/dtutils" - -du.check_min_api_version("9.2.0", "x-touch") - --- set up 8 mimic sliders with the same function -for k = 1,8 do - dt.gui.mimic("slider", "knob ".. k, - function(action, element, effect, size) - -- take the number from the mimic name - local k = tonumber(action:sub(-1)) - - -- only operate in darkroom; return NAN otherwise - if dt.gui.current_view() ~= dt.gui.views.darkroom then - return 0/0 - end - - local maskval = 0/0 - if k < 8 then - -- first try if the mask slider at that position is active - local s = { "opacity", - "size", - "feather", - "hardness", - "rotation", - "curvature", - "compression" } - maskval = dt.gui.action("lib/masks/properties/" .. s[k], - element, effect, size) - end - -- if a value different from NAN is returned, the slider was active - if maskval == maskval then - return maskval - - -- try if colorzones module is focused; if so select element of graph - elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then - which = "iop/colorzones/graph" - local e = { "red", - "orange", - "yellow", - "green", - "aqua", - "blue", - "purple", - "magenta" } - element = e[k] - - - -- if the sigmoid rgb primaries is focused, - -- check sliders - elseif dt.gui.action("iop/sigmoid", "focus") ~= 0 and k <8 then - local e = { "red attenuation", "red rotation", "green attenuation", "green rotation", "blue attenuation", "blue rotation", "recover purity" } - which = "iop/sigmoid/primaries/"..e[k] - - -- if the rgb primaries is focused, - -- check sliders - elseif dt.gui.action("iop/primaries", "focus") ~= 0 and k >=1 then - local e = { "red hue", "red purity", "green hue", "green purity", "blue hue", "blue purity", "tint hue", "tint purity" } - which = "iop/primaries/" ..e[k] - - -- if the tone equalizer is focused, - -- select one of the sliders in the "simple" tab - elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then - which ="iop/toneequal/simple/"..(k-9).." EV" - - -- if color calibration is focused, - -- the last 4 knobs are sent there - elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0 - and k >= 5 then - -- knob 5 selects the active tab; pressing it resets to CAT - if k == 5 then - which = "iop/channelmixerrgb/page" - element = "CAT" - -- since the tab action is not a slider, - -- the effects need to be translated - if effect == "up" then effect = "next" - elseif effect == "down" then effect = "previous" - else effect = "activate" - end - else - -- knobs 6, 7 and 8 are for the three color sliders on each tab - which = "iop/focus/sliders" - local e = { "1st", - "2nd", - "3rd" } - element = e[k - 5] - end - - -- the 4th knob is contrast; - -- either colorbalance if it is focused, or filmic - elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0 - and k == 4 then - which = "iop/colorbalancergb/contrast" - - -- in all other cases use a default selection - else - local s = { "iop/exposure/exposure", - "iop/filmicrgb/white relative exposure", - "iop/filmicrgb/black relative exposure", - "iop/filmicrgb/contrast", - "iop/crop/left", - "iop/crop/right", - "iop/crop/top", - "iop/crop/bottom" } - which = s[k] - end - - -- now pass the element/effect/size to the selected slider - return dt.gui.action(which, element, effect, size) - end) -end +--[[ + This file is part of darktable, + copyright (c) 2023 Diederik ter Rahe + + 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 . +]] +--[[ +X-Touch Mini flexible encoder shortcuts + +This script will create virtual sliders that are mapped dynamically to +the most relevant sliders for the currently focused processing module. +Tailored modules are color zones, tone equalizer, color calibration and +mask manager properties. The script can easily be amended for other +devices or personal preferences. Virtual "toggle" buttons can be created +as well, that dynamically change meaning depending on current status. + +USAGE +* require this script from your main lua file +* restart darktable +* create shortcuts for each of the encoders on the x-touch mini + to a virtual slider under lua/x-touch + or import the following shortcutsrc file in the shortcuts dialog/preferences tab: + +None;midi:CC1=lua/x-touch/knob 1 +None;midi:CC2=lua/x-touch/knob 2 +None;midi:CC3=lua/x-touch/knob 3 +None;midi:CC4=lua/x-touch/knob 4 +None;midi:CC5=lua/x-touch/knob 5 +None;midi:CC6=lua/x-touch/knob 6 +None;midi:CC7=lua/x-touch/knob 7 +None;midi:CC8=lua/x-touch/knob 8 +midi:E0=global/modifiers +midi:F0=global/modifiers;ctrl +midi:F#0=global/modifiers;alt +midi:G#-1=iop/blend/tools/show and edit mask elements +midi:A-1=iop/colorzones;focus +midi:A#-1=iop/toneequal;focus +midi:B-1=iop/colorbalancergb;focus +midi:C0=iop/channelmixerrgb;focus +]] + +local dt = require "darktable" +local du = require "lib/dtutils" + +du.check_min_api_version("9.2.0", "x-touch") + +local gettext = dt.gettext.gettext +dt.gettext.bindtextdomain("gui_action", 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 = "x-touch", + purpose = _("example of how to control an x-touch midi device"), + author = "Diederik ter Rahe", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/examples/x-touch" +} + +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 + +-- set up 8 mimic sliders with the same function +for k = 1,8 do + dt.gui.mimic("slider", "knob ".. k, + function(action, element, effect, size) + -- take the number from the mimic name + local k = tonumber(action:sub(-1)) + + -- only operate in darkroom; return NAN otherwise + if dt.gui.current_view() ~= dt.gui.views.darkroom then + return 0/0 + end + + local maskval = 0/0 + if k < 8 then + -- first try if the mask slider at that position is active + local s = { "opacity", + "size", + "feather", + "hardness", + "rotation", + "curvature", + "compression" } + maskval = dt.gui.action("lib/masks/properties/" .. s[k], + element, effect, size) + end + -- if a value different from NAN is returned, the slider was active + if maskval == maskval then + return maskval + + -- try if colorzones module is focused; if so select element of graph + elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then + which = "iop/colorzones/graph" + local e = { "red", + "orange", + "yellow", + "green", + "aqua", + "blue", + "purple", + "magenta" } + element = e[k] + + + -- if the sigmoid rgb primaries is focused, + -- check sliders + elseif dt.gui.action("iop/sigmoid", "focus") ~= 0 and k <8 then + local e = { "red attenuation", "red rotation", "green attenuation", "green rotation", "blue attenuation", "blue rotation", "recover purity" } + which = "iop/sigmoid/primaries/"..e[k] + + -- if the rgb primaries is focused, + -- check sliders + elseif dt.gui.action("iop/primaries", "focus") ~= 0 and k >=1 then + local e = { "red hue", "red purity", "green hue", "green purity", "blue hue", "blue purity", "tint hue", "tint purity" } + which = "iop/primaries/" ..e[k] + + -- if the tone equalizer is focused, + -- select one of the sliders in the "simple" tab + elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then + which ="iop/toneequal/simple/"..(k-9).." EV" + + -- if color calibration is focused, + -- the last 4 knobs are sent there + elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0 + and k >= 5 then + -- knob 5 selects the active tab; pressing it resets to CAT + if k == 5 then + which = "iop/channelmixerrgb/page" + element = "CAT" + -- since the tab action is not a slider, + -- the effects need to be translated + if effect == "up" then effect = "next" + elseif effect == "down" then effect = "previous" + else effect = "activate" + end + else + -- knobs 6, 7 and 8 are for the three color sliders on each tab + which = "iop/focus/sliders" + local e = { "1st", + "2nd", + "3rd" } + element = e[k - 5] + end + + -- the 4th knob is contrast; + -- either colorbalance if it is focused, or filmic + elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0 + and k == 4 then + which = "iop/colorbalancergb/contrast" + + -- in all other cases use a default selection + else + local s = { "iop/exposure/exposure", + "iop/filmicrgb/white relative exposure", + "iop/filmicrgb/black relative exposure", + "iop/filmicrgb/contrast", + "iop/crop/left", + "iop/crop/right", + "iop/crop/top", + "iop/crop/bottom" } + which = s[k] + end + + -- now pass the element/effect/size to the selected slider + return dt.gui.action(which, element, effect, size) + end) +end + +local function destroy() + -- nothing to destroy +end + +script_data.destroy = destroy + +return script_data diff --git a/official/check_for_updates.lua b/official/check_for_updates.lua index db18435..de92c7c 100644 --- a/official/check_for_updates.lua +++ b/official/check_for_updates.lua @@ -34,10 +34,25 @@ local cjson = require "cjson" du.check_min_api_version("2.0.0", "check_for_updates") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("check_for_updates", dt.configuration.config_dir .."/lua/locale/") + +local function _(msg) + return gettext(msg) +end + -- return data structure for script_manager local script_data = {} +script_data.metadata = { + name = "check_for_updates", + purpose = _("check for newer darktable releases"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/check_for_updates" +} + 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 diff --git a/official/copy_paste_metadata.lua b/official/copy_paste_metadata.lua index a44270e..0c765ec 100644 --- a/official/copy_paste_metadata.lua +++ b/official/copy_paste_metadata.lua @@ -31,10 +31,23 @@ local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "copy_paste_metadata") +dt.gettext.bindtextdomain("copy_paste_metadata", 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_paste_metadata", + purpose = _("adds keyboard shortcuts and buttons to copy/paste metadata between images"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/copy_paste_metadata" +} + 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 @@ -58,12 +71,6 @@ local publisher = "" local rights = "" local tags = {} -gettext.bindtextdomain("copy_paste_metadata", dt.configuration.config_dir .."/lua/locale/") - -local function _(msgid) - return gettext(msgid) -end - local function copy(image) if not image then have_data = false diff --git a/official/delete_long_tags.lua b/official/delete_long_tags.lua index 2c5d0e6..2c807e1 100644 --- a/official/delete_long_tags.lua +++ b/official/delete_long_tags.lua @@ -33,10 +33,25 @@ local du = require "lib/dtutils" du.check_min_api_version("2.0.0", "delete_long_tags") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("delete_long_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 = "delete_long_tags", + purpose = _("delete all tags longer than a set length"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/delete_long_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 script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again diff --git a/official/delete_unused_tags.lua b/official/delete_unused_tags.lua index e169068..bcdceaf 100644 --- a/official/delete_unused_tags.lua +++ b/official/delete_unused_tags.lua @@ -37,10 +37,25 @@ local function destroy() -- noting to destroy end +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("delete_unused_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 = "delete_unused_tags", + purpose = _("delete unused tags"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/delete_unused_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 script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again diff --git a/official/enfuse.lua b/official/enfuse.lua index 9aa5815..c8df51b 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -43,10 +43,23 @@ local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "enfuse") +dt.gettext.bindtextdomain("enfuse", 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 = "enfuse", + purpose = _("exposure blend images"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/enfuse" +} + 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 @@ -57,12 +70,6 @@ enf.event_registered = false enf.module_installed = false enf.lib_widgets = {} -gettext.bindtextdomain("enfuse", dt.configuration.config_dir .."/lua/locale/") - -local function _(msgid) - return gettext(msgid) -end - local function install_module() if not enf.module_installed then dt.register_lib( diff --git a/official/generate_image_txt.lua b/official/generate_image_txt.lua index c955988..deacefa 100644 --- a/official/generate_image_txt.lua +++ b/official/generate_image_txt.lua @@ -40,7 +40,7 @@ require "darktable.debug" local gettext = dt.gettext.gettext -gettext.bindtextdomain("generate_image_txt", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("generate_image_txt", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -52,6 +52,13 @@ du.check_min_api_version("7.0.0", "generate_image_txt") local script_data = {} +script_data.metadata = { + name = "generate_image_txt", + purpose = _("overlay metadata on the selected image(s)"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/generate_image_txt" +} + 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 diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua index e81a6cb..fd9e3fb 100644 --- a/official/image_path_in_ui.lua +++ b/official/image_path_in_ui.lua @@ -33,10 +33,25 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "image_path_in_ui") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("image_path_in_ui", 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_path_in_ui", + purpose = _("print the image path in the UI"), + author = "Jérémy Rosen", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/image_path_in_ui" +} + 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 diff --git a/official/import_filter_manager.lua b/official/import_filter_manager.lua index 05bc45d..9b16ee3 100644 --- a/official/import_filter_manager.lua +++ b/official/import_filter_manager.lua @@ -32,14 +32,28 @@ USAGE local dt = require "darktable" -local gettext = dt.gettext.gettext +local gettext = dt.gettext.gettext -gettext.bindtextdomain("import_filter_manager", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("import_filter_manager", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) end +local script_data = {} + +script_data.metadata = { + name = "import_filter_manager", + purpose = _("manage import filters"), + author = "Tobias Ellinghaus", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/import_filter_manager" +} + +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 import_filter_list = {} local n_import_filters = 1 @@ -83,6 +97,12 @@ dt.register_import_filter = function(name, callback) if name == active_filter then filter_dropdown.value = n_import_filters end end +local function destroy() + --noting to destroy +end +script_data.destroy = destroy + +return script_data -- vim: shiftwidth=2 expandtab tabstop=2 cindent -- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; diff --git a/official/import_filters.lua b/official/import_filters.lua index 807dec6..165ec3f 100644 --- a/official/import_filters.lua +++ b/official/import_filters.lua @@ -30,6 +30,28 @@ USAGE local dt = require "darktable" +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("import_filters", dt.configuration.config_dir .."/lua/locale/") + +local function _(msg) + return gettext(msg) +end + +local script_data = {} + +script_data.metadata = { + name = "import_filters", + purpose = _("import filtering"), + author = "Tobias Ellinghaus & Christian Mandel", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/import_filters" +} + +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 + -- we get fed a sorted list of filenames. just setting images to ignore to nil is enough -- ignore jpeg @@ -88,5 +110,13 @@ dt.register_import_filter("prefer raw over jpeg", function(event, images) end) +local function destroy() + -- nothing to destroy +end + +script_data.destroy = destroy + +return script_data + -- vim: shiftwidth=2 expandtab tabstop=2 cindent -- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; diff --git a/official/save_selection.lua b/official/save_selection.lua index f37ad0b..865ca26 100644 --- a/official/save_selection.lua +++ b/official/save_selection.lua @@ -38,9 +38,9 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "save_selection") -local gettext = dt.gettext.gettext +local gettext = dt.gettext.gettext -gettext.bindtextdomain("save_selection", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("save_selection", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -50,6 +50,13 @@ end local script_data = {} +script_data.metadata = { + name = "save_selection", + purpose = _("shortcuts providing multiple selection buffers"), + author = "Jérémy Rosen", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/save_selection" +} + 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 diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 116f0d7..18a7be5 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -38,9 +38,9 @@ local du = require "lib/dtutils" du.check_min_api_version("7.0.0", "selection_to_pdf") -local gettext = dt.gettext.gettext +local gettext = dt.gettext.gettext -gettext.bindtextdomain("selection_to_pdf", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("selection_to_pdf", dt.configuration.config_dir .."/lua/locale/") local function _(msg) return gettext(msg) @@ -50,6 +50,13 @@ end local script_data = {} +script_data.metadata = { + name = "selection_to_pdf", + purpose = _("generate a pdf file of selected images"), + author = "Jérémy Rosen & Pascal Obry", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/official/selection_to_pdf" +} + 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 diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index 4865974..58a055a 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -34,10 +34,25 @@ local df = require "lib/dtutils.file" du.check_min_api_version("7.0.0", "executable_manager") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("executable_manager", dt.configuration.config_dir .."/lua/locale/") + +local function _(msg) + return gettext(msg) +end + -- return data structure for script_manager local script_data = {} +script_data.metadata = { + name = "executable_manager", + purpose = _("manage the list of external executables used by the lua scripts"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/tools/executable_manager" +} + 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 @@ -45,8 +60,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 exec_man = {} -- our own namespace exec_man.module_installed = false exec_man.event_registered = false @@ -55,12 +68,6 @@ exec_man.event_registered = false -- F U N C T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - - - - - -gettext.bindtextdomain("executable_manager", dt.configuration.config_dir .."/lua/locale/") - -local function _(msg) - return gettext(msg) -end - local function grep(file, pattern) local result = {} diff --git a/tools/get_lib_manpages.lua b/tools/get_lib_manpages.lua index 2e59918..a3c3915 100644 --- a/tools/get_lib_manpages.lua +++ b/tools/get_lib_manpages.lua @@ -12,6 +12,14 @@ local libname = nil du.check_min_api_version("3.0.0", "get_lib_manpages") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("get_lib_manpages", dt.configuration.config_dir .."/lua/locale/") + +local function _(msg) + return gettext(msg) +end + local function destroy() -- nothing to destroy end @@ -79,6 +87,14 @@ for line in output:lines() do end local script_data = {} + +script_data.metadata = { + name = "get_lib_manpages", + purpose = _("output the internal library documentation as man pages"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/tools/get_lib_manpages" +} + script_data.destroy = destroy return script_data diff --git a/tools/get_libdoc.lua b/tools/get_libdoc.lua index d22516f..5cb0812 100644 --- a/tools/get_libdoc.lua +++ b/tools/get_libdoc.lua @@ -9,6 +9,14 @@ local du = require "lib/dtutils" du.check_min_api_version("3.0.0", "get_libdoc") +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain("get_libdoc", dt.configuration.config_dir .."/lua/locale/") + +local function _(msg) + return gettext(msg) +end + local function destroy() -- nothing to destroy end @@ -53,6 +61,14 @@ for line in output:lines() do end local script_data = {} + +script_data.metadata = { + name = "get_libdoc", + purpose = _("retrieve and print the documentation to the console"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/tools/get_libdoc" +} + script_data.destroy = destroy return script_data From 5c3b2777f077b03820876a2eb45aa33f8b7a6e19 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Thu, 16 May 2024 11:44:35 -0400 Subject: [PATCH 19/40] tools/script_manager - fixed gettext.bindtextdomain --- tools/script_manager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/script_manager.lua b/tools/script_manager.lua index 3938d94..7160932 100644 --- a/tools/script_manager.lua +++ b/tools/script_manager.lua @@ -60,7 +60,7 @@ local debug = require "darktable.debug" local gettext = dt.gettext.gettext -gettext.bindtextdomain("script_manager", dt.configuration.config_dir .."/lua/locale/") +dt.gettext.bindtextdomain("script_manager", dt.configuration.config_dir .."/lua/locale/") local function _(msgid) return gettext(msgid) From 3e2afffed82ff9488c0805bcfd389d8361269c7c Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 18 May 2024 21:59:11 -0400 Subject: [PATCH 20/40] lib/dtutils/string - Added categories to substitution functionality. This makes it feature complete. Some substitutions aren't implemented since the current use case for this is creating export directories. The results from the not implemented substitutions wouldn't work well in path/file names (such as comma separated lists or newlines). --- lib/dtutils/string.lua | 291 +++++++++++++++++++++++++++-------------- 1 file changed, 195 insertions(+), 96 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index e315eda..1cece46 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -477,6 +477,7 @@ function dtutils_string.get_filetype(str) end local substitutes = {} +local category_substitutes = {} -- - - - - - - - - - - - - - - - - - - - - - - - -- C O N S T A N T S @@ -488,7 +489,7 @@ local PLACEHOLDERS = {"ROLL.NAME", "FILE.EXTENSION", "ID", "VERSION", - "VERSION.IF.MULTI", -- Not Implemented + "VERSION.IF.MULTI", "VERSION.NAME", "DARKTABLE.VERSION", "DARKTABLE.NAME", -- Not Implemented @@ -504,14 +505,20 @@ local PLACEHOLDERS = {"ROLL.NAME", "WIDTH.MAX", -- Not Implemented "HEIGHT.MAX", -- Not Implemented "YEAR", + "YEAR.SHORT", "MONTH", + "MONTH.LONG", + "MONTH.SHORT", "DAY", "HOUR", "MINUTE", "SECOND", "MSEC", "EXIF.YEAR", + "EXIF.YEAR.SHORT", "EXIF.MONTH", + "EXIF.MONTH.LONG", + "EXIF.MONTH.SHORT", "EXIF.DAY", "EXIF.HOUR", "EXIF.MINUTE", @@ -523,17 +530,22 @@ local PLACEHOLDERS = {"ROLL.NAME", "EXIF.EXPOSURE", "EXIF.EXPOSURE.BIAS", "EXIF.APERTURE", + "EXIF.CROP.FACTOR", "EXIF.FOCAL.LENGTH", + "EXIF.FOCAL.LENGTH.EQUIV", -- Not Implemented "EXIF.FOCUS.DISTANCE", + "IMAGE.EXIF", -- Not Implemented "LONGITUDE", "LATITUDE", - "ALTITUDE", + "ELEVATION", + "GPS.LOCATION", -- Not Implemented "STARS", "RATING.ICONS", -- Not Implemented "LABELS", "LABELS.ICONS", -- Not Implemented "MAKER", "MODEL", + "LENS", "TITLE", "DESCRIPTION", "CREATOR", @@ -547,7 +559,7 @@ local PLACEHOLDERS = {"ROLL.NAME", "FOLDER.DESKTOP", "OPENCL.ACTIVATED", -- Not Implemented "USERNAME", - "NL", + "NL", -- Not Implemented "JOBCODE" -- Not Implemented } @@ -560,14 +572,19 @@ local DESKTOP = HOME .. PS .. "Desktop" local function get_colorlabels(image) local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) + local colorlabels = {} + if image.red then table.insert(colorlabels, "red") end if image.yellow then table.insert(colorlabels, "yellow") end if image.green then table.insert(colorlabels, "green") end if image.blue then table.insert(colorlabels, "blue") end if image.purple then table.insert(colorlabels, "purple") end - local labels = #colorlabels == 1 and colorlabels[1] or du.join(colorlabels, ",") + + local labels = #colorlabels == 1 and colorlabels[1] or du.join(colorlabels, "_") + log.log_level(old_log_level) + return labels end @@ -575,9 +592,10 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { Name = [[build_substitution_list]], Synopsis = [[build a list of variable substitutions]], Usage = [[local ds = require "lib/dtutils.string" - ds.build_substitution_list(image, sequence, [username], [pic_folder], [home], [desktop]) + ds.build_substitution_list(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed sequence - integer - the sequence number of the image + variable_string - string - the substitution variable string [username] - string - optional - user name. Will be determined if not supplied [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied [home] - string - optional - home directory. Will be determined if not supplied @@ -594,7 +612,46 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { Copyright = [[]], } -function dtutils_string.build_substition_list(image, sequence, username, pic_folder, home, desktop) +local function build_category_substitution_list(image, variable_string) + -- scan the variable string for CATEGORYn(tag name) entries and build the substitutions + local old_log_level = log.log_level() + -- log.log_level(dtutils_string.log_level) + --log.log_level(log.debug) + + for match in string.gmatch(variable_string, "%$%(.-%)?%)") do + log.msg(log.info, "match is " .. match) + local var = string.match(match, "%$%((.-%)?)%)") + log.msg(log.info, "var is " .. var) + if string.match(var, "CATEGORY%d") then + local element, tag = string.match(var, "CATEGORY(%d)%((.-)%)") + element = element + 1 + log.msg(log.debug, "element is " .. element .. " and tag is " .. tag) + local tags = image:get_tags() + log.msg(log.debug, "got " .. #tags .. " from image " .. image.filename) + for _, image_tag in ipairs(tags) do + log.msg(log.debug, "checking tag " .. image_tag.name) + if string.match(image_tag.name, tag) then + parts = du.split(image_tag.name, "|") + substitutes[var] = parts[element] + log.msg(log.info, "set substitute for " .. var .. " to " .. parts[element]) + log.msg(log.info, "double check substitutes[" .. var .. "] is " .. substitutes[var]) + end + end + end + end + -- scan the variable string looking for CATEGORYn + -- retrieve the tag and compute the replacement string + -- add the found string as a PLACEHOLDER + -- add the replacement to the corresponding spot in the replacement table + log.log_level(old_log_level) +end + +local function exiftime2systime(exiftime) + local yr,mo,dy,h,m,s = string.match(exiftime, "(%d-):(%d-):(%d-) (%d-):(%d-):(%d+)") + return(os.time{year=yr, month=mo, day=dy, hour=h, min=m, sec=s}) +end + +function dtutils_string.build_substition_list(image, sequence, variable_string, username, pic_folder, home, desktop) -- build the argument substitution list from each image local old_log_level = log.log_level() @@ -606,6 +663,8 @@ function dtutils_string.build_substition_list(image, sequence, username, pic_fol end local datetime = os.date("*t") + local long_month = os.date("%B") + local short_month = os.date("%b") local user_name = username or USER local pictures_folder = pic_folder or PICTURES local home_folder = home or HOME @@ -629,7 +688,8 @@ function dtutils_string.build_substition_list(image, sequence, username, pic_fol dtutils_string.get_filetype(image.filename),-- FILE.EXTENSION image.id, -- ID image.duplicate_index, -- VERSION - "", -- VERSION.IF_MULTI + -- #image:get_group_members() > 1 and image.duplicate_index or "", -- VERSION.IF_MULTI + "", -- VERSION.IF_MULTI image.version_name, -- VERSION.NAME dt.configuration.version, -- DARKTABLE.VERSION "", -- DARKTABLE.NAME @@ -645,57 +705,71 @@ function dtutils_string.build_substition_list(image, sequence, username, pic_fol "", -- WIDTH.MAX "", -- HEIGHT.MAX string.format("%4d", datetime.year), -- YEAR + string.sub(datetime.year, 3), -- YEAR.SHORT string.format("%02d", datetime.month), -- MONTH + long_month, -- MONTH.LONG + short_month, -- MONTH.SHORT string.format("%02d", datetime.day), -- DAY string.format("%02d", datetime.hour), -- HOUR string.format("%02d", datetime.min), -- MINUTE string.format("%02d", datetime.sec), -- SECOND - "", -- MSEC + 0, -- MSEC eyear, -- EXIF.YEAR + string.sub(eyear, 3), -- EXIF.YEAR.SHORT emon, -- EXIF.MONTH + os.date("%B", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.LONG + os.date("%b", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.SHORT eday, -- EXIF.DAY ehour, -- EXIF.HOUR emin, -- EXIF.MINUTE esec, -- EXIF.SECOND emsec, -- EXIF.MSEC - "", -- EXIF.DATE.REGIONAL - "", -- EXIF.TIME.REGIONAL + "", -- EXIF.DATE.REGIONAL - wont be implemented + "", -- EXIF.TIME.REGIONAL - wont be implemented string.format("%d", image.exif_iso), -- EXIF.ISO - string.format("1/%.0f", 1./image.exif_exposure), -- EXIF.EXPOSURE + string.format("%.0f", 1./image.exif_exposure), -- EXIF.EXPOSURE image.exif_exposure_bias, -- EXIF.EXPOSURE.BIAS string.format("%.01f", image.exif_aperture), -- EXIF.APERTURE + string.format("%.01f", image.exif_crop),-- EXIF.CROP_FACTOR string.format("%.0f", image.exif_focal_length), -- EXIF.FOCAL.LENGTH + string.format("%.0f", image.exif_focal_length * image.exif_crop), -- EXIF.FOCAL.LENGTH.EQUIV image.exif_focus_distance, -- EXIF.FOCUS.DISTANCE + "", -- IMAGE.EXIF image.longitude or "", -- LONGITUDE image.latitude or "", -- LATITUDE - image.elevation or "", -- ALTITUDE + image.elevation or "", -- ELEVATION + "", -- GPS.LOCATION - wont be implemented image.rating, -- STARS - "", -- RATING.ICONS + "", -- RATING.ICONS - wont be implemented labels, -- LABELS - "", -- LABELS.ICONS + "", -- LABELS.ICONS - wont be implemented image.exif_maker, -- MAKER image.exif_model, -- MODEL + image.exif_lens, -- LENS image.title, -- TITLE image.description, -- DESCRIPTION image.creator, -- CREATOR image.publisher, -- PUBLISHER image.rights, -- RIGHTS - "", -- TAGS - "", -- CATEGORYn - "", -- SIDECAR.TXT + "", -- TAGS - wont be implemented + "", -- CATEGORY + "", -- SIDECAR.TXT - wont be implemented pictures_folder, -- FOLDER.PICTURES home_folder, -- FOLDER.HOME desktop_folder, -- FOLDER.DESKTOP - "", -- OPENCL.ACTIVATED + "", -- OPENCL.ACTIVATED - wont be implemented user_name, -- USERNAME - "\n", -- NL - "" -- JOBCODE + "", -- NL - wont be implemented + "" -- JOBCODE - wont be implemented } for i = 1, #PLACEHOLDERS, 1 do substitutes[PLACEHOLDERS[i]] = replacements[i] log.msg(log.info, "setting " .. PLACEHOLDERS[i] .. " to " .. tostring(replacements[i])) end + + build_category_substitution_list(image, variable_string) + log.log_level(old_log_level) end @@ -712,86 +786,105 @@ end local function treat(var_string) local old_log_level = log.log_level() - log.log_level(dtutils_string.log_level) + --log.log_level(dtutils_string.log_level) + --log.log_level(log.info) local ret_val = "" -- remove the var from the string local var = string.match(var_string, "[%a%._]+") var = check_legacy_vars(var) log.msg(log.info, "var_string is " .. tostring(var_string) .. " and var is " .. tostring(var)) - ret_val = substitutes[var] - if not ret_val then + if string.match(var_string, "CATEGORY%d") then + log.msg(log.info, "substituting for " .. var_string) + ret_val = substitutes[var_string] + log.msg(log.info, "ret_val is " .. ret_val) + else + ret_val = substitutes[var] + end + local valid_var = false + + if ret_val then + valid_var = true + --elseif string.match(var, "CATEGORY%d") then + --valid_var = true + end + + if not valid_var then log.msg(log.error, "variable " .. var .. " is not an allowed variable, returning empty value") log.log_level(old_log_level) return "" end - local args = string.gsub(var_string, var, "") - log.msg(log.info, "args is " .. tostring(args)) - if string.len(args) > 0 then - if string.match(args, '^%^%^') then - ret_val = string.upper(ret_val) - elseif string.match(args, "^%^") then - ret_val = string.gsub(ret_val, "^%a", string.upper, 1) - elseif string.match(args, "^,,") then - ret_val = string.lower(ret_val) - elseif string.match(args, "^,") then - ret_val = string.gsub(ret_val, "^%a", string.lower, 1) - elseif string.match(args, "^:%-?%d+:%-?%d+") then - local soffset, slen = string.match(args, ":(%-?%d+):(%-?%d+)") - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - if tonumber(soffset) >= 0 then - soffset = soffset + 1 + if string.match(var, "CATEGORY%d") then + ret_val = process_category(image, var, var_string) + else + local args = string.gsub(var_string, var, "") + log.msg(log.info, "args is " .. tostring(args)) + if string.len(args) > 0 then + if string.match(args, '^%^%^') then + ret_val = string.upper(ret_val) + elseif string.match(args, "^%^") then + ret_val = string.gsub(ret_val, "^%a", string.upper, 1) + elseif string.match(args, "^,,") then + ret_val = string.lower(ret_val) + elseif string.match(args, "^,") then + ret_val = string.gsub(ret_val, "^%a", string.lower, 1) + elseif string.match(args, "^:%-?%d+:%-?%d+") then + local soffset, slen = string.match(args, ":(%-?%d+):(%-?%d+)") + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + if tonumber(soffset) >= 0 then + soffset = soffset + 1 + end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + if tonumber(soffset) < 0 and tonumber(slen) < 0 then + local temp = soffset + soffset = slen + slen = temp + end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + ret_val = string.sub(ret_val, soffset, slen) + log.msg(log.info, "ret_val is " .. ret_val) + elseif string.match(args, "^:%-?%d+") then + local soffset= string.match(args, ":(%-?%d+)") + if tonumber(soffset) >= 0 then + soffset = soffset + 1 + end + ret_val = string.sub(ret_val, soffset, -1) + elseif string.match(args, "^-%$%(.-%)") then + local replacement = string.match(args, "-%$%(([%a%._]+)%)") + replacement = check_legacy_vars(replacement) + if string.len(ret_val) == 0 then + ret_val = substitutes[replacement] + end + elseif string.match(args, "^-.+$") then + local replacement = string.match(args, "-(.+)$") + if string.len(ret_val) == 0 then + ret_val = replacement + end + elseif string.match(args, "^+.+") then + local replacement = string.match(args, "+(.+)") + if string.len(ret_val) > 0 then + ret_val = replacement + end + elseif string.match(args, "^#.+") then + local pattern = string.match(args, "#(.+)") + log.msg(log.info, "pattern to remove is " .. tostring(pattern)) + ret_val = string.gsub(ret_val, "^" .. dtutils_string.sanitize_lua(pattern), "") + elseif string.match(args, "^%%.+") then + local pattern = string.match(args, "%%(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", "") + elseif string.match(args, "^//.-/.+") then + local pattern, replacement = string.match(args, "//(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement) + elseif string.match(args, "^/#.+/.+") then + local pattern, replacement = string.match(args, "/#(.+)/(.+)") + ret_val = string.gsub(ret_val, "^" .. pattern, replacement, 1) + elseif string.match(args, "^/%%.-/.+") then + local pattern, replacement = string.match(args, "/%%(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", replacement) + elseif string.match(args, "^/.-/.+") then + log.msg(log.info, "took replacement branch") + local pattern, replacement = string.match(args, "/(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement, 1) end - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - if tonumber(soffset) < 0 and tonumber(slen) < 0 then - local temp = soffset - soffset = slen - slen = temp - end - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - ret_val = string.sub(ret_val, soffset, slen) - log.msg(log.info, "ret_val is " .. ret_val) - elseif string.match(args, "^:%-?%d+") then - local soffset= string.match(args, ":(%-?%d+)") - if tonumber(soffset) >= 0 then - soffset = soffset + 1 - end - ret_val = string.sub(ret_val, soffset, -1) - elseif string.match(args, "^-%$%(.-%)") then - local replacement = string.match(args, "-%$%(([%a%._]+)%)") - replacement = check_legacy_vars(replacement) - if string.len(ret_val) == 0 then - ret_val = substitutes[replacement] - end - elseif string.match(args, "^-.+$") then - local replacement = string.match(args, "-(.+)$") - if string.len(ret_val) == 0 then - ret_val = replacement - end - elseif string.match(args, "^+.+") then - local replacement = string.match(args, "+(.+)") - if string.len(ret_val) > 0 then - ret_val = replacement - end - elseif string.match(args, "^#.+") then - local pattern = string.match(args, "#(.+)") - log.msg(log.info, "pattern to remove is " .. tostring(pattern)) - ret_val = string.gsub(ret_val, "^" .. dtutils_string.sanitize_lua(pattern), "") - elseif string.match(args, "^%%.+") then - local pattern = string.match(args, "%%(.+)") - ret_val = string.gsub(ret_val, pattern .. "$", "") - elseif string.match(args, "^//.-/.+") then - local pattern, replacement = string.match(args, "//(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern, replacement) - elseif string.match(args, "^/#.+/.+") then - local pattern, replacement = string.match(args, "/#(.+)/(.+)") - ret_val = string.gsub(ret_val, "^" .. pattern, replacement, 1) - elseif string.match(args, "^/%%.-/.+") then - local pattern, replacement = string.match(args, "/%%(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern .. "$", replacement) - elseif string.match(args, "^/.-/.+") then - log.msg(log.info, "took replacement branch") - local pattern, replacement = string.match(args, "/(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern, replacement, 1) end end log.log_level(old_log_level) @@ -848,9 +941,10 @@ dtutils_string.libdoc.functions["clear_substitute_list"] = { function dtutils_string.clear_substitute_list() local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) - for i = 1, #PLACEHOLDERS, 1 do - substitutes[PLACEHOLDERS[i]] = nil - end + + substitutes = {} + category_substitutes = {} + log.log_level(old_log_level) end @@ -858,9 +952,10 @@ dtutils_string.libdoc.functions["substitute"] = { Name = [[substitute]], Synopsis = [[Check if a string has been sanitized]], Usage = [[local ds = require "lib/dtutils.string" - ds.substitute(image, sequence, [username], [pic_folder], [home], [desktop]) + ds.substitute(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed sequence - integer - the sequence number of the image + variable_string - string - the substitution variable string [username] - string - optional - user name. Will be determined if not supplied [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied [home] - string - optional - home directory. Will be determined if not supplied @@ -880,13 +975,17 @@ dtutils_string.libdoc.functions["substitute"] = { function dtutils_string.substitute(image, sequence, variable_string, username, pic_folder, home, desktop) local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) + dtutils_string.clear_substitute_list() - dtutils_string.build_substition_list(image, sequence, username, pic_folder, home, desktop) + + dtutils_string.build_substition_list(image, sequence, variable_string, username, pic_folder, home, desktop) + local str = dtutils_string.substitute_list(variable_string) + log.log_level(old_log_level) + return str end - return dtutils_string From 7b2018412a7180c09ab502062dac2d8939c8dec0 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 18 May 2024 22:01:10 -0400 Subject: [PATCH 21/40] lib/dtutils/string - Cleaned up code to make it more readable. Fixed VERSION_IF_MULTI. Added safety check in category to make sure we don't try and read a tag field that doesn't exist. --- lib/dtutils/string.lua | 495 +++++++++++++++++++++++------------------ 1 file changed, 279 insertions(+), 216 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 1cece46..dad0d55 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -476,118 +476,6 @@ function dtutils_string.get_filetype(str) return parts["filetype"] end -local substitutes = {} -local category_substitutes = {} - --- - - - - - - - - - - - - - - - - - - - - - - - --- C O N S T A N T S --- - - - - - - - - - - - - - - - - - - - - - - - - -local PLACEHOLDERS = {"ROLL.NAME", - "FILE.FOLDER", - "FILE.NAME", - "FILE.EXTENSION", - "ID", - "VERSION", - "VERSION.IF.MULTI", - "VERSION.NAME", - "DARKTABLE.VERSION", - "DARKTABLE.NAME", -- Not Implemented - "SEQUENCE", - "WIDTH.SENSOR", - "HEIGHT.SENSOR", - "WIDTH.RAW", - "HEIGHT.RAW", - "WIDTH.CROP", - "HEIGHT.CROP", - "WIDTH.EXPORT", - "HEIGHT.EXPORT", - "WIDTH.MAX", -- Not Implemented - "HEIGHT.MAX", -- Not Implemented - "YEAR", - "YEAR.SHORT", - "MONTH", - "MONTH.LONG", - "MONTH.SHORT", - "DAY", - "HOUR", - "MINUTE", - "SECOND", - "MSEC", - "EXIF.YEAR", - "EXIF.YEAR.SHORT", - "EXIF.MONTH", - "EXIF.MONTH.LONG", - "EXIF.MONTH.SHORT", - "EXIF.DAY", - "EXIF.HOUR", - "EXIF.MINUTE", - "EXIF.SECOND", - "EXIF.MSEC", - "EXIF.DATE.REGIONAL", -- Not Implemented - "EXIF.TIME.REGIONAL", -- Not Implemented - "EXIF.ISO", - "EXIF.EXPOSURE", - "EXIF.EXPOSURE.BIAS", - "EXIF.APERTURE", - "EXIF.CROP.FACTOR", - "EXIF.FOCAL.LENGTH", - "EXIF.FOCAL.LENGTH.EQUIV", -- Not Implemented - "EXIF.FOCUS.DISTANCE", - "IMAGE.EXIF", -- Not Implemented - "LONGITUDE", - "LATITUDE", - "ELEVATION", - "GPS.LOCATION", -- Not Implemented - "STARS", - "RATING.ICONS", -- Not Implemented - "LABELS", - "LABELS.ICONS", -- Not Implemented - "MAKER", - "MODEL", - "LENS", - "TITLE", - "DESCRIPTION", - "CREATOR", - "PUBLISHER", - "RIGHTS", - "TAGS", -- Not Implemented - "CATEGORY", -- Not Implemented - "SIDECAR.TXT", -- Not Implemented - "FOLDER.PICTURES", - "FOLDER.HOME", - "FOLDER.DESKTOP", - "OPENCL.ACTIVATED", -- Not Implemented - "USERNAME", - "NL", -- Not Implemented - "JOBCODE" -- Not Implemented -} - -local PS = dt.configuration.running_os == "windows" and "\\" or "/" -local USER = os.getenv("USERNAME") -local HOME = dt.configuration.running_os == "windows" and os.getenv("HOMEPATH") or os.getenv("HOME") -local PICTURES = HOME .. PS .. (dt.configuration.running_os == "windows" and "My Pictures" or "Pictures") -local DESKTOP = HOME .. PS .. "Desktop" - -local function get_colorlabels(image) - local old_log_level = log.log_level() - log.log_level(dtutils_string.log_level) - - local colorlabels = {} - - if image.red then table.insert(colorlabels, "red") end - if image.yellow then table.insert(colorlabels, "yellow") end - if image.green then table.insert(colorlabels, "green") end - if image.blue then table.insert(colorlabels, "blue") end - if image.purple then table.insert(colorlabels, "purple") end - - local labels = #colorlabels == 1 and colorlabels[1] or du.join(colorlabels, "_") - - log.log_level(old_log_level) - - return labels -end - dtutils_string.libdoc.functions["build_substitution_list"] = { Name = [[build_substitution_list]], Synopsis = [[build a list of variable substitutions]], @@ -612,51 +500,175 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { Copyright = [[]], } -local function build_category_substitution_list(image, variable_string) - -- scan the variable string for CATEGORYn(tag name) entries and build the substitutions - local old_log_level = log.log_level() - -- log.log_level(dtutils_string.log_level) - --log.log_level(log.debug) +local substitutes = {} +local category_substitutes = {} - for match in string.gmatch(variable_string, "%$%(.-%)?%)") do +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local PLACEHOLDERS = {"ROLL.NAME", + "FILE.FOLDER", + "FILE.NAME", + "FILE.EXTENSION", + "ID", + "VERSION", + "VERSION.IF.MULTI", + "VERSION.NAME", + "DARKTABLE.VERSION", + "DARKTABLE.NAME", -- Not Implemented + "SEQUENCE", + "WIDTH.SENSOR", + "HEIGHT.SENSOR", + "WIDTH.RAW", + "HEIGHT.RAW", + "WIDTH.CROP", + "HEIGHT.CROP", + "WIDTH.EXPORT", + "HEIGHT.EXPORT", + "WIDTH.MAX", -- Not Implemented + "HEIGHT.MAX", -- Not Implemented + "YEAR", + "YEAR.SHORT", + "MONTH", + "MONTH.LONG", + "MONTH.SHORT", + "DAY", + "HOUR", + "MINUTE", + "SECOND", + "MSEC", + "EXIF.YEAR", + "EXIF.YEAR.SHORT", + "EXIF.MONTH", + "EXIF.MONTH.LONG", + "EXIF.MONTH.SHORT", + "EXIF.DAY", + "EXIF.HOUR", + "EXIF.MINUTE", + "EXIF.SECOND", + "EXIF.MSEC", + "EXIF.DATE.REGIONAL", -- Not Implemented + "EXIF.TIME.REGIONAL", -- Not Implemented + "EXIF.ISO", + "EXIF.EXPOSURE", + "EXIF.EXPOSURE.BIAS", + "EXIF.APERTURE", + "EXIF.CROP.FACTOR", + "EXIF.FOCAL.LENGTH", + "EXIF.FOCAL.LENGTH.EQUIV", -- Not Implemented + "EXIF.FOCUS.DISTANCE", + "IMAGE.EXIF", -- Not Implemented + "LONGITUDE", + "LATITUDE", + "ELEVATION", + "GPS.LOCATION", -- Not Implemented + "STARS", + "RATING.ICONS", -- Not Implemented + "LABELS", + "LABELS.ICONS", -- Not Implemented + "MAKER", + "MODEL", + "LENS", + "TITLE", + "DESCRIPTION", + "CREATOR", + "PUBLISHER", + "RIGHTS", + "TAGS", -- Not Implemented + "SIDECAR.TXT", -- Not Implemented + "FOLDER.PICTURES", + "FOLDER.HOME", + "FOLDER.DESKTOP", + "OPENCL.ACTIVATED", -- Not Implemented + "USERNAME", + "NL", -- Not Implemented + "JOBCODE" -- Not Implemented +} + +local PS = dt.configuration.running_os == "windows" and "\\" or "/" +local USER = os.getenv("USERNAME") +local HOME = dt.configuration.running_os == "windows" and os.getenv("HOMEPATH") or os.getenv("HOME") +local PICTURES = HOME .. PS .. (dt.configuration.running_os == "windows" and "My Pictures" or "Pictures") +local DESKTOP = HOME .. PS .. "Desktop" + +local function get_colorlabels(image) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + + local colorlabels = {} + + if image.red then table.insert(colorlabels, "red") end + if image.yellow then table.insert(colorlabels, "yellow") end + if image.green then table.insert(colorlabels, "green") end + if image.blue then table.insert(colorlabels, "blue") end + if image.purple then table.insert(colorlabels, "purple") end + + local labels = #colorlabels == 1 and colorlabels[1] or du.join(colorlabels, "_") + + log.log_level(old_log_level) + + return labels +end + +-- find the $CATEGORYn requests and add them to the substitute list + +local function build_category_substitution_list(image, variable_string) + local old_log_level = log.log_level() + log.log_level(dtutils_string.log_level) + + for match in string.gmatch(variable_string, "%$%(.-%)?%)") do -- grab each complete variable log.msg(log.info, "match is " .. match) - local var = string.match(match, "%$%((.-%)?)%)") + + local var = string.match(match, "%$%((.-%)?)%)") -- strip of the leading $( and trailing ) log.msg(log.info, "var is " .. var) + if string.match(var, "CATEGORY%d") then - local element, tag = string.match(var, "CATEGORY(%d)%((.-)%)") - element = element + 1 + local element, tag = string.match(var, "CATEGORY(%d)%((.-)%)") -- get the element number and the tag to match + + element = element + 1 -- add one to element since lua arrays are 1 based log.msg(log.debug, "element is " .. element .. " and tag is " .. tag) + local tags = image:get_tags() log.msg(log.debug, "got " .. #tags .. " from image " .. image.filename) + for _, image_tag in ipairs(tags) do log.msg(log.debug, "checking tag " .. image_tag.name) + if string.match(image_tag.name, tag) then - parts = du.split(image_tag.name, "|") - substitutes[var] = parts[element] - log.msg(log.info, "set substitute for " .. var .. " to " .. parts[element]) - log.msg(log.info, "double check substitutes[" .. var .. "] is " .. substitutes[var]) + fields = du.split(image_tag.name, "|") + + if element <= #fields then + substitutes[var] = fields[element] + else + substitutes[var] = "" + log.msg(log.warn, "requested field for tag " .. tag .. " doesn't exist") + end + + log.msg(log.info, "set substitute for " .. var .. " to " .. fields[element]) + end end end end - -- scan the variable string looking for CATEGORYn - -- retrieve the tag and compute the replacement string - -- add the found string as a PLACEHOLDER - -- add the replacement to the corresponding spot in the replacement table log.log_level(old_log_level) end +-- convert image.exif_datetime_taken to system time + local function exiftime2systime(exiftime) local yr,mo,dy,h,m,s = string.match(exiftime, "(%d-):(%d-):(%d-) (%d-):(%d-):(%d+)") return(os.time{year=yr, month=mo, day=dy, hour=h, min=m, sec=s}) end -function dtutils_string.build_substition_list(image, sequence, variable_string, username, pic_folder, home, desktop) - -- build the argument substitution list from each image +-- build the argument substitution list from each image +function dtutils_string.build_substition_list(image, sequence, variable_string, username, pic_folder, home, desktop) local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) + -- is time millisecond aware? Implemented in API 9.1.0 + local is_api_9_1 = true if dt.configuration.api_version_string < "9.1.0" then is_api_9_1 = false @@ -668,11 +680,10 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, local user_name = username or USER local pictures_folder = pic_folder or PICTURES local home_folder = home or HOME - log.msg(log.info, "home is " .. tostring(home) .. " and HOME is " .. tostring(HOME) .. " and home_folder is " .. tostring(home_folder)) local desktop_folder = desktop or DESKTOP local labels = get_colorlabels(image) - log.msg(log.info, "image date time taken is " .. image.exif_datetime_taken) + local eyear, emon, eday, ehour, emin, esec, emsec if dt.preferences.read("darktable", "lighttable/ui/milliseconds", "bool") and is_api_9_1 then eyear, emon, eday, ehour, emin, esec, emsec = @@ -682,14 +693,16 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, eyear, emon, eday, ehour, emin, esec = string.match(image.exif_datetime_taken, "(%d+):(%d+):(%d+) (%d+):(%d+):(%d+)$") end + + local version_multi = #image:get_group_members() > 1 and image.version or "" + local replacements = {image.film, -- ROLL.NAME image.path, -- FILE.FOLDER image.filename, -- FILE.NAME dtutils_string.get_filetype(image.filename),-- FILE.EXTENSION image.id, -- ID image.duplicate_index, -- VERSION - -- #image:get_group_members() > 1 and image.duplicate_index or "", -- VERSION.IF_MULTI - "", -- VERSION.IF_MULTI + version_multi, -- VERSION.IF_MULTI image.version_name, -- VERSION.NAME dt.configuration.version, -- DARKTABLE.VERSION "", -- DARKTABLE.NAME @@ -698,12 +711,12 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, image.height, -- HEIGHT.SENSOR is_api_9_1 and image.p_width or "", -- WIDTH.RAW is_api_9_1 and image.p_height or "", -- HEIGHT.RAW - is_api_9_1 and image.final_width or "", -- WIDTH.CROP + is_api_9_1 and image.final_width or "", -- WIDTH.CROP is_api_9_1 and image.final_height or "", -- HEIGHT.CROP is_api_9_1 and image.final_width or "", -- WIDTH.EXPORT is_api_9_1 and image.final_height or "", -- HEIGHT.EXPORT - "", -- WIDTH.MAX - "", -- HEIGHT.MAX + "", -- WIDTH.MAX -- from export module + "", -- HEIGHT.MAX -- from export module string.format("%4d", datetime.year), -- YEAR string.sub(datetime.year, 3), -- YEAR.SHORT string.format("%02d", datetime.month), -- MONTH @@ -717,8 +730,8 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, eyear, -- EXIF.YEAR string.sub(eyear, 3), -- EXIF.YEAR.SHORT emon, -- EXIF.MONTH - os.date("%B", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.LONG - os.date("%b", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.SHORT + os.date("%B", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.LONG + os.date("%b", exiftime2systime(image.exif_datetime_taken)), -- EXIF.MONTH.SHORT eday, -- EXIF.DAY ehour, -- EXIF.HOUR emin, -- EXIF.MINUTE @@ -752,7 +765,6 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, image.publisher, -- PUBLISHER image.rights, -- RIGHTS "", -- TAGS - wont be implemented - "", -- CATEGORY "", -- SIDECAR.TXT - wont be implemented pictures_folder, -- FOLDER.PICTURES home_folder, -- FOLDER.HOME @@ -763,36 +775,50 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, "" -- JOBCODE - wont be implemented } + -- populate the substitution list + for i = 1, #PLACEHOLDERS, 1 do substitutes[PLACEHOLDERS[i]] = replacements[i] log.msg(log.info, "setting " .. PLACEHOLDERS[i] .. " to " .. tostring(replacements[i])) end + -- do category substitutions separately + build_category_substitution_list(image, variable_string) log.log_level(old_log_level) end +-- handle different versions of names + local function check_legacy_vars(var_name) local var = var_name + if string.match(var, "_") then var = string.gsub(var, "_", ".") end + if string.match(var, "^HOME$") then var = "FOLDER.HOME" end if string.match(var, "^PICTURES.FOLDER$") then var = "FOLDER.PICTURES" end if string.match(var, "^DESKTOP$") then var = "FOLDER.DESKTOP" end + return var end +-- get the substitution and do any string manipulations requested + local function treat(var_string) local old_log_level = log.log_level() - --log.log_level(dtutils_string.log_level) - --log.log_level(log.info) + log.log_level(dtutils_string.log_level) + local ret_val = "" + -- remove the var from the string local var = string.match(var_string, "[%a%._]+") + var = check_legacy_vars(var) log.msg(log.info, "var_string is " .. tostring(var_string) .. " and var is " .. tostring(var)) + if string.match(var_string, "CATEGORY%d") then log.msg(log.info, "substituting for " .. var_string) ret_val = substitutes[var_string] @@ -800,12 +826,11 @@ local function treat(var_string) else ret_val = substitutes[var] end + local valid_var = false if ret_val then valid_var = true - --elseif string.match(var, "CATEGORY%d") then - --valid_var = true end if not valid_var then @@ -813,79 +838,109 @@ local function treat(var_string) log.log_level(old_log_level) return "" end - if string.match(var, "CATEGORY%d") then - ret_val = process_category(image, var, var_string) - else - local args = string.gsub(var_string, var, "") - log.msg(log.info, "args is " .. tostring(args)) - if string.len(args) > 0 then - if string.match(args, '^%^%^') then - ret_val = string.upper(ret_val) - elseif string.match(args, "^%^") then - ret_val = string.gsub(ret_val, "^%a", string.upper, 1) - elseif string.match(args, "^,,") then - ret_val = string.lower(ret_val) - elseif string.match(args, "^,") then - ret_val = string.gsub(ret_val, "^%a", string.lower, 1) - elseif string.match(args, "^:%-?%d+:%-?%d+") then - local soffset, slen = string.match(args, ":(%-?%d+):(%-?%d+)") - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - if tonumber(soffset) >= 0 then - soffset = soffset + 1 - end - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - if tonumber(soffset) < 0 and tonumber(slen) < 0 then - local temp = soffset - soffset = slen - slen = temp - end - log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) - ret_val = string.sub(ret_val, soffset, slen) - log.msg(log.info, "ret_val is " .. ret_val) - elseif string.match(args, "^:%-?%d+") then - local soffset= string.match(args, ":(%-?%d+)") - if tonumber(soffset) >= 0 then - soffset = soffset + 1 - end - ret_val = string.sub(ret_val, soffset, -1) - elseif string.match(args, "^-%$%(.-%)") then - local replacement = string.match(args, "-%$%(([%a%._]+)%)") - replacement = check_legacy_vars(replacement) - if string.len(ret_val) == 0 then - ret_val = substitutes[replacement] - end - elseif string.match(args, "^-.+$") then - local replacement = string.match(args, "-(.+)$") - if string.len(ret_val) == 0 then - ret_val = replacement - end - elseif string.match(args, "^+.+") then - local replacement = string.match(args, "+(.+)") - if string.len(ret_val) > 0 then - ret_val = replacement - end - elseif string.match(args, "^#.+") then - local pattern = string.match(args, "#(.+)") - log.msg(log.info, "pattern to remove is " .. tostring(pattern)) - ret_val = string.gsub(ret_val, "^" .. dtutils_string.sanitize_lua(pattern), "") - elseif string.match(args, "^%%.+") then - local pattern = string.match(args, "%%(.+)") - ret_val = string.gsub(ret_val, pattern .. "$", "") - elseif string.match(args, "^//.-/.+") then - local pattern, replacement = string.match(args, "//(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern, replacement) - elseif string.match(args, "^/#.+/.+") then - local pattern, replacement = string.match(args, "/#(.+)/(.+)") - ret_val = string.gsub(ret_val, "^" .. pattern, replacement, 1) - elseif string.match(args, "^/%%.-/.+") then - local pattern, replacement = string.match(args, "/%%(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern .. "$", replacement) - elseif string.match(args, "^/.-/.+") then - log.msg(log.info, "took replacement branch") - local pattern, replacement = string.match(args, "/(.-)/(.+)") - ret_val = string.gsub(ret_val, pattern, replacement, 1) + + -- string modifications + + local args = string.gsub(var_string, var, "") + log.msg(log.info, "args is " .. tostring(args)) + + if string.len(args) > 0 then + + if string.match(args, '^%^%^') then + ret_val = string.upper(ret_val) + + elseif string.match(args, "^%^") then + ret_val = string.gsub(ret_val, "^%a", string.upper, 1) + + elseif string.match(args, "^,,") then + ret_val = string.lower(ret_val) + + elseif string.match(args, "^,") then + ret_val = string.gsub(ret_val, "^%a", string.lower, 1) + + elseif string.match(args, "^:%-?%d+:%-?%d+") then + + local soffset, slen = string.match(args, ":(%-?%d+):(%-?%d+)") + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + + if tonumber(soffset) >= 0 then + soffset = soffset + 1 end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + + if tonumber(soffset) < 0 and tonumber(slen) < 0 then + local temp = soffset + soffset = slen + slen = temp + end + log.msg(log.info, "soffset is " .. soffset .. " and slen is " .. slen) + + ret_val = string.sub(ret_val, soffset, slen) + log.msg(log.info, "ret_val is " .. ret_val) + + elseif string.match(args, "^:%-?%d+") then + + local soffset= string.match(args, ":(%-?%d+)") + if tonumber(soffset) >= 0 then + soffset = soffset + 1 + end + ret_val = string.sub(ret_val, soffset, -1) + + elseif string.match(args, "^-%$%(.-%)") then + + local replacement = string.match(args, "-%$%(([%a%._]+)%)") + replacement = check_legacy_vars(replacement) + if string.len(ret_val) == 0 then + ret_val = substitutes[replacement] + end + + elseif string.match(args, "^-.+$") then + + local replacement = string.match(args, "-(.+)$") + if string.len(ret_val) == 0 then + ret_val = replacement + end + + elseif string.match(args, "^+.+") then + + local replacement = string.match(args, "+(.+)") + if string.len(ret_val) > 0 then + ret_val = replacement + end + + elseif string.match(args, "^#.+") then + + local pattern = string.match(args, "#(.+)") + log.msg(log.info, "pattern to remove is " .. tostring(pattern)) + ret_val = string.gsub(ret_val, "^" .. dtutils_string.sanitize_lua(pattern), "") + + elseif string.match(args, "^%%.+") then + + local pattern = string.match(args, "%%(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", "") + + elseif string.match(args, "^//.-/.+") then + + local pattern, replacement = string.match(args, "//(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement) + + elseif string.match(args, "^/#.+/.+") then + + local pattern, replacement = string.match(args, "/#(.+)/(.+)") + ret_val = string.gsub(ret_val, "^" .. pattern, replacement, 1) + + elseif string.match(args, "^/%%.-/.+") then + + local pattern, replacement = string.match(args, "/%%(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern .. "$", replacement) + + elseif string.match(args, "^/.-/.+") then + + log.msg(log.info, "took replacement branch") + local pattern, replacement = string.match(args, "/(.-)/(.+)") + ret_val = string.gsub(ret_val, pattern, replacement, 1) end + end log.log_level(old_log_level) return ret_val @@ -911,15 +966,22 @@ dtutils_string.libdoc.functions["substitute_list"] = { function dtutils_string.substitute_list(str) local old_log_level = log.log_level() log.log_level(dtutils_string.log_level) + -- replace the substitution variables in a string for match in string.gmatch(str, "%$%(.-%)?%)") do + local var = string.match(match, "%$%((.-%)?)%)") + local treated_var = treat(var) log.msg(log.info, "var is " .. var .. " and treated var is " .. tostring(treated_var)) + str = string.gsub(str, "%$%(".. dtutils_string.sanitize_lua(var) .."%)", tostring(treated_var)) log.msg(log.info, "str after replacement is " .. str) + end + log.log_level(old_log_level) + return str end @@ -988,4 +1050,5 @@ function dtutils_string.substitute(image, sequence, variable_string, username, p end + return dtutils_string From 97e33672ea79d29073aef37364c6c523bd6d5bad Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sun, 19 May 2024 23:04:01 -0400 Subject: [PATCH 22/40] lib/dtutils/string - fixed default formatting of sequence --- lib/dtutils/string.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index dad0d55..c172ff6 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -706,7 +706,7 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, image.version_name, -- VERSION.NAME dt.configuration.version, -- DARKTABLE.VERSION "", -- DARKTABLE.NAME - sequence, -- SEQUENCE + string.format("%04d", sequence), -- SEQUENCE image.width, -- WIDTH.SENSOR image.height, -- HEIGHT.SENSOR is_api_9_1 and image.p_width or "", -- WIDTH.RAW From 3ed4219e6c2f92cdc01eabb9d88227b972c83948 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 20 May 2024 00:56:01 -0400 Subject: [PATCH 23/40] lib/dtutils/string - added [] to sanitize_lua(). added 4.8 syntax to CATEGORY added 4.8 SEQUENCE changes (syntax, start, width) --- lib/dtutils/string.lua | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index c172ff6..2e4b7d8 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -335,6 +335,8 @@ function dtutils_string.sanitize_lua(str) str = string.gsub(str, "%-", "%%-") str = string.gsub(str, "%(", "%%(") str = string.gsub(str, "%)", "%%)") + str = string.gsub(str, "%[", "%%[") + str = string.gsub(str, "%]", "%%]") str = string.gsub(str, "+", "%%+") log.log_level(old_log_level) return str @@ -623,8 +625,15 @@ local function build_category_substitution_list(image, variable_string) local var = string.match(match, "%$%((.-%)?)%)") -- strip of the leading $( and trailing ) log.msg(log.info, "var is " .. var) - if string.match(var, "CATEGORY%d") then - local element, tag = string.match(var, "CATEGORY(%d)%((.-)%)") -- get the element number and the tag to match + if string.match(var, "CATEGORY%d") or string.match(var, "CATEGORY%[") then + local element + local tag + + if string.match(var, "CATEGORY%d") then + element, tag = string.match(var, "CATEGORY(%d)%((.-)%)") -- get the element number and the tag to match + else + element, tag = string.match(var, "%[(%d),(.-)%]") -- new syntax + end element = element + 1 -- add one to element since lua arrays are 1 based log.msg(log.debug, "element is " .. element .. " and tag is " .. tag) @@ -696,7 +705,7 @@ function dtutils_string.build_substition_list(image, sequence, variable_string, local version_multi = #image:get_group_members() > 1 and image.version or "" - local replacements = {image.film, -- ROLL.NAME + local replacements = {image.film.path, -- ROLL.NAME image.path, -- FILE.FOLDER image.filename, -- FILE.NAME dtutils_string.get_filetype(image.filename),-- FILE.EXTENSION @@ -819,10 +828,18 @@ local function treat(var_string) var = check_legacy_vars(var) log.msg(log.info, "var_string is " .. tostring(var_string) .. " and var is " .. tostring(var)) - if string.match(var_string, "CATEGORY%d") then + if string.match(var_string, "CATEGORY%d") or string.match(var_string, "CATEGORY%[") then log.msg(log.info, "substituting for " .. var_string) ret_val = substitutes[var_string] log.msg(log.info, "ret_val is " .. ret_val) + + elseif string.match(var_string, "SEQUENCE%[") then + local start, width = string.match(var_string, "(%d+),(%d)") + local seq_val = tonumber(substitutes[var]) + local pat = "%0" .. width .. "d" + substitutes[var_string] = string.format(pat, start + (seq_val - 1)) + ret_val = substitutes[var_string] + else ret_val = substitutes[var] end @@ -943,6 +960,7 @@ local function treat(var_string) end log.log_level(old_log_level) + dt.print_log("returning ret_val of " .. ret_val) return ret_val end @@ -965,7 +983,8 @@ dtutils_string.libdoc.functions["substitute_list"] = { function dtutils_string.substitute_list(str) local old_log_level = log.log_level() - log.log_level(dtutils_string.log_level) + -- log.log_level(dtutils_string.log_level) + log.log_level(log.info) -- replace the substitution variables in a string for match in string.gmatch(str, "%$%(.-%)?%)") do @@ -975,6 +994,8 @@ function dtutils_string.substitute_list(str) local treated_var = treat(var) log.msg(log.info, "var is " .. var .. " and treated var is " .. tostring(treated_var)) + dt.print_log("str is " .. str) + str = string.gsub(str, "%$%(".. dtutils_string.sanitize_lua(var) .."%)", tostring(treated_var)) log.msg(log.info, "str after replacement is " .. str) From 232baab86bd559684d97aab3c154da6c240d5deb Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 20 May 2024 10:07:13 -0400 Subject: [PATCH 24/40] lib/dtutils/string - removed debugging statements --- lib/dtutils/string.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 2e4b7d8..7690d59 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -960,7 +960,6 @@ local function treat(var_string) end log.log_level(old_log_level) - dt.print_log("returning ret_val of " .. ret_val) return ret_val end @@ -983,8 +982,7 @@ dtutils_string.libdoc.functions["substitute_list"] = { function dtutils_string.substitute_list(str) local old_log_level = log.log_level() - -- log.log_level(dtutils_string.log_level) - log.log_level(log.info) + log.log_level(dtutils_string.log_level) -- replace the substitution variables in a string for match in string.gmatch(str, "%$%(.-%)?%)") do @@ -994,8 +992,6 @@ function dtutils_string.substitute_list(str) local treated_var = treat(var) log.msg(log.info, "var is " .. var .. " and treated var is " .. tostring(treated_var)) - dt.print_log("str is " .. str) - str = string.gsub(str, "%$%(".. dtutils_string.sanitize_lua(var) .."%)", tostring(treated_var)) log.msg(log.info, "str after replacement is " .. str) From 417c165d16dc7d65ccfd2be5906ab05e0bb12c85 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 20 May 2024 18:18:46 -0400 Subject: [PATCH 25/40] lib/dtutils/string - updated documentation --- lib/dtutils/string.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 7690d59..f3236fc 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -484,7 +484,7 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { Usage = [[local ds = require "lib/dtutils.string" ds.build_substitution_list(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed - sequence - integer - the sequence number of the image + sequence - integer - the sequence number of the image being processed (exported) variable_string - string - the substitution variable string [username] - string - optional - user name. Will be determined if not supplied [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied @@ -496,7 +496,7 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { Limitations = [[If the value for a variable can not be determined, or if it is not supported, then an empty string is used for the value.]], Example = [[]], - See_Also = [[https://docs.darktable.org/usermanual/4.2/en/special-topics/variables/]], + See_Also = [[https://docs.darktable.org/usermanual/4.6/en/special-topics/variables/]], Reference = [[]], License = [[]], Copyright = [[]], @@ -613,7 +613,7 @@ local function get_colorlabels(image) return labels end --- find the $CATEGORYn requests and add them to the substitute list +-- find the $CATEGORYn and $CATEGORY[n,m] requests and add them to the substitute list local function build_category_substitution_list(image, variable_string) local old_log_level = log.log_level() @@ -974,7 +974,7 @@ dtutils_string.libdoc.functions["substitute_list"] = { Return_Value = [[result - string - the input string with values substituted for the variables]], Limitations = [[]], Example = [[]], - See_Also = [[]], + See_Also = [[https://docs.darktable.org/usermanual/4.6/en/special-topics/variables/]], Reference = [[]], License = [[]], Copyright = [[]], @@ -1033,7 +1033,7 @@ dtutils_string.libdoc.functions["substitute"] = { Usage = [[local ds = require "lib/dtutils.string" ds.substitute(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed - sequence - integer - the sequence number of the image + sequence - integer - the number of the image being processed (exported) variable_string - string - the substitution variable string [username] - string - optional - user name. Will be determined if not supplied [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied @@ -1045,7 +1045,7 @@ dtutils_string.libdoc.functions["substitute"] = { Return_Value = [[result - string - the input string with values substituted for the variables]], Limitations = [[]], Example = [[]], - See_Also = [[]], + See_Also = [[https://docs.darktable.org/usermanual/4.6/en/special-topics/variables/]], Reference = [[]], License = [[]], Copyright = [[]], From dcbe575e9c50665209c429842edbe309a8191192 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 20 May 2024 22:13:29 -0400 Subject: [PATCH 26/40] lib/dtutils/string - updated embedded documentation --- lib/dtutils/string.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index f3236fc..342a576 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -478,11 +478,11 @@ function dtutils_string.get_filetype(str) return parts["filetype"] end -dtutils_string.libdoc.functions["build_substitution_list"] = { - Name = [[build_substitution_list]], +dtutils_string.libdoc.functions["build_substitute_list"] = { + Name = [[build_substitute_list]], Synopsis = [[build a list of variable substitutions]], Usage = [[local ds = require "lib/dtutils.string" - ds.build_substitution_list(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) + ds.build_substitute_list(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed sequence - integer - the sequence number of the image being processed (exported) variable_string - string - the substitution variable string @@ -490,7 +490,7 @@ dtutils_string.libdoc.functions["build_substitution_list"] = { [pic_folder] - string - optional - pictures folder name. Will be determined if not supplied [home] - string - optional - home directory. Will be determined if not supplied [desktop] - string - optional - desktop directory. Will be determined if not supplied]], - Description = [[build_substitution_list populates variables with values from the arguments + Description = [[build_substitute_list populates variables with values from the arguments and determined from the system and darktable.]], Return_Value = [[]], Limitations = [[If the value for a variable can not be determined, or if it is not supported, @@ -1057,7 +1057,7 @@ function dtutils_string.substitute(image, sequence, variable_string, username, p dtutils_string.clear_substitute_list() - dtutils_string.build_substition_list(image, sequence, variable_string, username, pic_folder, home, desktop) + dtutils_string.build_substitute_list(image, sequence, variable_string, username, pic_folder, home, desktop) local str = dtutils_string.substitute_list(variable_string) From fecbb39347eb315d61f8532ecc3b741a44d58935 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 20 May 2024 23:43:47 -0400 Subject: [PATCH 27/40] lib/dtutils/string - more embedded doc updates --- lib/dtutils/string.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 342a576..926c667 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -1029,7 +1029,7 @@ end dtutils_string.libdoc.functions["substitute"] = { Name = [[substitute]], - Synopsis = [[Check if a string has been sanitized]], + Synopsis = [[Perform all the variable substitution steps with one function call]], Usage = [[local ds = require "lib/dtutils.string" ds.substitute(image, sequence, variable_string, [username], [pic_folder], [home], [desktop]) image - dt_lua_image_t - the image being processed @@ -1040,7 +1040,7 @@ dtutils_string.libdoc.functions["substitute"] = { [home] - string - optional - home directory. Will be determined if not supplied [desktop] - string - optional - desktop directory. Will be determined if not supplied]], Description = [[substitute initializes the substitution list by calling clear_substitute_list(), - then builds the substitutions by calling build_substitution_list() and finally does the + then builds the substitutions by calling build_substitute_list() and finally does the substitution by calling substitute_list(), then returns the result string.]], Return_Value = [[result - string - the input string with values substituted for the variables]], Limitations = [[]], From a3b295112f1ac8afe9f2454ec865cac81a8dcd07 Mon Sep 17 00:00:00 2001 From: Krzysztof Kotowicz Date: Mon, 27 May 2024 13:03:00 +0200 Subject: [PATCH 28/40] Update OpenInExplorer.lua In OpenInExplorer, use AppleScript instead of `open -R` for OSX. That way multiple files can be selected. --- contrib/OpenInExplorer.lua | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index dba04d0..64d478a 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -118,9 +118,26 @@ open_dir.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesk local open_files = {} open_files.windows = "explorer.exe /select, %s" -open_files.macos = "open -Rn %s" +open_files.macos = "osascript -e 'tell application \"Finder\" to (reveal {%s}) activate'" open_files.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowItems ass %d %s ""]] +reveal_file_osx_cmd = "\"%s\" as POSIX file" + +--Call the osx Finder with each selected image selected. +--For images in multiple folders, Finder will open a separate window for each +local function call_list_of_files_osx(selected_images) + local cmds = {} + for _, image in pairs(selected_images) do + current_image = image.path..PS..image.filename + -- AppleScript needs double quoted strings, and the whole command is wrapped in single quotes. + table.insert(cmds, string.format(reveal_file_osx_cmd, string.gsub(string.gsub(current_image, "'", "'\\''"), "\"", "\\\"") )) + end + reveal_cmd = table.concat(cmds, ",") + run_cmd = string.format(open_files.macos, reveal_cmd) + dt.print_log("OSX run_cmd = "..run_cmd) + dsys.external_command(run_cmd) +end + --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) @@ -188,6 +205,8 @@ local function open_in_fmanager() else if act_os == "linux" then call_list_of_files(images) + elseif act_os == "macos" then + call_list_of_files_osx(images) else call_file_by_file(images) end From f1d8ad7fce66aa04a539ef6eab4e1daae531ea4a Mon Sep 17 00:00:00 2001 From: Krzysztof Kotowicz Date: Mon, 27 May 2024 18:26:35 +0200 Subject: [PATCH 29/40] Fix quoting. --- contrib/OpenInExplorer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/OpenInExplorer.lua b/contrib/OpenInExplorer.lua index 64d478a..1633a1a 100644 --- a/contrib/OpenInExplorer.lua +++ b/contrib/OpenInExplorer.lua @@ -130,7 +130,7 @@ local function call_list_of_files_osx(selected_images) for _, image in pairs(selected_images) do current_image = image.path..PS..image.filename -- AppleScript needs double quoted strings, and the whole command is wrapped in single quotes. - table.insert(cmds, string.format(reveal_file_osx_cmd, string.gsub(string.gsub(current_image, "'", "'\\''"), "\"", "\\\"") )) + table.insert(cmds, string.format(reveal_file_osx_cmd, string.gsub(string.gsub(current_image, "\"", "\\\""), "'", "'\"'\"'"))) end reveal_cmd = table.concat(cmds, ",") run_cmd = string.format(open_files.macos, reveal_cmd) From 81b0f1fb484a9c293663191b99393eb9f322fc1c Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Mon, 3 Jun 2024 18:08:30 -0400 Subject: [PATCH 30/40] contrib/dbmaint - remove database records for missing film rolls and images. --- contrib/dbmaint.lua | 314 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 contrib/dbmaint.lua diff --git a/contrib/dbmaint.lua b/contrib/dbmaint.lua new file mode 100644 index 0000000..7f2f21e --- /dev/null +++ b/contrib/dbmaint.lua @@ -0,0 +1,314 @@ +--[[ + + dbmaint.lua - perform database maintenance + + Copyright (C) 2024 Bill Ferguson . + + This program 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. + + This program 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 this program. If not, see . +]] +--[[ + dbmaint - perform database maintenance + + Perform database maintenance to clean up missing images and filmstrips. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + None + + USAGE + * start dbmaint from script_manager + * scan for missing film rolls or missing images + * look at the results and choose to delete or not + + BUGS, COMMENTS, SUGGESTIONS + Bill Ferguson + + CHANGES +]] + +local dt = require "darktable" +local du = require "lib/dtutils" +local df = require "lib/dtutils.file" +local log = require "lib/dtutils.log" + + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local MODULE = "dbmaint" +local DEFAULT_LOG_LEVEL = log.error +local PS = dt.configuration.running_os == "windows" and "\\" or "/" + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- A P I C H E C K +-- - - - - - - - - - - - - - - - - - - - - - - - + +du.check_min_api_version("7.0.0", MODULE) -- choose the minimum version that contains the features you need + + +-- - - - - - - - - - - - - - - - - - - - - - - - - - +-- I 1 8 N +-- - - - - - - - - - - - - - - - - - - - - - - - - - + +local gettext = dt.gettext.gettext + +dt.gettext.bindtextdomain(MODULE , dt.configuration.config_dir .. "/lua/locale/") + +local function _(msgid) + return gettext(MODULE, 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.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 + +script_data.metadata = { + name = "dbmaint", + purpose = _("perform database maintenance"), + author = "Bill Ferguson ", + help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/dbmaint/" +} + + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- L O G L E V E L +-- - - - - - - - - - - - - - - - - - - - - - - - + +log.log_level(DEFAULT_LOG_LEVEL) + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- N A M E S P A C E +-- - - - - - - - - - - - - - - - - - - - - - - - + +local dbmaint = {} + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- G L O B A L V A R I A B L E S +-- - - - - - - - - - - - - - - - - - - - - - - - + +dbmaint.main_widget = nil + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- A L I A S E S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local namespace = dbmaint + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- F U N C T I O N S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local function scan_film_rolls() + local missing_films = {} + + for _, filmroll in ipairs(dt.films) do + if not df.check_if_file_exists(filmroll.path) then + table.insert(missing_films, filmroll) + end + end + + return missing_films +end + +local function scan_images(film) + local missing_images = {} + + if film then + for i = 1, #film do + local image = film[i] + log.log_msg(log.debug, "checking " .. image.filename) + if not df.check_if_file_exists(image.path .. PS .. image.filename) then + log.log_msg(log.info, image.filename .. " not found") + table.insert(missing_images, image) + end + end + end + + return missing_images +end + +local function remove_missing_film_rolls(list) + for _, filmroll in ipairs(list) do + filmroll:delete(true) + end +end + +-- force the lighttable to reload + +local function refresh_lighttable(film) + local rules = dt.gui.libs.collect.filter() + dt.gui.libs.collect.filter(rules) +end + +local function remove_missing_images(list) + local film = list[1].film + for _, image in ipairs(list) do + image:delete() + end + refresh_lighttable(film) +end + +local function install_module() + if not namespace.module_installed then + dt.register_lib( + MODULE, -- Module name + _("DB maintenance"), -- Visible name + true, -- expandable + true, -- resetable + {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 0}}, -- containers + namespace.main_widget, + nil,-- view_enter + nil -- view_leave + ) + namespace.module_installed = true + end +end + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- U S E R I N T E R F A C E +-- - - - - - - - - - - - - - - - - - - - - - - - + +dbmaint.list_widget = dt.new_widget("text_view"){ + editable = false, + reset_callback = function(this) + this.text = "" + end +} + +dbmaint.chooser = dt.new_widget("combobox"){ + label = "scan for", + selected = 1, + "film rolls", "images", + reset_callback = function(this) + this.selected = 1 + end +} + +dbmaint.scan_button = dt.new_widget("button"){ + label = "scan", + tooltip = "click to scan for missing film rolls/files", + clicked_callback = function(this) + local found = nil + local found_text = "" + if dbmaint.chooser.value == "film rolls" then + found = scan_film_rolls() + if #found > 0 then + for _, film in ipairs(found) do + local dir_name = du.split(film.path, PS) + found_text = found_text .. dir_name[#dir_name] .. "\n" + end + end + else + log.log_msg(log.debug, "checking path " .. dt.collection[1].path .. " for missing files") + found = scan_images(dt.collection[1].film) + if #found > 0 then + for _, image in ipairs(found) do + found_text = found_text .. image.filename .. "\n" + end + end + end + if #found > 0 then + dbmaint.list_widget.text = found_text + dbmaint.found = found + dbmaint.remove_button.sensitive = true + end + end, + reset_callback = function(this) + dbmaint.found = nil + end +} + +dbmaint.remove_button = dt.new_widget("button"){ + label = "remove", + tooltip = "remove missing film rolls/images", + sensitive = false, + clicked_callback = function(this) + if dbmaint.chooser.value == "film rolls" then + remove_missing_film_rolls(dbmaint.found) + else + remove_missing_images(dbmaint.found) + end + dbmaint.found = nil + dbmaint.list_widget.text = "" + this.sensitive = false + end, + reset_callback = function(this) + this.sensitive = false + end +} + +dbmaint.main_widget = dt.new_widget("box"){ + orientation = "vertical", + dt.new_widget("section_label"){label = "missing items"}, + dbmaint.list_widget, + dt.new_widget("label"){label = ""}, + dbmaint.chooser, + dt.new_widget("label"){label = ""}, + dbmaint.scan_button, + dbmaint.remove_button +} + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- D A R K T A B L E I N T E G R A T I O N +-- - - - - - - - - - - - - - - - - - - - - - - - + +local function destroy() + dt.gui.libs[MODULE].visible = false + + if namespace.event_registered then + dt.destroy_event(MODULE, "view-changed") + end + + return +end + +local function restart() + dt.gui.libs[MODULE].visible = true + + return +end + +script_data.destroy = destroy +script_data.restart = restart +script_data.destroy_method = "hide" +script_data.show = restart + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- E V E N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +if dt.gui.current_view().id == "lighttable" then + install_module() +else + if not namespace.event_registered then + dt.register_event(MODULE, "view-changed", + function(event, old_view, new_view) + if new_view.name == "lighttable" and old_view.name == "darkroom" then + install_module() + end + end + ) + namespace.event_registered = true + end +end + +return script_data \ No newline at end of file From 2f330ea9cc6afe8795bd290697637d4c68f8662a Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Tue, 4 Jun 2024 23:16:19 -0400 Subject: [PATCH 31/40] lib/dtutils/system - added wrapper functions io_popen and os_execute to wrap io.popen and os.execute system calls respectively. These wrapper functions provide the necessary quoting on windows to get handle strings with spaces and special characters. --- lib/dtutils/system.lua | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/dtutils/system.lua b/lib/dtutils/system.lua index f41f821..8f794f4 100644 --- a/lib/dtutils/system.lua +++ b/lib/dtutils/system.lua @@ -129,4 +129,55 @@ function dtutils_system.launch_default_app(path) end +dtutils_system.libdoc.functions["os_execute"] = { + Name = [[os_execute]], + Synopsis = [[wrapper around the lua os.execute function]], + Usage = [[local dsys = require "lib/dtutils.file" + + result = dsys.os_execute(cmd) + cmd - string - a command to execute on the operating system]], + Description = [[os_execute wraps the lua os.execute system call to provide + correct sanitization of windows commands]], + Return_Value = [[see the lua os.execute documentation]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_system.os_execute(cmd) + if _scripts_install.dt.configuration.running_os == "windows" then + cmd = "\"" .. cmd .. "\"" + end + return os.execute(cmd) +end + +dtutils_system.libdoc.functions["io_popen"] = { + Name = [[io_popen]], + Synopsis = [[wrapper around the lua io.popen function]], + Usage = [[local dsys = require "lib/dtutils.file" + + result = dsys.io_popen(cmd) + cmd - string - a command to execute and attach to]], + Description = [[io_popen wraps the lua io.popen system call to provide + correct sanitization of windows commands]], + Return_Value = [[see the lua io.popen documentation]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_system.io_popen(cmd) + if _scripts_install.dt.configuration.running_os == "windows" then + cmd = "\"" .. cmd .. "\"" + end + return io.popen(cmd) +end + + return dtutils_system From fe48d7498c8d40bd222c62104e454aa1f92dd39b Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Tue, 4 Jun 2024 23:41:07 -0400 Subject: [PATCH 32/40] lib/dtutils/file - replaced os.execute and io.popen with wrapper functions to sanitize windows calls --- lib/dtutils/file.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/dtutils/file.lua b/lib/dtutils/file.lua index cd898e7..b871711 100644 --- a/lib/dtutils/file.lua +++ b/lib/dtutils/file.lua @@ -42,7 +42,7 @@ end local function _win_os_execute(cmd) local result = nil - local p = io.popen(cmd) + local p = dsys.io_popen(cmd) local output = p:read("*a") p:close() if string.match(output, "true") then @@ -94,7 +94,7 @@ dtutils_file.libdoc.functions["test_file"] = { function dtutils_file.test_file(path, test) local cmd = "test -" - local engine = os.execute + local engine = dsys.os_execute local cmdstring = "" if dt.configuration.running_os == "windows" then @@ -167,7 +167,7 @@ local function _search_for_bin_windows(bin) for _,arg in ipairs(args) do local cmd = "where " .. arg .. " " .. ds.sanitize(bin) - local p = io.popen(cmd) + local p = dsys.io_popen(cmd) local output = p:read("*a") p:close() local lines = du.split(output, "\n") @@ -191,7 +191,7 @@ end local function _search_for_bin_nix(bin) local result = false - local p = io.popen("command -v " .. bin) + local p = dsys.io_popen("command -v " .. bin) local output = p:read("*a") p:close() if string.len(output) > 0 then @@ -220,7 +220,7 @@ local function _search_for_bin_macos(bin) search_start = "/Applications/" .. bin .. ".app" end - local p = io.popen("find " .. search_start .. " -type f -name " .. bin .. " -print") + local p = dsys.io_popen("find " .. search_start .. " -type f -name " .. bin .. " -print") local output = p:read("*a") p:close() local lines = du.split(output, "\n") @@ -445,7 +445,7 @@ function dtutils_file.check_if_file_exists(filepath) local result = false if (dt.configuration.running_os == 'windows') then filepath = string.gsub(filepath, '[\\/]+', '\\') - local p = io.popen("if exist " .. dtutils_file.sanitize_filename(filepath) .. " (echo 'yes') else (echo 'no')") + local p = dsys.io_popen("if exist " .. dtutils_file.sanitize_filename(filepath) .. " (echo 'yes') else (echo 'no')") local ans = p:read("*all") p:close() if string.match(ans, "yes") then @@ -456,7 +456,7 @@ function dtutils_file.check_if_file_exists(filepath) -- result = false -- end elseif (dt.configuration.running_os == "linux") then - result = os.execute('test -e ' .. dtutils_file.sanitize_filename(filepath)) + result = dsys.os_execute('test -e ' .. dtutils_file.sanitize_filename(filepath)) if not result then result = false end @@ -522,9 +522,9 @@ function dtutils_file.file_copy(fromFile, toFile) local result = nil -- if cp exists, use it if dt.configuration.running_os == "windows" then - result = os.execute('copy "' .. fromFile .. '" "' .. toFile .. '"') + result = dsys.os_execute('copy "' .. fromFile .. '" "' .. toFile .. '"') elseif dtutils_file.check_if_bin_exists("cp") then - result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'") + result = dsys.os_execute("cp '" .. fromFile .. "' '" .. toFile .. "'") end -- if cp was not present, or if cp failed, then a pure lua solution @@ -575,7 +575,7 @@ function dtutils_file.file_move(fromFile, toFile) if not success then -- an error occurred, so let's try using the operating system function if dtutils_file.check_if_bin_exists("mv") then - success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'") + success = dsys.os_execute("mv '" .. fromFile .. "' '" .. toFile .. "'") end -- if the mv didn't exist or succeed, then... if not success then From 038418b89fac9e99a309a536eee6aa4f13c19428 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Tue, 4 Jun 2024 23:43:21 -0400 Subject: [PATCH 33/40] contrib/autostyle replaced io.popen functions with wrapper contrib/color_profile_manager to properly quote windows commands so contrib/fujifilm_dynamic_range that they are sanitized for special contrib/fujifilm_ratings characters and spaces contrib/geoJSON_export contrib/geoToolbox contrib/image_stack contrib/image_time contrib/kml_export official/enfuse tools/executable_manager tools/get_lib_manpages tools/get_libdoc --- contrib/autostyle.lua | 3 ++- contrib/color_profile_manager.lua | 3 ++- contrib/fujifilm_dynamic_range.lua | 3 ++- contrib/fujifilm_ratings.lua | 5 +++-- contrib/geoJSON_export.lua | 3 ++- contrib/geoToolbox.lua | 3 ++- contrib/image_stack.lua | 2 +- contrib/image_time.lua | 7 ++++--- contrib/kml_export.lua | 2 +- official/enfuse.lua | 2 +- tools/executable_manager.lua | 5 +++-- tools/get_lib_manpages.lua | 5 +++-- tools/get_libdoc.lua | 3 ++- 13 files changed, 28 insertions(+), 18 deletions(-) diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index a12cd0a..319b8f3 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -39,6 +39,7 @@ GPLv2 local darktable = require "darktable" local du = require "lib/dtutils" local filelib = require "lib/dtutils.file" +local syslib = require "lib/dtutils.system" du.check_min_api_version("7.0.0", "autostyle") @@ -68,7 +69,7 @@ script_data.show = nil -- only required for libs since the destroy_method only h -- run command and retrieve stdout local function get_stdout(cmd) -- Open the command, for reading - local fd = assert(io.popen(cmd, 'r')) + local fd = assert(syslib.io_popen(cmd, 'r')) darktable.control.read(fd) -- slurp the whole file local data = assert(fd:read('*a')) diff --git a/contrib/color_profile_manager.lua b/contrib/color_profile_manager.lua index ed08317..d87d9a6 100644 --- a/contrib/color_profile_manager.lua +++ b/contrib/color_profile_manager.lua @@ -45,6 +45,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" du.check_min_api_version("7.0.0", "color_profile_manager") @@ -106,7 +107,7 @@ end local function list_profiles(dir) local files = {} - local p = io.popen(DIR_CMD .. " " .. dir) + local p = dtsys.io_popen(DIR_CMD .. " " .. dir) if p then for line in p:lines() do table.insert(files, line) diff --git a/contrib/fujifilm_dynamic_range.lua b/contrib/fujifilm_dynamic_range.lua index d373d13..1034411 100644 --- a/contrib/fujifilm_dynamic_range.lua +++ b/contrib/fujifilm_dynamic_range.lua @@ -60,6 +60,7 @@ cameras may behave in other ways. local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "fujifilm_dynamic_range") @@ -105,7 +106,7 @@ local function detect_dynamic_range(event, image) -- without -n flag, exiftool will round to the nearest tenth command = command .. " -RawExposureBias -n -t " .. RAF_filename dt.print_log(command) - output = io.popen(command) + output = dtsys.io_popen(command) local raf_result = output:read("*all") output:close() if #raf_result == 0 then diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index f9bb1c8..ef93513 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -26,6 +26,7 @@ Dependencies: local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "fujifilm_ratings") @@ -61,7 +62,7 @@ local function detect_rating(event, image) local JPEG_filename = string.gsub(RAF_filename, "%.RAF$", ".JPG") local command = "exiftool -Rating " .. JPEG_filename dt.print_error(command) - local output = io.popen(command) + local output = dtsys.io_popen(command) local jpeg_result = output:read("*all") output:close() if string.len(jpeg_result) > 0 then @@ -72,7 +73,7 @@ local function detect_rating(event, image) end command = "exiftool -Rating " .. RAF_filename dt.print_error(command) - output = io.popen(command) + output = dtsys.io_popen(command) local raf_result = output:read("*all") output:close() if string.len(raf_result) > 0 then diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 695976a..406c37c 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -35,6 +35,7 @@ USAGE local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "geoJSON_export") @@ -330,7 +331,7 @@ dt.preferences.register("geoJSON_export", _("opens the geoJSON file after the export with the standard program for geoJSON files"), false ) -local handle = io.popen("xdg-user-dir DESKTOP") +local handle = dtsys.io_popen("xdg-user-dir DESKTOP") local result = handle:read() handle:close() if (result == nil) then diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index 83caa13..d654eeb 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -28,6 +28,7 @@ require "geoToolbox" local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" local gettext = dt.gettext.gettext du.check_min_api_version("7.0.0", "geoToolbox") @@ -411,7 +412,7 @@ local function reverse_geocode() -- jq could be replaced with a Lua JSON parser startCommand = string.format("curl --silent \"https://api.mapbox.com/geocoding/v5/mapbox.places/%s,%s.json?types=%s&access_token=%s\" | jq '.features | .[0] | '.text''", lon1, lat1, types, tokan) - local handle = io.popen(startCommand) + local handle = dtsys.io_popen(startCommand) local result = trim12(handle:read("*a")) handle:close() diff --git a/contrib/image_stack.lua b/contrib/image_stack.lua index c63ff16..ba0909b 100644 --- a/contrib/image_stack.lua +++ b/contrib/image_stack.lua @@ -348,7 +348,7 @@ local function list_files(search_string) search_string = string.gsub(search_string, "/", "\\\\") end - local f = io.popen(ls .. search_string) + local f = dtsys.io_popen(ls .. search_string) if f then local found_file = f:read() while found_file do diff --git a/contrib/image_time.lua b/contrib/image_time.lua index f20e500..fa00b57 100644 --- a/contrib/image_time.lua +++ b/contrib/image_time.lua @@ -107,6 +107,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" local ds = require "lib/dtutils.string" +local dtsys = require "lib/dtutils.system" local gettext = dt.gettext.gettext local img_time = {} @@ -225,7 +226,7 @@ local function get_image_taken_time(image) local exiv2 = df.check_if_bin_exists("exiv2") if exiv2 then - p = io.popen(exiv2 .. " -K Exif.Image.DateTime " .. image.path .. PS .. image.filename) + p = dtsys.io_popen(exiv2 .. " -K Exif.Image.DateTime " .. image.path .. PS .. image.filename) if p then for line in p:lines() do if string.match(line, "Exif.Image.DateTime") then @@ -243,7 +244,7 @@ end local function _get_windows_image_file_creation_time(image) local datetime = nil - local p = io.popen("dir " .. image.path .. PS .. image.filename) + local p = dtsys.io_popen("dir " .. image.path .. PS .. image.filename) if p then for line in p:lines() do if string.match(line, ds.sanitize_lua(image.filename)) then @@ -264,7 +265,7 @@ end local function _get_nix_image_file_creation_time(image) local datetime = nil - local p = io.popen("ls -lL --time-style=full-iso " .. image.path .. PS .. image.filename) + local p = dtsys.io_popen("ls -lL --time-style=full-iso " .. image.path .. PS .. image.filename) if p then for line in p:lines() do if string.match(line, ds.sanitize_lua(image.filename)) then diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index ec1aa04..ec7218c 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -343,7 +343,7 @@ if dt.configuration.running_os == "windows" then elseif dt.configuration.running_os == "macos" then defaultDir = os.getenv("HOME") else - local handle = io.popen("xdg-user-dir DESKTOP") + local handle = dsys.io_popen("xdg-user-dir DESKTOP") defaultDir = handle:read() handle:close() end diff --git a/official/enfuse.lua b/official/enfuse.lua index c8df51b..c193c35 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -116,7 +116,7 @@ if enfuse_installed then local version = nil - local p = io.popen(enfuse_installed .. " --version") + local p = dtsys.io_popen(enfuse_installed .. " --version") local f = p:read("all") p:close() version = string.match(f, "enfuse (%d.%d)") diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index 58a055a..0ac35ad 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -31,6 +31,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" du.check_min_api_version("7.0.0", "executable_manager") @@ -75,7 +76,7 @@ local function grep(file, pattern) if dt.configuration.running_os == "windows" then -- use find to get the matches local command = "\\windows\\system32\\find.exe " .. "\"" .. pattern .. "\"" .. " " .. file - local f = io.popen(command) + local f = dtsys.io_popen(command) local output = f:read("all") f:close() -- strip out the first line @@ -84,7 +85,7 @@ local function grep(file, pattern) else -- use grep and just return the answers local command = "grep " .. pattern .. " " .. file - local f = io.popen(command) + local f = dtsys.io_popen(command) local output = f:read("all") f:close() result = du.split(output, "\n") diff --git a/tools/get_lib_manpages.lua b/tools/get_lib_manpages.lua index a3c3915..33d2d03 100644 --- a/tools/get_lib_manpages.lua +++ b/tools/get_lib_manpages.lua @@ -7,6 +7,7 @@ local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" +local dtsys = require "lib/dtutils.system" local log = require "lib/dtutils.log" local libname = nil @@ -33,7 +34,7 @@ local function output_man(d) libname = name end local fname = "/tmp/" .. name .. ".3" - local mf = io.open(fname, "w") + local mf = dtsys.io_open(fname, "w") if mf then mf:write(".TH " .. string.upper(name) .. " 3 \"\" \"\" \"Darktable " .. libname .. " functions\"\n") for _,section in ipairs(keys) do @@ -59,7 +60,7 @@ end -- find the libraries -local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort") +local output = dtsys.io_popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort") -- loop through the libraries diff --git a/tools/get_libdoc.lua b/tools/get_libdoc.lua index 5cb0812..2328014 100644 --- a/tools/get_libdoc.lua +++ b/tools/get_libdoc.lua @@ -6,6 +6,7 @@ local dt = require "darktable" local du = require "lib/dtutils" +local dtsys = require "lib/dtutils.system" du.check_min_api_version("3.0.0", "get_libdoc") @@ -36,7 +37,7 @@ end -- find the libraries -local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort") +local output = dtsys.io_popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort") -- loop through the libraries From 96471ae7e77e9146989f40ce3f7a670b04b3225b Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 00:00:43 -0400 Subject: [PATCH 34/40] lib/dtutils - fixed documentation error --- lib/dtutils.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/dtutils.lua b/lib/dtutils.lua index c17ce33..c8331cb 100644 --- a/lib/dtutils.lua +++ b/lib/dtutils.lua @@ -82,8 +82,7 @@ dtutils.libdoc.functions["check_max_api_version"] = { run against the current api version. This function is used when a part of the Lua API that the script relies on is removed. If the maximum api version is not met, then an error message is printed saying the script_name failed to load, then an error is thrown causing the - program to stop executing. - + program to stop executing.]], Return_Value = [[result - true if the maximum api version is available, false if not.]], Limitations = [[When using the default handler on a script being executed from the luarc file, the error thrown will stop the luarc file from executing any remaining statements. This limitation does not apply to script_manger.]], From 67538a4de2efb78b9c96134e963166f55ed23848 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 00:01:17 -0400 Subject: [PATCH 35/40] lib/dtutils/system code cleanup --- lib/dtutils/system.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dtutils/system.lua b/lib/dtutils/system.lua index 8f794f4..87a1f23 100644 --- a/lib/dtutils/system.lua +++ b/lib/dtutils/system.lua @@ -148,7 +148,7 @@ dtutils_system.libdoc.functions["os_execute"] = { } function dtutils_system.os_execute(cmd) - if _scripts_install.dt.configuration.running_os == "windows" then + if dt.configuration.running_os == "windows" then cmd = "\"" .. cmd .. "\"" end return os.execute(cmd) @@ -173,7 +173,7 @@ dtutils_system.libdoc.functions["io_popen"] = { } function dtutils_system.io_popen(cmd) - if _scripts_install.dt.configuration.running_os == "windows" then + if dt.configuration.running_os == "windows" then cmd = "\"" .. cmd .. "\"" end return io.popen(cmd) From 32e966f8d9b8135fcabc5bab26e1b1a80708b2de Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 00:01:47 -0400 Subject: [PATCH 36/40] tools/git_lib_manpages code cleanup --- tools/get_lib_manpages.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/get_lib_manpages.lua b/tools/get_lib_manpages.lua index 33d2d03..fbc38b8 100644 --- a/tools/get_lib_manpages.lua +++ b/tools/get_lib_manpages.lua @@ -34,7 +34,7 @@ local function output_man(d) libname = name end local fname = "/tmp/" .. name .. ".3" - local mf = dtsys.io_open(fname, "w") + local mf = dtsys.io_popen(fname, "w") if mf then mf:write(".TH " .. string.upper(name) .. " 3 \"\" \"\" \"Darktable " .. libname .. " functions\"\n") for _,section in ipairs(keys) do @@ -46,7 +46,7 @@ local function output_man(d) mf:close() if df.check_if_bin_exists("groff") then if df.check_if_bin_exists("ps2pdf") then - os.execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf") + dtsys.os_execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf") else log.msg(log.error, "Missing ps2pdf. Can't generate pdf man pages.") end From 2abb83b485922892ec1f7318481dd11c38d83fda Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 00:09:18 -0400 Subject: [PATCH 37/40] tools/get_lib_manpages - more code cleanup --- tools/get_lib_manpages.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/get_lib_manpages.lua b/tools/get_lib_manpages.lua index fbc38b8..91d5dbb 100644 --- a/tools/get_lib_manpages.lua +++ b/tools/get_lib_manpages.lua @@ -34,7 +34,7 @@ local function output_man(d) libname = name end local fname = "/tmp/" .. name .. ".3" - local mf = dtsys.io_popen(fname, "w") + local mf = io.open(fname, "w") if mf then mf:write(".TH " .. string.upper(name) .. " 3 \"\" \"\" \"Darktable " .. libname .. " functions\"\n") for _,section in ipairs(keys) do From 9f2dbef4f09f00c7043eba5fc16d26180805ccfe Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 12:15:01 -0400 Subject: [PATCH 38/40] lib/dtutils/system added local helper function quote_windows_command() to wrap a windows command in quotes. Added a sanitize step to windows_external_command() plus quote_windows_command() to deal with all the windows username possibilities --- lib/dtutils/system.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/dtutils/system.lua b/lib/dtutils/system.lua index 87a1f23..e8ce9af 100644 --- a/lib/dtutils/system.lua +++ b/lib/dtutils/system.lua @@ -1,6 +1,7 @@ local dtutils_system = {} local dt = require "darktable" +local ds = require "lib/dtutils.string" dtutils_system.libdoc = { Name = [[dtutils.system]], @@ -50,9 +51,9 @@ function dtutils_system.external_command(command) local result = nil if dt.configuration.running_os == "windows" then - result = dtutils_system.windows_command(command) + result = dtutils_system.windows_command(ds.sanitize(command)) else - result = dt.control.execute(command) + result = dt.control.execute(ds.sanitize(command)) end return result @@ -77,15 +78,20 @@ dtutils_system.libdoc.functions["windows_command"] = { Copyright = [[]], } +local function quote_windows_command(command) + return "\"" .. command .. "\"" +end + function dtutils_system.windows_command(command) local result = 1 - local fname = dt.configuration.tmp_dir .. "/run_command.bat" + local fname = ds.sanitize(dt.configuration.tmp_dir .. "/run_command.bat") local file = io.open(fname, "w") if file then dt.print_log("opened file") command = string.gsub(command, "%%", "%%%%") -- escape % from windows shell + command = quote_windows-command(command) file:write(command) file:close() @@ -149,7 +155,7 @@ dtutils_system.libdoc.functions["os_execute"] = { function dtutils_system.os_execute(cmd) if dt.configuration.running_os == "windows" then - cmd = "\"" .. cmd .. "\"" + cmd = quote_windows_command(cmd) end return os.execute(cmd) end @@ -174,7 +180,7 @@ dtutils_system.libdoc.functions["io_popen"] = { function dtutils_system.io_popen(cmd) if dt.configuration.running_os == "windows" then - cmd = "\"" .. cmd .. "\"" + cmd = quote_windows_command(cmd) end return io.popen(cmd) end From 3e032616a038cb4317c6ed897aadb5976dfac5cc Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 14:49:06 -0400 Subject: [PATCH 39/40] tools/executable_manager - fix position not visible on windows --- tools/executable_manager.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/executable_manager.lua b/tools/executable_manager.lua index 58a055a..cc98cd9 100644 --- a/tools/executable_manager.lua +++ b/tools/executable_manager.lua @@ -107,13 +107,19 @@ local function update_combobox_choices(combobox, choice_table, selected) end local function install_module() + local panel = "DT_UI_CONTAINER_PANEL_LEFT_BOTTOM" + local panel_pos = 600 + if dt.configuration.running_os == "windows" then + panel = "DT_UI_CONTAINER_PANEL_LEFT_CENTER" + panel_pos = 100 + end if not exec_man.module_installed then dt.register_lib( "executable_manager", -- Module name "executable manager", -- Visible name true, -- expandable false, -- resetable - {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_BOTTOM", 600}}, -- containers + {[dt.gui.views.lighttable] = {panel, panel_pos}}, -- containers dt.new_widget("box") -- widget { orientation = "vertical", From 539f25517bbf0a4fcc58a3408d13d9eafe3ef1b4 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 5 Jun 2024 22:16:40 -0400 Subject: [PATCH 40/40] contrib/fujifilm_ratings - added check to ensure the image is a fujifilm file. --- contrib/fujifilm_ratings.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/contrib/fujifilm_ratings.lua b/contrib/fujifilm_ratings.lua index ef93513..b2f11fe 100644 --- a/contrib/fujifilm_ratings.lua +++ b/contrib/fujifilm_ratings.lua @@ -54,6 +54,9 @@ script_data.restart = nil -- how to restart the (lib) script after it's been hid script_data.show = nil -- only required for libs since the destroy_method only hides them local function detect_rating(event, image) + if not string.match(image.filename, "%.RAF$") and not string.match(image.filename, "%.raf$") then + return + end if not df.check_if_bin_exists("exiftool") then dt.print_error(_("exiftool not found")) return @@ -61,25 +64,25 @@ local function detect_rating(event, image) local RAF_filename = df.sanitize_filename(tostring(image)) local JPEG_filename = string.gsub(RAF_filename, "%.RAF$", ".JPG") local command = "exiftool -Rating " .. JPEG_filename - dt.print_error(command) + dt.print_log(command) local output = dtsys.io_popen(command) local jpeg_result = output:read("*all") output:close() if string.len(jpeg_result) > 0 then jpeg_result = string.gsub(jpeg_result, "^Rating.*(%d)", "%1") image.rating = tonumber(jpeg_result) - dt.print_error(string.format(_("using JPEG rating: %d"), jpeg_result)) + dt.print_log("using JPEG rating: " .. jpeg_result) return end command = "exiftool -Rating " .. RAF_filename - dt.print_error(command) + dt.print_log(command) output = dtsys.io_popen(command) local raf_result = output:read("*all") output:close() if string.len(raf_result) > 0 then raf_result = string.gsub(raf_result, "^Rating.*(%d)", "%1") image.rating = tonumber(raf_result) - dt.print_error(string.format(_("using RAF rating: %d"), raf_result)) + dt.print_log("using RAF rating: " .. raf_result) end end