diff --git a/README.md b/README.md index 2eb1620..7577026 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ CollectHelper|Yes|LMW|Add buttons to selected images module to manipulate the co copy_attach_detach_tags|Yes|LMW|Copy and paste tags from/to images cr2hdr|Yes|L|Process image created with Magic Lantern Dual ISO enfuseAdvanced|No|LMW|Merge multiple images into Dynamic Range Increase (DRI) or Depth From Focus (DFF) images +ext_editor|No|LW|Export pictures to collection and edit them with up to nine user-defined external editors face_recognition|No|LM|Identify and tag images using facial recognition fujifilm_ratings|No|LM|Support importing Fujifilm ratings geoJSON_export|No|L|Create a geo JSON script with thumbnails for use in ... @@ -59,7 +60,6 @@ rename-tags|Yes|LMW|Change a tag name select_untagged|Yes|LMW|Enable selection of untagged images slideshowMusic|No|L|Play music during a slideshow video_ffmpeg|No|LMW|Export video from darktable -video_mencoder|No|L|Export video from darktable ### Example Scripts @@ -68,10 +68,13 @@ These scripts provide examples of how to use specific portions of the API. They Name|Standalone|OS |Purpose ----|:--------:|:---:|------- api_version|Yes|LMW|Print the current API version +darkroom_demo|Yes|LMW|Demonstrate changing images in darkoom gettextExample|Yes|LM|How to use translation hello_world|Yes|LMW|Prints hello world when darktable starts +lighttable_demo|Yes|LMW|Demonstrate controlling lighttable mode, zoom, sorting and filtering moduleExample|Yes|LMW|How to create a lighttable module multi_os|No|LMW|How to create a cross platform script that calls an external executable +panels_demo|Yes|LMW|Demonstrate hiding and showing darktable panels preferenceExamples|Yes|LMW|How to use preferences in a script printExamples|Yes|LMW|How to use various print functions from a script running_os|Yes|LMW|Print out the running operating system diff --git a/contrib/video_mencoder.lua b/contrib/video_mencoder.lua deleted file mode 100644 index 71c8a4d..0000000 --- a/contrib/video_mencoder.lua +++ /dev/null @@ -1,124 +0,0 @@ ---[[ - This file is part of darktable, - Copyright 2014 by Tobias Jakobs. - - 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 . -]] ---[[ -darktable video export script - -ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT -* mencoder (MEncoder is from the MPlayer Team) -* xdg-open -* xdg-user-dir - -WARNING -This script is only tested with Linux - -USAGE -* require this script from your main lua file -]] - -local dt = require "darktable" -local du = require "lib/dtutils" -local df = require "lib/dtutils.file" -require "official/yield" -local gettext = dt.gettext - -du.check_min_api_version("2.0.1", "video_mencoder") - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("video_mencoder",dt.configuration.config_dir.."/lua/locale/") - -local function _(msgid) - return gettext.dgettext("video_mencoder", msgid) -end - -local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print("Export Image "..tostring(number).."/"..tostring(total)) -end - -local function create_video_mencoder(storage, image_table, extra_data) - dt.print("video_mencoder is deprecated. Please use video_ffmpeg instead. Please see the log for more details.") - dt.print_log("The mencoder executable is no longer distributed as part of most distributions,") - dt.print_log("therefore video_mencoder is deprecated. video_ffmpeg should be used in it's place. video_mencoder") - dt.print_log("will be removed when darktable 2.8 is released.") - if not df.check_if_bin_exists("mencoder") then - dt.print_error(_("mencoder not found")) - return - end - if not df.check_if_bin_exists("xdg-open") then - dt.print_error(_("xdg-open not found")) - return - end - if not df.check_if_bin_exists("xdg-user-dir") then - dt.print_error(_("xdg-user-dir not found")) - return - end - - exportDirectory = dt.preferences.read("video_mencoder","ExportDirectory","string") - exportFilename = "output.avi" - framsePerSecond = dt.preferences.read("video_mencoder","FramesPerSecond","integer") - - dt.print_error("Will try to create video now") - -- Set the codec - local codec = "" - local codecPreferences = "" - - codecPreferences = dt.preferences.read("video_mencoder","Codec","string") - if (codecPreferences == "H.264 encoding") then - codec = 'x264' - end - if (codecPreferences == "XviD encoding") then - codec = 'xvid' - end - if not codecPreferences then - codec = 'x264' - end - - -- Create the command - local command = "mencoder -idx -nosound -noskip -ovc "..codec.." -lavcopts vcodec=mjpeg -o "..exportDirectory.."/"..exportFilename.." -mf fps="..framsePerSecond .." mf://" - - for _,v in pairs(image_table) do - command = command..v.."," - end - - dt.print_error("this is the command: "..command) - dt.control.execute( command) - - dt.print("Video created in "..exportDirectory) - - if ( dt.preferences.read("video_mencoder","OpenVideo","bool") == true ) then - local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename - dt.control.execute( playVideoCommand) - end -end - --- Preferences -dt.preferences.register("video_mencoder", "FramesPerSecond", "float", "Video exort (MEncoder): Frames per second", "Frames per Second in the Video export", 15, 1, 99, 0.1 ) -dt.preferences.register("video_mencoder", "OpenVideo", "bool", "Video exort (MEncoder): Open video after export", "Opens the Video after the export with the standard video player", false ) - -local handle = io.popen("xdg-user-dir VIDEOS") -local result = handle:read() -handle:close() -if (result == nil) then - result = "" -end -dt.preferences.register("video_mencoder", "ExportDirectory", "directory", "Video exort (MEncoder): Video export directory","A directory that will be used to export a Video",result) - --- Get the MEncoder codec list with: mencoder -ovc help -dt.preferences.register("video_mencoder", "Codec", "enum", "Video exort (MEncoder): Codec","Video codec","H.264 encoding","H.264 encoding","XviD encoding") - --- Register -dt.register_storage("video_mencoder", "Video Export (MEncoder)", show_status, create_video) diff --git a/examples/darkroom_demo.lua b/examples/darkroom_demo.lua new file mode 100644 index 0000000..e0e4052 --- /dev/null +++ b/examples/darkroom_demo.lua @@ -0,0 +1,98 @@ +--[[ + This file is part of darktable, + copyright (c) 2019 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 . +]] +--[[ + darkroom_demo - an example script demonstrating how to control image display in darkroom mode + + darkroom_demo is an example script showing how to control the currently displayed image in + darkroom mode using lua. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + * none + + USAGE + * require this script from your main lua file + + BUGS, COMMENTS, SUGGESTIONS + * Send to Bill Ferguson, wpferguson@gmail.com + + CHANGES +]] + +local dt = require "darktable" +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 + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local MODULE_NAME = "darkroom" +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 function _(msgid) + return gettext.dgettext(MODULE_NAME, msgid) +end + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- M A I N +-- - - - - - - - - - - - - - - - - - - - - - - - + +-- alias dt.control.sleep to sleep +local sleep = dt.control.sleep + +-- save the configuration + +local current_view = dt.gui.current_view() + +-- enter darkroom view + +dt.gui.current_view(dt.gui.views.darkroom) + +local max_images = 10 + +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(_("Displaying image " .. i)) + dt.gui.views.darkroom.display_image(img) + sleep(1500) + if i == max_images then + break + end +end + +-- return to lighttable view + +dt.print(_("Restoring view")) +sleep(1500) +dt.gui.current_view(current_view) + diff --git a/examples/lighttable_demo.lua b/examples/lighttable_demo.lua new file mode 100644 index 0000000..c3629ba --- /dev/null +++ b/examples/lighttable_demo.lua @@ -0,0 +1,198 @@ +--[[ + This file is part of darktable, + copyright (c) 2019 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 . +]] +--[[ + lighttable_demo - an example script demonstrating how to control lighttable display modes + + lighttable_demo is an example script showing how to control lighttable layout, sorting, and + filtering from a lua script. If the selected directory has different ratings, color labels, etc, + then the sorting and filtering display is a little clearer. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + * none + + USAGE + * require this script from your main lua file + + BUGS, COMMENTS, SUGGESTIONS + * Send to Bill Ferguson, wpferguson@gmail.com + + CHANGES +]] + +local dt = require "darktable" +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", "lighttable_demo") -- darktable 3.0 + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local MODULE_NAME = "lighttable" +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 function _(msgid) + return gettext.dgettext(MODULE_NAME, msgid) +end + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- F U N C T I O N S +-- - - - - - - - - - - - - - - - - - - - - - - - + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- M A I N +-- - - - - - - - - - - - - - - - - - - - - - - - + +-- alias dt.control.sleep to sleep +local sleep = dt.control.sleep + +local layouts = { + "DT_LIGHTTABLE_LAYOUT_ZOOMABLE", + "DT_LIGHTTABLE_LAYOUT_FILEMANAGER", + "DT_LIGHTTABLE_LAYOUT_CULLING", +} + +local sorts = { + "DT_COLLECTION_SORT_NONE", + "DT_COLLECTION_SORT_FILENAME", + "DT_COLLECTION_SORT_DATETIME", + "DT_COLLECTION_SORT_RATING", + "DT_COLLECTION_SORT_ID", + "DT_COLLECTION_SORT_COLOR", + "DT_COLLECTION_SORT_GROUP", + "DT_COLLECTION_SORT_PATH", + "DT_COLLECTION_SORT_CUSTOM_ORDER", + "DT_COLLECTION_SORT_TITLE", + "DT_COLLECTION_SORT_DESCRIPTION", + "DT_COLLECTION_SORT_ASPECT_RATIO", + "DT_COLLECTION_SORT_SHUFFLE" +} + +local sort_orders = { + "DT_COLLECTION_SORT_ORDER_ASCENDING", + "DT_COLLECTION_SORT_ORDER_DESCENDING" +} + +local ratings = { + "DT_COLLECTION_FILTER_ALL", + "DT_COLLECTION_FILTER_STAR_NO", + "DT_COLLECTION_FILTER_STAR_1", + "DT_COLLECTION_FILTER_STAR_2", + "DT_COLLECTION_FILTER_STAR_3", + "DT_COLLECTION_FILTER_STAR_4", + "DT_COLLECTION_FILTER_STAR_5", + "DT_COLLECTION_FILTER_REJECT", + "DT_COLLECTION_FILTER_NOT_REJECT" +} + +local rating_comparators = { + "DT_COLLECTION_RATING_COMP_LT", + "DT_COLLECTION_RATING_COMP_LEQ", + "DT_COLLECTION_RATING_COMP_EQ", + "DT_COLLECTION_RATING_COMP_GEQ", + "DT_COLLECTION_RATING_COMP_GT", + "DT_COLLECTION_RATING_COMP_NE" +} + +local zoom_levels = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + + +-- save filter, view, and collection parameters + +local current_layout = dt.gui.libs.lighttable_mode.layout() +local current_zoom_level = dt.gui.libs.lighttable_mode.zoom_level() +local current_rating = dt.gui.libs.filter.rating() +local current_rating_comparator = dt.gui.libs.filter.rating_comparator() +local current_sort = dt.gui.libs.filter.sort() +local current_sort_order = dt.gui.libs.filter.sort_order() + +-- cycle through layouts and zooms + +dt.print(_("lighttable layout and zoom level demonstration")) +sleep(2000) + +for n, layout in ipairs(layouts) do + dt.gui.libs.lighttable_mode.layout(layout) + dt.print(_("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)) + sleep(1500) + end + for i = 9, 1, -1 do + dt.gui.libs.lighttable_mode.zoom_level(i) + dt.print(_("Set zoom level to " .. i)) + sleep(1500) + end +end + +-- cycle through sorts + +dt.print(_("lighttable sorting demonstration")) +dt.gui.libs.lighttable_mode.layout("DT_LIGHTTABLE_LAYOUT_FILEMANAGER") +dt.gui.libs.lighttable_mode.zoom_level(5) + +for n, sort in ipairs(sorts) do + dt.gui.libs.filter.sort(sort) + dt.print(_("set lighttable sort to " .. 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)) + sleep(1500) + end +end + +-- cycle through filters + +dt.print(_("lighttable filtering demonstration")) + +for n, rating in ipairs(ratings) do + dt.gui.libs.filter.rating(rating) + dt.print(_("set filter to " .. 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)) + sleep(1500) + end +end + +-- restore settings + +dt.print(_("restoring settings")) + +current_layout = dt.gui.libs.lighttable_mode.layout(current_layout) +current_zoom_level = dt.gui.libs.lighttable_mode.zoom_level(current_zoom_level) +current_rating = dt.gui.libs.filter.rating(current_rating) +current_rating_comparator = dt.gui.libs.filter.rating_comparator(current_rating_comparator) +current_sort =dt.gui.libs.filter.sort(current_sort) +current_sort_order = dt.gui.libs.filter.sort_order(current_sort_order) diff --git a/examples/panels_demo.lua b/examples/panels_demo.lua new file mode 100644 index 0000000..edab6ae --- /dev/null +++ b/examples/panels_demo.lua @@ -0,0 +1,136 @@ +--[[ + This file is part of darktable, + copyright (c) 2019 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 . +]] +--[[ + panels_demo - an example script demonstrating how to contol panel visibility + + panels_demo is an example script showing how to control panel visibility. It cycles + through the panels hiding them one by one, then showing them one by one, then + hiding all, then showing all. Finally, the original panel visibility is restored. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + * none + + USAGE + * require this script from your main lua file + + BUGS, COMMENTS, SUGGESTIONS + * Send to Bill Ferguson, wpferguson@gmail.com + + CHANGES +]] + +local dt = require "darktable" +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", "panels_demo") -- darktable 3.0 + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- C O N S T A N T S +-- - - - - - - - - - - - - - - - - - - - - - - - + +local MODULE_NAME = "panels" +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 function _(msgid) + return gettext.dgettext(MODULE_NAME, msgid) +end + +-- - - - - - - - - - - - - - - - - - - - - - - - +-- M A I N +-- - - - - - - - - - - - - - - - - - - - - - - - + +-- alias dt.control.sleep to sleep +local sleep = dt.control.sleep + +local panels = {"DT_UI_PANEL_CENTER_TOP", -- center top panel + "DT_UI_PANEL_CENTER_BOTTOM", -- center bottom panel + "DT_UI_PANEL_TOP", -- complete top panel + "DT_UI_PANEL_LEFT", -- left panel + "DT_UI_PANEL_RIGHT", -- right panel + "DT_UI_PANEL_BOTTOM"} -- complete bottom panel + +local panel_status = {} + +-- save panel visibility + +for i = 1,#panels do + panel_status[i] = dt.gui.panel_visible(panels[i]) +end + +-- show all just in case + +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")) +sleep(1500) + +for i = 1, #panels do + 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")) + sleep(1500) + + for i = #panels, 1, -1 do + dt.print(_("Showing " .. panels[i])) + dt.gui.panel_show(panels[i]) + sleep(1500) + end + +-- hide all + +dt.print(_("Hiding all panels")) +sleep(1500) + +dt.gui.panel_hide_all() +sleep(1500) + +-- show all + +dt.print(_("Showing all panels")) +sleep(1500) + +dt.gui.panel_show_all() +sleep(1500) + +-- restore + +dt.print(_("Restoring panels to starting configuration")) +for i = 1, #panels do + if panel_status[i] then + dt.gui.panel_show(panels[i]) + else + dt.gui.panel_hide(panels[i]) + end +end diff --git a/locale/de_DE/LC_MESSAGES/select_untagged.mo b/locale/de_DE/LC_MESSAGES/select_untagged.mo deleted file mode 100644 index 340ba90..0000000 Binary files a/locale/de_DE/LC_MESSAGES/select_untagged.mo and /dev/null differ diff --git a/locale/fr_FR/LC_MESSAGES/select_untagged.mo b/locale/fr_FR/LC_MESSAGES/select_untagged.mo deleted file mode 100644 index 1bb384a..0000000 Binary files a/locale/fr_FR/LC_MESSAGES/select_untagged.mo and /dev/null differ