Compare commits
234 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d609823491 | ||
|
|
8f414f783a | ||
|
|
2e521553bf | ||
|
|
e93f5fc812 | ||
|
|
3dbbb7dfd5 | ||
|
|
fbb92e1023 | ||
|
|
ea4c6373f9 | ||
|
|
40b2569a21 | ||
|
|
ef6e4d8f0b | ||
|
|
657407c7a0 | ||
|
|
b254577bc8 | ||
|
|
63763bedc8 | ||
|
|
3d50d0fdb4 | ||
|
|
1ca6b18f5e | ||
|
|
b82ffc2af3 | ||
|
|
d142151055 | ||
|
|
91b78529fe | ||
|
|
7aec6884f4 | ||
|
|
7f140828bb | ||
|
|
4f13a56814 | ||
|
|
27d3ea253d | ||
|
|
5209b9899d | ||
|
|
6a40c836c0 | ||
|
|
c4df81bdef | ||
|
|
e99827d237 | ||
|
|
a0cbe8efd5 | ||
|
|
b4ee97a768 | ||
|
|
4bdaaaf1ce | ||
|
|
3cf0fea092 | ||
|
|
97e1451dc6 | ||
|
|
4cbb7724f2 | ||
|
|
8f6c2c82d3 | ||
|
|
a6d5001e84 | ||
|
|
6af180a313 | ||
|
|
86cc22d943 | ||
|
|
c1fbfd80d4 | ||
|
|
040a83fb17 | ||
|
|
2bc23a1446 | ||
|
|
97f4c911ed | ||
|
|
53d9a42a1a | ||
|
|
c96c5234c4 | ||
|
|
9a3eb7bc3e | ||
|
|
53f15ba8b8 | ||
|
|
ecdc74b5a6 | ||
|
|
422fdbe2cf | ||
|
|
887bc03f32 | ||
|
|
e32c0c70a8 | ||
|
|
440dfcadfd | ||
|
|
93cc0adb39 | ||
|
|
f8ec85ddae | ||
|
|
688333f756 | ||
|
|
8f314059e4 | ||
|
|
9386a08af0 | ||
|
|
19cd118f8f | ||
|
|
c196f98bc6 | ||
|
|
56ec258cc7 | ||
|
|
5da64a7da0 | ||
|
|
f272aeb9fe | ||
|
|
cf26b82d87 | ||
|
|
2041fb34c9 | ||
|
|
4b63240ab9 | ||
|
|
9d59479049 | ||
|
|
350cdfa436 | ||
|
|
15de64dcf5 | ||
|
|
d9c2519a83 | ||
|
|
9885e34f82 | ||
|
|
ed0adfbae1 | ||
|
|
beafb6c21b | ||
|
|
7810791991 | ||
|
|
1d10d5234f | ||
|
|
9900f46be4 | ||
|
|
0d2c4dfb3a | ||
|
|
752e27d97f | ||
|
|
33523fbe36 | ||
|
|
db47dd5110 | ||
|
|
a71097a8c9 | ||
|
|
931e448ebd | ||
|
|
abd8bf4a60 | ||
|
|
aee1f82d04 | ||
|
|
8112472df5 | ||
|
|
c9fa13b97b | ||
|
|
73cd301ff4 | ||
|
|
aa33ae0706 | ||
|
|
4e9c45c162 | ||
|
|
f35cea75d3 | ||
|
|
4053ceb9e5 | ||
|
|
448da35327 | ||
|
|
6d9c4c90ba | ||
|
|
5b8282e933 | ||
|
|
b1498aa664 | ||
|
|
2b28f021ee | ||
|
|
dc4938c377 | ||
|
|
69b846a856 | ||
|
|
1460396d4f | ||
|
|
b9804d9d48 | ||
|
|
ade7008127 | ||
|
|
da0235ab27 | ||
|
|
c17e832572 | ||
|
|
c12d6f01e7 | ||
|
|
778ad2ce20 | ||
|
|
33ef58ac97 | ||
|
|
8091ba9398 | ||
|
|
8e0bf9e991 | ||
|
|
daee82aa6a | ||
|
|
359a1fa3a9 | ||
|
|
021b32c1d4 | ||
|
|
1d1eb6a768 | ||
|
|
a9fd0718b0 | ||
|
|
6341a0a459 | ||
|
|
952b8b2eb2 | ||
|
|
b08d7f27d2 | ||
|
|
a71889021f | ||
|
|
367631af99 | ||
|
|
62753d1a50 | ||
|
|
dfe589e843 | ||
|
|
d09574bb17 | ||
|
|
2be12e5b37 | ||
|
|
d2086b6480 | ||
|
|
132668d04c | ||
|
|
0a4aa95965 | ||
|
|
af1e774d1f | ||
|
|
e5271d79a0 | ||
|
|
dfd714540e | ||
|
|
a0fd22be19 | ||
|
|
c0dc55b18e | ||
|
|
258def1cf8 | ||
|
|
b2095fd947 | ||
|
|
e51278f76e | ||
|
|
9af60063d8 | ||
|
|
37b523f989 | ||
|
|
96ba075e86 | ||
|
|
e86a3a3236 | ||
|
|
622a9ebab4 | ||
|
|
b26ec58f9f | ||
|
|
b41b2a1566 | ||
|
|
b893383353 | ||
|
|
ddcf3ed3f4 | ||
|
|
da05748393 | ||
|
|
976ad4ab17 | ||
|
|
8dcf19834c | ||
|
|
43315bb9cc | ||
|
|
4ab20d8088 | ||
|
|
485de32bb4 | ||
|
|
536b9726b2 | ||
|
|
41ae43e741 | ||
|
|
b5b49245fa | ||
|
|
d172ac7049 | ||
|
|
8808306a5f | ||
|
|
00dac577f6 | ||
|
|
85c218b350 | ||
|
|
6f71ef4d6b | ||
|
|
394cbdb454 | ||
|
|
62e2a7969d | ||
|
|
d9c284b54d | ||
|
|
bd2bc3659c | ||
|
|
f76fa01240 | ||
|
|
45d62f418c | ||
|
|
650325257b | ||
|
|
a0a8a61d56 | ||
|
|
998732287b | ||
|
|
509c7da384 | ||
|
|
771e03ce76 | ||
|
|
7d9b8dbdda | ||
|
|
912ae93d10 | ||
|
|
b613cc266a | ||
|
|
dfb8d4e7c6 | ||
|
|
b8e3ec4302 | ||
|
|
d4e21b7877 | ||
|
|
d10cf968f1 | ||
|
|
880ec7fc58 | ||
|
|
432b6b5dd7 | ||
|
|
5f5ad426bf | ||
|
|
52acdb9036 | ||
|
|
138b23674a | ||
|
|
8a710798f7 | ||
|
|
be5557080b | ||
|
|
994b9c6472 | ||
|
|
d05536bed4 | ||
|
|
cc4f1d7251 | ||
|
|
2ddd0965cd | ||
|
|
4e68e420cc | ||
|
|
50be8a9240 | ||
|
|
d1e330eee0 | ||
|
|
6aa5893b5f | ||
|
|
797d668ebb | ||
|
|
b23595ff54 | ||
|
|
6903f8385b | ||
|
|
e8205c6435 | ||
|
|
c114856699 | ||
|
|
57a9a8495c | ||
|
|
53bb95e6fd | ||
|
|
a40fe3099d | ||
|
|
8d38ea0cf2 | ||
|
|
ac81c95f7e | ||
|
|
48b915b0b2 | ||
|
|
593917db9a | ||
|
|
2d49b49bec | ||
|
|
323c8b6845 | ||
|
|
e5ab30006b | ||
|
|
14b97cdbd9 | ||
|
|
8f0f0a5298 | ||
|
|
497dbc8eaa | ||
|
|
11baf14280 | ||
|
|
948e8690dd | ||
|
|
802c17d590 | ||
|
|
71e72b688f | ||
|
|
877b56ad67 | ||
|
|
87502fb17f | ||
|
|
ed3e141601 | ||
|
|
f66d3ed3aa | ||
|
|
5488e45c78 | ||
|
|
72bd66d3f5 | ||
|
|
1378441dfa | ||
|
|
26d97b8cdf | ||
|
|
2e27b812d6 | ||
|
|
fd97ac18da | ||
|
|
b9d14a2711 | ||
|
|
1c9042c496 | ||
|
|
60fa4b9ee0 | ||
|
|
33f91af1af | ||
|
|
05d86e89da | ||
|
|
a02176fc63 | ||
|
|
23131a301b | ||
|
|
aef7363bee | ||
|
|
4455347930 | ||
|
|
5709cfebd4 | ||
|
|
01184bee72 | ||
|
|
286ef77663 | ||
|
|
28b9073010 | ||
|
|
fe97e29654 | ||
|
|
792e782e8c | ||
|
|
33b99a97e4 | ||
|
|
a8e5a9b453 | ||
|
|
2d69536489 |
94
ChangeLog.md
Normal file
94
ChangeLog.md
Normal file
@@ -0,0 +1,94 @@
|
||||
## Changes from most recent to oldest
|
||||
**22 Oct 2021 - wpferguson for Volker Bödker - make sure sequence is 4 digits in rename_images.lua**
|
||||
**31 Aug 2021 - wpferguson - remove styles hiding from AutoGrouper.lua**
|
||||
**02 Jul 2021 - wpferguson - merged API-7.0.0-dev branch to master**
|
||||
* API-7.0.0 is darktable 3.6
|
||||
* breaking changes
|
||||
* register_event argments changed
|
||||
* register_action arguments changed
|
||||
* register_selection arguments changed
|
||||
* register_event arguments changed
|
||||
* scripts updated to API-7.0.0 compatibility
|
||||
* script_manger updated to be API aware and check out the proper branch
|
||||
based on darktable API version
|
||||
|
||||
**01 Jul 2021 - wpferguson - created branch for API-6.1.0 - darktable 3.4**
|
||||
|
||||
**20 Jun 2021 - wpferguson - created branches for older API versions**
|
||||
* API-6.0.0 - darktable 3.2.1
|
||||
* API-5.0.2 - darktable 3.0
|
||||
* API-5.0.1 - darktable 2.6.1
|
||||
* API-5.0.0 - darktable 2.4
|
||||
* API-4.0.0 - darktable 2.2
|
||||
* API-3.0.0 - darktable 2.0
|
||||
|
||||
**19 Jun 2021 - wpferguson - fix issue 312, image_path_in_ui**
|
||||
|
||||
**02 Jun 2021 - wpferguson - fix contrib/quicktag**
|
||||
* set new entry field is_password to false so entry
|
||||
is visible to user while typing.
|
||||
|
||||
**19 Mar 2021 - wpferguson - fixed crash in contrib/HDRmerge.lua**
|
||||
* Made generated filename routine gracefully handle names that
|
||||
are not in the expected format.
|
||||
|
||||
**15 Mar 2021 - scheckmedia - updated contrib/photils.lua**
|
||||
* refactor print method
|
||||
* add option to apply selected tags from a single image to multiple images
|
||||
* add setting parameter to enable/disable the export of an image before tag suggestion
|
||||
|
||||
**25 Feb 2021 - wpferguson - added detached mode to contrib/gimp.lua**
|
||||
|
||||
* Added run_detached checkbox to the exporter GUI. Selecting run_detached
|
||||
let's GIMP keep running and accepting additional images. It does not return
|
||||
the edited images to darktable.
|
||||
|
||||
**24 Feb 2021 - Mark64 - make ext_editor lib visible in darkroom view**
|
||||
|
||||
**17 Feb 2021 - wpferguson - API 6.2.3 register_action changes**
|
||||
|
||||
* Added check for API version and supplied a name argument if the
|
||||
API version was greater than or equal to 6.2.3
|
||||
|
||||
**10 Feb 2021 - wpferguson - bugfix select_untagged**
|
||||
|
||||
* Fixed callback to return a list of images as expected instead of
|
||||
doing the selection in the callback
|
||||
|
||||
**10 Feb 2021 - wpferguson - bugfix API 6.2.1 compatibility**
|
||||
|
||||
* The inline check for API version didn't handle argument return
|
||||
correctly so added a transition library with a register_event function
|
||||
override to check the API version and process the arguments correctly.
|
||||
|
||||
**9 Feb 2021 - wpferguson - bugfix API 6.2.2 compatibility**
|
||||
|
||||
* The inline check for API version didn't handle argument return
|
||||
correctly so changed it to a full if/else block
|
||||
|
||||
**4 Reb 2021 - wpferguson - API 6.2.2 compatibililty**
|
||||
|
||||
* Added check for API version and supplied a name argument to register_selection
|
||||
if the API version was greater than or eqal to 6.2.2
|
||||
|
||||
**1 Feb 2021 - wpferguson - API 6.2.1 compatibility**
|
||||
|
||||
* Added check for API version and supplied a name argument to register_event
|
||||
if the API version was greater than or eqal to 6.2.1
|
||||
|
||||
**21 Jan 2021 - wpferguson - Modified dtutils function find_image_by_id**
|
||||
|
||||
* For users with API 6.2.0 or greater - Enabled use of new API function
|
||||
darktable.database_get_image() in find_image_by_id().
|
||||
|
||||
**19 Jan 2021 - schwerdf - Added dtutils library function find_image_by_id()**
|
||||
|
||||
* Added new library function to retrieve an image from the library based on it's ID instead
|
||||
of it's row number in the database
|
||||
|
||||
**10 Jan 2021 - chrisaga - copy_attach_detach_tags localization**
|
||||
|
||||
**7 Jan 2021 - dtorop - add contrib/fujifilm_dynamic_range**
|
||||
|
||||
* add a new contrib script, fujifilm_dynamic_range to adjust exposure
|
||||
based on the exposure bias camera setting
|
||||
182
README.md
182
README.md
@@ -7,23 +7,25 @@ efforts of the darktable developers, maintainers, contributors and community. Th
|
||||
contained in the repository, whether they can be run by themselves (Standalone - Yes) or depend on other
|
||||
scripts (Standalone - No), what operating systems they are known to work on (L - Linux, M - MacOS, W - Windows), and their purpose.
|
||||
|
||||
For the latest changes, see the [ChangeLog](ChangeLog.md)
|
||||
|
||||
### Official Scripts
|
||||
|
||||
These scripts are written primarily by the darktable developers and maintained by the authors and/or repository maintainers. They are located in the official/ directory.
|
||||
|
||||
Name|Standalone|OS |Purpose
|
||||
----|:--------:|:---:|-------
|
||||
check_for_updates|Yes|LMW|Check for updates to darktable
|
||||
copy_paste_metadata|Yes|LMW|Copy and paste metadata, tags, ratings, and color labels between images
|
||||
delete_long_tags|Yes|LMW|Delete all tags longer than a specified length
|
||||
delete_unused_tags|Yes|LMW|Delete tags that have no associated images
|
||||
enfuse|No|L|Exposure blend several images (HDR)
|
||||
generate_image_txt|No|L|Generate txt sidecar files to be overlaid on zoomed images
|
||||
image_path_in_ui|Yes|LMW|Plugin to display selected image path
|
||||
import_filter_manager|Yes|LMW|Manager for import filters
|
||||
import_filters|No|LMW|Two import filters for use with import_filter_manager
|
||||
save_selection|Yes|LMW|Provide save and restore from multiple selection buffers
|
||||
selection_to_pdf|No|L|Generate a PDF file from the selected images
|
||||
[check_for_updates](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/check_for_updates)|Yes|LMW|Check for updates to darktable
|
||||
[copy_paste_metadata](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/copy_paste_metadata)|Yes|LMW|Copy and paste metadata, tags, ratings, and color labels between images
|
||||
[delete_long_tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/delete_long_tags)|Yes|LMW|Delete all tags longer than a specified length
|
||||
[delete_unused_tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/delete_unused_tags)|Yes|LMW|Delete tags that have no associated images
|
||||
[enfuse](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/enfuse)|No|L|Exposure blend several images (HDR)
|
||||
[generate_image_txt](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/generate_image_txt)|No|L|Generate txt sidecar files to be overlaid on zoomed images
|
||||
[image_path_in_ui](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/image_path_in_ui)|Yes|LMW|Plugin to display selected image path
|
||||
[import_filter_manager](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/import_filter_manager)|Yes|LMW|Manager for import filters
|
||||
[import_filters](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/import_filters)|No|LMW|Two import filters for use with import_filter_manager
|
||||
[save_selection](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/save_selection)|Yes|LMW|Provide save and restore from multiple selection buffers
|
||||
[selection_to_pdf](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/official/selection_to_pdf)|No|L|Generate a PDF file from the selected images
|
||||
|
||||
|
||||
### Contributed Scripts
|
||||
@@ -32,36 +34,40 @@ These scripts are contributed by users. They are meant to have an "owner", i.e.
|
||||
|
||||
Name|Standalone|OS |Purpose
|
||||
----|:--------:|:---:|-------
|
||||
AutoGrouper|Yes|LMW|Group images together by time
|
||||
autostyle|Yes|LMW|Automatically apply styles on import
|
||||
clear_GPS|Yes|LMW|Reset GPS information for selected images
|
||||
CollectHelper|Yes|LMW|Add buttons to selected images module to manipulate the collection
|
||||
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 ...
|
||||
geoToolbox|No|LMW|A toolbox of geo functions
|
||||
gimp|No|LMW|Open an image in GIMP for editing and return the result
|
||||
gpx_export|No|LMW|Export a GPX track file from selected images GPS data
|
||||
HDRMerge|No|LMW|Combind the selected images into an HDR DNG and return the result
|
||||
hugin|No|LMW|Combine selected images into a panorama and return the result
|
||||
image_stack|No|LMW|Combine a stack of images to remove noise or transient objects
|
||||
kml_export|No|L|Export photos with a KML file for usage in Google Earth
|
||||
LabelsToTags|Yes|LMW|Apply tags based on color labels and ratings
|
||||
OpenInExplorer|No|LMW|Open the selected images in the system file manager
|
||||
passport_guide|Yes|LMW|Add passport cropping guide to darkroom crop tool
|
||||
pdf_slideshow|No|LM|Export images to a PDF slideshow
|
||||
quicktag|Yes|LMW|Create shortcuts for quickly applying tags
|
||||
rate_group|Yes|LMW|Apply or remove a star rating from grouped images
|
||||
rename-tags|Yes|LMW|Change a tag name
|
||||
RL_out_sharp|No|LW|Output sharpening using GMic (Richardson-Lucy algorithm)
|
||||
select_untagged|Yes|LMW|Enable selection of untagged images
|
||||
slideshowMusic|No|L|Play music during a slideshow
|
||||
transfer_hierarchy|Yes|LMW|Image move/copy preserving directory hierarchy
|
||||
video_ffmpeg|No|LMW|Export video from darktable
|
||||
[AutoGrouper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/AutoGrouper)|Yes|LMW|Group images together by time
|
||||
[autostyle](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/autostyle)|Yes|LMW|Automatically apply styles on import
|
||||
[clear_GPS](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/clear_GPS)|Yes|LMW|Reset GPS information for selected images
|
||||
[CollectHelper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/CollectHelper)|Yes|LMW|Add buttons to selected images module to manipulate the collection
|
||||
[copy_attach_detach_tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/copy_attach_detach_tags)|Yes|LMW|Copy and paste tags from/to images
|
||||
[cr2hdr](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/cr2hdr)|Yes|L|Process image created with Magic Lantern Dual ISO
|
||||
[enfuseAdvanced](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/enfuseAdvanced)|No|LMW|Merge multiple images into Dynamic Range Increase (DRI) or Depth From Focus (DFF) images
|
||||
[exportLUT](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/exportLUT)|Yes|LMW|Create a LUT from a style and export it
|
||||
[ext_editor](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/ext_editor)|No|LW|Export pictures to collection and edit them with up to nine user-defined external editors
|
||||
[face_recognition](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/face_recognition)|No|LM|Identify and tag images using facial recognition
|
||||
[fujifilm_dynamic_range](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/fujifilm_dynamic_range)|No|LMW|Correct fujifilm exposure based on exposure bias camera setting
|
||||
[fujifilm_ratings](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/fujifilm_ratings)|No|LM|Support importing Fujifilm ratings
|
||||
[geoJSON_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geoJSON_export)|No|L|Create a geo JSON script with thumbnails for use in ...
|
||||
[geoToolbox](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geoToolbox)|No|LMW|A toolbox of geo functions
|
||||
[gimp](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/gimp)|No|LMW|Open an image in GIMP for editing and return the result
|
||||
[gpx_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/gpx_export)|No|LMW|Export a GPX track file from selected images GPS data
|
||||
[HDRMerge](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/HDRMerge)|No|LMW|Combine the selected images into an HDR DNG and return the result
|
||||
[hugin](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/hugin)|No|LMW|Combine selected images into a panorama and return the result
|
||||
[image_stack](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/image_stack)|No|LMW|Combine a stack of images to remove noise or transient objects
|
||||
[image_time](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/image_time)|Yes|LMW|Adjust the EXIF image time
|
||||
[kml_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/kml_export)|No|L|Export photos with a KML file for usage in Google Earth
|
||||
[LabelsToTags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/LabelsToTags)|Yes|LMW|Apply tags based on color labels and ratings
|
||||
[OpenInExplorer](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/OpenInExplorer)|No|LMW|Open the selected images in the system file manager
|
||||
[passport_guide](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/passport_guide)|Yes|LMW|Add passport cropping guide to darkroom crop tool
|
||||
[pdf_slideshow](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/pdf_slideshow)|No|LM|Export images to a PDF slideshow
|
||||
[photils](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/photils)|No|LM|Automatic tag suggestions for your images
|
||||
[quicktag](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/quicktag)|Yes|LMW|Create shortcuts for quickly applying tags
|
||||
[rate_group](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rate_group)|Yes|LMW|Apply or remove a star rating from grouped images
|
||||
[rename-tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rename-tags)|Yes|LMW|Change a tag name
|
||||
[RL_out_sharp](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/RL_out_sharp)|No|LW|Output sharpening using GMic (Richardson-Lucy algorithm)
|
||||
[select_untagged](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/select_untagged)|Yes|LMW|Enable selection of untagged images
|
||||
[slideshowMusic](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/slideshowMusic)|No|L|Play music during a slideshow
|
||||
[transfer_hierarchy](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/transfer_hierarchy)|Yes|LMW|Image move/copy preserving directory hierarchy
|
||||
[video_ffmpeg](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/video_ffmpeg)|No|LMW|Export video from darktable
|
||||
|
||||
### Example Scripts
|
||||
|
||||
@@ -69,17 +75,17 @@ 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
|
||||
[api_version](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/api_version)|Yes|LMW|Print the current API version
|
||||
[darkroom_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/darkroom_demo)|Yes|LMW|Demonstrate changing images in darkoom
|
||||
[gettextExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/gettextExample)|Yes|LM|How to use translation
|
||||
[hello_world](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/hello_world)|Yes|LMW|Prints hello world when darktable starts
|
||||
[lighttable_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/lighttable_demo)|Yes|LMW|Demonstrate controlling lighttable mode, zoom, sorting and filtering
|
||||
[moduleExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/moduleExample)|Yes|LMW|How to create a lighttable module
|
||||
[multi_os](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/multi_os)|No|LMW|How to create a cross platform script that calls an external executable
|
||||
[panels_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/panels_demo)|Yes|LMW|Demonstrate hiding and showing darktable panels
|
||||
[preferenceExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/preferenceExamples)|Yes|LMW|How to use preferences in a script
|
||||
[printExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/printExamples)|Yes|LMW|How to use various print functions from a script
|
||||
[running_os](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/running_os)|Yes|LMW|Print out the running operating system
|
||||
|
||||
### Tools
|
||||
|
||||
@@ -87,11 +93,11 @@ Tool scripts perform functions relating to the repository, such as generating do
|
||||
|
||||
Name|Standalone|OS |Purpose
|
||||
----|:--------:|:---:|-------
|
||||
executable_manager|Yes|LMW|Manage the external executables used by the lua scripts
|
||||
gen_i18n_mo|No|LMW|Generate compiled translation files (.mo) from source files (.po)
|
||||
get_lib_manpages|No|LM|Retrieve the library documentation and output it in man page and PDF format
|
||||
get_libdoc|No|LMW|Retrieve the library documentation and output it as text
|
||||
script_manager|No|LMW|Manage (install, update, enable, disable) the lua scripts
|
||||
[executable_manager](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/tools/executable_manager)|Yes|LMW|Manage the external executables used by the lua scripts
|
||||
[gen_i18n_mo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/tools/gen_i18n_mo)|No|LMW|Generate compiled translation files (.mo) from source files (.po)
|
||||
[get_lib_manpages](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/tools/get_lib_manpages)|No|LM|Retrieve the library documentation and output it in man page and PDF format
|
||||
[get_libdoc](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/tools/get_libdoc)|No|LMW|Retrieve the library documentation and output it as text
|
||||
[script_manager](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/tools/script_manager)|No|LMW|Manage (install, update, enable, disable) the lua scripts
|
||||
|
||||
### Related third-party projects
|
||||
|
||||
@@ -116,14 +122,24 @@ are met as well as providing an easy update path. Single scripts listed as stand
|
||||
|
||||
### snap packages
|
||||
|
||||
The snap version of darktable comes with lua included starting with version 2.4.3snap2. It is currently in the edge channel, but should reach the stable channel soon.
|
||||
The snap version of darktable comes with lua included starting with version 2.4.3snap2.
|
||||
|
||||
Ensure git is installed on your system. If it isn't, use the package manager to install it. Then open a terminal and:
|
||||
|
||||
cd ~/snap/darktable/current
|
||||
git clone https://github.com/darktable-org/lua-scripts.git lua
|
||||
|
||||
### flatpak and appimage packages
|
||||
### flatpak packages
|
||||
|
||||
Flatpak packages now use the internal lua interpreter.
|
||||
|
||||
|
||||
Ensure git is installed on your system. If it isn't, use the package manager to install it. Then open a terminal and:
|
||||
|
||||
cd ~/.var/app/org.darktable.Darktable/config/darktable
|
||||
git clone https://github.com/darktable-org/lua-scripts.git lua
|
||||
|
||||
### appimage packages
|
||||
|
||||
These packages run in their own environment and don't have access to a lua interpreter, therefore the scripts can't run. The packagers could enable the internal interpreter, or allow the package to link the interpreter from the operating system, or bundle a copy of lua with the package. If you use one of these packages and wish to use the lua scripts, please contact the package maintainer and suggest the above fixes.
|
||||
|
||||
@@ -138,8 +154,6 @@ Ensure git is installed on your system. If it isn't, use the package manager to
|
||||
|
||||
Ensure git is installed on your system. Git can be obtained from https://gitforwindows.org/, as well as other places. If you use the gitforwindows.org distribution, install the Git Bash Shell also as it will aid in debugging the scripts if necessary. Then open a command prompt and run:
|
||||
|
||||
Open a command prompt.
|
||||
|
||||
cd %LOCALAPPDATA%\darktable
|
||||
git clone https://github.com/darktable-org/lua-scripts.git lua
|
||||
|
||||
@@ -149,6 +163,24 @@ If you don't have %LOCALAPPDATA%\darktable you have to start dartable at least o
|
||||
|
||||
When darktable starts it looks for a file name `~/.config/darktable/luarc` (`%LOCALAPPDATA%\darktable\luarc` for windows) and reads it to see which scripts to include. The file is a plain text file with entries of the form `require "<directory>/<name>"` where directory is the directory containing the scripts, from the above list, and name is the name from the above list. To include GIMP the line would be `require "contrib/gimp"`.
|
||||
|
||||
The recommended way to enable and disable specific scripts is using the script manager module. To use script manager do the following:
|
||||
|
||||
### Linux or MacOS
|
||||
|
||||
echo 'require "tools/script_manager"' > ~/.config/darktable/luarc
|
||||
|
||||
### Windows
|
||||
|
||||
echo "require 'tools/script_manager'" > %LOCALAPPDATA%\darktable\luarc
|
||||
|
||||
### Snap
|
||||
|
||||
echo 'require "tools/script_manager"' > ~/snap/darktable/current/luarc
|
||||
|
||||
### Flatpak
|
||||
|
||||
echo require "tools/script_manager"' > ~/.var/app/org.darktable.Darktable/config/darktable/luarc
|
||||
|
||||
You can also create or add lines to the luarc file from the command line:
|
||||
|
||||
`echo 'require "contrib/gimp"' > ~/.config/darktable/luarc` to create the file with a gimp entry\
|
||||
@@ -172,6 +204,12 @@ To update the script repository, open a terminal or command prompt and do the fo
|
||||
cd ~/snap/darktable/current/lua
|
||||
git pull
|
||||
|
||||
|
||||
### Flatpak
|
||||
|
||||
cd ~/.var/app/org.darktable.Darktable/config/darktable/lua
|
||||
git pull
|
||||
|
||||
### Linux and MacOS
|
||||
|
||||
cd ~/.config/darktable/lua/
|
||||
@@ -184,15 +222,19 @@ To update the script repository, open a terminal or command prompt and do the fo
|
||||
|
||||
## Documentation
|
||||
|
||||
Each script includes its own documentation and usage in its header, please refer to them.
|
||||
The [Lua Scripts Manual](https://darktable-org.github.io/luadocs/lua.scripts.manual/) provides documentation
|
||||
for the scripts transcribed from the header comments. Each script also contains comments and usage instructions
|
||||
in the header comments.
|
||||
|
||||
Lua-script libraries documentation may be generated using the tools in the tools/ directory.
|
||||
The [Lua Scripts Library API Manual](https://darktable-org.github.io/luadocs/lua.scripts.api.manual/) provides
|
||||
documentation of the libraries and functions. Lua-script libraries documentation may also be generated using
|
||||
the tools in the tools/ directory.
|
||||
|
||||
More information about the scripting with Lua can be found in the darktable user manual:
|
||||
https://www.darktable.org/usermanual/en/lua_chapter.html
|
||||
[Scripting with Lua](https://darktable-org.github.io/dtdocs/lua/)
|
||||
|
||||
The darktable Lua API documentation is here:
|
||||
https://www.darktable.org/lua-api/
|
||||
The [Lua API Manual](https://darktable-org.github.io/luadocs/lua.api.manual/) provides docuemntation of the
|
||||
darktable Lua API.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -202,13 +244,17 @@ Running darktable with Lua debugging enabled provides more information about wha
|
||||
|
||||
Open a terminal and start darktable with the command `snap run darktable -d lua`. This provides debugging information to give you insight into what is happening.
|
||||
|
||||
### Linux and MacOS
|
||||
### Linux
|
||||
|
||||
Open a terminal and start darktable with the command `darktable -d lua`. This provides debugging information to give you insight into what is happening.
|
||||
|
||||
### MacOS
|
||||
|
||||
Open a terminal and start darktable with the command `/Applications/darktable.app/Contents/MacOS/darktable -d lua`. This provides debugging information to give you insight into what is happening.
|
||||
|
||||
### Windows
|
||||
|
||||
Open the Git Bash Shell. Start darktable with the command `/c/Program\ Files/darktable/bin/darktable -d lua`. This provides debugging information to give you insight into what is happening.
|
||||
Open a command prompt. Start darktable with the command "C:\Program Files\darktable\bin\darktable" -d lua > log.txt. This provides debugging information to give you insight into what is happening.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -37,122 +37,182 @@ selected images, the other button performs grouping on the entire active collect
|
||||
]]
|
||||
|
||||
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
|
||||
|
||||
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 function _(msgid)
|
||||
return gettext.dgettext("AutoGrouper", msgid)
|
||||
return gettext.dgettext("AutoGrouper", 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
|
||||
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
|
||||
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}
|
||||
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)
|
||||
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()
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
-- GUI --
|
||||
GUI = {
|
||||
gap = {},
|
||||
selected = {},
|
||||
collection = {}
|
||||
}
|
||||
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
|
||||
}
|
||||
dt.register_lib(
|
||||
'AutoGroup_Lib', -- 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"){
|
||||
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
|
||||
|
||||
@@ -46,6 +46,7 @@ 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 previous = nil
|
||||
local all_active = false
|
||||
@@ -53,6 +54,16 @@ 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
|
||||
|
||||
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
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("CollectHelper", msgid)
|
||||
end
|
||||
@@ -65,6 +76,7 @@ local function CheckSingleImage(selection)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function CheckHasColorLabel(selection)
|
||||
local ret = false
|
||||
for _,image in pairs(selection) do
|
||||
@@ -81,6 +93,7 @@ local function PreviousCollection()
|
||||
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
|
||||
@@ -101,6 +114,7 @@ local function CollectOnFolder(all_rules, all_active)
|
||||
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
|
||||
@@ -157,6 +171,7 @@ local function CollectOnColors(all_rules, all_active)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function CollectOnAll_AND()
|
||||
local images = dt.gui.selection()
|
||||
if CheckSingleImage(images) then
|
||||
@@ -172,29 +187,42 @@ local function CollectOnAll_AND()
|
||||
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(
|
||||
_("collect: previous"),
|
||||
"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(
|
||||
_("collect: folder"),
|
||||
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(
|
||||
_("collect: color label(s)"),
|
||||
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(
|
||||
_("collect: all (AND)"),
|
||||
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")
|
||||
)
|
||||
@@ -204,7 +232,7 @@ end
|
||||
dt.preferences.register("module_CollectHelper", "all_and", -- name
|
||||
"bool", -- type
|
||||
_('CollectHelper: All'), -- label
|
||||
_('Will create a collect parameter set that utelizes all enabled CollectHelper types (AND)'), -- tooltip
|
||||
_('Will create a collect parameter set that utilizes all enabled CollectHelper types (AND)'), -- tooltip
|
||||
true -- default
|
||||
)
|
||||
dt.preferences.register("module_CollectHelper", "colors", -- name
|
||||
@@ -219,3 +247,7 @@ dt.preferences.register("module_CollectHelper", "folder", -- name
|
||||
_('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
|
||||
|
||||
@@ -45,380 +45,434 @@ Select a style, whether you want tags to be copied from the original, and any ad
|
||||
]]
|
||||
|
||||
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
|
||||
|
||||
|
||||
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.bindtextdomain('HDRMerge',dt.configuration.config_dir..'/lua/locale/')
|
||||
gettext.bindtextdomain('HDRMerge', dt.configuration.config_dir..'/lua/locale/')
|
||||
local function _(msgid)
|
||||
return gettext.dgettext('HDRMerge', 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'}
|
||||
}
|
||||
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 = {},
|
||||
}
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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 locatoin'))
|
||||
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'))
|
||||
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
|
||||
dt.print(_('update unsuccessful, please try again'))
|
||||
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)
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
_, source_name, source_id = GetFileName(image.filename)
|
||||
source_id = tonumber(source_id)
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
-- create run command and execute
|
||||
local run_cmd = BuildExecuteCmd(HDRM)
|
||||
resp = dsys.external_command(run_cmd)
|
||||
end
|
||||
|
||||
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
|
||||
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')
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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')
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
orientation = 'vertical',
|
||||
GUI.exes.HDRMerge,
|
||||
GUI.exes.update
|
||||
}
|
||||
GUI.stack = dt.new_widget('stack'){
|
||||
GUI.options,
|
||||
exes_box
|
||||
GUI.options,
|
||||
exes_box
|
||||
}
|
||||
if dt.preferences.read(mod, 'bin_exists', 'bool') then
|
||||
GUI.stack.active = 1
|
||||
GUI.stack.active = 1
|
||||
else
|
||||
GUI.stack.active = 2
|
||||
GUI.stack.active = 2
|
||||
end
|
||||
|
||||
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
|
||||
}
|
||||
)
|
||||
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
|
||||
@@ -50,11 +50,23 @@
|
||||
local darktable = require("darktable")
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("3.0.0", "LabelsToTags")
|
||||
du.check_min_api_version("7.0.0", "LabelsToTags")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Lua 5.3 no longer has "unpack" but "table.unpack"
|
||||
unpack = unpack or table.unpack
|
||||
|
||||
local ltt = {}
|
||||
ltt.module_installed = false
|
||||
ltt.event_registered = false
|
||||
|
||||
local LIB_ID = "LabelsToTags"
|
||||
|
||||
-- Helper functions: BEGIN
|
||||
@@ -139,16 +151,16 @@ local mappingComboBox = darktable.new_widget("combobox"){
|
||||
tooltip = getComboboxTooltip(),
|
||||
reset_callback = function(selfC)
|
||||
if selfC == nil then
|
||||
return
|
||||
return
|
||||
end
|
||||
i = 1
|
||||
for _,m in pairs(keySet(getAvailableMappings())) do
|
||||
selfC[i] = m
|
||||
i = i+1
|
||||
selfC[i] = m
|
||||
i = i+1
|
||||
end
|
||||
n = #selfC
|
||||
for j = i,n do
|
||||
selfC[i] = nil
|
||||
selfC[i] = nil
|
||||
end
|
||||
selfC.value = 1
|
||||
selfC.tooltip = getComboboxTooltip()
|
||||
@@ -167,24 +179,24 @@ local function doTagging(selfC)
|
||||
local tagsToApply = {}
|
||||
local hash = generateLabelHash(img)
|
||||
for k,v in pairs(availableMappings[mappingComboBox.value]) do
|
||||
if hashMatch(hash,k) then
|
||||
for _,tag in ipairs(v) do
|
||||
tagsToApply[tag] = true
|
||||
end
|
||||
end
|
||||
if hashMatch(hash,k) then
|
||||
for _,tag in ipairs(v) do
|
||||
tagsToApply[tag] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for k,_ in pairs(tagsToApply) do
|
||||
if memoizedTags[k] == nil then
|
||||
memoizedTags[k] = darktable.tags.create(k)
|
||||
end
|
||||
darktable.tags.attach(memoizedTags[k],img)
|
||||
if memoizedTags[k] == nil then
|
||||
memoizedTags[k] = darktable.tags.create(k)
|
||||
end
|
||||
darktable.tags.attach(memoizedTags[k],img)
|
||||
end
|
||||
job.percent = job.percent + pctIncrement
|
||||
end
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local my_widget = darktable.new_widget("box") {
|
||||
ltt.my_widget = darktable.new_widget("box") {
|
||||
orientation = "vertical",
|
||||
mappingComboBox,
|
||||
darktable.new_widget("button") {
|
||||
@@ -203,20 +215,37 @@ darktable.register_tag_mapping = function(name, mapping)
|
||||
end
|
||||
for pattern,tags in pairs(mapping) do
|
||||
if string.match(pattern,PATTERN_PATTERN) == nil then
|
||||
darktable.print_error("In tag mapping '" .. name .. "': Pattern '" .. pattern .. "' invalid")
|
||||
return
|
||||
darktable.print_error("In tag mapping '" .. name .. "': Pattern '" .. pattern .. "' invalid")
|
||||
return
|
||||
end
|
||||
for _,tag in ipairs(tags) do
|
||||
if type(tag) ~= "string" then
|
||||
darktable.print_error("In tag mapping '" .. name .. "': All tag mappings must be lists of strings")
|
||||
return
|
||||
end
|
||||
if type(tag) ~= "string" then
|
||||
darktable.print_error("In tag mapping '" .. name .. "': All tag mappings must be lists of strings")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
availableMappings[name] = mapping
|
||||
mappingComboBox.reset_callback(mappingComboBox)
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not ltt.module_installed then
|
||||
darktable.register_lib(LIB_ID,"labels to tags",true,true,{
|
||||
[darktable.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",20},
|
||||
},ltt.my_widget,nil,nil)
|
||||
ltt.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
darktable.gui.libs[LIB_ID].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
darktable.gui.libs[LIB_ID].visible = true
|
||||
end
|
||||
|
||||
--[[
|
||||
darktable.register_tag_mapping("Example",
|
||||
{ ["+----*"] = { "Red", "Only red" },
|
||||
@@ -229,6 +258,25 @@ darktable.register_tag_mapping("Example",
|
||||
["*****R"] = { "Rejected" } })
|
||||
]]
|
||||
|
||||
darktable.register_lib(LIB_ID,"labels to tags",true,true,{
|
||||
[darktable.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",20},
|
||||
},my_widget,nil,nil)
|
||||
if darktable.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not ltt.event_registered then
|
||||
darktable.register_event(
|
||||
LIB_ID, "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
ltt.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
|
||||
|
||||
@@ -32,12 +32,18 @@ Install: (see here for more detail: https://github.com/darktable-org/lua-scripts
|
||||
|
||||
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 before Catalina) will open one window for each selected image at the file's location. The file name will be highlighted.
|
||||
- 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 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?).
|
||||
- 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----
|
||||
]]
|
||||
|
||||
@@ -48,8 +54,17 @@ local dsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext
|
||||
|
||||
--Check API version
|
||||
du.check_min_api_version("5.0.0", "OpenInExplorer")
|
||||
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
|
||||
|
||||
-- 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)
|
||||
@@ -59,53 +74,164 @@ end
|
||||
local act_os = dt.configuration.running_os
|
||||
local PS = act_os == "windows" and "\\" or "/"
|
||||
|
||||
--Detect OS and quit if it is not supported--
|
||||
local proper_install = true
|
||||
--Detect OS and quit if it is not supported.
|
||||
if act_os ~= "macos" and act_os ~= "windows" and act_os ~= "linux" then
|
||||
proper_install = false
|
||||
dt.print_error(_('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
|
||||
|
||||
--Format strings for the commands to open the corresponding OS' file manager
|
||||
local fmng_cmd = {}
|
||||
fmng_cmd.linux = [[busctl --user call org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1 ShowItems ass %d %s""]]
|
||||
fmng_cmd.macos = 'open -Rn %s'
|
||||
fmng_cmd.windows = 'explorer.exe /select, %s'
|
||||
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
|
||||
|
||||
--The working function that opens the file manager windows with the selected image file names highlighted.
|
||||
local function open_in_fmanager(op_sys, fmcmd)
|
||||
local images = dt.gui.selection()
|
||||
local curr_image, run_cmd, file_uris = '', '', ''
|
||||
if #images == 0 then
|
||||
dt.print(_('Please select an image'))
|
||||
elseif #images <= 15 then
|
||||
for _,image in pairs(images) do
|
||||
curr_image = image.path..PS..image.filename
|
||||
if op_sys == 'linux' then
|
||||
file_uris = file_uris .. df.sanitize_filename("file://" .. curr_image) .. " "
|
||||
dt.print_log("file_uris is " .. file_uris)
|
||||
else
|
||||
run_cmd = string.format(fmcmd, df.sanitize_filename(curr_image))
|
||||
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
|
||||
dsys.external_command(run_cmd)
|
||||
end
|
||||
end
|
||||
if op_sys == 'linux' then
|
||||
run_cmd = string.format(fmcmd, #images, file_uris)
|
||||
dt.print_log("OpenInExplorer run_cmd = "..run_cmd)
|
||||
dsys.external_command(run_cmd)
|
||||
end
|
||||
else
|
||||
dt.print(_('Please select fewer images (max 15)'))
|
||||
--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 --
|
||||
if proper_install then
|
||||
dt.gui.libs.image.register_action(
|
||||
_("show in file explorer"),
|
||||
function() open_in_fmanager(act_os, fmng_cmd[act_os]) end,
|
||||
_("Opens the file manager at the selected image's location")
|
||||
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
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
--[[
|
||||
Richardson-Lucy output sharpening for darktable using GMic
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
--[[
|
||||
DESCRIPTION
|
||||
RL_out_sharp.lua - Richardson-Lucy output sharpening using GMic
|
||||
|
||||
This script provides a new target storage "RL output sharpen".
|
||||
Images exported will be sharpened using GMic (RL deblur algorithm)
|
||||
|
||||
REQUIRED SOFTWARE
|
||||
GMic command line interface (CLI) https://gmic.eu/download.shtml
|
||||
|
||||
USAGE
|
||||
* require this script from main lua file
|
||||
* in lua preferences, select the GMic cli executable
|
||||
@@ -33,7 +52,6 @@
|
||||
|
||||
CHANGES
|
||||
* 20200308 - initial version
|
||||
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
@@ -45,7 +63,15 @@ local dtsys = require "lib/dtutils.system"
|
||||
local MODULE_NAME = "RL_out_sharp"
|
||||
|
||||
-- check API version
|
||||
du.check_min_api_version("5.0.0", MODULE_NAME)
|
||||
du.check_min_api_version("7.0.0", MODULE_NAME)
|
||||
|
||||
-- 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
|
||||
|
||||
-- OS compatibility
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
@@ -137,6 +163,12 @@ local function export2RL(storage, image_table, extra_data)
|
||||
dt.print(_("finished exporting"))
|
||||
end
|
||||
|
||||
-- script_manager integration
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("exp2RL")
|
||||
end
|
||||
|
||||
-- new widgets ----------------------------------------------------------------
|
||||
|
||||
output_folder_selector = dt.new_widget("file_chooser_button"){
|
||||
@@ -156,7 +188,7 @@ sigma_slider = dt.new_widget("slider"){
|
||||
soft_max = 2.0,
|
||||
hard_min = 0.0,
|
||||
hard_max = 3.0,
|
||||
step = 0.1,
|
||||
step = 0.05,
|
||||
digits = 2,
|
||||
value = 1.0
|
||||
}
|
||||
@@ -206,6 +238,12 @@ sigma_slider.value = dt.preferences.read(MODULE_NAME, "sigma", "float")
|
||||
iterations_slider.value = dt.preferences.read(MODULE_NAME, "iterations", "float")
|
||||
jpg_quality_slider.value = dt.preferences.read(MODULE_NAME, "jpg_quality", "float")
|
||||
|
||||
-- script_manager integration
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
-- end of script --------------------------------------------------------------
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
@@ -40,100 +40,18 @@ local darktable = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local filelib = require "lib/dtutils.file"
|
||||
|
||||
-- Forward declare the functions
|
||||
local autostyle_apply_one_image,autostyle_apply_one_image_event,autostyle_apply,exiftool_attribute,capture
|
||||
du.check_min_api_version("7.0.0", "autostyle")
|
||||
|
||||
-- Tested it with darktable 1.6.1 and darktable git from 2014-01-25
|
||||
du.check_min_api_version("2.0.2", "autostyle")
|
||||
-- return data structure for script_manager
|
||||
|
||||
-- Receive the event triggered
|
||||
function autostyle_apply_one_image_event(event,image)
|
||||
autostyle_apply_one_image(image)
|
||||
end
|
||||
local script_data = {}
|
||||
|
||||
-- Apply the style to an image, if it matches the tag condition
|
||||
function autostyle_apply_one_image (image)
|
||||
-- We need the tag, the value and the style_name provided from the configuration string
|
||||
local tag,value,style_name=string.match(darktable.preferences.read("autostyle","exif_tag","string"),"(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)")
|
||||
|
||||
-- check they all exist (correct syntax)
|
||||
if (not tag) then
|
||||
darktable.print("EXIF TAG not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return 0
|
||||
end
|
||||
if (not value) then
|
||||
darktable.print("value to match not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return 0
|
||||
end
|
||||
if (not style_name) then
|
||||
darktable.print("style name not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return 0
|
||||
end
|
||||
if not filelib.check_if_bin_exists("exiftool") then
|
||||
darktable.print("Can't find exiftool")
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
-- First find the style (we have its name)
|
||||
local styles= darktable.styles
|
||||
local style
|
||||
for _,s in ipairs(styles) do
|
||||
if s.name == style_name then
|
||||
style=s
|
||||
end
|
||||
end
|
||||
if (not style) then
|
||||
darktable.print("style not found for autostyle: " .. style_name)
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Apply the style to image, if it is tagged
|
||||
local ok,auto_dr_attr= pcall(exiftool_attribute,image.path .. '/' .. image.filename,tag)
|
||||
--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")
|
||||
return 0
|
||||
end
|
||||
if auto_dr_attr==value then
|
||||
darktable.print_log("Image " .. image.filename .. ": autostyle automatically applied " .. darktable.preferences.read("autostyle","exif_tag","string") )
|
||||
darktable.styles.apply(style,image)
|
||||
return 1
|
||||
else
|
||||
darktable.print_log("Image " .. image.filename .. ": autostyle not applied, exif tag " .. darktable.preferences.read("autostyle","exif_tag","string") .. " not matched: " .. auto_dr_attr)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function autostyle_apply( shortcut)
|
||||
local images = darktable.gui.action_images
|
||||
local images_processed =0
|
||||
local images_submitted =0
|
||||
for _,image in pairs(images) do
|
||||
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)")
|
||||
end
|
||||
|
||||
-- Retrieve the attribute through exiftool
|
||||
function exiftool_attribute(path,attr)
|
||||
local cmd="exiftool -" .. attr .. " '" .. path .. "'";
|
||||
local exifresult=get_stdout(cmd)
|
||||
local attribute=string.match(exifresult,": (.*)")
|
||||
if (attribute == nil) then
|
||||
darktable.print_error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">")
|
||||
-- Raise an error to the caller
|
||||
error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">");
|
||||
end
|
||||
-- darktable.print_error("Returning attribute: " .. attribute)
|
||||
return attribute
|
||||
end
|
||||
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
|
||||
|
||||
-- run command and retrieve stdout
|
||||
function get_stdout(cmd)
|
||||
local function get_stdout(cmd)
|
||||
-- Open the command, for reading
|
||||
local fd = assert(io.popen(cmd, 'r'))
|
||||
darktable.control.read(fd)
|
||||
@@ -150,12 +68,108 @@ function get_stdout(cmd)
|
||||
return data
|
||||
end
|
||||
|
||||
-- Retrieve the attribute through exiftool
|
||||
local function exiftool_attribute(path, attr)
|
||||
local cmd = "exiftool -" .. attr .. " '" .. path .. "'";
|
||||
local exifresult = get_stdout(cmd)
|
||||
local attribute = string.match(exifresult, ": (.*)")
|
||||
if (attribute == nil) then
|
||||
darktable.print_error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">")
|
||||
-- Raise an error to the caller
|
||||
error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">");
|
||||
end
|
||||
-- darktable.print_error("Returning attribute: " .. attribute)
|
||||
return attribute
|
||||
end
|
||||
|
||||
-- Apply the style to an image, if it matches the tag condition
|
||||
local function autostyle_apply_one_image (image)
|
||||
|
||||
local pref = darktable.preferences.read("autostyle", "exif_tag", "string")
|
||||
-- We need the tag, the value and the style_name provided from the configuration string
|
||||
local tag, value, style_name = string.match(pref, "(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)")
|
||||
|
||||
-- check they all exist (correct syntax)
|
||||
if (not tag) then
|
||||
darktable.print("EXIF TAG not found in " .. pref)
|
||||
return 0
|
||||
end
|
||||
if (not value) then
|
||||
darktable.print("value to match not found in " .. pref)
|
||||
return 0
|
||||
end
|
||||
if (not style_name) then
|
||||
darktable.print("style name not found in " .. pref)
|
||||
return 0
|
||||
end
|
||||
if not filelib.check_if_bin_exists("exiftool") then
|
||||
darktable.print("Can't find exiftool")
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
-- First find the style (we have its name)
|
||||
local styles = darktable.styles
|
||||
local style
|
||||
for _, s in ipairs(styles) do
|
||||
if s.name == style_name then
|
||||
style = s
|
||||
end
|
||||
end
|
||||
if (not style) then
|
||||
darktable.print("style not found for autostyle: " .. style_name)
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Apply the style to image, if it is tagged
|
||||
local ok, auto_dr_attr = pcall(exiftool_attribute, image.path .. '/' .. image.filename,tag)
|
||||
--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")
|
||||
return 0
|
||||
end
|
||||
if auto_dr_attr == value then
|
||||
darktable.print_log("Image " .. image.filename .. ": autostyle automatically applied " .. pref)
|
||||
darktable.styles.apply(style,image)
|
||||
return 1
|
||||
else
|
||||
darktable.print_log("Image " .. image.filename .. ": autostyle not applied, exif tag " .. pref .. " not matched: " .. auto_dr_attr)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Receive the event triggered
|
||||
local function autostyle_apply_one_image_event(event,image)
|
||||
autostyle_apply_one_image(image)
|
||||
end
|
||||
|
||||
local function autostyle_apply(shortcut)
|
||||
local images = darktable.gui.action_images
|
||||
local images_processed = 0
|
||||
local images_submitted = 0
|
||||
for _,image in pairs(images) do
|
||||
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)")
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
darktable.destroy_event("autostyle", "shortcut")
|
||||
darktable.destroy_event("autostyle", "post-import-image")
|
||||
end
|
||||
|
||||
-- Registering events
|
||||
darktable.register_event("shortcut",autostyle_apply,
|
||||
darktable.register_event("autostyle", "shortcut", autostyle_apply,
|
||||
"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("post-import-image",autostyle_apply_one_image_event)
|
||||
darktable.register_event("autostyle", "post-import-image",
|
||||
autostyle_apply_one_image_event)
|
||||
|
||||
|
||||
script_data.destroy = destroy
|
||||
return script_data
|
||||
@@ -1,6 +1,6 @@
|
||||
--[[
|
||||
|
||||
clear_GPS.lua - export and edit with GIMP
|
||||
clear_GPS.lua - plugin for Darktable
|
||||
|
||||
Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
|
||||
@@ -38,13 +38,21 @@
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
-- 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
|
||||
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
-- not a number
|
||||
local NaN = 0/0
|
||||
|
||||
du.check_min_api_version("3.0.0", "clear_GPS")
|
||||
|
||||
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/")
|
||||
@@ -62,15 +70,23 @@ local function clear_GPS(images)
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_event("clear_GPS", "shortcut")
|
||||
dt.gui.libs.image.destroy_action("clear_GPS")
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
_("clear GPS data"),
|
||||
"clear_GPS", _("clear GPS data"),
|
||||
function(event, images) clear_GPS(images) end,
|
||||
"clear GPS data"
|
||||
_("Clear GPS data from selected images")
|
||||
)
|
||||
|
||||
dt.register_event(
|
||||
"shortcut",
|
||||
"clear_GPS", "shortcut",
|
||||
function(event, shortcut) clear_GPS(dt.gui.action_images) end,
|
||||
"clear GPS data"
|
||||
_("Clear GPS data")
|
||||
)
|
||||
|
||||
return script_data
|
||||
|
||||
372
contrib/color_profile_manager.lua
Normal file
372
contrib/color_profile_manager.lua
Normal file
@@ -0,0 +1,372 @@
|
||||
--[[
|
||||
|
||||
color_profile_manager.lua - manage external darktable color profiles
|
||||
|
||||
Copyright (C) 2021 Bill Ferguson <wpferguson@gmail.com>.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
color_profile_manager - manage external darktable color profiles
|
||||
|
||||
This script provides a tool to manage input and output external color
|
||||
profiles used by darktable. Color profiles can be added or removed
|
||||
to/from the correct directories so that darktable can find and use
|
||||
them.
|
||||
|
||||
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
|
||||
* None
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file
|
||||
* select the input or output set of color profiles
|
||||
* a list of profiles is displayed. Click the check box beside the
|
||||
profile name to select it for removal. Click the "remove profile"
|
||||
button to remove the profile.
|
||||
* use the file selector to select a color profile to add to the currently
|
||||
selected set (input or output)
|
||||
* click the "add profile" button to add the profile to the selected set
|
||||
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
* Send to Bill Ferguson, wpferguson@gmail.com or raise an issue on
|
||||
https://github.com/dakrtable-org/lua-scripts
|
||||
]]
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
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 function _(msgid)
|
||||
return gettext.dgettext("color_profile_manager", msgid)
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- C O N S T A N T S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
local MODULE_NAME = "color_profile_manager"
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
local CS = dt.configuration.running_os == "windows" and "&" or ";"
|
||||
local DIR_CMD = dt.configuration.running_os == "windows" and "dir /b" or "ls"
|
||||
local COLOR_IN_DIR = dt.configuration.config_dir .. PS .. "color" .. PS .. "in"
|
||||
local COLOR_OUT_DIR = dt.configuration.config_dir .. PS .. "color" .. PS .. "out"
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- N A M E S P A C E
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
local cpm = {}
|
||||
cpm.widgets = {}
|
||||
cpm.widgets.profile_box = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
}
|
||||
cpm.module_installed = false
|
||||
cpm.event_registered = false
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- F U N C T I O N S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
local function check_for_directories()
|
||||
if not df.test_file(COLOR_IN_DIR, "d") then
|
||||
dt.print_log("didn't find " .. COLOR_IN_DIR)
|
||||
return false
|
||||
elseif not df.test_file(COLOR_OUT_DIR, "d") then
|
||||
dt.print_log("didn't find " .. COLOR_OUT_DIR)
|
||||
return false
|
||||
else
|
||||
dt.print_log("both directories exist")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function add_directories()
|
||||
df.mkdir(COLOR_IN_DIR)
|
||||
df.mkdir(COLOR_OUT_DIR)
|
||||
end
|
||||
|
||||
local function list_profiles(dir)
|
||||
local files = {}
|
||||
local p = io.popen(DIR_CMD .. " " .. dir)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
table.insert(files, line)
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
return files
|
||||
end
|
||||
|
||||
local function add_profile(file, dir)
|
||||
df.file_copy(file, dir)
|
||||
dt.print(_("added color profile " .. file .. " to " .. 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_log("color profile " .. file .. " removed from " .. dir)
|
||||
end
|
||||
|
||||
local function clear_profile_box()
|
||||
for i = #cpm.widgets.profile_box, 1, -1 do
|
||||
cpm.widgets.profile_box[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function add_profile_callback()
|
||||
local profile_dir = COLOR_IN_DIR
|
||||
if cpm.widgets.profile_set.selected == 2 then
|
||||
profile_dir = COLOR_OUT_DIR
|
||||
end
|
||||
|
||||
local new_profile = cpm.widgets.profile_selector.value
|
||||
if string.lower(df.get_filetype(new_profile)) ~= "icm" and string.lower(df.get_filetype(new_profile)) ~= "icc" then
|
||||
dt.print(_("ERROR: color profile must be an icc or icm file"))
|
||||
dt.print_error(new_profile .. " selected and isn't an icc or icm file")
|
||||
return
|
||||
end
|
||||
|
||||
-- set selector value to directory that new profile came from
|
||||
-- in case there are more
|
||||
cpm.widgets.profile_selector.value = df.get_path(cpm.widgets.profile_selector.value)
|
||||
add_profile(new_profile, profile_dir)
|
||||
local files = list_profiles(profile_dir)
|
||||
local widgets = {}
|
||||
|
||||
local profile_ptr = 1
|
||||
for i, file in ipairs(files) do
|
||||
if #cpm.widgets.profile_box == 0 or cpm.widgets.profile_box[profile_ptr].label ~= file then
|
||||
table.insert(widgets, dt.new_widget("check_button"){value = false, label = file})
|
||||
else
|
||||
table.insert(widgets, cpm.widgets.profile_box[profile_ptr])
|
||||
profile_ptr = profile_ptr + 1
|
||||
if profile_ptr > #cpm.widgets.profile_box then
|
||||
profile_ptr = #cpm.widgets.profile_box
|
||||
end
|
||||
end
|
||||
end
|
||||
clear_profile_box()
|
||||
for _, widget in ipairs(widgets) do
|
||||
table.insert(cpm.widgets.profile_box, widget)
|
||||
end
|
||||
if not cpm.widgets.remove_box.visible then
|
||||
cpm.widgets.remove_box.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_profile_callback()
|
||||
local widgets_to_keep = {}
|
||||
local profile_dir = COLOR_IN_DIR
|
||||
if cpm.widgets.profile_set.selected == 2 then
|
||||
profile_dir = COLOR_OUT_DIR
|
||||
end
|
||||
|
||||
for _, widget in ipairs(cpm.widgets.profile_box) do
|
||||
if widget.value == true then
|
||||
remove_profile(widget.label, profile_dir)
|
||||
else
|
||||
table.insert(widgets_to_keep, widget)
|
||||
end
|
||||
end
|
||||
clear_profile_box()
|
||||
for _, widget in ipairs(widgets_to_keep) do
|
||||
table.insert(cpm.widgets.profile_box, widget)
|
||||
end
|
||||
if #cpm.widgets.profile_box == 0 then
|
||||
cpm.widgets.remove_box.visible = false
|
||||
else
|
||||
cpm.widgets.remove_box.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
local function list_profile_callback(choice)
|
||||
local list_dir = COLOR_IN_DIR
|
||||
if choice == 2 then
|
||||
list_dir = COLOR_OUT_DIR
|
||||
end
|
||||
|
||||
local files = list_profiles(list_dir)
|
||||
|
||||
if #files == 0 then
|
||||
cpm.widgets.remove_box.visible = false
|
||||
else
|
||||
cpm.widgets.remove_box.visible = true
|
||||
end
|
||||
|
||||
clear_profile_box()
|
||||
|
||||
for i, file in ipairs(files) do
|
||||
cpm.widgets.profile_box[i] = dt.new_widget("check_button"){value = false, label = file}
|
||||
end
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not cpm.module_installed then
|
||||
dt.register_lib(
|
||||
MODULE_NAME, -- Module name
|
||||
_("color profile manager"), -- Visible name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 0}}, -- containers
|
||||
cpm.widgets.main_widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
cpm.module_installed = true
|
||||
dt.control.sleep(500)
|
||||
if not cpm.initialized then
|
||||
cpm.widgets.profile_set.visible = false
|
||||
cpm.widgets.add_box.visible = false
|
||||
cpm.widgets.remove_box.visible = false
|
||||
else
|
||||
cpm.widgets.profile_set.selected = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs[MODULE_NAME].visible = false
|
||||
return
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
return
|
||||
end
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- W I D G E T S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
cpm.initialized = check_for_directories()
|
||||
dt.print_log("cpm.initialized is " .. tostring(cpm.initialized))
|
||||
|
||||
if not cpm.initialized then
|
||||
dt.print_log("creating init_box")
|
||||
cpm.widgets.init_box = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button"){
|
||||
label = _("initialize color profiles"),
|
||||
tooltip = _("create the directory structure to contain the color profiles"),
|
||||
clicked_callback = function(this)
|
||||
add_directories()
|
||||
cpm.initialized = true
|
||||
cpm.widgets.profile_set.visible = true
|
||||
cpm.widgets.add_box.visible = true
|
||||
cpm.widgets.remove_box.visible = false
|
||||
cpm.widgets.init_box.visible = false
|
||||
cpm.widgets.profile_set.selected = 1
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
cpm.widgets.profile_set = dt.new_widget("combobox"){
|
||||
label = _("select profile set"),
|
||||
tooltip = _("select input or output profiles"),
|
||||
visible = cpm.initialized and false or true,
|
||||
changed_callback = function(this)
|
||||
if cpm.initialized then
|
||||
list_profile_callback(this.selected)
|
||||
end
|
||||
end,
|
||||
_("input"), _("output"),
|
||||
}
|
||||
|
||||
cpm.widgets.profile_selector = dt.new_widget("file_chooser_button"){
|
||||
title = _("select color profile to add"),
|
||||
tooltip = _("select the .icc or .icm file to add"),
|
||||
is_directory = false
|
||||
}
|
||||
|
||||
cpm.widgets.add_box = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
visible = cpm.initialized and true or false,
|
||||
dt.new_widget("section_label"){label = _("add profile")},
|
||||
cpm.widgets.profile_selector,
|
||||
dt.new_widget("button"){
|
||||
label = _("add selected color profile"),
|
||||
tooltip = _("add selected file to profiles"),
|
||||
clicked_callback = function(this)
|
||||
add_profile_callback()
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
cpm.widgets.remove_box = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
visible = cpm.initialized and true or false,
|
||||
dt.new_widget("section_label"){label = _("remove profile")},
|
||||
cpm.widgets.profile_box,
|
||||
dt.new_widget("button"){
|
||||
label = _("remove selected profile(s)"),
|
||||
tooltip = _("remove the checked profile(s)"),
|
||||
clicked_callback = function(this)
|
||||
remove_profile_callback()
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local main_widgets = {}
|
||||
|
||||
if not cpm.initialized then
|
||||
table.insert(main_widgets, cpm.widgets.init_box)
|
||||
end
|
||||
table.insert(main_widgets, cpm.widgets.profile_set)
|
||||
table.insert(main_widgets, cpm.widgets.remove_box)
|
||||
table.insert(main_widgets, cpm.widgets.add_box)
|
||||
|
||||
cpm.widgets.main_widget = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
table.unpack(main_widgets)
|
||||
}
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- M A I N
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not cpm.event_registered then
|
||||
dt.register_event(
|
||||
MODULE_NAME, "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
cpm.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
local script_data = {}
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = restart
|
||||
|
||||
return script_data
|
||||
@@ -42,7 +42,15 @@ local debug = require "darktable.debug"
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("3.0.0", "copy_attach_detach_tags")
|
||||
du.check_min_api_version("7.0.0", "copy_attach_detach_tags")
|
||||
|
||||
-- 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
|
||||
|
||||
-- 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/")
|
||||
@@ -51,6 +59,11 @@ local function _(msgid)
|
||||
return gettext.dgettext("copy_attach_detach_tags", msgid)
|
||||
end
|
||||
|
||||
local cadt = {}
|
||||
cadt.module_installed = false
|
||||
cadt.event_registered = false
|
||||
cadt.widget_table = {}
|
||||
|
||||
|
||||
local image_tags = {}
|
||||
|
||||
@@ -107,7 +120,7 @@ local function mcopy_tags()
|
||||
local function attach_tags()
|
||||
|
||||
if next(image_tags) == nil then
|
||||
dt.print(_('No tags to attached, please copy tags first.'))
|
||||
dt.print(_('No tag to attach, please copy tags first.'))
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -156,6 +169,61 @@ local function replace_tags()
|
||||
dt.print(_('Tags replaced'))
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not cadt.module_installed then
|
||||
dt.register_lib("tagging_addon",_('tagging addon'),true,true,{
|
||||
[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",500}
|
||||
},
|
||||
dt.new_widget("box") {
|
||||
-- orientation = "vertical",
|
||||
reset_callback = function()
|
||||
taglist_label.label = ""
|
||||
image_tags = {}
|
||||
end,
|
||||
table.unpack(cadt.widget_table),
|
||||
},
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
cadt.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_event("cadt_ct", "shortcut")
|
||||
dt.destroy_event("cadt_at", "shortcut")
|
||||
dt.destroy_event("cadt_dt", "shortcut")
|
||||
dt.destroy_event("cadt_rt", "shortcut")
|
||||
dt.gui.libs["tagging_addon"].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
-- shortcut for copy
|
||||
dt.register_event("cadt_ct", "shortcut",
|
||||
mcopy_tags,
|
||||
_('copy tags from selected image(s)'))
|
||||
|
||||
-- shortcut for attach
|
||||
dt.register_event("cadt_at", "shortcut",
|
||||
attach_tags,
|
||||
_('paste tags to selected image(s)'))
|
||||
|
||||
-- shortcut for detaching tags
|
||||
dt.register_event("cadt_dt", "shortcut",
|
||||
detach_tags,
|
||||
_('remove tags from selected image(s)'))
|
||||
|
||||
-- shortcut for replace tags
|
||||
dt.register_event("cadt_rt", "shortcut",
|
||||
replace_tags,
|
||||
_('replace tags from selected image(s)'))
|
||||
dt.gui.libs["tagging_addon"].visible = true
|
||||
end
|
||||
|
||||
local function show()
|
||||
dt.gui.libs["tagging_addon"].visible = true
|
||||
end
|
||||
|
||||
-- create modul Tagging addons
|
||||
taglist_label.reset_callback = mcopy_tags
|
||||
|
||||
@@ -169,73 +237,82 @@ local taglabel = dt.new_widget("label") {
|
||||
local box1 = dt.new_widget("box"){
|
||||
orientation = "horizontal",
|
||||
dt.new_widget("button") {
|
||||
label = _('multi copy tags'),
|
||||
clicked_callback = mcopy_tags},
|
||||
label = _('multi copy tags'),
|
||||
tooltip = _('copy tags from selected image(s)'),
|
||||
clicked_callback = mcopy_tags},
|
||||
dt.new_widget("button") {
|
||||
label = _('paste tags'),
|
||||
clicked_callback = attach_tags}
|
||||
|
||||
tooltip = _('paste tags to selected image(s)'),
|
||||
label = _('paste tags'),
|
||||
clicked_callback = attach_tags}
|
||||
}
|
||||
|
||||
local box2 = dt.new_widget("box"){
|
||||
orientation = "horizontal",
|
||||
dt.new_widget("button") {
|
||||
label = _('replace tags'),
|
||||
clicked_callback = replace_tags},
|
||||
label = _('replace tags'),
|
||||
tooltip = _('replace tags from selected image(s)'),
|
||||
clicked_callback = replace_tags},
|
||||
dt.new_widget("button") {
|
||||
label = _('remove all tags'),
|
||||
clicked_callback = detach_tags}
|
||||
label = _('remove all tags'),
|
||||
tooltip = _('remove tags from selected image(s)'),
|
||||
clicked_callback = detach_tags}
|
||||
}
|
||||
|
||||
local sep = dt.new_widget("separator"){}
|
||||
|
||||
-- pack elements into widget table for a nicer layout
|
||||
local widget_table = {}
|
||||
|
||||
widget_table[1] = box1
|
||||
widget_table[#widget_table+1] = box2
|
||||
cadt.widget_table[1] = box1
|
||||
cadt.widget_table[#cadt.widget_table+1] = box2
|
||||
|
||||
widget_table[#widget_table+1] = sep
|
||||
widget_table[#widget_table+1] = taglabel
|
||||
widget_table[#widget_table+1] = taglist_label
|
||||
cadt.widget_table[#cadt.widget_table+1] = sep
|
||||
cadt.widget_table[#cadt.widget_table+1] = taglabel
|
||||
cadt.widget_table[#cadt.widget_table+1] = taglist_label
|
||||
|
||||
|
||||
-- create modul
|
||||
dt.register_lib("tagging_addon","Tagging addon",true,true,{
|
||||
[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",500}
|
||||
},
|
||||
dt.new_widget("box") {
|
||||
-- orientation = "vertical",
|
||||
reset_callback = function()
|
||||
taglist_label.label = ""
|
||||
image_tags = {}
|
||||
end,
|
||||
table.unpack(widget_table),
|
||||
},
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not cadt.event_registered then
|
||||
dt.register_event(
|
||||
"cadt", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
cadt.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- shortcut for copy
|
||||
dt.register_event("shortcut",
|
||||
dt.register_event("cadt_ct", "shortcut",
|
||||
mcopy_tags,
|
||||
_('copy tags from selected image(s)'))
|
||||
|
||||
-- shortcut for attach
|
||||
dt.register_event("shortcut",
|
||||
dt.register_event("cadt_at", "shortcut",
|
||||
attach_tags,
|
||||
_('paste tags to selected image(s)'))
|
||||
|
||||
-- shortcut for detaching tags
|
||||
dt.register_event("shortcut",
|
||||
dt.register_event("cadt_dt", "shortcut",
|
||||
detach_tags,
|
||||
_('remove tags from selected image(s)'))
|
||||
|
||||
-- shortcut for replace tags
|
||||
dt.register_event("shortcut",
|
||||
dt.register_event("cadt_rt", "shortcut",
|
||||
replace_tags,
|
||||
_('replace tags from selected image(s)'))
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = show
|
||||
|
||||
return script_data
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
|
||||
@@ -35,8 +35,15 @@ USAGE
|
||||
local darktable = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
-- Tested with darktable 2.0.1
|
||||
du.check_min_api_version("2.0.0", "cr2hdr")
|
||||
du.check_min_api_version("7.0.0", "cr2hdr")
|
||||
|
||||
-- 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
|
||||
|
||||
local queue = {}
|
||||
local processed_files = {}
|
||||
@@ -107,8 +114,21 @@ local function convert_action_images(shortcut)
|
||||
convert_images()
|
||||
end
|
||||
|
||||
darktable.register_event("shortcut", convert_action_images, "Run cr2hdr (Magic Lantern DualISO converter) on selected images")
|
||||
darktable.register_event("post-import-image", file_imported)
|
||||
darktable.register_event("post-import-film", film_imported)
|
||||
local function destroy()
|
||||
darktable.destroy_event("cr2hdr", "shortcut")
|
||||
darktable.destroy_event("cr2hdr", "post-import-image")
|
||||
darktable.destroy_event("cr2hdr", "post-import-film")
|
||||
end
|
||||
|
||||
darktable.register_event("cr2hdr", "shortcut",
|
||||
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)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -65,7 +65,15 @@ local mod = 'module_enfuseAdvanced'
|
||||
local os_path_seperator = '/'
|
||||
if dt.configuration.running_os == 'windows' then os_path_seperator = '\\' end
|
||||
|
||||
du.check_min_api_version('5.0.0', 'enfuseAdvanced')
|
||||
du.check_min_api_version("7.0.0", "enfuseAdvanced")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
local gettext = dt.gettext
|
||||
@@ -180,6 +188,11 @@ for _,i in pairs(dt.styles) do
|
||||
end
|
||||
|
||||
-- FUNCTION --
|
||||
|
||||
local function sanitize_decimals(cmd) -- make sure decimal separator is a '.'
|
||||
return string.gsub(cmd, '(%d),(%d)', "%1.%2")
|
||||
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
|
||||
@@ -240,7 +253,7 @@ end
|
||||
|
||||
local function ExeUpdate(prog_tbl) --updates executable paths and verifies them
|
||||
dt.preferences.write(mod, 'bin_exists', 'bool', true)
|
||||
for _,prog in pairs(prog_tbl) do
|
||||
for x,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
|
||||
@@ -311,7 +324,7 @@ local function UpdateENFargs(image_table, prefix) --updates the Enfuse arguments
|
||||
local largest_id = 0
|
||||
local first_raw = {}
|
||||
for raw, temp_image in pairs(image_table) do
|
||||
_, source_name, source_id = GetFileName(raw.filename)
|
||||
local _, source_name, source_id = GetFileName(raw.filename)
|
||||
source_id = tonumber(source_id)
|
||||
if source_id < smallest_id then
|
||||
smallest_id = source_id
|
||||
@@ -435,6 +448,9 @@ local function main(storage, image_table, extra_data)
|
||||
local job = dt.gui.create_job('aligning images')
|
||||
image_table, images_to_remove, AIS.images_string = UpdateAISargs(image_table, images_to_remove)
|
||||
local run_cmd = BuildExecuteCmd(AIS)
|
||||
dt.print_log("AIS run command is " .. run_cmd)
|
||||
run_cmd = sanitize_decimals(run_cmd)
|
||||
dt.print_log("AIS decimaal sanitized command is " .. run_cmd)
|
||||
local resp = dsys.external_command(run_cmd)
|
||||
job.valid = false
|
||||
if resp ~= 0 then
|
||||
@@ -455,11 +471,14 @@ local function main(storage, image_table, extra_data)
|
||||
local image_num = 0
|
||||
local job = dt.gui.create_job('blending '..#variants..' image(s)', true) --create a GUI job bar to display enfuse progress
|
||||
UpdateActivePreference() --load current GUI values into active preference (only applies to elements without a clicked/changed callback)
|
||||
for _,prefix in pairs(variants) do --for each image to be created load in the preference values, build arguments string, output image, and run command then execute.
|
||||
for x,prefix in pairs(variants) do --for each image to be created load in the preference values, build arguments string, output image, and run command then execute.
|
||||
job.percent = image_num /(#variants)
|
||||
image_num = image_num+1
|
||||
ENF.images_string, final_image, source_raw = UpdateENFargs(image_table, prefix)
|
||||
local run_cmd = BuildExecuteCmd(ENF)
|
||||
dt.print_log("ENF run command is " .. run_cmd)
|
||||
run_cmd = sanitize_decimals(run_cmd)
|
||||
dt.print_log("ENF decimaal sanitized command is " .. run_cmd)
|
||||
local resp = dsys.external_command(run_cmd)
|
||||
if resp ~= 0 then
|
||||
remove_temp_files(images_to_remove)
|
||||
@@ -470,11 +489,16 @@ local function main(storage, image_table, extra_data)
|
||||
|
||||
--copy exif data from original file
|
||||
run_cmd = EXF.bin..' -TagsFromFile '..df.sanitize_filename(source_raw.path..os_path_seperator..source_raw.filename)..' -exif:all --subifd:all -overwrite_original '..df.sanitize_filename(final_image)
|
||||
-- replace comma decimal separator with period
|
||||
dt.print_log("EXF run command is " .. run_cmd)
|
||||
run_cmd = sanitize_decimals(run_cmd)
|
||||
dt.print_log("EXF decimaal sanitized command is " .. run_cmd)
|
||||
resp = dsys.external_command(run_cmd)
|
||||
|
||||
|
||||
if GUI.Target.auto_import.value then --import image into dt if specified
|
||||
local imported = dt.database.import(final_image)
|
||||
dt.print_log("image imported")
|
||||
if GUI.Target.apply_style.selected > 1 then --apply specified style to imported image
|
||||
local set_style = styles[GUI.Target.apply_style.selected - 1]
|
||||
dt.styles.apply(set_style , imported)
|
||||
@@ -500,6 +524,10 @@ local function main(storage, image_table, extra_data)
|
||||
dt.print('image fusion process complete')
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage('module_enfuseAdvanced')
|
||||
end
|
||||
|
||||
--GUI--
|
||||
stack_compression = dt.new_widget('stack'){}
|
||||
local label_AIS_options= dt.new_widget('section_label'){
|
||||
@@ -939,7 +967,7 @@ GUI.Presets.current_preset = dt.new_widget('combobox'){
|
||||
end
|
||||
}
|
||||
GUI.Presets.load = dt.new_widget('button'){
|
||||
label = _('laod fusion preset'),
|
||||
label = _('load fusion preset'),
|
||||
tooltip = _('load current fusion parameters from selected preset'),
|
||||
clicked_callback = function() LoadFromPreference(GUI.Presets.current_preset.value) end
|
||||
}
|
||||
@@ -1126,3 +1154,7 @@ else
|
||||
GUI.options_contain.active = 4
|
||||
GUI.show_options.sensitive = false
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
198
contrib/exportLUT.lua
Normal file
198
contrib/exportLUT.lua
Normal file
@@ -0,0 +1,198 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2020 Noah Clarke
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
Add the following line to .config/darktable/luarc to enable this lightable module:
|
||||
require "contrib/exportLut"
|
||||
|
||||
Given a haldCLUT identity file this script generates haldCLUTS from all the user's
|
||||
styles and exports them to a location of their choosing.
|
||||
|
||||
Warning: during export if a naming collision occurs the older file is automatically
|
||||
overwritten silently.
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require("lib/dtutils.file")
|
||||
local ds = require("lib/dtutils.system")
|
||||
|
||||
du.check_min_api_version("7.0.0", "exportLUT")
|
||||
|
||||
-- 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
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
gettext.bindtextdomain("exportLUT",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("exportLUT", msgid)
|
||||
end
|
||||
|
||||
du.check_min_api_version("5.0.0", "exportLUT")
|
||||
|
||||
local eL = {}
|
||||
eL.module_installed = false
|
||||
eL.event_registered = false
|
||||
eL.widgets = {}
|
||||
|
||||
-- Thanks Kevin Ertel for this bit
|
||||
local os_path_seperator = '/'
|
||||
if dt.configuration.running_os == 'windows' then os_path_seperator = '\\' end
|
||||
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"),
|
||||
value = "",
|
||||
is_directory = false
|
||||
}
|
||||
|
||||
local export_chooser_button = dt.new_widget("file_chooser_button"){
|
||||
title = _("Export_location_chooser"),
|
||||
value = "",
|
||||
is_directory = true
|
||||
}
|
||||
|
||||
local identity_label = dt.new_widget("label"){
|
||||
label = _("choose the identity haldclut file")
|
||||
}
|
||||
|
||||
local output_label = dt.new_widget("label"){
|
||||
label = _("choose the output location")
|
||||
}
|
||||
|
||||
local warning_label = dt.new_widget("label"){
|
||||
label = _("WARNING: files may be silently overwritten")
|
||||
}
|
||||
|
||||
local function end_job(job)
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local function output_path(style_name, job)
|
||||
local output_location = export_chooser_button.value .. os_path_seperator .. style_name .. ".png"
|
||||
output_location = string.gsub(output_location, "|", os_path_seperator)
|
||||
local output_dir = string.reverse(output_location)
|
||||
output_dir = string.gsub(output_dir, ".-" .. os_path_seperator, os_path_seperator, 1)
|
||||
output_dir = string.reverse(output_dir)
|
||||
if(output_dir ~= "") then
|
||||
df.mkdir(df.sanitize_filename(output_dir))
|
||||
end
|
||||
return output_location
|
||||
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"))
|
||||
else
|
||||
local job = dt.gui.create_job(_('Exporting styles as haldCLUTs'), true, end_job)
|
||||
|
||||
local size = 1
|
||||
|
||||
for style_num, style in ipairs(dt.styles) do
|
||||
size = size + 1
|
||||
end
|
||||
|
||||
local count = 0
|
||||
for style_num, style in ipairs(dt.styles) do
|
||||
|
||||
identity:reset()
|
||||
dt.styles.apply(style, identity)
|
||||
local io_lut = dt.new_format("png")
|
||||
io_lut.bpp = 8
|
||||
|
||||
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))
|
||||
end
|
||||
dt.print(_("Done exporting haldCLUTs"))
|
||||
job.valid = false
|
||||
identity:reset()
|
||||
end
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not eL.module_installed then
|
||||
dt.register_lib(
|
||||
"export haldclut",
|
||||
_("export haldclut"),
|
||||
true,
|
||||
false,
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}},
|
||||
dt.new_widget("box")
|
||||
{
|
||||
orientation = "vertical",
|
||||
table.unpack(eL.widgets),
|
||||
},
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
eL.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs["export haldclut"].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs["export haldclut"].visible = true
|
||||
end
|
||||
|
||||
local export_button = dt.new_widget("button"){
|
||||
label = _("export"),
|
||||
clicked_callback = export_luts
|
||||
}
|
||||
|
||||
table.insert(eL.widgets, identity_label)
|
||||
table.insert(eL.widgets, file_chooser_button)
|
||||
table.insert(eL.widgets, output_label)
|
||||
table.insert(eL.widgets, export_chooser_button)
|
||||
table.insert(eL.widgets, warning_label)
|
||||
table.insert(eL.widgets, export_button)
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not eL.event_registered then
|
||||
dt.register_event(
|
||||
"exportLUT", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
eL.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
|
||||
@@ -1,64 +1,67 @@
|
||||
--[[
|
||||
ext_editor.lua - edit images with external editors
|
||||
|
||||
DESCRIPTION
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
--[[
|
||||
ext_editor.lua - edit images with external editors
|
||||
|
||||
This script provides helpers to edit image files with programs external to darktable.
|
||||
It adds:
|
||||
- a new target storage "collection". Image exported will be reimported to collection for
|
||||
further edit with external programs
|
||||
- a new lighttable module "external editors", to select a program from a list of up to
|
||||
- 9 external editors and run it on a selected image (adjust this limit by changing MAX_EDITORS)
|
||||
- a set of lua preferences in order to configure name and path of up to 9 external editors
|
||||
- a set of lua shortcuts in order to quick launch the external editors
|
||||
This script provides helpers to edit image files with programs external to darktable. It adds:
|
||||
- a new target storage "collection". Image exported will be reimported to collection for further edit with external programs
|
||||
- a new module "external editors", visible in lightable and darkroom, to select a program from a list
|
||||
- of up to 9 external editors and run it on a selected image (adjust this limit by changing MAX_EDITORS)
|
||||
- a set of lua preferences in order to configure name and path of up to 9 external editors
|
||||
- a set of lua shortcuts in order to quick launch the external editors
|
||||
|
||||
USAGE
|
||||
* require this script from main lua file
|
||||
|
||||
-- setup --
|
||||
* in "preferences/lua options" configure name and path/command of external programs
|
||||
* note that if a program name is left empty, that and all following entries will be ignored
|
||||
* in "preferences/shortcuts/lua" configure shortcuts for external programs (optional)
|
||||
* whenever programs preferences are changed, in lighttable/external editors, press "update list"
|
||||
-- setup --
|
||||
* in "preferences/lua options" configure name and path/command of external programs
|
||||
* note that if a program name is left empty, that and all following entries will be ignored
|
||||
* in "preferences/shortcuts/lua" configure shortcuts for external programs (optional)
|
||||
* whenever programs preferences are changed, in external editors GUI, press "update list"
|
||||
|
||||
-- use --
|
||||
* in the export dialog choose "collection" and select the format and bit depth for the
|
||||
exported image
|
||||
* press "export"
|
||||
* the exported image will be imported into collection and grouped with the original image
|
||||
-- use --
|
||||
* in the export dialog choose "collection" and select the format and bit depth for the
|
||||
exported image
|
||||
* press "export"
|
||||
* the exported image will be imported into collection and grouped with the original image
|
||||
|
||||
* select an image for editing with en external program, and:
|
||||
* in lighttable/external editors, select program and press "edit"
|
||||
* edit the image with the external editor, overwite the file, quit the external program
|
||||
* the selected image will be updated
|
||||
or
|
||||
* in lighttable/external editors, select program and press "edit a copy"
|
||||
* edit the image with the external editor, overwite the file, quit the external program
|
||||
* a copy of the selected image will be created and updated
|
||||
or
|
||||
* in lighttable select target storage "collection"
|
||||
* enter in darkroom
|
||||
* to create an export or a copy press CRTL+E
|
||||
* use the shortcut to edit the current image with the corresponding external editor
|
||||
* overwite the file, quit the external program
|
||||
* the darkroom view will be updated
|
||||
* in lighttable, select an image for editing with en external program
|
||||
* (or in darkroom for the image being edited):
|
||||
* in external editors GUI, select program and press "edit"
|
||||
* edit the image with the external editor, overwite the file, quit the external program
|
||||
* the selected image will be updated
|
||||
or
|
||||
* in external editors GUI, select program and press "edit a copy"
|
||||
* edit the image with the external editor, overwite the file, quit the external program
|
||||
* a copy of the selected image will be created and updated
|
||||
or
|
||||
* use the shortcut to edit the current image with the corresponding external editor
|
||||
* overwite the file, quit the external program
|
||||
* the image will be updated
|
||||
|
||||
* warning: mouseover on lighttable/filmstrip will prevail on current image
|
||||
* this is the default DT behavior, not a bug of this script
|
||||
* warning: mouseover on lighttable/filmstrip will prevail on current image
|
||||
* this is the default DT behavior, not a bug of this script
|
||||
|
||||
CAVEATS
|
||||
* MAC compatibility not tested
|
||||
CAVEATS
|
||||
* MAC compatibility not tested
|
||||
|
||||
TODO
|
||||
* send multiple images to the same program, maybe
|
||||
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
* send to Marco Carrarini, marco.carrarini@gmail.com
|
||||
|
||||
CHANGES
|
||||
* 20191224 - initial version
|
||||
* 20191227 - added button "update list", better error handling, fixed bug with groups/tags in "edit"
|
||||
|
||||
]]
|
||||
|
||||
|
||||
@@ -70,22 +73,32 @@ local dtsys = require "lib/dtutils.system"
|
||||
|
||||
-- module name
|
||||
local MODULE_NAME = "ext_editor"
|
||||
du.check_min_api_version("7.0.0", MODULE_NAME)
|
||||
|
||||
-- return data structure for script_manager
|
||||
|
||||
-- check API version
|
||||
du.check_min_api_version("5.0.2", MODULE_NAME) -- darktable 3.0
|
||||
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
|
||||
|
||||
-- OS compatibility
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
|
||||
-- namespace
|
||||
local ee = {}
|
||||
ee.module_installed = false
|
||||
ee.event_registered = false
|
||||
ee.widgets = {}
|
||||
|
||||
|
||||
-- translation
|
||||
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
|
||||
end
|
||||
|
||||
-- maximum number of external programs, can be increased to necessity
|
||||
local MAX_EDITORS = 9
|
||||
@@ -98,10 +111,11 @@ local n_entries
|
||||
local allowed_file_types = {"JPG", "jpg", "JPEG", "jpeg", "TIF", "tif", "TIFF", "tiff", "EXR", "exr", "PNG", "png"}
|
||||
|
||||
|
||||
-- last used editor initialization
|
||||
if not dt.preferences.read(MODULE_NAME, "initialized", "bool") then
|
||||
dt.preferences.write(MODULE_NAME, "lastchoice", "integer", 0)
|
||||
dt.preferences.write(MODULE_NAME, "initialized", "bool", true)
|
||||
end
|
||||
end
|
||||
local lastchoice = 0
|
||||
|
||||
|
||||
@@ -126,24 +140,24 @@ local function UpdateProgramList(combobox, button_edit, button_edit_copy, update
|
||||
program_names[i] = name
|
||||
program_paths[i] = df.sanitize_filename(dt.preferences.read(MODULE_NAME, "program_path_"..i, "string"))
|
||||
n_entries = i
|
||||
end
|
||||
end
|
||||
|
||||
lastchoice = dt.preferences.read(MODULE_NAME, "lastchoice", "integer")
|
||||
if lastchoice == 0 and n_entries > 0 then lastchoice = 1 end
|
||||
if lastchoice > n_entries then lastchoice = n_entries end
|
||||
dt.preferences.write(MODULE_NAME, "lastchoice", "integer", lastchoice)
|
||||
|
||||
-- widgets enabled if there is at least one program configured
|
||||
combobox.selected = lastchoice
|
||||
local active = n_entries > 0
|
||||
combobox.sensitive = active
|
||||
button_edit.sensitive = active
|
||||
button_edit_copy.sensitive = active
|
||||
|
||||
if update_button_pressed then dt.print(n_entries.._(" editors configured")) end
|
||||
end
|
||||
|
||||
lastchoice = dt.preferences.read(MODULE_NAME, "lastchoice", "integer")
|
||||
if lastchoice == 0 and n_entries > 0 then lastchoice = 1 end
|
||||
if lastchoice > n_entries then lastchoice = n_entries end
|
||||
dt.preferences.write(MODULE_NAME, "lastchoice", "integer", lastchoice)
|
||||
|
||||
-- widgets enabled if there is at least one program configured
|
||||
combobox.selected = lastchoice
|
||||
local active = n_entries > 0
|
||||
combobox.sensitive = active
|
||||
button_edit.sensitive = active
|
||||
button_edit_copy.sensitive = active
|
||||
|
||||
if update_button_pressed then dt.print(n_entries.._(" editors configured")) end
|
||||
end
|
||||
|
||||
|
||||
-- callback for buttons "edit" and "edit a copy" ------------------------------
|
||||
local function OpenWith(images, choice, copy)
|
||||
@@ -152,22 +166,18 @@ local function OpenWith(images, choice, copy)
|
||||
if choice > n_entries then
|
||||
dt.print(_("not a valid choice"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- check if one image is selected, return if not
|
||||
if #images ~= 1 then
|
||||
dt.print(_("please select one image"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local bin = program_paths[choice]
|
||||
local friendly_name = program_names[choice]
|
||||
|
||||
-- check if external program executable exists, return if not
|
||||
if not df.check_if_bin_exists(bin) then
|
||||
dt.print(friendly_name.._(" not found"))
|
||||
return
|
||||
end
|
||||
if dt.configuration.running_os == "macos" then bin = "open -W -a "..bin end
|
||||
|
||||
-- image to be edited
|
||||
local image
|
||||
@@ -175,24 +185,24 @@ local function OpenWith(images, choice, copy)
|
||||
local name = image.path..PS..image.filename
|
||||
|
||||
-- check if image format is allowed
|
||||
local file_ext = df.get_filetype (image.filename)
|
||||
local file_ext = df.get_filetype(image.filename)
|
||||
local allowed = false
|
||||
for i,v in pairs(allowed_file_types) do
|
||||
if v == file_ext then
|
||||
allowed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not allowed then
|
||||
dt.print(_("file type not allowed"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- save image tags, rating and color
|
||||
local tags = {}
|
||||
for i, tag in ipairs(dt.tags.get_tags(image)) do
|
||||
for i, tag in ipairs(dt.tags.get_tags(image)) do
|
||||
if not (string.sub(tag.name, 1, 9) == "darktable") then table.insert(tags, tag) end
|
||||
end
|
||||
end
|
||||
local rating = image.rating
|
||||
local red = image.red
|
||||
local blue = image.blue
|
||||
@@ -207,19 +217,15 @@ local function OpenWith(images, choice, copy)
|
||||
if copy then
|
||||
|
||||
-- create unique filename
|
||||
while df.check_if_file_exists(df.sanitize_filename(new_name)) do
|
||||
new_name = df.filename_increment(new_name)
|
||||
-- limit to 50 more exports of the original export
|
||||
if string.match(df.get_basename(new_name), "_%d%d$") == "_50" then break end
|
||||
end
|
||||
new_name = df.create_unique_filename(new_name)
|
||||
|
||||
-- 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)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- launch the external editor, check result, return if error
|
||||
local run_cmd = bin.." "..df.sanitize_filename(new_name)
|
||||
@@ -228,7 +234,7 @@ local function OpenWith(images, choice, copy)
|
||||
if result ~= 0 then
|
||||
dt.print(_("error launching ")..friendly_name)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if copy then
|
||||
-- import in database and group
|
||||
@@ -253,7 +259,7 @@ local function OpenWith(images, choice, copy)
|
||||
while not found do
|
||||
index, new_leader = next(group_members, index)
|
||||
if new_leader ~= image_leader then found = true end
|
||||
end
|
||||
end
|
||||
new_leader:make_group_leader()
|
||||
image:delete()
|
||||
if image.local_copy then image:drop_cache() end -- to fix fail to allocate cache error
|
||||
@@ -266,21 +272,17 @@ local function OpenWith(images, choice, copy)
|
||||
if image.local_copy then image:drop_cache() end -- to fix fail to allocate cache error
|
||||
new_image = dt.database.import(name)
|
||||
new_image:group_with()
|
||||
end
|
||||
end
|
||||
else
|
||||
-- case 3: image is in a group but is not leader
|
||||
image:delete()
|
||||
if image.local_copy then image:drop_cache() end -- to fix fail to allocate cache error
|
||||
new_image = dt.database.import(name)
|
||||
new_image:group_with(image_leader)
|
||||
end
|
||||
-- refresh darkroom view
|
||||
if dt.gui.current_view() == dt.gui.views.darkroom then
|
||||
dt.gui.views.darkroom.display_image(new_image)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- restore image tags, rating and color, must be put after refresh darkroom view
|
||||
-- restore image tags, rating and color
|
||||
for i, tag in ipairs(tags) do dt.tags.attach(tag, new_image) end
|
||||
new_image.rating = rating
|
||||
new_image.red = red
|
||||
@@ -292,21 +294,25 @@ local function OpenWith(images, choice, copy)
|
||||
-- select the new image
|
||||
local selection = {}
|
||||
table.insert(selection, new_image)
|
||||
dt.gui.selection (selection)
|
||||
dt.gui.selection(selection)
|
||||
|
||||
-- refresh darkroom view
|
||||
if dt.gui.current_view().id == "darkroom" then
|
||||
dt.gui.views.darkroom.display_image(new_image)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- callback function for shortcuts --------------------------------------------
|
||||
local function program_shortcut(event, shortcut)
|
||||
OpenWith(dt.gui.action_images, tonumber(string.sub(shortcut, -2)), false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- export images and reimport in collection -----------------------------------
|
||||
local function export2collection(storage, image_table, extra_data)
|
||||
|
||||
local new_name, new_image, result
|
||||
local temp_name, new_name, new_image, move_success
|
||||
|
||||
for image, temp_name in pairs(image_table) do
|
||||
|
||||
@@ -314,32 +320,72 @@ local function export2collection(storage, image_table, extra_data)
|
||||
|
||||
-- create unique filename
|
||||
new_name = image.path..PS..df.get_filename(temp_name)
|
||||
while df.check_if_file_exists(df.sanitize_filename(new_name)) do
|
||||
new_name = df.filename_increment(new_name)
|
||||
-- limit to 50 more exports of the original export
|
||||
if string.match(df.get_basename(new_name), "_%d%d$") == "_50" then break end
|
||||
end
|
||||
new_name = df.create_unique_filename(new_name)
|
||||
|
||||
-- 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)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- import in database and group
|
||||
new_image = dt.database.import(new_name)
|
||||
new_image:group_with(image.group_leader)
|
||||
end
|
||||
|
||||
dt.print (_("finished exporting"))
|
||||
end
|
||||
|
||||
dt.print(_("finished exporting"))
|
||||
end
|
||||
|
||||
-- register new storage -------------------------------------------------------
|
||||
-- note that placing this declaration later makes the export selected module
|
||||
-- not to remember the choice "collection" when restarting DT, don't know why
|
||||
dt.register_storage("exp2coll", _("collection"), null, export2collection)
|
||||
|
||||
-- install the module in the UI -----------------------------------------------
|
||||
local function install_module(dr)
|
||||
|
||||
local views = {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 90}}
|
||||
if dr then
|
||||
views = {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 90},
|
||||
[dt.gui.views.darkroom] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 100}}
|
||||
end
|
||||
|
||||
if not ee.module_installed then
|
||||
-- register new module "external editors" in lighttable and darkroom ----
|
||||
dt.register_lib(
|
||||
MODULE_NAME,
|
||||
_("external editors"),
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
views,
|
||||
dt.new_widget("box") {
|
||||
orientation = "vertical",
|
||||
table.unpack(ee.widgets),
|
||||
},
|
||||
nil, -- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
ee.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
for i = 1, MAX_EDITORS do
|
||||
dt.destroy_event(MODULE_NAME .. i, "shortcut")
|
||||
end
|
||||
dt.destroy_storage("exp2coll")
|
||||
dt.gui.libs[MODULE_NAME].visible = false
|
||||
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))
|
||||
end
|
||||
dt.register_storage("exp2coll", _("collection"), nil, export2collection)
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
end
|
||||
|
||||
local function show()
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
end
|
||||
|
||||
|
||||
-- combobox, with variable number of entries ----------------------------------
|
||||
@@ -350,7 +396,7 @@ local combobox = dt.new_widget("combobox") {
|
||||
dt.preferences.write(MODULE_NAME, "lastchoice", "integer", self.selected)
|
||||
end,
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- button edit ----------------------------------------------------------------
|
||||
@@ -360,8 +406,8 @@ local button_edit = dt.new_widget("button") {
|
||||
--sensitive = false,
|
||||
clicked_callback = function()
|
||||
OpenWith(dt.gui.action_images, combobox.selected, false)
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
-- button edit a copy ---------------------------------------------------------
|
||||
@@ -370,8 +416,8 @@ local button_edit_copy = dt.new_widget("button") {
|
||||
tooltip = _("create a copy of the selected image and open it in external editor"),
|
||||
clicked_callback = function()
|
||||
OpenWith(dt.gui.action_images, combobox.selected, true)
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
-- button update list ---------------------------------------------------------
|
||||
@@ -380,58 +426,81 @@ local button_update_list = dt.new_widget("button") {
|
||||
tooltip = _("update list of programs if lua preferences are changed"),
|
||||
clicked_callback = function()
|
||||
UpdateProgramList(combobox, button_edit, button_edit_copy, true)
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
-- box for the buttons --------------------------------------------------------
|
||||
-- it doesn't seem there is a way to make the buttons equal in size
|
||||
local box1 = dt.new_widget("box") {
|
||||
orientation = "horizontal",
|
||||
orientation = "horizontal",
|
||||
button_edit,
|
||||
button_edit_copy,
|
||||
button_update_list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- register new module "external editors" in lighttable ------------------------
|
||||
dt.register_lib(
|
||||
MODULE_NAME,
|
||||
_("external editors"),
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}},
|
||||
dt.new_widget("box") {
|
||||
orientation = "vertical",
|
||||
combobox,
|
||||
box1
|
||||
},
|
||||
nil, -- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
-- table with all the widgets --------------------------------------------------
|
||||
table.insert(ee.widgets, combobox)
|
||||
table.insert(ee.widgets, box1)
|
||||
|
||||
|
||||
-- register new module, but only when in lighttable ----------------------------
|
||||
local show_dr = dt.preferences.read(MODULE_NAME, "show_in_darkrooom", "bool")
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module(show_dr)
|
||||
else
|
||||
if not ee.event_registered then
|
||||
dt.register_event(
|
||||
MODULE_NAME, "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module(show_dr)
|
||||
end
|
||||
end
|
||||
)
|
||||
ee.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- initialize list of programs and widgets ------------------------------------
|
||||
UpdateProgramList(combobox, button_edit, button_edit_copy, false)
|
||||
|
||||
|
||||
-- register new storage -------------------------------------------------------
|
||||
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,
|
||||
_("select executable for external editor") , _("(None)"))
|
||||
|
||||
dt.preferences.register(MODULE_NAME, "program_name_"..i, "string",
|
||||
_("name of external editor ")..i,
|
||||
_("friendly name of external editor"), "")
|
||||
end
|
||||
end
|
||||
dt.preferences.register(MODULE_NAME, "show_in_darkrooom", "bool",
|
||||
_("show external editors in darkroom"),
|
||||
_("check to show external editors module also in darkroom (requires restart)"), false)
|
||||
|
||||
|
||||
-- register the new shortcuts -------------------------------------------------
|
||||
for i = 1, MAX_EDITORS do
|
||||
dt.register_event("shortcut", program_shortcut, _("edit with program ")..string.format("%02d", i))
|
||||
end
|
||||
dt.register_event(MODULE_NAME .. i, "shortcut",
|
||||
program_shortcut, _("edit with program ")..string.format("%02d", i))
|
||||
end
|
||||
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = show
|
||||
|
||||
return script_data
|
||||
|
||||
-- end of script --------------------------------------------------------------
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
@@ -52,12 +52,21 @@ local MODULE = "face_recognition"
|
||||
local PS = dt.configuration.running_os == "windows" and '\\' or '/'
|
||||
local OUTPUT = dt.configuration.tmp_dir .. PS .. "facerecognition.txt"
|
||||
|
||||
du.check_min_api_version("7.0.0", MODULE)
|
||||
|
||||
-- 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
|
||||
|
||||
-- namespace
|
||||
|
||||
local fc = {}
|
||||
|
||||
-- ensure we meet the minimum api
|
||||
du.check_min_api_version("5.0.0", "face_recognition")
|
||||
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/")
|
||||
@@ -337,6 +346,30 @@ local function face_recognition ()
|
||||
end
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not fc.module_installed then
|
||||
dt.register_lib(
|
||||
MODULE, -- Module name
|
||||
_("face recognition"), -- Visible name
|
||||
true, -- expandable
|
||||
true, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 300}}, -- containers
|
||||
fc.widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
fc.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs[MODULE].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs[MODULE].visible = true
|
||||
end
|
||||
|
||||
-- build the interface
|
||||
|
||||
fc.unknown_tag = dt.new_widget("entry"){
|
||||
@@ -466,16 +499,21 @@ fc.widget = dt.new_widget("box"){
|
||||
table.unpack(widgets),
|
||||
}
|
||||
|
||||
dt.register_lib(
|
||||
"face_recognition", -- Module name
|
||||
_("face recognition"), -- Visible name
|
||||
true, -- expandable
|
||||
true, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 300}}, -- containers
|
||||
fc.widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not fc.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
|
||||
)
|
||||
fc.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
fc.tolerance.value = dt.preferences.read(MODULE, "tolerance", "float")
|
||||
|
||||
@@ -487,5 +525,11 @@ if not dt.preferences.read(MODULE, "initialized", "bool") then
|
||||
dt.preferences.write(MODULE, "initialized", "bool", true)
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = restart
|
||||
|
||||
return script_data
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
126
contrib/fujifilm_dynamic_range.lua
Normal file
126
contrib/fujifilm_dynamic_range.lua
Normal file
@@ -0,0 +1,126 @@
|
||||
--[[ fujifilm_dynamic_range-0.1
|
||||
|
||||
Compensate for Fujifilm raw files made using "dynamic range".
|
||||
|
||||
Copyright (C) 2021 Dan Torop <dant@pnym.net>
|
||||
|
||||
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 2 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, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
]]
|
||||
|
||||
--[[About this Plugin
|
||||
Support for adjusting darktable exposure by Fujifilm raw exposure
|
||||
bias. This corrects for a DR100/DR200/DR400 "dynamic range" setting.
|
||||
|
||||
Dependencies:
|
||||
- exiftool (https://www.sno.phy.queensu.ca/~phil/exiftool/)
|
||||
|
||||
Based upon fujifilm_ratings by Ben Mendis
|
||||
|
||||
The relevant tag is RawExposureBias (0x9650). This appears to
|
||||
represent the shift in EV for the chosen DR setting (whether manual or
|
||||
automatic). Note that even at 100DR ("standard") there is an EV shift:
|
||||
|
||||
100 DR -> -0.72 EV
|
||||
200 DR -> -1.72 EV
|
||||
400 DR -> -2.72 EV
|
||||
|
||||
The ideal would be to use exiv2 to read this tag, as this is the same
|
||||
code which darktable import uses. Unfortunately, exiv2 as of v0.27.3
|
||||
can't read this tag. As it is encoded as a 4-byte ratio of two signed
|
||||
shorts -- a novel data type -- it will require some attention to fix
|
||||
this.
|
||||
|
||||
There is an exiv2-readable DevelopmentDynamicRange tag which maps to
|
||||
RawExposureBias as above. DevelopmentDynamicRange is only present
|
||||
when tag DynamicRangeSetting (0x1402) is Manual/Raw (0x0001). When it
|
||||
is Auto (0x0000), the equivalent data is tag AutoDynamicRange
|
||||
(0x140b). But exiv2 currently can't read that tag either.
|
||||
|
||||
Hence for now this code uses exiftool to read RawExposureBias, as a
|
||||
more general solution. As exiftool is approx. 10x slower than exiv2
|
||||
(Perl vs. C++), this may slow large imports.
|
||||
|
||||
These tags have been checked on a Fujifilm X100S and X100V. Other
|
||||
cameras may behave in other ways.
|
||||
|
||||
--]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
du.check_min_api_version("7.0.0", "fujifilm_dynamic_range")
|
||||
|
||||
-- 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
|
||||
|
||||
local function detect_dynamic_range(event, image)
|
||||
if image.exif_maker ~= "FUJIFILM" then
|
||||
dt.print_log("[fujifilm_dynamic_range] ignoring non-Fujifilm image")
|
||||
return
|
||||
end
|
||||
-- it would be nice to check image.is_raw but this appears to not yet be set
|
||||
if not string.match(image.filename, "%.RAF$") then
|
||||
dt.print_log("[fujifilm_dynamic_range] ignoring non-raw image")
|
||||
return
|
||||
end
|
||||
local command = df.check_if_bin_exists("exiftool")
|
||||
if not command then
|
||||
dt.print_error("[fujifilm_dynamic_range] exiftool not found")
|
||||
return
|
||||
end
|
||||
local RAF_filename = df.sanitize_filename(tostring(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)
|
||||
local raf_result = output:read("*all")
|
||||
output:close()
|
||||
if #raf_result == 0 then
|
||||
dt.print_error("[fujifilm_dynamic_range] no output returned by exiftool")
|
||||
return
|
||||
end
|
||||
raf_result = string.match(raf_result, "\t(.*)")
|
||||
if not raf_result then
|
||||
dt.print_error("[fujifilm_dynamic_range] could not parse exiftool output")
|
||||
return
|
||||
end
|
||||
if image.exif_exposure_bias ~= image.exif_exposure_bias then
|
||||
-- is NAN (this is unlikely as RAFs should have ExposureBiasValue set)
|
||||
image.exif_exposure_bias = 0
|
||||
end
|
||||
-- this should be auto-applied if plugins/darkroom/workflow is scene-referred
|
||||
-- note that scene-referred workflow exposure preset also pushes exposure up by 0.5 EV
|
||||
image.exif_exposure_bias = image.exif_exposure_bias + tonumber(raf_result)
|
||||
dt.print_log("[fujifilm_dynamic_range] raw exposure bias " .. tostring(raf_result))
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_event("fujifilm_dr", "post-import-image")
|
||||
end
|
||||
|
||||
dt.register_event("fujifilm_dr", "post-import-image",
|
||||
detect_dynamic_range)
|
||||
|
||||
dt.print_log("[fujifilm_dynamic_range] loaded")
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
@@ -28,7 +28,15 @@ local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("4.0.0", "fujifilm_ratings")
|
||||
du.check_min_api_version("7.0.0", "fujifilm_ratings")
|
||||
|
||||
-- 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
|
||||
|
||||
gettext.bindtextdomain("fujifilm_ratings", dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
@@ -41,7 +49,7 @@ local function detect_rating(event, image)
|
||||
dt.print_error(_("exiftool not found"))
|
||||
return
|
||||
end
|
||||
local RAF_filename = tostring(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)
|
||||
@@ -66,6 +74,12 @@ local function detect_rating(event, image)
|
||||
end
|
||||
end
|
||||
|
||||
dt.register_event("post-import-image", detect_rating)
|
||||
local function destroy()
|
||||
dt.destroy_event("fujifilm_rat", "post-import-image")
|
||||
end
|
||||
|
||||
print(_("fujifilm_ratings loaded."))
|
||||
dt.register_event("fujifilm_rat", "post-import-image",
|
||||
detect_rating)
|
||||
|
||||
script_data.destroy = destroy
|
||||
return script_data
|
||||
|
||||
@@ -35,10 +35,17 @@ USAGE
|
||||
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("3.0.0", "geoJSON_export")
|
||||
du.check_min_api_version("7.0.0", "geoJSON_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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("geoJSON_export",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -292,6 +299,10 @@ local function create_geoJSON_file(storage, image_table, extra_data)
|
||||
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("geoJSON_export")
|
||||
end
|
||||
|
||||
-- Preferences
|
||||
dt.preferences.register("geoJSON_export",
|
||||
"CreateMapBoxHTMLFile",
|
||||
@@ -327,3 +338,7 @@ dt.preferences.register("geoJSON_export",
|
||||
|
||||
-- Register
|
||||
dt.register_storage("geoJSON_export", "geoJSON Export", nil, create_geoJSON_file)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -28,10 +28,17 @@ require "geoToolbox"
|
||||
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("3.0.0", "geoToolbox")
|
||||
du.check_min_api_version("7.0.0", "geoToolbox")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("geoToolbox",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -40,6 +47,12 @@ local function _(msgid)
|
||||
return gettext.dgettext("geoToolbox", msgid)
|
||||
end
|
||||
|
||||
|
||||
local gT = {}
|
||||
gT.module_installed = false
|
||||
gT.event_registered = false
|
||||
|
||||
|
||||
-- <GUI>
|
||||
local labelDistance = dt.new_widget("label")
|
||||
labelDistance.label = _("Distance:")
|
||||
@@ -417,7 +430,7 @@ local function get_distance(lat1, lon1, ele1, lat2, lon2, ele2)
|
||||
math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) *
|
||||
math.sin(dLon/2) * math.sin(dLon/2)
|
||||
;
|
||||
local angle = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a));
|
||||
local angle = 2 * math.atan(math.sqrt(a), math.sqrt(1-a));
|
||||
local distance = earthRadius * angle; -- Distance in km
|
||||
|
||||
-- Add the elevation to the calculation
|
||||
@@ -572,6 +585,49 @@ local function altitude_profile()
|
||||
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not gT.module_installed then
|
||||
dt.register_lib(
|
||||
"geoToolbox", -- Module name
|
||||
"geo toolbox", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
gT.widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
gT.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs["geoToolbox"].visible = false
|
||||
dt.destroy_event("geoToolbox_cd", "shortcut")
|
||||
dt.destroy_event("geoToolbox", "mouse-over-image-changed")
|
||||
dt.destroy_event("geoToolbox_wg", "shortcut")
|
||||
dt.destroy_event("geoToolbox_ng", "shortcut")
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.register_event("geoToolbox_cd", "shortcut",
|
||||
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"))
|
||||
dt.register_event("geoToolbox_ng", "shortcut",
|
||||
select_without_gps, _("Select all images without GPS information"))
|
||||
|
||||
dt.gui.libs["geoToolbox"].visible = true
|
||||
end
|
||||
|
||||
local function show()
|
||||
dt.gui.libs["geoToolbox"].visible = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
local separator = dt.new_widget("separator"){}
|
||||
local separator2 = dt.new_widget("separator"){}
|
||||
@@ -579,13 +635,7 @@ local separator3 = dt.new_widget("separator"){}
|
||||
local separator4 = dt.new_widget("separator"){}
|
||||
local separator5 = dt.new_widget("separator"){}
|
||||
|
||||
dt.register_lib(
|
||||
"geoToolbox", -- Module name
|
||||
"geo toolbox", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
dt.new_widget("box")
|
||||
gT.widget = dt.new_widget("box")
|
||||
{
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button")
|
||||
@@ -664,10 +714,24 @@ dt.register_lib(
|
||||
clicked_callback = altitude_profile
|
||||
},
|
||||
labelDistance
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not gT.event_registered then
|
||||
dt.register_event(
|
||||
"geoToolbox", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
gT.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Preferences
|
||||
dt.preferences.register("geoToolbox",
|
||||
@@ -678,11 +742,21 @@ dt.preferences.register("geoToolbox",
|
||||
'' )
|
||||
|
||||
-- Register
|
||||
dt.register_event("shortcut", print_calc_distance, _("Calculate the distance from latitude and longitude in km"))
|
||||
dt.register_event("mouse-over-image-changed", toolbox_calc_distance)
|
||||
dt.register_event("geoToolbox_cd", "shortcut",
|
||||
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("shortcut", select_with_gps, _("Select all images with GPS information"))
|
||||
dt.register_event("shortcut", select_without_gps, _("Select all images without GPS information"))
|
||||
dt.register_event("geoToolbox_wg", "shortcut",
|
||||
select_with_gps, _("Select all images with GPS information"))
|
||||
dt.register_event("geoToolbox_ng", "shortcut",
|
||||
select_without_gps, _("Select all images without GPS information"))
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = show
|
||||
|
||||
return script_data
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: hl Lua;
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
* require this script from your main lua file
|
||||
* select an image or images for editing with GIMP
|
||||
* in the export dialog select "Edit with GIMP" and select the format and bit depth for the
|
||||
exported image
|
||||
exported image. Check the "run_detached" button to run GIMP in detached mode. Images
|
||||
will not be returned to darktable in this mode, but additional images can be sent to
|
||||
GIMP without stopping it.
|
||||
* Press "export"
|
||||
* Edit the image with GIMP then save the changes with File->Overwrite....
|
||||
* Exit GIMP
|
||||
@@ -70,7 +72,15 @@ local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext
|
||||
local gimp_widget = nil
|
||||
|
||||
du.check_min_api_version("5.0.0", "gimp")
|
||||
du.check_min_api_version("7.0.0", "gimp")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -103,6 +113,8 @@ end
|
||||
|
||||
local function gimp_edit(storage, image_table, extra_data) --finalize
|
||||
|
||||
local run_detached = dt.preferences.read("gimp", "run_detached", "bool")
|
||||
|
||||
local gimp_executable = df.check_if_bin_exists("gimp")
|
||||
|
||||
if not gimp_executable then
|
||||
@@ -111,7 +123,11 @@ local function gimp_edit(storage, image_table, extra_data) --finalize
|
||||
end
|
||||
|
||||
if dt.configuration.running_os == "macos" then
|
||||
gimp_executable = "open -W -a " .. gimp_executable
|
||||
if run_detached then
|
||||
gimp_executable = "open -a " .. gimp_executable
|
||||
else
|
||||
gimp_executable = "open -W -a " .. gimp_executable
|
||||
end
|
||||
end
|
||||
|
||||
-- list of exported images
|
||||
@@ -130,55 +146,75 @@ local function gimp_edit(storage, image_table, extra_data) --finalize
|
||||
local gimpStartCommand
|
||||
gimpStartCommand = gimp_executable .. " " .. img_list
|
||||
|
||||
if run_detached then
|
||||
if dt.configuration.running_os == "windows" then
|
||||
gimpStartCommand = "start /b \"\" " .. gimpStartCommand
|
||||
else
|
||||
gimpStartCommand = gimpStartCommand .. " &"
|
||||
end
|
||||
end
|
||||
|
||||
dt.print_log(gimpStartCommand)
|
||||
|
||||
dtsys.external_command(gimpStartCommand)
|
||||
|
||||
-- for each of the image, exported image pairs
|
||||
-- move the exported image into the directory with the original
|
||||
-- then import the image into the database which will group it with the original
|
||||
-- and then copy over any tags other than darktable tags
|
||||
if not run_detached then
|
||||
|
||||
for image,exported_image in pairs(image_table) do
|
||||
-- for each of the image, exported image pairs
|
||||
-- move the exported image into the directory with the original
|
||||
-- then import the image into the database which will group it with the original
|
||||
-- and then copy over any tags other than darktable tags
|
||||
|
||||
local myimage_name = image.path .. "/" .. df.get_filename(exported_image)
|
||||
for image,exported_image in pairs(image_table) do
|
||||
|
||||
while df.check_if_file_exists(myimage_name) do
|
||||
myimage_name = df.filename_increment(myimage_name)
|
||||
-- limit to 99 more exports of the original export
|
||||
if string.match(df.get_basename(myimage_name), "_(d-)$") == "99" then
|
||||
break
|
||||
local myimage_name = image.path .. "/" .. df.get_filename(exported_image)
|
||||
|
||||
while df.check_if_file_exists(myimage_name) do
|
||||
myimage_name = df.filename_increment(myimage_name)
|
||||
-- limit to 99 more exports of the original export
|
||||
if string.match(df.get_basename(myimage_name), "_(d-)$") == "99" then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dt.print_log("moving " .. exported_image .. " to " .. myimage_name)
|
||||
local result = df.file_move(exported_image, myimage_name)
|
||||
dt.print_log("moving " .. exported_image .. " to " .. myimage_name)
|
||||
local result = df.file_move(exported_image, myimage_name)
|
||||
|
||||
if result then
|
||||
dt.print_log("importing file")
|
||||
local myimage = dt.database.import(myimage_name)
|
||||
if result then
|
||||
dt.print_log("importing file")
|
||||
local myimage = dt.database.import(myimage_name)
|
||||
|
||||
group_if_not_member(image, myimage)
|
||||
group_if_not_member(image, myimage)
|
||||
|
||||
for _,tag in pairs(dt.tags.get_tags(image)) do
|
||||
if not (string.sub(tag.name,1,9) == "darktable") then
|
||||
dt.print_log("attaching tag")
|
||||
dt.tags.attach(tag,myimage)
|
||||
for _,tag in pairs(dt.tags.get_tags(image)) do
|
||||
if not (string.sub(tag.name,1,9) == "darktable") then
|
||||
dt.print_log("attaching tag")
|
||||
dt.tags.attach(tag,myimage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("module_gimp")
|
||||
end
|
||||
|
||||
-- Register
|
||||
|
||||
local executables = {"gimp"}
|
||||
|
||||
if dt.configuration.running_os ~= "linux" then
|
||||
gimp_widget = df.executable_path_widget(executables)
|
||||
end
|
||||
gimp_widget = dt.new_widget("check_button"){
|
||||
label = _("run detached"),
|
||||
tooltip = _("don't import resulting image back into darktable"),
|
||||
value = dt.preferences.read("gimp", "run_detached", "bool"),
|
||||
clicked_callback = function(this)
|
||||
dt.preferences.write("gimp", "run_detached", "bool", this.value)
|
||||
end
|
||||
}
|
||||
|
||||
dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit, nil, nil, gimp_widget)
|
||||
|
||||
--
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -27,7 +27,15 @@ local df = require "lib/dtutils.file"
|
||||
local dl = require "lib/dtutils"
|
||||
local gettext = dt.gettext
|
||||
|
||||
dl.check_min_api_version("3.0.0", "gpx-export")
|
||||
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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("gpx_export",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -36,6 +44,10 @@ local function _(msgid)
|
||||
return gettext.dgettext("gpx_export", msgid)
|
||||
end
|
||||
|
||||
local gpx = {}
|
||||
gpx.module_installed = false
|
||||
gpx.event_registered = false
|
||||
|
||||
local path_entry = dt.new_widget("entry")
|
||||
{
|
||||
text = dt.preferences.read("gpx_exporter", "gpxExportPath", "string"),
|
||||
@@ -127,31 +139,69 @@ local function create_gpx_file()
|
||||
end
|
||||
end
|
||||
|
||||
dt.register_lib(
|
||||
"gpx_exporter",
|
||||
"gpx export",
|
||||
true, -- expandable
|
||||
true, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
local function install_module()
|
||||
if not gpx.module_installed then
|
||||
dt.register_lib(
|
||||
"gpx_exporter",
|
||||
"gpx export",
|
||||
true, -- expandable
|
||||
true, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
gpx.widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
gpx.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs["gpx_exporter"].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs["gpx_exporter"].visible = true
|
||||
end
|
||||
|
||||
gpx.widget = dt.new_widget("box")
|
||||
{
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button")
|
||||
{
|
||||
label = _("export"),
|
||||
tooltip = _("export gpx file"),
|
||||
clicked_callback = create_gpx_file
|
||||
},
|
||||
dt.new_widget("box")
|
||||
{
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button")
|
||||
orientation = "horizontal",
|
||||
dt.new_widget("label")
|
||||
{
|
||||
label = _("export"),
|
||||
tooltip = _("export gpx file"),
|
||||
clicked_callback = create_gpx_file
|
||||
},
|
||||
dt.new_widget("box")
|
||||
{
|
||||
orientation = "horizontal",
|
||||
dt.new_widget("label")
|
||||
{
|
||||
label = _("file:"),
|
||||
},
|
||||
path_entry
|
||||
label = _("file:"),
|
||||
},
|
||||
path_entry
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not gpx.event_registered then
|
||||
dt.register_event(
|
||||
"gpx_export", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
gpx.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
|
||||
return script_data
|
||||
|
||||
78
contrib/harmonic_armature_guide.lua
Normal file
78
contrib/harmonic_armature_guide.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--[[
|
||||
harmonic artmature guide for darktable
|
||||
|
||||
copyright (c) 2021 Hubert Kowalski
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
--[[
|
||||
HARMONIC ARMATURE GUIDE
|
||||
Harmonic Armature (also known as 14 line armature)
|
||||
|
||||
INSTALLATION
|
||||
* copy this file in $CONFIGDIR/lua/contrib where CONFIGDIR is your darktable configuration directory
|
||||
* add the following line in the file $CONFIGDIR/luarc
|
||||
require "contrib/harmonic_armature_guide"
|
||||
|
||||
USAGE
|
||||
* when using guides, select "harmonic armature" as guide
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local gettext = dt.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)
|
||||
end
|
||||
|
||||
dt.guides.register_guide("harmonic armature",
|
||||
-- draw
|
||||
function(cairo, x, y, width, height, zoom_scale)
|
||||
cairo:save()
|
||||
|
||||
cairo:translate(x, y)
|
||||
cairo:scale(width, height)
|
||||
|
||||
cairo:move_to(0,0)
|
||||
cairo:line_to(1, 0.5)
|
||||
cairo:line_to(0.5, 1)
|
||||
cairo:line_to(0,0)
|
||||
cairo:line_to(1, 1)
|
||||
cairo:line_to(0.5, 0)
|
||||
cairo:line_to(0, 0.5)
|
||||
cairo:line_to(1, 1)
|
||||
|
||||
cairo:move_to(1, 0)
|
||||
cairo:line_to(0, 0.5)
|
||||
cairo:line_to(0.5, 1)
|
||||
cairo:line_to(1, 0)
|
||||
cairo:line_to(0, 1)
|
||||
cairo:line_to(0.5, 0)
|
||||
cairo:line_to(1, 0.5)
|
||||
cairo:line_to(0, 1)
|
||||
|
||||
cairo:restore()
|
||||
end,
|
||||
-- gui
|
||||
function()
|
||||
return dt.new_widget("label"){label = _("harmonic armature"), halign = "start"}
|
||||
end
|
||||
)
|
||||
@@ -40,7 +40,6 @@ local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local log = require "lib/dtutils.log"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
require "official/yield"
|
||||
local gettext = dt.gettext
|
||||
|
||||
local namespace = 'module_hugin'
|
||||
@@ -55,7 +54,15 @@ local executable_table = {"hugin", "hugin_executor", "pto_gen"}
|
||||
local PQ = dt.configuration.running_os == "windows" and '"' or "'"
|
||||
|
||||
-- works with darktable API version from 5.0.0 on
|
||||
du.check_min_api_version("5.0.0", "hugin")
|
||||
du.check_min_api_version("7.0.0", "hugin")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("hugin",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -206,6 +213,10 @@ local function create_panorama(storage, image_table, extra_data) --finalize
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage(namespace)
|
||||
end
|
||||
|
||||
-- Register
|
||||
if dt.configuration.running_os ~= "linux" then
|
||||
exec_widget = df.executable_path_widget(executable_table)
|
||||
@@ -225,6 +236,8 @@ hugin_widget = dt.new_widget("box") {
|
||||
|
||||
dt.register_storage(namespace, _("hugin panorama"), show_status, create_panorama, nil, nil, hugin_widget)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
@@ -71,7 +71,15 @@ local job = nil
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
|
||||
-- works with LUA API version 5.0.0
|
||||
du.check_min_api_version("5.0.0", "image_stack")
|
||||
du.check_min_api_version("7.0.0", "image_stack")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("image_stack",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -452,6 +460,10 @@ local function stop_job()
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("module_image_stack")
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- main program
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -585,3 +597,6 @@ dt.preferences.register("align_image_stack", "align_use_gpu", -- name
|
||||
|
||||
dt.register_storage("module_image_stack", _("image stack"), show_status, image_stack, nil, nil, image_stack_widget)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
586
contrib/image_time.lua
Normal file
586
contrib/image_time.lua
Normal file
@@ -0,0 +1,586 @@
|
||||
--[[
|
||||
|
||||
image_time.lua - synchronize image time for images shot with different cameras
|
||||
|
||||
Copyright (C) 2019, 2020 Bill Ferguson <wpferguson@gmail.com>.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
image_time - non-destructively modify the image time
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
image_time non destructively adjusts image times by modifying the
|
||||
database image exif_datetime_taken field. There are 4 modes: adjust time,
|
||||
set time, synchronize time, and reset time.
|
||||
|
||||
ADJUST TIME
|
||||
|
||||
adjust time mode lets you chose an offset in terms of years, months,
|
||||
days, hours, minutes, and seconds. The adjustment can be added or
|
||||
subtracted.
|
||||
|
||||
WARNING: When adding and subtracting months the result will usually
|
||||
be what is expected unless the time being adjusted is at the end of
|
||||
the month. This is because a month is a variable amount of time that
|
||||
can be 28, 29, 30 or 31 days depending on the month. Example: It's
|
||||
March 31st and I subtract a month which not sets the time to February
|
||||
31st. When that gets set to a valid time, then the date changes to
|
||||
March 3rd.
|
||||
|
||||
SET TIME
|
||||
|
||||
set time mode allows you to pick a date and time and set the image
|
||||
time accordingly. Fields may be left out. This is useful when
|
||||
importing scanned images that don't have an embedded date.
|
||||
|
||||
SYNCHRONIZE TIME
|
||||
|
||||
I recently purchased a 7DmkII to replace my aging 7D. My 7D was still
|
||||
serviceable, so I bought a remote control and figured I'd try shooting
|
||||
events from 2 different perspectives. I didn't think to synchonize the
|
||||
time between the 2 cameras, so when I loaded the images and sorted by
|
||||
time it was a disaster. I hacked a script together with hard coded values
|
||||
to adjust the exif_datetime_taken value in the database for the 7D images
|
||||
so that everything sorted properly. I've tried shooting with 2 cameras
|
||||
several times since that first attempt. I've gotten better at getting the
|
||||
camera times close, but still haven't managed to get them to sync. So I
|
||||
decided to think the problem through and write a proper script to take
|
||||
care of the problem.
|
||||
|
||||
RESET TIME
|
||||
|
||||
Select the images and click reset.
|
||||
|
||||
USAGE
|
||||
|
||||
ADJUST TIME
|
||||
|
||||
Change the year, month, day, hour, minute, second dropdowns to the amount
|
||||
of change desired. Select add or subtract. Select the images. Click
|
||||
adjust.
|
||||
|
||||
SET TIME
|
||||
|
||||
Set the time fields to the desired time. Select the images to change. Click
|
||||
set.
|
||||
|
||||
SYNCHRONIZE TIME
|
||||
|
||||
Select 2 images, one from each camera, of the same moment in time. Click
|
||||
the Calculate button to calculate the time difference. The difference is
|
||||
displayed in the difference entry. You can manually adjust it by changing
|
||||
the value if necessary.
|
||||
|
||||
Select the images that need their time adjusted. Determine which way to adjust
|
||||
adjust the time (add or subtract) and select the appropriate choice.
|
||||
|
||||
If the image times get messed up and you just want to start over, select reset time
|
||||
from the mode and reset the image times.
|
||||
|
||||
RESET TIME
|
||||
|
||||
Select the images and click reset.
|
||||
|
||||
ADDITIONAL SOFTWARE REQUIRED
|
||||
* exiv2
|
||||
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
* Send to Bill Ferguson, wpferguson@gmail.com
|
||||
|
||||
CHANGES
|
||||
|
||||
]]
|
||||
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 img_time = {}
|
||||
img_time.module_installed = false
|
||||
img_time.event_registered = false
|
||||
|
||||
du.check_min_api_version("7.0.0", "image_time")
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
-- 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)
|
||||
end
|
||||
|
||||
local PS = dt.configuration.runnin_os == "windows" and "\\" or "/"
|
||||
local ERROR = -1
|
||||
|
||||
-- function to convert from exif time 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 to convert from systime to exif time
|
||||
local function systime2exiftime(systime)
|
||||
local t = os.date("*t", systime)
|
||||
return(string.format("%4d:%02d:%02d %02d:%02d:%02d", t.year, t.month, t.day, t.hour, t.min, t.sec))
|
||||
end
|
||||
|
||||
local function vars2exiftime(year, month, day, hour, min, sec)
|
||||
local y = tonumber(year) and string.format("%4d", year) or " "
|
||||
local mo = tonumber(month) and string.format("%02d", month) or " "
|
||||
local d = tonumber(day) and string.format("%02d", day) or " "
|
||||
local h = tonumber(hour) and string.format("%02d", hour) or " "
|
||||
local m = tonumber(min) and string.format("%02d", min) or " "
|
||||
local s = tonumber(sec) and string.format("%02d", sec) or " "
|
||||
return(y .. ":" .. mo .. ":" .. d .. " " .. h .. ":" .. m .. ":" .. s)
|
||||
end
|
||||
|
||||
local function exiftime2vars(exiftime)
|
||||
return string.match(exiftime, "(%d+):(%d+):(%d+) (%d+):(%d+):(%d+)")
|
||||
end
|
||||
|
||||
local function calc_time_difference(image1, image2)
|
||||
return math.abs(exiftime2systime(image1.exif_datetime_taken) - exiftime2systime(image2.exif_datetime_taken))
|
||||
end
|
||||
|
||||
local function adjust_image_time(image, difference)
|
||||
image.exif_datetime_taken = systime2exiftime(exiftime2systime(image.exif_datetime_taken) + difference)
|
||||
return
|
||||
end
|
||||
|
||||
local function calculate_difference(images)
|
||||
if #images == 2 then
|
||||
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"))
|
||||
end
|
||||
end
|
||||
|
||||
local function synchronize_times(images, difference)
|
||||
for _, image in ipairs(images) do
|
||||
adjust_image_time(image, difference)
|
||||
end
|
||||
end
|
||||
|
||||
local function synchronize_time(images)
|
||||
local sign = 1
|
||||
if img_time.sdir.value == "subtract" then
|
||||
sign = -1
|
||||
end
|
||||
synchronize_times(images, tonumber(img_time.diff_entry.text) * sign)
|
||||
end
|
||||
|
||||
local function add_time(images)
|
||||
synchronize_times(images, tonumber(img_time.diff_entry.text))
|
||||
end
|
||||
|
||||
local function year_month2months(year, month)
|
||||
year_months = tonumber(year) and year * 12 or 0
|
||||
local months = tonumber(month) and tonumber(month) or 0
|
||||
|
||||
return year_months + months
|
||||
end
|
||||
|
||||
local function months2year_month(months)
|
||||
dt.print_log("months is " .. months)
|
||||
local year = math.floor(months / 12)
|
||||
local month = months - (year * 12)
|
||||
|
||||
return year, month
|
||||
end
|
||||
|
||||
local function get_image_taken_time(image)
|
||||
-- get original image time
|
||||
local datetime = nil
|
||||
|
||||
local exiv2 = df.check_if_bin_exists("exiv2")
|
||||
if exiv2 then
|
||||
p = 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
|
||||
datetime = string.match(line, "(%d-:%d-:%d- %d-:%d-:%d+)")
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
end
|
||||
else
|
||||
dt.print(_("unable to detect exiv2"))
|
||||
datetime = ERROR
|
||||
end
|
||||
return datetime
|
||||
end
|
||||
|
||||
local function _get_windows_image_file_creation_time(image)
|
||||
local datetime = nil
|
||||
local p = 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
|
||||
local mo, day, yr, hr, min, apm = string.match(line, "(%d+)/(%d+)/(%d+) (%d-):(%d+) (%S+)")
|
||||
if apm == "PM" then
|
||||
hr = hr + 12
|
||||
end
|
||||
datetime = vars2exiftime(yr, mo, day, hr, min, 0)
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
else
|
||||
dt.print(_("unable to get information for ") .. image.filename)
|
||||
datetime = ERROR
|
||||
end
|
||||
return datetime
|
||||
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)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
if string.match(line, ds.sanitize_lua(image.filename)) then
|
||||
datetime = vars2exiftime(string.match(line, "(%d+)%-(%d-)%-(%d-) (%d-):(%d-):(%d+)."))
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
else
|
||||
dt.print(_("unable to get information for ") .. image.filename)
|
||||
datetime = ERROR
|
||||
end
|
||||
return datetime
|
||||
end
|
||||
|
||||
local function get_image_file_creation_time(image)
|
||||
-- no exif time in the image file so get the creation time
|
||||
local datetime = nil
|
||||
if dt.configuration.running_os == "windows" then
|
||||
datetime = _get_windows_image_file_creation_time(image)
|
||||
else
|
||||
datetime = _get_nix_image_file_creation_time(image)
|
||||
end
|
||||
return datetime
|
||||
end
|
||||
|
||||
local function get_original_image_time(image)
|
||||
local image_time = image.exif_datetime_taken
|
||||
local reset_time = nil
|
||||
|
||||
reset_time = get_image_taken_time(image)
|
||||
|
||||
if reset_time then
|
||||
if reset_time == ERROR then
|
||||
return image_time
|
||||
else
|
||||
return reset_time
|
||||
end
|
||||
else
|
||||
reset_time = get_image_file_creation_time(image)
|
||||
|
||||
if reset_time then
|
||||
if reset_time == ERROR then
|
||||
return image_time
|
||||
else
|
||||
return reset_time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function reset_time(images)
|
||||
if #images > 0 then
|
||||
for _, image in ipairs(images) do
|
||||
image.exif_datetime_taken = get_original_image_time(image)
|
||||
end
|
||||
else
|
||||
dt.print_error(_("reset time: no images selected"))
|
||||
dt.print(_("please select the images that need their time reset"))
|
||||
end
|
||||
end
|
||||
|
||||
local function adjust_time(images)
|
||||
local SEC_MIN = 60
|
||||
local SEC_HR = SEC_MIN * 60
|
||||
local SEC_DY = SEC_HR * 24
|
||||
|
||||
local offset = nil
|
||||
local sign = 1
|
||||
|
||||
if #images < 1 then
|
||||
dt.print(_("please select some images and try again"))
|
||||
return
|
||||
end
|
||||
|
||||
if img_time.adir.value == _("subtract") then
|
||||
sign = -1
|
||||
end
|
||||
|
||||
for _, image in ipairs(images) do
|
||||
local y, mo, d, h, m, s = exiftime2vars(image.exif_datetime_taken)
|
||||
local image_months = year_month2months(y, mo)
|
||||
local months_diff = year_month2months(img_time.ayr.value, img_time.amo.value)
|
||||
y, mo = months2year_month(image_months + (months_diff * sign))
|
||||
local exif_new = vars2exiftime(y, mo, d, h, m, s)
|
||||
offset = img_time.ady.value * SEC_DY
|
||||
offset = offset + img_time.ahr.value * SEC_HR
|
||||
offset = offset + img_time.amn.value * SEC_MIN
|
||||
offset = offset + img_time.asc.value
|
||||
offset = offset * sign
|
||||
image.exif_datetime_taken = systime2exiftime(exiftime2systime(exif_new) + offset)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_time(images)
|
||||
if #images < 1 then
|
||||
dt.print(_("please select some images and try again"))
|
||||
return
|
||||
end
|
||||
|
||||
local y = img_time.syr.value
|
||||
local mo = img_time.smo.value
|
||||
local d = img_time.sdy.value
|
||||
local h = img_time.shr.value
|
||||
local m = img_time.smn.value
|
||||
local s = img_time.ssc.value
|
||||
|
||||
for _, image in ipairs(images) do
|
||||
image.exif_datetime_taken = vars2exiftime(y, mo, d, h, m, s)
|
||||
end
|
||||
end
|
||||
|
||||
local function seq(first, last)
|
||||
local result = {}
|
||||
|
||||
local num = first
|
||||
|
||||
while num <= last do
|
||||
table.insert(result, num)
|
||||
num = num + 1
|
||||
end
|
||||
|
||||
return table.unpack(result)
|
||||
end
|
||||
|
||||
local function reset_widgets()
|
||||
dt.print_log("took the reset function")
|
||||
img_time.ayr.selected = 1
|
||||
img_time.amo.selected = 1
|
||||
img_time.ady.selected = 1
|
||||
img_time.ahr.selected = 1
|
||||
img_time.ayr.selected = 1
|
||||
img_time.amn.selected = 1
|
||||
img_time.asc.selected = 1
|
||||
img_time.adir.selected = 1
|
||||
img_time.syr.selected = #img_time.syr
|
||||
img_time.smo.selected = 1
|
||||
img_time.sdy.selected = 1
|
||||
img_time.shr.selected = 1
|
||||
img_time.smn.selected = 1
|
||||
img_time.ssc.selected = 1
|
||||
img_time.adir.selected = 1
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not img_time.module_installed then
|
||||
dt.register_lib(
|
||||
"image_time", -- Module name
|
||||
_("image time"), -- Visible name
|
||||
true, -- expandable
|
||||
true, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
img_time.widget,
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
img_time.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs["image_time"].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs["image_time"].visible = true
|
||||
end
|
||||
|
||||
-- widgets
|
||||
|
||||
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},
|
||||
{"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},
|
||||
{"adir", "combobox", _("add/subtract"), _("add or subtract time"), {_("add"), _("subtract")}, 1},
|
||||
{"syr", "combobox", _("year"), _("year to set, 1900 - now"), {" ", seq(1900,os.date("*t", os.time()).year)}, 1},
|
||||
{"smo", "combobox", _("month"), _("month to set, 1-12"), {" ", seq(1,12)}, 1},
|
||||
{"sdy", "combobox", _("day"), _("day to set, 1-31"), {" ", seq(1,31)}, 1},
|
||||
{"shr", "combobox", _("hour"), _("hour to set, 0-23"), {" ", seq(0,23)}, 1},
|
||||
{"smn", "combobox", _("minute"), _("minutes to set, 0-59"), {" ", seq(0, 59)}, 1},
|
||||
{"ssc", "combobox", _("seconds"), _("seconds to set, 0-59"), {" ", seq(0,59)}, 1},
|
||||
{"sdir", "combobox", _("add/subtract"), _("add or subtract time"), {_("add"), _("subtract")}, 1},
|
||||
}
|
||||
|
||||
for _, widget in ipairs(img_time.widgets) do
|
||||
img_time[widget[1]] = dt.new_widget(widget[2]){
|
||||
label = widget[3],
|
||||
tooltip = widget[4],
|
||||
selected = widget[6],
|
||||
table.unpack(widget[5])
|
||||
}
|
||||
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"),
|
||||
text = "",
|
||||
}
|
||||
|
||||
img_time.calc_btn = dt.new_widget("button"){
|
||||
label = _("Calculate"),
|
||||
tooltip = _("calculate time difference between 2 images"),
|
||||
clicked_callback = function()
|
||||
calculate_difference(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
|
||||
img_time.btn = dt.new_widget("button"){
|
||||
label = _("synchronize image times"),
|
||||
tooltip = _("apply the time difference from selected images"),
|
||||
sensitive = false,
|
||||
clicked_callback = function()
|
||||
synchronize_time(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
|
||||
img_time.stack = dt.new_widget("stack"){
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
dt.new_widget("label"){label = _("adjust time")},
|
||||
dt.new_widget("section_label"){label = _("days, months, years")},
|
||||
img_time.ady,
|
||||
img_time.amo,
|
||||
img_time.ayr,
|
||||
dt.new_widget("section_label"){label = _("hours, minutes, seconds")},
|
||||
img_time.ahr,
|
||||
img_time.amn,
|
||||
img_time.asc,
|
||||
dt.new_widget("section_label"){label = _("adjustment direction")},
|
||||
img_time.adir,
|
||||
dt.new_widget("button"){
|
||||
label = _("adjust"),
|
||||
clicked_callback = function()
|
||||
adjust_time(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
},
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
dt.new_widget("label"){label = _("set time")},
|
||||
dt.new_widget("section_label"){label = _("date: ")},
|
||||
img_time.sdy,
|
||||
img_time.smo,
|
||||
img_time.syr,
|
||||
dt.new_widget("section_label"){label = _("time:")},
|
||||
img_time.shr,
|
||||
img_time.smn,
|
||||
img_time.ssc,
|
||||
dt.new_widget("button"){
|
||||
label = _("set"),
|
||||
clicked_callback = function()
|
||||
set_time(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
},
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
dt.new_widget("label"){label = _("synchronize image time")},
|
||||
dt.new_widget("section_label"){label = _("calculate difference between images")},
|
||||
img_time.diff_entry,
|
||||
img_time.calc_btn,
|
||||
dt.new_widget("section_label"){label = _("apply difference")},
|
||||
img_time.sdir,
|
||||
img_time.btn,
|
||||
},
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
dt.new_widget("label"){label = _("reset to original time")},
|
||||
dt.new_widget("separator"){},
|
||||
dt.new_widget("button"){
|
||||
label = _("reset"),
|
||||
clicked_callback = function()
|
||||
reset_time(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
img_time.mode = dt.new_widget("combobox"){
|
||||
label = _("mode"),
|
||||
tooltip = _("select mode"),
|
||||
selected = 1,
|
||||
changed_callback = function(this)
|
||||
img_time.stack.active = this.selected
|
||||
end,
|
||||
_("adjust time"),
|
||||
_("set time"),
|
||||
_("synchronize time"),
|
||||
_("reset time")
|
||||
}
|
||||
|
||||
img_time.widget = dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
reset_callback = function(this)
|
||||
reset_widgets()
|
||||
end,
|
||||
img_time.mode,
|
||||
img_time.stack,
|
||||
}
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not img_time.event_registered then
|
||||
dt.register_event(
|
||||
"image_time", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
img_time.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
|
||||
@@ -43,7 +43,15 @@ local gettext = dt.gettext
|
||||
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
|
||||
du.check_min_api_version("5.0.0", kml_export)
|
||||
du.check_min_api_version("7.0.0", "kml_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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("kml_export",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -301,6 +309,10 @@ local function create_kml_file(storage, image_table, extra_data)
|
||||
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("kml_export")
|
||||
end
|
||||
|
||||
-- Preferences
|
||||
if dt.configuration.running_os == "windows" then
|
||||
dt.preferences.register("kml_export",
|
||||
@@ -369,5 +381,9 @@ else
|
||||
dt.register_storage("kml_export", _("KML/KMZ Export"), nil, create_kml_file)
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: hl Lua;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
--[[
|
||||
PASSPORT CROPPING GUIDE
|
||||
guides for cropping passport photos based on documents from the Finnish police
|
||||
(https://www.poliisi.fi/instancedata/prime_product_julkaisu/intermin/embeds/poliisiwwwstructure/38462_Passikuvaohje_EN.pdf) describing passport photo dimensions of 47x36 mm and 500x653 px for digital biometric data stored in passports. They use ISO 19794-5 standard based on ICAO 9303 regulations which should also be compliant for all of Europe.
|
||||
(https://poliisi.fi/documents/25235045/31329600/Passport-photograph-instructions-by-the-police-2020-EN-fixed.pdf/1eec2f4c-aed7-68e0-c112-0a8f25e0328d/Passport-photograph-instructions-by-the-police-2020-EN-fixed.pdf) describing passport photo dimensions of 47x36 mm and 500x653 px for digital biometric data stored in passports. They use ISO 19794-5 standard based on ICAO 9303 regulations which should also be compliant for all of Europe.
|
||||
|
||||
INSTALLATION
|
||||
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
|
||||
|
||||
@@ -41,7 +41,6 @@ format (all fields can be the empty string):
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
require "official/yield"
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
@@ -57,7 +56,15 @@ if not df.check_if_bin_exists("pdflatex") then
|
||||
return
|
||||
end
|
||||
|
||||
du.check_min_api_version("4.0.0", "pdf_slideshow")
|
||||
du.check_min_api_version("7.0.0", "pdf_slideshow")
|
||||
|
||||
-- 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
|
||||
|
||||
dt.preferences.register
|
||||
("pdf_slideshow","open with","string",
|
||||
@@ -165,6 +172,10 @@ local function slide(latexfile,i,image,file)
|
||||
my_write(latexfile,"\\end{figure}\n")
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("pdf_slideshow")
|
||||
end
|
||||
|
||||
dt.register_storage("pdf_slideshow",_("pdf slideshow"),
|
||||
nil,
|
||||
function(storage,image_table)
|
||||
@@ -244,5 +255,8 @@ dt.register_storage("pdf_slideshow",_("pdf slideshow"),
|
||||
nil,
|
||||
widget)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
504
contrib/photils.lua
Normal file
504
contrib/photils.lua
Normal file
@@ -0,0 +1,504 @@
|
||||
--[[ photils Auto Tagging plugin
|
||||
copyright (c) 2020 Tobias Scheck
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
--]]
|
||||
|
||||
--[[
|
||||
A darktable plugin that tries to predict keywords based on the selected image.
|
||||
This plugin uses photils-cli to handle this task. Photils-cli is an application
|
||||
that passes the image through a neural network, classifies it, and extracts the
|
||||
suggested tags. Everything happens offline without the need that your data are
|
||||
sent over the internet.
|
||||
|
||||
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
|
||||
* photils-cli - https://github.com/scheckmedia/photils-cli at the moment only
|
||||
available for Linux and MacOS
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file
|
||||
To do this add this line to the file .config/darktable/luarc:
|
||||
require "contrib/photils"
|
||||
* Select an image
|
||||
* Press "get tags"
|
||||
* Select the tags you want from a list of suggestions
|
||||
* Press "Attach .. Tags" to add the selected tags to your image
|
||||
--]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
|
||||
local MODULE_NAME = "photils"
|
||||
du.check_min_api_version("7.0.0", MODULE_NAME)
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
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 exporter = dt.new_format("jpeg")
|
||||
exporter.quality = 80
|
||||
exporter.max_height = 224
|
||||
exporter.max_width = 224
|
||||
|
||||
-- helper functions
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext(MODULE_NAME, msgid)
|
||||
end
|
||||
|
||||
local function num_keys(tbl)
|
||||
local num = 0
|
||||
for _ in pairs(tbl) do num = num + 1 end
|
||||
return num
|
||||
end
|
||||
|
||||
local function has_key(tbl, value)
|
||||
for k, _ in pairs(tbl) do
|
||||
if k == value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local photils_installed = df.check_if_bin_exists("photils-cli")
|
||||
|
||||
--[[
|
||||
local state object
|
||||
|
||||
maybe per_page is a preference variable but I think 10
|
||||
is a good value for the ui
|
||||
]]
|
||||
local PHOTILS = {
|
||||
tags = {},
|
||||
confidences = {},
|
||||
page = 1,
|
||||
per_page = 10,
|
||||
selected_tags = {},
|
||||
in_pagination = false,
|
||||
tagged_image = "",
|
||||
module_installed = false,
|
||||
event_registered = false,
|
||||
plugin_display_views = {
|
||||
[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100},
|
||||
[dt.gui.views.darkroom] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 100}
|
||||
},
|
||||
}
|
||||
|
||||
local GUI = {
|
||||
container = dt.new_widget("box") {
|
||||
orientation = "vertical",
|
||||
sensitive = true,
|
||||
dt.new_widget("button") {
|
||||
label = _("get tags"),
|
||||
sensitive = photils_installed,
|
||||
clicked_callback = function() PHOTILS.on_tags_clicked() end
|
||||
},
|
||||
reset_callback = function() PHOTILS.on_reset(true) end
|
||||
},
|
||||
stack = dt.new_widget("stack"),
|
||||
prev_button = dt.new_widget("button") {
|
||||
label = "<",
|
||||
sensitive = false,
|
||||
clicked_callback = function()
|
||||
PHOTILS.page = PHOTILS.page - 1
|
||||
PHOTILS.paginate()
|
||||
end
|
||||
},
|
||||
next_button = dt.new_widget("button") {
|
||||
label = ">",
|
||||
sensitive = false,
|
||||
clicked_callback = function()
|
||||
PHOTILS.page = PHOTILS.page + 1
|
||||
PHOTILS.paginate()
|
||||
end
|
||||
},
|
||||
tag_box = dt.new_widget("box") {orientation = "vertical"},
|
||||
tag_view = dt.new_widget("box") {orientation = "vertical"},
|
||||
page_label = dt.new_widget("label") {label = ""},
|
||||
error_view = dt.new_widget("box") {orientation = "vertical"},
|
||||
warning_label = dt.new_widget("label") {
|
||||
label = ""
|
||||
},
|
||||
restart_required_label = dt.new_widget("label") {
|
||||
label = _("requires a restart to be applied")
|
||||
},
|
||||
attach_button = dt.new_widget("button") {
|
||||
label = "",
|
||||
sensitive = false,
|
||||
clicked_callback = function(self) PHOTILS.attach_tags() end
|
||||
},
|
||||
confidence_slider = dt.new_widget("slider") {
|
||||
step = 1,
|
||||
digits = 0,
|
||||
value = 90,
|
||||
hard_max = 100,
|
||||
hard_min = 0,
|
||||
soft_max = 100,
|
||||
soft_min = 0,
|
||||
label = _("min confidence value")
|
||||
},
|
||||
warning = dt.new_widget("label")
|
||||
}
|
||||
|
||||
function PHOTILS.image_changed()
|
||||
local current_image = tostring(dt.gui.selection()[1])
|
||||
if current_image ~= PHOTILS.tagged_image then
|
||||
if PHOTILS.tagged_image ~= "" then
|
||||
PHOTILS.tagged_image_has_changed()
|
||||
end
|
||||
|
||||
PHOTILS.tagged_image = tostring(current_image)
|
||||
end
|
||||
end
|
||||
|
||||
function PHOTILS.tagged_image_has_changed()
|
||||
GUI.warning.label = _("The suggested tags were not generated\n for the currently selected image!")
|
||||
end
|
||||
|
||||
function PHOTILS.paginate()
|
||||
PHOTILS.in_pagination = true
|
||||
local num_pages = math.ceil(#PHOTILS.tags / PHOTILS.per_page)
|
||||
GUI.page_label.label = string.format(_(" page %s of %s "), PHOTILS.page,
|
||||
num_pages)
|
||||
|
||||
if PHOTILS.page <= 1 then
|
||||
PHOTILS.page = 1
|
||||
GUI.prev_button.sensitive = false
|
||||
else
|
||||
GUI.prev_button.sensitive = true
|
||||
end
|
||||
|
||||
if PHOTILS.page > num_pages - 1 then
|
||||
PHOTILS.page = num_pages
|
||||
GUI.next_button.sensitive = false
|
||||
else
|
||||
GUI.next_button.sensitive = true
|
||||
end
|
||||
|
||||
--[[
|
||||
calculates the start positon in the tag array based on the current page
|
||||
and takes N tags from that array to show these in darktable
|
||||
e.g. page 1 goes from 1 to 10, page 2 from 11 to 20 a.s.o.
|
||||
the paginaton approach is related to a problem with the dynamic addition
|
||||
of mutliple widgets https://github.com/darktable-org/darktable/issues/4934#event-3318100463
|
||||
]]--
|
||||
local offset = ((PHOTILS.page - 1) * PHOTILS.per_page) + 1
|
||||
local tag_index = 1
|
||||
for i = offset, offset + PHOTILS.per_page - 1, 1 do
|
||||
local tag = PHOTILS.tags[i]
|
||||
local conf = PHOTILS.confidences[i]
|
||||
|
||||
GUI.tag_box[tag_index].value = has_key(PHOTILS.selected_tags, tag)
|
||||
|
||||
if tag then
|
||||
if dt.preferences.read(MODULE_NAME, "show_confidence", "bool") then
|
||||
tag = tag .. string.format(" (%.3f)", conf)
|
||||
end
|
||||
|
||||
GUI.tag_box[tag_index].label = tag
|
||||
GUI.tag_box[tag_index].sensitive = true
|
||||
else
|
||||
GUI.tag_box[tag_index].label = ""
|
||||
GUI.tag_box[tag_index].sensitive = false
|
||||
end
|
||||
tag_index = tag_index + 1
|
||||
end
|
||||
|
||||
PHOTILS.in_pagination = false
|
||||
end
|
||||
|
||||
function PHOTILS.attach_tags()
|
||||
local num_selected = #dt.gui.selection()
|
||||
local job = dt.gui.create_job(_("Apply tag to image"), true)
|
||||
|
||||
for i = 1, num_selected, 1 do
|
||||
local image = dt.gui.selection()[i]
|
||||
for tag, _ in pairs(PHOTILS.selected_tags) do
|
||||
local dt_tag = dt.tags.create(tag)
|
||||
dt.tags.attach(dt_tag, image)
|
||||
end
|
||||
|
||||
job.percent = i / num_selected
|
||||
end
|
||||
|
||||
dt.print(_("Tags successfully attached to image"))
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
function PHOTILS.get_tags(image, with_export)
|
||||
|
||||
local tmp_file = df.create_tmp_file()
|
||||
local in_arg = df.sanitize_filename(tostring(image))
|
||||
local out_arg = df.sanitize_filename(tmp_file)
|
||||
local executable = photils_installed
|
||||
|
||||
if dt.configuration.running_os == "macos" then
|
||||
executable = executable .. "/Contents/MacOS/photils-cli"
|
||||
end
|
||||
|
||||
if with_export then
|
||||
dt.print_log("use export to for prediction")
|
||||
local export_file = df.create_tmp_file()
|
||||
exporter:write_image(image, export_file)
|
||||
in_arg = df.sanitize_filename(tostring(export_file))
|
||||
end
|
||||
|
||||
local command = executable .. " -c " .. " -i " .. in_arg .. " -o " .. out_arg
|
||||
|
||||
local ret = dtsys.external_command(command)
|
||||
if ret > 0 then
|
||||
dt.print_error(string.format("command %s returned error code %d", command, ret))
|
||||
os.remove(tmp_file)
|
||||
|
||||
-- try to export the image and run tagging
|
||||
if not with_export then
|
||||
return PHOTILS.get_tags(image, true)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
for i = #PHOTILS.tags, 1, -1 do
|
||||
PHOTILS.tags[i] = nil
|
||||
PHOTILS.confidences[i] = nil
|
||||
end
|
||||
|
||||
for tag in io.lines(tmp_file) do
|
||||
local splitted = du.split(tag, ":")
|
||||
if 100 * tonumber(splitted[2]) >= GUI.confidence_slider.value then
|
||||
PHOTILS.tags[#PHOTILS.tags + 1] = splitted[1]
|
||||
PHOTILS.confidences[#PHOTILS.confidences+1] = splitted[2]
|
||||
end
|
||||
end
|
||||
|
||||
dt.print(string.format(_("%s found %d tags for your image"), MODULE_NAME,
|
||||
#PHOTILS.tags))
|
||||
os.remove(tmp_file)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function PHOTILS.on_tags_clicked()
|
||||
PHOTILS.page = 1
|
||||
GUI.warning.label = ""
|
||||
|
||||
PHOTILS.on_reset(false)
|
||||
|
||||
local images = dt.gui.selection()
|
||||
|
||||
if #images == 0 then
|
||||
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.gui.selection({images[1]})
|
||||
dt.control.sleep(2000)
|
||||
end
|
||||
|
||||
with_export = dt.preferences.read(MODULE_NAME, "export_image_before_for_tags", "bool")
|
||||
if not PHOTILS.get_tags(images[1], with_export) then
|
||||
local msg = string.format(_("%s failed, see terminal output for details"), MODULE_NAME)
|
||||
GUI.warning_label.label = msg
|
||||
GUI.stack.active = GUI.error_view
|
||||
dt.print(msg)
|
||||
return
|
||||
end
|
||||
|
||||
if #PHOTILS.tags == 0 then
|
||||
local msg = string.format(_("no tags where found"), MODULE_NAME)
|
||||
GUI.warning_label.label = msg
|
||||
GUI.stack.active = GUI.error_view
|
||||
return
|
||||
end
|
||||
|
||||
GUI.stack.active = GUI.tag_view
|
||||
PHOTILS.paginate()
|
||||
end
|
||||
end
|
||||
|
||||
function PHOTILS.tag_selected(tag_button)
|
||||
if PHOTILS.in_pagination then return end
|
||||
|
||||
if tag_button.value then
|
||||
local tag = tag_button.label
|
||||
if dt.preferences.read(MODULE_NAME, "show_confidence", "bool") then
|
||||
local idx = string.find(tag, "%(") - 2
|
||||
tag = string.sub(tag, 0, idx)
|
||||
end
|
||||
|
||||
PHOTILS.selected_tags[tag] = tag
|
||||
else
|
||||
PHOTILS.selected_tags[tag_button.label] = nil
|
||||
end
|
||||
|
||||
local num_selected = num_keys(PHOTILS.selected_tags)
|
||||
if num_selected == 0 then
|
||||
GUI.attach_button.label = ""
|
||||
GUI.attach_button.sensitive = false
|
||||
else
|
||||
GUI.attach_button.label = string.format(_("attach %d tags"),
|
||||
num_selected)
|
||||
GUI.attach_button.sensitive = true
|
||||
end
|
||||
end
|
||||
|
||||
function PHOTILS.on_reset(with_view)
|
||||
if with_view then GUI.stack.active = 1 end
|
||||
|
||||
for k, _ in pairs(PHOTILS.selected_tags) do
|
||||
PHOTILS.selected_tags[k] = nil
|
||||
end
|
||||
|
||||
for _, v in ipairs(GUI.tag_box) do
|
||||
v.value = false
|
||||
end
|
||||
|
||||
GUI.attach_button.label = ""
|
||||
GUI.attach_button.sensitive = false
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not PHOTILS.module_installed then
|
||||
dt.register_lib(MODULE_NAME,
|
||||
"photils autotagger",
|
||||
true,
|
||||
true,
|
||||
PHOTILS.plugin_display_views,
|
||||
GUI.container,
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
PHOTILS.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs[MODULE_NAME].visible = false
|
||||
dt.destroy_event("photils", "mouse-over-image-changed")
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
dt.register_event("photils", "mouse-over-image-changed",
|
||||
PHOTILS.image_changed)
|
||||
end
|
||||
|
||||
local function show()
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
end
|
||||
|
||||
|
||||
-- add a fix number of buttons
|
||||
for _ = 1, PHOTILS.per_page, 1 do
|
||||
local btn_tag = dt.new_widget("check_button") {
|
||||
label = "",
|
||||
sensitive = false,
|
||||
clicked_callback = PHOTILS.tag_selected
|
||||
}
|
||||
|
||||
table.insert(GUI.tag_box, btn_tag)
|
||||
end
|
||||
|
||||
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.")
|
||||
end
|
||||
|
||||
GUI.pagination = dt.new_widget("box") {
|
||||
orientation = "horizontal",
|
||||
GUI.prev_button,
|
||||
GUI.page_label,
|
||||
GUI.next_button
|
||||
}
|
||||
|
||||
|
||||
table.insert(GUI.error_view, GUI.warning_label)
|
||||
if not photils_installed then
|
||||
table.insert(GUI.error_view, df.executable_path_widget({"photils-cli"}))
|
||||
table.insert(GUI.error_view, GUI.restart_required_label)
|
||||
end
|
||||
table.insert(GUI.stack, GUI.error_view)
|
||||
table.insert(GUI.stack, GUI.tag_view)
|
||||
|
||||
table.insert(GUI.tag_view, GUI.pagination)
|
||||
table.insert(GUI.tag_view, GUI.tag_box)
|
||||
table.insert(GUI.tag_view, GUI.attach_button)
|
||||
table.insert(GUI.tag_view, GUI.warning)
|
||||
|
||||
table.insert(GUI.container, GUI.confidence_slider)
|
||||
table.insert(GUI.container, GUI.stack)
|
||||
|
||||
GUI.stack.active = 1
|
||||
|
||||
|
||||
|
||||
-- uses photils: prefix because script settings are all together and not seperated by script
|
||||
dt.preferences.register(MODULE_NAME,
|
||||
"show_confidence",
|
||||
"bool",
|
||||
_("photils: show confidence value"),
|
||||
_("if enabled, the confidence value for each tag is displayed"),
|
||||
true)
|
||||
|
||||
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."),
|
||||
true)
|
||||
|
||||
dt.register_event("photils", "mouse-over-image-changed",
|
||||
PHOTILS.image_changed)
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not PHOTILS.event_registered then
|
||||
dt.register_event(
|
||||
"photils", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
PHOTILS.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = show
|
||||
|
||||
return script_data
|
||||
@@ -47,11 +47,23 @@ local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local debug = require "darktable.debug"
|
||||
|
||||
du.check_min_api_version("7.0.0", "quicktag")
|
||||
|
||||
-- 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
|
||||
|
||||
local qt = {}
|
||||
qt.module_installed = false
|
||||
qt.event_registered = false
|
||||
qt.widget_table = {}
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("3.0.0", "quicktag")
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("quicktag",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
@@ -156,7 +168,7 @@ abbrevate_tags(quicktag_table)
|
||||
local button = {}
|
||||
|
||||
-- function to create buttons with tags as labels
|
||||
for j=1,qnr do
|
||||
for j = 1, qnr do
|
||||
button[#button+1] = dt.new_widget("button") {
|
||||
label = j..": "..quicktag_table[j],
|
||||
clicked_callback = function() tagattach(tostring(quicktag_table[j]),j) end}
|
||||
@@ -177,12 +189,56 @@ local function update_quicktag_list()
|
||||
end
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not qt.module_installed then
|
||||
dt.register_lib(
|
||||
"quicktag", -- Module name
|
||||
"quicktag", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 490}},
|
||||
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
table.unpack(qt.widget_table),
|
||||
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
qt.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs["quicktag"].visible = false
|
||||
for i=1,qnr do
|
||||
dt.destroy_event("quicktag " .. tostring(i), "shortcut")
|
||||
end
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs["quicktag"].visible = true
|
||||
for i = 1 ,qnr do
|
||||
dt.register_event("quicktag", "shortcut",
|
||||
function(event, shortcut) tagattach(tostring(quicktag_table[i])) end,
|
||||
string.format(_("quicktag %i"),i))
|
||||
end
|
||||
end
|
||||
|
||||
local function show()
|
||||
dt.gui.libs["quicktag"].visible = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
update_quicktag_list()
|
||||
|
||||
local new_quicktag = dt.new_widget("entry"){
|
||||
text = "",
|
||||
placeholder = _("new tag"),
|
||||
is_password = true,
|
||||
is_password = false,
|
||||
editable = true,
|
||||
tooltip = _("enter your tag here")
|
||||
}
|
||||
@@ -213,40 +269,46 @@ local new_qt_widget = dt.new_widget ("box") {
|
||||
|
||||
-- back UI elements in a table
|
||||
-- thanks to wpferguson for the hint
|
||||
local widget_table = {}
|
||||
|
||||
for i=1,qnr do
|
||||
widget_table[#widget_table + 1] = button[i]
|
||||
qt.widget_table[#qt.widget_table + 1] = button[i]
|
||||
end
|
||||
|
||||
widget_table[#widget_table + 1] = dt.new_widget("separator"){}
|
||||
widget_table[#widget_table + 1] = old_quicktag
|
||||
widget_table[#widget_table + 1] = new_qt_widget
|
||||
qt.widget_table[#qt.widget_table + 1] = dt.new_widget("separator"){}
|
||||
qt.widget_table[#qt.widget_table + 1] = old_quicktag
|
||||
qt.widget_table[#qt.widget_table + 1] = new_qt_widget
|
||||
|
||||
|
||||
--create module
|
||||
dt.register_lib(
|
||||
"quicktag", -- Module name
|
||||
"quicktag", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 490}},
|
||||
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
table.unpack(widget_table),
|
||||
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not qt.event_registered then
|
||||
dt.register_event(
|
||||
"quicktag", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
qt.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
-- create shortcuts
|
||||
for i=1,qnr do
|
||||
dt.register_event("shortcut",
|
||||
dt.register_event("quicktag " .. tostring(i), "shortcut",
|
||||
function(event, shortcut) tagattach(tostring(quicktag_table[i])) end,
|
||||
string.format(_("quicktag %i"),i))
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = show
|
||||
|
||||
return script_data
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
|
||||
@@ -42,7 +42,15 @@ local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
-- added version check
|
||||
du.check_min_api_version("3.0.0", "rate_group")
|
||||
du.check_min_api_version("7.0.0", "rate_group")
|
||||
|
||||
-- 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
|
||||
|
||||
local function apply_rating(rating)
|
||||
local images = dt.gui.action_images
|
||||
@@ -59,30 +67,51 @@ local function apply_rating(rating)
|
||||
end
|
||||
end
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
local function destroy()
|
||||
dt.destroy_event("rg_reject", "shortcut")
|
||||
dt.destroy_event("rg0", "shortcut")
|
||||
dt.destroy_event("rg1", "shortcut")
|
||||
dt.destroy_event("rg2", "shortcut")
|
||||
dt.destroy_event("rg3", "shortcut")
|
||||
dt.destroy_event("rg4", "shortcut")
|
||||
dt.destroy_event("rg5", "shortcut")
|
||||
end
|
||||
|
||||
dt.register_event("rg_reject", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(-1)
|
||||
end, "Reject group")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg0", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(0)
|
||||
end, "Rate group 0")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg1", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(1)
|
||||
end, "Rate group 1")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg2", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(2)
|
||||
end, "Rate group 2")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg3", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(3)
|
||||
end, "Rate group 3")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg4", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(4)
|
||||
end, "Rate group 4")
|
||||
|
||||
dt.register_event("shortcut",function(event, shortcut)
|
||||
dt.register_event("rg5", "shortcut",
|
||||
function(event, shortcut)
|
||||
apply_rating(5)
|
||||
end, "Rate group 5")
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -33,7 +33,19 @@ local du = require "lib/dtutils"
|
||||
local debug = require "darktable.debug"
|
||||
|
||||
-- check API version
|
||||
du.check_min_api_version("3.0.0", "rename-tags")
|
||||
du.check_min_api_version("7.0.0", "rename-tags")
|
||||
|
||||
-- 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
|
||||
|
||||
local rt = {}
|
||||
rt.module_installed = false
|
||||
rt.event_registered = false
|
||||
|
||||
-- GUI entries
|
||||
local old_tag = darktable.new_widget("entry") { tooltip = "Enter old tag" }
|
||||
@@ -99,6 +111,21 @@ local function rename_tags()
|
||||
rename_reset()
|
||||
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)
|
||||
rt.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
darktable.gui.libs["rename_tags"].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
darktable.gui.libs["rename_tags"].visible = true
|
||||
end
|
||||
|
||||
-- GUI
|
||||
local old_widget = darktable.new_widget ("box") {
|
||||
orientation = "horizontal",
|
||||
@@ -112,7 +139,7 @@ local new_widget = darktable.new_widget ("box") {
|
||||
new_tag
|
||||
}
|
||||
|
||||
local rename_widget = darktable.new_widget ("box") {
|
||||
rt.rename_widget = darktable.new_widget ("box") {
|
||||
orientation = "vertical",
|
||||
reset_callback = rename_reset,
|
||||
old_widget,
|
||||
@@ -120,6 +147,27 @@ local rename_widget = darktable.new_widget ("box") {
|
||||
darktable.new_widget("button") { label = "Go", clicked_callback = rename_tags }
|
||||
}
|
||||
|
||||
if darktable.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not rt.event_registered then
|
||||
darktable.register_event(
|
||||
"rename_tags", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
rt.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
|
||||
|
||||
darktable.register_lib ("rename_tags", "rename tag", true, true, {[darktable.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 20},}, rename_widget, nil, nil)
|
||||
|
||||
|
||||
352
contrib/rename_images.lua
Normal file
352
contrib/rename_images.lua
Normal file
@@ -0,0 +1,352 @@
|
||||
--[[
|
||||
|
||||
rename.lua - rename image file(s)
|
||||
|
||||
Copyright (C) 2020, 2021 Bill Ferguson <wpferguson@gmail.com>.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
rename - rename an image file or files
|
||||
|
||||
This shortcut resets the GPS information to that contained within
|
||||
the image file. If no GPS info is in the image file, the GPS data
|
||||
is cleared.
|
||||
|
||||
USAGE
|
||||
* require this script from your luarc file or start it from script_manager
|
||||
* select an image or images
|
||||
* enter a renaming pattern
|
||||
* click the button to rename the files
|
||||
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
* Send to Bill Ferguson, wpferguson@gmail.com
|
||||
|
||||
CHANGES
|
||||
|
||||
TODO
|
||||
* Add pattern builder
|
||||
* Add new name preview
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
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 function _(msgid)
|
||||
return gettext.dgettext("rename_images", msgid)
|
||||
end
|
||||
|
||||
-- namespace variable
|
||||
local rename = {
|
||||
presets = {},
|
||||
substitutes = {},
|
||||
placeholders = {"ROLL_NAME","FILE_FOLDER","FILE_NAME","FILE_EXTENSION","ID","VERSION","SEQUENCE","YEAR","MONTH","DAY",
|
||||
"HOUR","MINUTE","SECOND","EXIF_YEAR","EXIF_MONTH","EXIF_DAY","EXIF_HOUR","EXIF_MINUTE","EXIF_SECOND",
|
||||
"STARS","LABELS","MAKER","MODEL","TITLE","CREATOR","PUBLISHER","RIGHTS","USERNAME","PICTURES_FOLDER",
|
||||
"HOME","DESKTOP","EXIF_ISO","EXIF_EXPOSURE","EXIF_EXPOSURE_BIAS","EXIF_APERTURE","EXIF_FOCUS_DISTANCE",
|
||||
"EXIF_FOCAL_LENGTH","LONGITUDE","LATITUDE","ELEVATION","LENS","DESCRIPTION","EXIF_CROP"},
|
||||
widgets = {},
|
||||
}
|
||||
rename.module_installed = false
|
||||
rename.event_registered = false
|
||||
|
||||
-- script_manager integration
|
||||
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
|
||||
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- C O N S T A N T S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
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 DESKTOP = HOME .. PS .. "Desktop"
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- F U N C T I O N S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
local function build_substitution_list(image, sequence, datetime, username, pic_folder, home, desktop)
|
||||
-- build the argument substitution list from each image
|
||||
-- local datetime = os.date("*t")
|
||||
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 eyear,emon,eday,ehour,emin,esec = string.match(image.exif_datetime_taken, "(%d-):(%d-):(%d-) (%d-):(%d-):(%d-)$")
|
||||
local replacements = {image.film,
|
||||
image.path,
|
||||
df.get_filename(image.filename),
|
||||
string.upper(df.get_filetype(image.filename)),
|
||||
image.id,image.duplicate_index,
|
||||
string.format("%04d", sequence),
|
||||
datetime.year,
|
||||
string.format("%02d", datetime.month),
|
||||
string.format("%02d", datetime.day),
|
||||
string.format("%02d", datetime.hour),
|
||||
string.format("%02d", datetime.min),
|
||||
string.format("%02d", datetime.sec),
|
||||
eyear,
|
||||
emon,
|
||||
eday,
|
||||
ehour,
|
||||
emin,
|
||||
esec,
|
||||
image.rating,
|
||||
labels,
|
||||
image.exif_maker,
|
||||
image.exif_model,
|
||||
image.title,
|
||||
image.creator,
|
||||
image.publisher,
|
||||
image.rights,
|
||||
username,
|
||||
pic_folder,
|
||||
home,
|
||||
desktop,
|
||||
image.exif_iso,
|
||||
image.exif_exposure,
|
||||
image.exif_exposure_bias,
|
||||
image.exif_aperture,
|
||||
image.exif_focus_distance,
|
||||
image.exif_focal_length,
|
||||
image.longitude,
|
||||
image.latitude,
|
||||
image.elevation,
|
||||
image.exif_lens,
|
||||
image.description,
|
||||
image.exif_crop
|
||||
}
|
||||
|
||||
for i=1,#rename.placeholders,1 do rename.substitutes[rename.placeholders[i]] = replacements[i] end
|
||||
end
|
||||
|
||||
local function substitute_list(str)
|
||||
-- replace the substitution variables in a string
|
||||
for match in string.gmatch(str, "%$%(.-%)") do
|
||||
local var = string.match(match, "%$%((.-)%)")
|
||||
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..."))
|
||||
return -1
|
||||
end
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
local function clear_substitute_list()
|
||||
for i=1,#rename.placeholders,1 do rename.substitutes[rename.placeholders[i]] = nil end
|
||||
end
|
||||
|
||||
local function stop_job(job)
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not rename.module_installed then
|
||||
dt.register_lib(
|
||||
MODULE_NAME,
|
||||
_("rename images"),
|
||||
true,
|
||||
true,
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",700}},
|
||||
dt.new_widget("box"){
|
||||
orientation = "vertical",
|
||||
rename.widgets.pattern,
|
||||
rename.widgets.button,
|
||||
},
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
rename.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
dt.gui.libs[MODULE_NAME].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs[MODULE_NAME].visible = true
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- M A I N
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
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))
|
||||
if string.len(pattern) > 0 then
|
||||
local datetime = os.date("*t")
|
||||
|
||||
local job = dt.gui.create_job(_("renaming images"), true, stop_job)
|
||||
for i, image in ipairs(images) do
|
||||
if job.valid then
|
||||
job.percent = i / #images
|
||||
build_substitution_list(image, i, datetime, USER, PICTURES, HOME, DESKTOP)
|
||||
local new_name = substitute_list(pattern)
|
||||
if new_name == -1 then
|
||||
dt.print(_("unable to do variable substitution, exiting..."))
|
||||
stop_job(job)
|
||||
return
|
||||
end
|
||||
clear_substitute_list()
|
||||
local args = {}
|
||||
local path = string.sub(df.get_path(new_name), 1, -2)
|
||||
if string.len(path) == 0 then
|
||||
path = image.path
|
||||
end
|
||||
local filename = df.get_filename(new_name)
|
||||
local filmname = image.path
|
||||
if path ~= image.path then
|
||||
if not df.check_if_file_exists(df.sanitize_filename(path)) then
|
||||
df.mkdir(df.sanitize_filename(path))
|
||||
end
|
||||
filmname = path
|
||||
end
|
||||
args[1] = dt.films.new(filmname)
|
||||
args[2] = image
|
||||
if filename ~= image.filename then
|
||||
args[3] = filename
|
||||
end
|
||||
dt.database.move_image(table.unpack(args))
|
||||
end
|
||||
end
|
||||
stop_job(job)
|
||||
local collect_rules = dt.gui.libs.collect.filter()
|
||||
dt.gui.libs.collect.filter(collect_rules)
|
||||
dt.print(_("renamed " .. #images .. " images"))
|
||||
else -- pattern length
|
||||
dt.print_error("no pattern supplied, returning...")
|
||||
dt.print(_("please enter the new name or pattern"))
|
||||
end
|
||||
else -- image count
|
||||
dt.print_error("no images selected, returning...")
|
||||
dt.print(_("please select some images and try again"))
|
||||
end
|
||||
end
|
||||
|
||||
local function reset_callback()
|
||||
rename.widgets.pattern.text = ""
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- W I D G E T S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
rename.widgets.pattern = dt.new_widget("entry"){
|
||||
tooltip = _("$(ROLL_NAME) - film roll name\n") ..
|
||||
_("$(FILE_FOLDER) - image file folder\n") ..
|
||||
_("$(FILE_NAME) - image file name\n") ..
|
||||
_("$(FILE_EXTENSION) - image file extension\n") ..
|
||||
_("$(ID) - image id\n") ..
|
||||
_("$(VERSION) - version number\n") ..
|
||||
_("$(SEQUENCE) - sequence number of selection\n") ..
|
||||
_("$(YEAR) - current year\n") ..
|
||||
_("$(MONTH) - current month\n") ..
|
||||
_("$(DAY) - current day\n") ..
|
||||
_("$(HOUR) - current hour\n") ..
|
||||
_("$(MINUTE) - current minute\n") ..
|
||||
_("$(SECOND) - current second\n") ..
|
||||
_("$(EXIF_YEAR) - EXIF year\n") ..
|
||||
_("$(EXIF_MONTH) - EXIF month\n") ..
|
||||
_("$(EXIF_DAY) - EXIF day\n") ..
|
||||
_("$(EXIF_HOUR) - EXIF hour\n") ..
|
||||
_("$(EXIF_MINUTE) - EXIF minute\n") ..
|
||||
_("$(EXIF_SECOND) - EXIF seconds\n") ..
|
||||
_("$(EXIF_ISO) - EXIF ISO\n") ..
|
||||
_("$(EXIF_EXPOSURE) - EXIF exposure\n") ..
|
||||
_("$(EXIF_EXPOSURE_BIAS) - EXIF exposure bias\n") ..
|
||||
_("$(EXIF_APERTURE) - EXIF aperture\n") ..
|
||||
_("$(EXIF_FOCAL_LENGTH) - EXIF focal length\n") ..
|
||||
_("$(EXIF_FOCUS_DISTANCE) - EXIF focus distance\n") ..
|
||||
_("$(EXIF_CROP) - EXIF crop\n") ..
|
||||
_("$(LONGITUDE) - longitude\n") ..
|
||||
_("$(LATITUDE) - latitude\n") ..
|
||||
_("$(ELEVATION) - elevation\n") ..
|
||||
_("$(STARS) - star rating\n") ..
|
||||
_("$(LABELS) - color labels\n") ..
|
||||
_("$(MAKER) - camera maker\n") ..
|
||||
_("$(MODEL) - camera model\n") ..
|
||||
_("$(LENS) - lens\n") ..
|
||||
_("$(TITLE) - title from metadata\n") ..
|
||||
_("$(DESCRIPTION) - description from metadata\n") ..
|
||||
_("$(CREATOR) - creator from metadata\n") ..
|
||||
_("$(PUBLISHER) - publisher from metadata\n") ..
|
||||
_("$(RIGHTS) - rights from metadata\n") ..
|
||||
_("$(USERNAME) - username\n") ..
|
||||
_("$(PICTURES_FOLDER) - pictures folder\n") ..
|
||||
_("$(HOME) - user's home directory\n") ..
|
||||
_("$(DESKTOP) - desktop directory"),
|
||||
placeholder = _("enter pattern $(FILE_FOLDER)/$(FILE_NAME)"),
|
||||
text = ""
|
||||
}
|
||||
|
||||
local pattern_pref = dt.preferences.read(MODULE_NAME, "pattern", "string")
|
||||
if pattern_pref then
|
||||
rename.widgets.pattern.text = pattern_pref
|
||||
end
|
||||
|
||||
rename.widgets.button = dt.new_widget("button"){
|
||||
label = _("rename"),
|
||||
clicked_callback = function(this)
|
||||
do_rename(dt.gui.action_images)
|
||||
end
|
||||
}
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not rename.event_registered then
|
||||
dt.register_event(
|
||||
"rename_images", "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
rename.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
|
||||
@@ -22,7 +22,15 @@ local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("3.0.0", "select_untagged")
|
||||
du.check_min_api_version("7.0.0", "select_untagged")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("select_untagged",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -35,23 +43,23 @@ local function stop_job(job)
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local function select_untagged_images()
|
||||
local function select_untagged_images(event, images)
|
||||
job = dt.gui.create_job(_("select untagged images"), true, stop_job)
|
||||
|
||||
local selection = {}
|
||||
|
||||
for key,image in ipairs(dt.collection) do
|
||||
for key,image in ipairs(images) do
|
||||
if(job.valid) then
|
||||
job.percent = (key-1)/#dt.collection
|
||||
job.percent = (key - 1)/#images
|
||||
local tags = dt.tags.get_tags(image)
|
||||
local hasTags = false
|
||||
for _,tag in ipairs(tags) do
|
||||
if not string.match(tag.name,"darktable|") then
|
||||
if not string.match(tag.name, "darktable|") then
|
||||
hasTags = true
|
||||
end
|
||||
end
|
||||
if hasTags == false then
|
||||
table.insert(selection,image)
|
||||
table.insert(selection, image)
|
||||
end
|
||||
else
|
||||
break
|
||||
@@ -59,7 +67,19 @@ local function select_untagged_images()
|
||||
end
|
||||
|
||||
job.valid = false
|
||||
dt.gui.selection(selection)
|
||||
-- return table of images to set the selection to
|
||||
return selection
|
||||
end
|
||||
|
||||
dt.gui.libs.select.register_selection(_("select untagged"),select_untagged_images,_("select all images containing no tags or only tags added by darktable"))
|
||||
local function destroy()
|
||||
dt.gui.libs.select.destroy_selection("select_untagged")
|
||||
end
|
||||
|
||||
dt.gui.libs.select.register_selection(
|
||||
"select_untagged", _("select untagged"),
|
||||
select_untagged_images,
|
||||
_("select all images containing no tags or only tags added by darktable"))
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -27,10 +27,17 @@ USAGE
|
||||
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.2", "slideshowMusic")
|
||||
du.check_min_api_version("7.0.0", "slideshowMusic")
|
||||
|
||||
-- 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
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("slideshowMusic",dt.configuration.config_dir.."/lua/locale/")
|
||||
@@ -68,6 +75,12 @@ local function playSlideshowMusic(_, old_view, new_view)
|
||||
end
|
||||
end
|
||||
|
||||
function destroy()
|
||||
dt.destroy_event("slideshow_music", "view-changed")
|
||||
dt.preferences.destroy("slideshowMusic", "SlideshowMusic")
|
||||
dt.preferences.destroy("slideshowMusic", "PlaySlideshowMusic")
|
||||
end
|
||||
|
||||
-- Preferences
|
||||
dt.preferences.register("slideshowMusic", "SlideshowMusic", "file", _("Slideshow background music file"), "", "")
|
||||
dt.preferences.register("slideshowMusic",
|
||||
@@ -77,4 +90,9 @@ dt.preferences.register("slideshowMusic",
|
||||
_("Plays music with rhythmbox if a slideshow starts"),
|
||||
true)
|
||||
-- Register
|
||||
dt.register_event("view-changed",playSlideshowMusic)
|
||||
dt.register_event("slideshow_music", "view-changed",
|
||||
playSlideshowMusic)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -78,7 +78,15 @@ local dtutils_file = require("lib/dtutils.file")
|
||||
local dtutils_system = require("lib/dtutils.system")
|
||||
|
||||
local LIB_ID = "transfer_hierarchy"
|
||||
dtutils.check_min_api_version("5.0.0", LIB_ID)
|
||||
dtutils.check_min_api_version("7.0.0", LIB_ID)
|
||||
|
||||
-- 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
|
||||
|
||||
local MKDIR_COMMAND = darktable.configuration.running_os == "windows" and "mkdir " or "mkdir -p "
|
||||
local PATH_SEPARATOR = darktable.configuration.running_os == "windows" and "\\\\" or "/"
|
||||
@@ -99,6 +107,10 @@ end
|
||||
|
||||
-- Helper functions: BEGIN
|
||||
|
||||
local th = {}
|
||||
th.module_installed = false
|
||||
th.event_registered = false
|
||||
|
||||
local function pathExists(path)
|
||||
local success, err, errno = os.rename(path, path)
|
||||
if not success then
|
||||
@@ -122,6 +134,16 @@ local function createDirectory(path)
|
||||
end
|
||||
end
|
||||
|
||||
local function install_module()
|
||||
if not th.module_installed then
|
||||
darktable.register_lib(LIB_ID,
|
||||
"transfer hierarchy", true, true, {
|
||||
[darktable.gui.views.lighttable] = { "DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 700 }
|
||||
}, th.transfer_widget, nil, nil)
|
||||
th.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Helper functions: END
|
||||
|
||||
|
||||
@@ -287,12 +309,19 @@ local function doCopy()
|
||||
doTransfer(darktable.database.copy_image)
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
darktable.gui.libs[LIB_ID].visible = false
|
||||
end
|
||||
|
||||
local function restart()
|
||||
darktable.gui.libs[LIB_ID].visible = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local transfer_widget = darktable.new_widget("box") {
|
||||
th.transfer_widget = darktable.new_widget("box") {
|
||||
orientation = "vertical",
|
||||
darktable.new_widget("button") {
|
||||
label = _("calculate"),
|
||||
@@ -347,12 +376,26 @@ darktable.preferences.register(
|
||||
|
||||
-- Preferences: END
|
||||
|
||||
if darktable.gui.current_view().id == "lighttable" then
|
||||
install_module()
|
||||
else
|
||||
if not th.event_registered then
|
||||
darktable.register_event(
|
||||
LIB_ID, "view-changed",
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then
|
||||
install_module()
|
||||
end
|
||||
end
|
||||
)
|
||||
th.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart
|
||||
script_data.destroy_method = "hide"
|
||||
script_data.show = restart
|
||||
|
||||
|
||||
|
||||
darktable.register_lib(LIB_ID,
|
||||
"transfer hierarchy", true, true, {
|
||||
[darktable.gui.views.lighttable] = { "DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 700 }
|
||||
}, transfer_widget, nil, nil)
|
||||
return script_data
|
||||
@@ -39,7 +39,15 @@ local df = require "lib/dtutils.file"
|
||||
local dsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("5.0.0")
|
||||
du.check_min_api_version("7.0.0", "video_ffmpeg")
|
||||
|
||||
-- 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
|
||||
|
||||
local MODULE_NAME = "video_ffmpeg"
|
||||
|
||||
@@ -96,7 +104,7 @@ local resolutions = {
|
||||
}
|
||||
}
|
||||
|
||||
local framerates = {"15", "16", "23.98", "24", "25", "29,97", "30", "48", "50", "59.94", "60"}
|
||||
local framerates = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "15", "16", "23.98", "24", "25", "29,97", "30", "48", "50", "59.94", "60", "120", "240", "300"}
|
||||
|
||||
local formats = {
|
||||
["AVI"] = {
|
||||
@@ -448,6 +456,12 @@ local function finalize_export(storage, images_table, extra_data)
|
||||
df.rmdir(df.sanitize_filename(tmp_dir))
|
||||
end
|
||||
|
||||
-- script_manager integration
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_storage("module_video_ffmpeg")
|
||||
end
|
||||
|
||||
dt.register_storage(
|
||||
"module_video_ffmpeg",
|
||||
_(MODULE_NAME),
|
||||
@@ -458,3 +472,8 @@ dt.register_storage(
|
||||
module_widget
|
||||
)
|
||||
|
||||
-- script_manager integration
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -23,5 +23,19 @@ USAGE
|
||||
]]
|
||||
local dt = require "darktable"
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
local result = dt.configuration.api_version_string
|
||||
dt.print_error("API Version: "..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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -42,6 +42,12 @@ local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("5.0.2", "darkroom_mode") -- darktable 3.0
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- C O N S T A N T S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -70,6 +76,16 @@ local sleep = dt.control.sleep
|
||||
|
||||
local current_view = dt.gui.current_view()
|
||||
|
||||
-- check that there is an image selected, otherwise we can't activate darkroom viewe
|
||||
|
||||
local images = dt.gui.action_images
|
||||
dt.print_log(#images .. " images selected")
|
||||
if not images or #images == 0 then
|
||||
dt.print_log("no images selected, creating selection")
|
||||
dt.print_log("using image " .. dt.collection[1].filename)
|
||||
dt.gui.selection({dt.collection[1]})
|
||||
end
|
||||
|
||||
-- enter darkroom view
|
||||
|
||||
dt.gui.current_view(dt.gui.views.darkroom)
|
||||
@@ -96,3 +112,10 @@ dt.print(_("Restoring view"))
|
||||
sleep(1500)
|
||||
dt.gui.current_view(current_view)
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -58,6 +58,12 @@ local du = require "lib/dtutils"
|
||||
--check API version
|
||||
du.check_min_api_version("3.0.0", "gettextExample")
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
-- Not translated Text
|
||||
dt.print_error("Hello World!")
|
||||
|
||||
@@ -77,3 +83,11 @@ local function _(msgid)
|
||||
return gettext.dgettext("gettextExample", msgid)
|
||||
end
|
||||
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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -31,7 +31,20 @@ local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("2.0.0", "hello_world")
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
@@ -50,6 +50,12 @@ du.check_min_api_version("5.0.2", "lighttable_demo") -- darktable 3.0
|
||||
local MODULE_NAME = "lighttable"
|
||||
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- T R A N S L A T I O N S
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -75,6 +81,7 @@ local layouts = {
|
||||
"DT_LIGHTTABLE_LAYOUT_ZOOMABLE",
|
||||
"DT_LIGHTTABLE_LAYOUT_FILEMANAGER",
|
||||
"DT_LIGHTTABLE_LAYOUT_CULLING",
|
||||
"DT_LIGHTTABLE_LAYOUT_CULLING_DYNAMIC",
|
||||
}
|
||||
|
||||
local sorts = {
|
||||
@@ -139,6 +146,7 @@ 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))
|
||||
sleep(1500)
|
||||
for i = 1, 10 do
|
||||
dt.gui.libs.lighttable_mode.zoom_level(i)
|
||||
@@ -152,11 +160,17 @@ for n, layout in ipairs(layouts) do
|
||||
end
|
||||
end
|
||||
|
||||
dt.print_log("finished layout and zoom level testing")
|
||||
dt.print_log("starting sort demonstration")
|
||||
-- cycle through sorts
|
||||
|
||||
dt.print(_("lighttable sorting demonstration"))
|
||||
dt.print_log("setting lighttable to filemanager mode")
|
||||
dt.gui.libs.lighttable_mode.layout("DT_LIGHTTABLE_LAYOUT_FILEMANAGER")
|
||||
sleep(500)
|
||||
dt.print_log("setting lighttable to zoom level 5")
|
||||
dt.gui.libs.lighttable_mode.zoom_level(5)
|
||||
dt.print_log("starting sorts")
|
||||
|
||||
for n, sort in ipairs(sorts) do
|
||||
dt.gui.libs.filter.sort(sort)
|
||||
@@ -196,3 +210,11 @@ 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)
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -33,7 +33,15 @@ https://www.darktable.org/lua-api/index.html.php#darktable_new_widget
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("3.0.0", "moduleExample")
|
||||
du.check_min_api_version("7.0.0", "moduleExample")
|
||||
|
||||
-- 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
|
||||
|
||||
-- translation
|
||||
|
||||
@@ -46,6 +54,54 @@ local function _(msgid)
|
||||
return gettext.dgettext("moduleExample", msgid)
|
||||
end
|
||||
|
||||
-- declare a local namespace and a couple of variables we'll need to install the module
|
||||
local mE = {}
|
||||
mE.widgets = {}
|
||||
mE.event_registered = false -- keep track of whether we've added an event callback or not
|
||||
mE.module_installed = false -- keep track of whether the module is module_installed
|
||||
|
||||
--[[ We have to create the module in one of two ways depending on which view darktable starts
|
||||
in. In orker to not repeat code, we wrap the darktable.register_lib in a local function.
|
||||
]]
|
||||
|
||||
local function install_module()
|
||||
if not mE.module_installed then
|
||||
-- https://www.darktable.org/lua-api/index.html#darktable_register_lib
|
||||
dt.register_lib(
|
||||
"exampleModule", -- Module name
|
||||
"exampleModule", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
-- https://www.darktable.org/lua-api/types_lua_box.html
|
||||
dt.new_widget("box") -- widget
|
||||
{
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button")
|
||||
{
|
||||
label = _("MyButton"),
|
||||
clicked_callback = function (_)
|
||||
dt.print(_("Button clicked"))
|
||||
end
|
||||
},
|
||||
table.unpack(mE.widgets),
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
mE.module_installed = true
|
||||
end
|
||||
end
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
dt.gui.libs["exampleModule"].visible = false -- we haven't figured out how to destroy it yet, so we hide it for now
|
||||
end
|
||||
|
||||
local function restart()
|
||||
dt.gui.libs["exampleModule"].visible = true -- the user wants to use it again, so we just make it visible and it shows up in the UI
|
||||
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}
|
||||
@@ -90,35 +146,44 @@ local slider = dt.new_widget("slider")
|
||||
value = 52 -- The current value of the slider
|
||||
}
|
||||
|
||||
-- https://www.darktable.org/lua-api/index.html#darktable_register_lib
|
||||
dt.register_lib(
|
||||
"exampleModule", -- Module name
|
||||
"exampleModule", -- name
|
||||
true, -- expandable
|
||||
false, -- resetable
|
||||
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers
|
||||
-- https://www.darktable.org/lua-api/types_lua_box.html
|
||||
dt.new_widget("box") -- widget
|
||||
{
|
||||
orientation = "vertical",
|
||||
dt.new_widget("button")
|
||||
{
|
||||
label = _("MyButton"),
|
||||
clicked_callback = function (_)
|
||||
dt.print(_("Button clicked"))
|
||||
end
|
||||
},
|
||||
check_button,
|
||||
combobox,
|
||||
entry,
|
||||
file_chooser_button,
|
||||
label,
|
||||
separator,
|
||||
slider
|
||||
},
|
||||
nil,-- view_enter
|
||||
nil -- view_leave
|
||||
)
|
||||
-- pack the widgets in a table for loading in the module
|
||||
|
||||
table.insert(mE.widgets, check_button)
|
||||
table.insert(mE.widgets, combobox)
|
||||
table.insert(mE.widgets, entry)
|
||||
table.insert(mE.widgets, file_chooser_button)
|
||||
table.insert(mE.widgets, label)
|
||||
table.insert(mE.widgets, separator)
|
||||
table.insert(mE.widgets, slider)
|
||||
|
||||
-- ... and tell dt about it all
|
||||
|
||||
|
||||
if dt.gui.current_view().id == "lighttable" then -- make sure we are in lighttable view
|
||||
install_module() -- register the lib
|
||||
else
|
||||
if not mE.event_registered then -- if we are not in lighttable view then register an event to signal when we might be
|
||||
-- https://www.darktable.org/lua-api/index.html#darktable_register_event
|
||||
dt.register_event(
|
||||
"mdouleExample", "view-changed", -- we want to be informed when the view changes
|
||||
function(event, old_view, new_view)
|
||||
if new_view.name == "lighttable" and old_view.name == "darkroom" then -- if the view changes from darkroom to lighttable
|
||||
install_module() -- register the lib
|
||||
end
|
||||
end
|
||||
)
|
||||
mE.event_registered = true -- keep track of whether we have an event handler installed
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
script_data.destroy = destroy
|
||||
script_data.restart = restart -- only required for lib modules until we figure out how to destroy them
|
||||
script_data.destroy_method = "hide" -- tell script_manager that we are hiding the lib so it knows to use the restart function
|
||||
script_data.show = restart -- if the script was "off" when darktable exited, the module is hidden, so force it to show on start
|
||||
|
||||
return script_data
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: hl Lua;
|
||||
|
||||
@@ -86,7 +86,7 @@ end
|
||||
screen stating that you couldn't load because the minimum api version wasn't met.
|
||||
]]
|
||||
|
||||
du.check_min_api_version("5.0.0", "multi_os")
|
||||
du.check_min_api_version("7.0.0", "multi_os")
|
||||
|
||||
--[[
|
||||
copy_image_attributes is a local subroutine to copy image attributes in the database from the raw image
|
||||
@@ -196,6 +196,15 @@ local function extract_embedded_jpeg(images)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
script_manager integration to allow a script to be removed
|
||||
without restarting darktable
|
||||
]]
|
||||
|
||||
local function destroy()
|
||||
dt.destroy_event("multi_os", "shortcut") -- destroy the event since the callback will no longer be present
|
||||
dt.gui.libs.image.destroy_action("multi_os") -- remove the button from the selected images module
|
||||
end
|
||||
--[[
|
||||
Windows and MacOS don't place executables in the user's path so their location needs to be specified
|
||||
so that the script can find them. An exception to this is packages installed on MacOS with homebrew. Those
|
||||
@@ -204,31 +213,33 @@ end
|
||||
to see if the executable is there.
|
||||
]]
|
||||
|
||||
local executable = "ufraw-batch"
|
||||
local ufraw_batch_path_widget = dt.new_widget("file_chooser_button"){
|
||||
title = _("Select ufraw-batch[.exe] executable"),
|
||||
value = df.get_executable_path_preference(executable),
|
||||
is_directory = false,
|
||||
changed_callback = function(self)
|
||||
if df.check_if_bin_exists(self.value) then
|
||||
df.set_executable_path_preference(executable, self.value)
|
||||
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"),
|
||||
value = df.get_executable_path_preference(executable),
|
||||
is_directory = false,
|
||||
changed_callback = function(self)
|
||||
if df.check_if_bin_exists(self.value) then
|
||||
df.set_executable_path_preference(executable, self.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
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
|
||||
"ufraw-batch", -- default
|
||||
ufraw_batch_path_widget
|
||||
)
|
||||
}
|
||||
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
|
||||
"ufraw-batch", -- default
|
||||
ufraw_batch_path_widget
|
||||
)
|
||||
end
|
||||
|
||||
--[[
|
||||
Add a button to the selected images module in lighttable
|
||||
]]
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
_("extract embedded jpeg"),
|
||||
"multi_os", _("extract embedded jpeg"),
|
||||
function(event, images) extract_embedded_jpeg(images) end,
|
||||
"extract embedded jpeg"
|
||||
)
|
||||
@@ -238,7 +249,18 @@ dt.gui.libs.image.register_action(
|
||||
]]
|
||||
|
||||
dt.register_event(
|
||||
"shortcut",
|
||||
"multi_os", "shortcut",
|
||||
function(event, shortcut) extract_embedded_jpeg(dt.gui.action_images) end,
|
||||
"extract embedded jpeg"
|
||||
)
|
||||
|
||||
--[[
|
||||
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
|
||||
script_manager
|
||||
]]
|
||||
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -41,7 +41,13 @@ 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
|
||||
du.check_min_api_version("7.0.0", "panels_demo")
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- C O N S T A N T S
|
||||
@@ -134,3 +140,11 @@ for i = 1, #panels do
|
||||
dt.gui.panel_hide(panels[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -26,6 +26,7 @@ local du = require "lib/dtutils"
|
||||
|
||||
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
|
||||
@@ -34,14 +35,14 @@ dt.preferences.register("preferenceExamples", -- script: This is a string
|
||||
"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.
|
||||
"preferenceExamplesString", -- name
|
||||
"preferenceExamplesBool", -- name
|
||||
"bool", -- type
|
||||
"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.
|
||||
"preferenceExamplesString", -- name
|
||||
"preferenceExamplesInteger", -- name
|
||||
"integer", -- type
|
||||
"Example Integer", -- label
|
||||
"Example Integer Tooltip", -- tooltip
|
||||
@@ -50,7 +51,7 @@ dt.preferences.register("preferenceExamples", -- script: This is a string
|
||||
99) -- max
|
||||
|
||||
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
|
||||
"preferenceExamplesFloat", -- name
|
||||
"float", -- type
|
||||
"Example Float", -- label
|
||||
"Example Float Tooltip", -- tooltip
|
||||
@@ -60,21 +61,21 @@ dt.preferences.register("preferenceExamples", -- script: This is a string
|
||||
0.5) -- step
|
||||
|
||||
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
|
||||
"preferenceExamplesFile", -- name
|
||||
"file", -- type
|
||||
"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.
|
||||
"preferenceExamplesString", -- name
|
||||
"preferenceExamplesDirectory", -- name
|
||||
"directory", -- type
|
||||
"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.
|
||||
"preferenceExamplesString", -- name
|
||||
"preferenceExamplesEnum", -- name
|
||||
"enum", -- type
|
||||
"Example Enum", -- label
|
||||
"Example Enum Tooltip", -- tooltip
|
||||
|
||||
@@ -24,6 +24,12 @@ local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("5.0.0", "printExamples")
|
||||
|
||||
-- script_manager integration to allow a script to be removed
|
||||
-- without restarting darktable
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
-- Will print a string to the darktable control log (the long
|
||||
-- overlayed window that appears over the main panel).
|
||||
dt.print("print")
|
||||
@@ -38,5 +44,12 @@ dt.print_error("print error")
|
||||
-- to enable the Lua logdomain.
|
||||
dt.print_log("print log")
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
@@ -30,7 +30,21 @@ local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("5.0.0", "running_os")
|
||||
|
||||
-- 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)
|
||||
|
||||
-- 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
|
||||
-- script_manager
|
||||
local script_data = {}
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
|
||||
@@ -283,4 +283,51 @@ function dtutils.check_os(operating_systems)
|
||||
return false
|
||||
end
|
||||
|
||||
dtutils.libdoc.functions["find_image_by_id"] = {
|
||||
Name = [[find_image_by_id]],
|
||||
Synopsis = [[look up an image by ID in the database]],
|
||||
Usage = [[local du = require "lib/dtutils"
|
||||
local img = du.find_image_by_id(imgid)
|
||||
id - int - the ID to look up
|
||||
]],
|
||||
Description = [[find_image_by_id looks up an image by ID in the database.]],
|
||||
Return_Value = [[result - dt_lua_image_t - image with the given ID if found, nil if not]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils.find_image_by_id(imgid)
|
||||
if #dt.database == 0 or imgid > dt.database[#dt.database].id then
|
||||
return nil
|
||||
end
|
||||
if dt.configuration.api_version_string >= "6.2.0" then
|
||||
return dt.database.get_image(imgid)
|
||||
else
|
||||
local min = 1
|
||||
local max = #dt.database
|
||||
while (max-min)//2 > 0 do
|
||||
local mid = min + (max-min)//2
|
||||
local midID = dt.database[mid].id
|
||||
if imgid == midID then
|
||||
return dt.database[mid]
|
||||
elseif imgid < midID then
|
||||
max = mid-1
|
||||
else
|
||||
min = mid+1
|
||||
end
|
||||
end
|
||||
if dt.database[min].id == imgid then
|
||||
return dt.database[min]
|
||||
elseif dt.database[max].id == imgid then
|
||||
return dt.database[max]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return dtutils
|
||||
|
||||
@@ -35,14 +35,54 @@ local function _(msgid)
|
||||
return gettext.dgettext("dtutils.file", msgid)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["is_dir"] = {
|
||||
Name = [[is_dir]],
|
||||
Synopsis = [[check if a path is a directory]],
|
||||
--[[
|
||||
local function to run a test command on windows and return a true if it succeeds
|
||||
instead of returning true if it runs
|
||||
]]
|
||||
|
||||
local function _win_os_execute(cmd)
|
||||
local result = nil
|
||||
local p = io.popen(cmd)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
if string.match(output, "true") then
|
||||
result = true
|
||||
else
|
||||
result = false
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to determine if a path name is a windows executable
|
||||
]]
|
||||
|
||||
local function _is_windows_executable(path)
|
||||
local result = false
|
||||
if dtutils_file.test_file(path, "f") then
|
||||
if string.match(path, ".exe$") or string.match(path, ".EXE$") or
|
||||
string.match(path, ".com$") or string.match(path, ".COM$") or
|
||||
string.match(path, ".bat$") or string.match(path, ".BAT$") or
|
||||
string.match(path, ".cmd$") or string.match(path, ".CMD$") then
|
||||
result = true
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["test_file"] = {
|
||||
Name = [[test_file]],
|
||||
Synopsis = [[test a file to see what it is]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.is_dir(path)
|
||||
path - string - the path to check]],
|
||||
Description = [[is_dir checks a path to see if it is a directory]],
|
||||
local result = df.test_file(path, test)
|
||||
path - string - the path to check
|
||||
test - one of d, e, f, x where
|
||||
d - directory
|
||||
e - exists
|
||||
f - file
|
||||
x - executable]],
|
||||
Description = [[test_file checks a path to see if it is a directory]],
|
||||
Return_Value = [[result - boolean - true if path is a directory, nil if not]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
@@ -52,125 +92,71 @@ dtutils_file.libdoc.functions["is_dir"] = {
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.is_dir(path)
|
||||
local cmd = nil
|
||||
function dtutils_file.test_file(path, test)
|
||||
local cmd = "test -"
|
||||
local engine = os.execute
|
||||
local cmdstring = ""
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
cmd = "if exist " .. ds.sanitize(path .. "\\*")
|
||||
else
|
||||
cmd = "test -d " .. ds.sanitize(path)
|
||||
cmd = "if exist "
|
||||
engine = _win_os_execute
|
||||
end
|
||||
|
||||
return os.execute(cmd)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["is_file"] = {
|
||||
Name = [[is_file]],
|
||||
Synopsis = [[check if a path is a file]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.is_file(path)
|
||||
path - string - the path to check]],
|
||||
Description = [[is_file checks a path to see if it is a file]],
|
||||
Return_Value = [[result - boolean - true if path is a file, nil if not]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.is_file(path)
|
||||
local cmd = nil
|
||||
local result = false
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
if not dtutils_file.is_dir(path) then
|
||||
cmd = "if exist " .. ds.sanitize(path) .. " echo true"
|
||||
local p = io.popen(cmd)
|
||||
output = p:read("*a")
|
||||
p:close()
|
||||
if string.match(output, "true") then
|
||||
result = true
|
||||
if test == "d" then
|
||||
-- test if directory
|
||||
if dt.configuration.running_os == "windows" then
|
||||
cmdstring = cmd .. dtutils_file.sanitize_filename(path .. "\\*") .. " echo true"
|
||||
else
|
||||
cmdstring = cmd .. test .. " " .. dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
elseif test == "e" then
|
||||
-- test exists
|
||||
if dt.configuration.running_os == "windows" then
|
||||
cmdstring = cmd .. dtutils_file.sanitize_filename(path) .. " echo true"
|
||||
else
|
||||
cmdstring = cmd .. test .. " " .. dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
elseif test == "f" then
|
||||
-- test if file
|
||||
if dt.configuration.running_os == "windows" then
|
||||
if not dtutils_file.test_file(path, "d") then -- make sure it's not a directory
|
||||
cmdstring = cmd .. dtutils_file.sanitize_filename(path) .. " echo true"
|
||||
else
|
||||
result = false
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
cmdstring = cmd .. test .. " " .. dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
elseif test == "x" then
|
||||
-- test executable
|
||||
if dt.configuration.running_os == "windows" then
|
||||
return _is_windows_executable(path)
|
||||
else
|
||||
cmdstring = cmd .. test .. " " .. dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
else
|
||||
result = os.execute("test -f " .. ds.sanitize(path))
|
||||
dt.print_error("[test_file] unknown test " .. test)
|
||||
return false
|
||||
end
|
||||
|
||||
return result
|
||||
return engine(cmdstring)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["is_executable"] = {
|
||||
Name = [[is_executable]],
|
||||
Synopsis = [[check if a path is a executable]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
--[[
|
||||
local function to return a case insensitive pattern for matching
|
||||
i.e. gimp becomes [Gg][Ii][Mm][Pp] which should match any capitalization
|
||||
of gimp.
|
||||
]]
|
||||
|
||||
local result = df.is_executable(path)
|
||||
path - string - the path to check]],
|
||||
Description = [[is_executable checks a path to see if it is an executable]],
|
||||
Return_Value = [[result - boolean - true if path is an executable, nil if not]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
local function _is_windows_executable(path)
|
||||
local result = nil
|
||||
dt.print_log("checking " .. path)
|
||||
|
||||
if string.match(path, ".exe$") or string.match(path, ".EXE$") or
|
||||
string.match(path, ".com$") or string.match(path, ".COM$") or
|
||||
string.match(path, ".bat$") or string.match(path, ".BAT$") or
|
||||
string.match(path, ".cmd$") or string.match(path, ".CMD$") then
|
||||
result = true
|
||||
end
|
||||
return result
|
||||
local function _case_insensitive_pattern(pattern)
|
||||
return pattern:gsub("(.)", function(letter)
|
||||
return string.format("[%s$s]", letter:lower(), letter:upper())
|
||||
end)
|
||||
end
|
||||
|
||||
function dtutils_file.is_executable(path)
|
||||
|
||||
local result = nil
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
if _is_windows_executable(path) then
|
||||
result = true
|
||||
end
|
||||
else
|
||||
result = os.execute("test -x " .. ds.sanitize(path))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["check_if_bin_exists"] = {
|
||||
Name = [[check_if_bin_exists]],
|
||||
Synopsis = [[check if an executable exists]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_bin_exists(bin)
|
||||
bin - string - the binary to check for]],
|
||||
Description = [[check_if_bin_exists checks to see if the specified binary exists.
|
||||
check_if_bin_exists first checks to see if a preference for the binary has been
|
||||
registered and uses that if found. The presence of the file is verified, then
|
||||
quoted and returned. If no preference is specified and the operating system is
|
||||
linux then the which command is used to check for a binary in the path. If found
|
||||
that path is returned. If no binary is found, false is returned.]],
|
||||
Return_Value = [[result - string - the sanitized path of the binary, false if not found]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
--[[
|
||||
local function to search windows for an executable
|
||||
]]
|
||||
|
||||
local function _search_for_bin_windows(bin)
|
||||
local result = false
|
||||
@@ -185,9 +171,11 @@ local function _search_for_bin_windows(bin)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
local lines = du.split(output, "\n")
|
||||
local cibin = _case_insensitive_pattern(bin)
|
||||
for _,line in ipairs(lines) do
|
||||
if string.match(line, bin) then
|
||||
if dtutils_file.is_file(line) and dtutils_file.is_executable(line) then
|
||||
if string.match(line, cibin) then
|
||||
dt.print_log("found win search match " .. line)
|
||||
if dtutils_file.test_file(line, "f") and dtutils_file.test_file(line, "x") then
|
||||
dtutils_file.set_executable_path_preference(bin, line) -- save it so we don't have to search again
|
||||
return line
|
||||
end
|
||||
@@ -197,24 +185,33 @@ local function _search_for_bin_windows(bin)
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to search *nix systems for an executable
|
||||
]]
|
||||
|
||||
local function _search_for_bin_nix(bin)
|
||||
local result = false
|
||||
local p = io.popen("which " .. bin)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
if string.len(output) > 0 then
|
||||
local spath = dtutils_file.sanitize_filename(output:sub(1,-2))
|
||||
if dtutils_file.is_file(spath) and dtutils_file.is_executable(spath) then
|
||||
local spath = dtutils_file.sanitize_filename(output:sub(1, -2))
|
||||
if dtutils_file.test_file(spath, "f") and dtutils_file.test_file(spath, "x") then
|
||||
dtutils_file.set_executable_path_preference(bin, spath)
|
||||
result = spath
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to search macos systems for an executable
|
||||
]]
|
||||
|
||||
local function _search_for_bin_macos(bin)
|
||||
local result = false
|
||||
|
||||
result = _search_for_bin_nix(bin)
|
||||
result = _search_for_bin_nix(bin) -- see if it's in the path
|
||||
|
||||
if not result then
|
||||
local search_start = "/Applications"
|
||||
@@ -229,9 +226,9 @@ local function _search_for_bin_macos(bin)
|
||||
local lines = du.split(output, "\n")
|
||||
|
||||
for _,line in ipairs(lines) do
|
||||
local spath = dtutils_file.sanitize_filename(line:sub(1, -2))
|
||||
if dtutils_file.is_executable(spath) then
|
||||
dtutils_file.set_executable_path_preference(bin, spath)
|
||||
local spath = dtutils_file.sanitize_filename(line:sub(1, -1))
|
||||
if dtutils_file.test_file(spath, "x") then
|
||||
dtutils_file.set_executable_path_preference(bin, spath) -- save it so we don't have to search again
|
||||
result = spath
|
||||
end
|
||||
end
|
||||
@@ -240,11 +237,19 @@ local function _search_for_bin_macos(bin)
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to provide a generic search call that can be
|
||||
split into operating system specific calls
|
||||
]]
|
||||
|
||||
local function _search_for_bin(bin)
|
||||
local result = false
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
result = _search_for_bin_windows(bin)
|
||||
if result then
|
||||
result = dtutils_file.sanitize_filename(result)
|
||||
end
|
||||
elseif dt.configuration.running_os == "macos" then
|
||||
result = _search_for_bin_macos(bin)
|
||||
else
|
||||
@@ -254,6 +259,11 @@ local function _search_for_bin(bin)
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to check if an executable path is
|
||||
a windows executable on linux or macos, thus requiring wine to run
|
||||
]]
|
||||
|
||||
local function _check_path_for_wine_bin(path)
|
||||
local result = false
|
||||
|
||||
@@ -268,6 +278,12 @@ local function _check_path_for_wine_bin(path)
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to check if an executable path is
|
||||
a valid executable. Some generic checks are done before
|
||||
system specific checks are done.
|
||||
]]
|
||||
|
||||
local function _check_path_for_bin(bin)
|
||||
local result = false
|
||||
local path = nil
|
||||
@@ -279,13 +295,13 @@ local function _check_path_for_bin(bin)
|
||||
else
|
||||
path = dtutils_file.get_executable_path_preference(bin)
|
||||
-- reset path preference is the returned preference is a directory
|
||||
if dtutils_file.is_dir(path) then
|
||||
if dtutils_file.test_file(path, "d") then
|
||||
dtutils_file.set_executable_path_preference(bin, "")
|
||||
path = nil
|
||||
end
|
||||
end
|
||||
|
||||
if path and dtutils_file.is_dir(path) then
|
||||
if path and dtutils_file.test_file(path, "d") then
|
||||
path = nil
|
||||
end
|
||||
|
||||
@@ -294,7 +310,7 @@ local function _check_path_for_bin(bin)
|
||||
end
|
||||
|
||||
if path and not result then
|
||||
if dtutils_file.is_executable(path) then
|
||||
if dtutils_file.test_file(path, "x") then
|
||||
result = dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
end
|
||||
@@ -302,15 +318,79 @@ local function _check_path_for_bin(bin)
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
local function to the old check_if_bin_exists functionality
|
||||
on windows in order to decrease the amount of windows being
|
||||
created and destroyed by system calls.
|
||||
]]
|
||||
|
||||
local function _old_check_if_bin_exists(bin) -- only run on windows if preference checked
|
||||
local result = false
|
||||
local path = nil
|
||||
|
||||
if string.match(bin, "\\") then
|
||||
|
||||
path = bin
|
||||
else
|
||||
path = dtutils_file.get_executable_path_preference(bin)
|
||||
end
|
||||
|
||||
if string.len(path) > 0 then
|
||||
if dtutils_file.check_if_file_exists(path) then
|
||||
if (string.match(path, ".exe$") or string.match(path, ".EXE$")) then
|
||||
result = dtutils_file.sanitize_filename(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["check_if_bin_exists"] = {
|
||||
Name = [[check_if_bin_exists]],
|
||||
Synopsis = [[check if an executable exists]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_bin_exists(bin)
|
||||
bin - string - the binary to check for]],
|
||||
Description = [[check_if_bin_exists checks to see if the specified binary exists.
|
||||
check_if_bin_exists first checks to see if a preference for the binary has been
|
||||
registered and uses that if found, after it's verified to be an executable and
|
||||
exist. If no preference exissts, the user's path is checked for the executable.
|
||||
If the executable is not found in the users path, then a search of the operating
|
||||
system is conducted to see if the executable can be found.
|
||||
|
||||
If an executalble is found, it's verified to exist and be an executable. Once
|
||||
the executable is verified, the path is saved as a preference to speed up
|
||||
subsequent checks. The executable path is sanitized and returned.
|
||||
|
||||
If no executable is found, false is returned.]],
|
||||
Return_Value = [[result - string - the sanitized path of the binary, false if not found]],
|
||||
Limitations = [[If more than one executable that satisfies the search results is found, the
|
||||
wrong one may be returned. If the wrong value is returned, the user can still specify the
|
||||
correct execuable using tools/executable_manager. Most packages are well behaved with the
|
||||
notiable exception being GIMP on windows. Depending on the packager there are multiple
|
||||
gimp executables, often with version numbers. In this case, the user needs to specify
|
||||
the location of the correct executable using executable_manager.]],
|
||||
Example = [[]],
|
||||
See_Also = [[executable_manager]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.check_if_bin_exists(bin)
|
||||
local result = false
|
||||
|
||||
result = _check_path_for_bin(bin)
|
||||
if dt.configuration.running_os == "windows" and dt.preferences.read("dtutils.file", "use_old_check_if_bin_exists", "bool") then
|
||||
result = _old_check_if_bin_exists(bin)
|
||||
else
|
||||
|
||||
if not result then
|
||||
result = _search_for_bin(bin)
|
||||
result = _check_path_for_bin(bin)
|
||||
|
||||
if not result then
|
||||
result = _search_for_bin(bin)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -856,5 +936,54 @@ function dtutils_file.rmdir(path)
|
||||
return dsys.external_command(rm_cmd.." "..path)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["create_tmp_file"] = {
|
||||
Name = [[create_tmp_file]],
|
||||
Synopsis = [[creates a temporary file]],
|
||||
Usage = [[local df = require "lib/dtutils.file
|
||||
|
||||
local result = df.create_tmp_file()]],
|
||||
Description = [[create_tmp_file can be used to create temporary files]],
|
||||
Return_Value = [[result - string - path to the created temporary file.]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.create_tmp_file()
|
||||
local tmp_file = os.tmpname()
|
||||
if dt.configuration.running_os == "windows" then
|
||||
tmp_file = dt.configuration.tmp_dir .. tmp_file -- windows os.tmpname() defaults to root directory
|
||||
end
|
||||
|
||||
local f = io.open(tmp_file, "w")
|
||||
if not f then
|
||||
log.msg(log.error, string.format("Error writing to `%s`", tmp_file))
|
||||
os.remove(tmp_file)
|
||||
return nil
|
||||
end
|
||||
|
||||
return tmp_file
|
||||
end
|
||||
|
||||
--[[
|
||||
The new check_if_bin_exists() does multiple calls to the operating system to check
|
||||
if the file exists and is an executable. On windows, each call to the operating system
|
||||
causes a window to open in order to run the command, then the window closes when the
|
||||
command exits. If the user gets annoyed by the "flickering windows", then they can
|
||||
enable this preference to use the old check_if_bin_exists() that relys on the
|
||||
executable path preferences and doesn't do as many checks.
|
||||
]]
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
dt.preferences.register("dtutils.file", "use_old_check_if_bin_exists", "bool",
|
||||
"lua scripts use old check_if_bin_exists()",
|
||||
"lessen flickering windows effect when scripts run",
|
||||
false)
|
||||
end
|
||||
|
||||
|
||||
return dtutils_file
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ dtutils_log.libdoc = {
|
||||
|
||||
print out warning, error and success messages as code is running
|
||||
|
||||
log.log_level(debug)
|
||||
log.log_level(log.debug)
|
||||
|
||||
print out debugging messages too because this isnt working
|
||||
|
||||
log.log_level(info)
|
||||
log.log_level(log.info)
|
||||
|
||||
I want to make sure this is working ok
|
||||
|
||||
@@ -51,54 +51,63 @@ local dt_print_error = dt.print_error
|
||||
local dt_print_log = dt.print_log
|
||||
local dt_print = dt.print
|
||||
|
||||
|
||||
-- set the default log levels
|
||||
|
||||
dtutils_log.debug = {
|
||||
label = "DEBUG:",
|
||||
label = "DEBUG: ",
|
||||
enabled = false,
|
||||
engine = dt_print_log,
|
||||
caller_info = 3,
|
||||
level = 1,
|
||||
}
|
||||
dtutils_log.info = {
|
||||
label = "INFO:",
|
||||
label = "INFO: ",
|
||||
enable = false,
|
||||
engine = dt_print_log,
|
||||
caller_info = 1,
|
||||
level = 2,
|
||||
}
|
||||
dtutils_log.warn = {
|
||||
label = "WARN:",
|
||||
label = "WARN: ",
|
||||
enabled = false,
|
||||
engine = dt_print_log,
|
||||
caller_info = 2,
|
||||
level = 3,
|
||||
}
|
||||
dtutils_log.error = {
|
||||
label = "ERROR:",
|
||||
label = "ERROR: ",
|
||||
enabled = true,
|
||||
engine = dt_print_error,
|
||||
engine = dt_print_log,
|
||||
caller_info = 3,
|
||||
level = 4,
|
||||
}
|
||||
dtutils_log.success = {
|
||||
label = "SUCCESS:",
|
||||
label = "SUCCESS: ",
|
||||
enabled = true,
|
||||
engine = dt_print_log,
|
||||
caller_info = 2,
|
||||
level = 5,
|
||||
}
|
||||
dtutils_log.screen = {
|
||||
label = "",
|
||||
enabled = true,
|
||||
engine = dt_print,
|
||||
caller_info = 0,
|
||||
level = 9,
|
||||
}
|
||||
dtutils_log.always = {
|
||||
label = "",
|
||||
enabled = true,
|
||||
engine = dt_print_log,
|
||||
caller_info = 3,
|
||||
level = 9,
|
||||
}
|
||||
dtutils_log.critical = {
|
||||
label = "CRITICAL:",
|
||||
label = "CRITICAL: ",
|
||||
enabled = true,
|
||||
engine = print,
|
||||
caller_info = 3,
|
||||
level = 9,
|
||||
}
|
||||
|
||||
@@ -120,7 +129,7 @@ result = log.caller(level)
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_log.caller(level)
|
||||
function dtutils_log.caller(level, info)
|
||||
local name = debug.getinfo(level).name
|
||||
local lineno = nil
|
||||
local source = nil
|
||||
@@ -131,7 +140,16 @@ function dtutils_log.caller(level)
|
||||
-- we just need the filename, so grab it from the string
|
||||
-- Thanks, Tobias Jakobs :-)
|
||||
source = string.match(source, "@.-([^\\/]-%.?[^%.\\/]*)$")
|
||||
return name .. ": " .. source .. ": " .. lineno .. ":"
|
||||
|
||||
if info == 0 then
|
||||
return ""
|
||||
elseif info == 1 then
|
||||
return source .. ": "
|
||||
elseif info == 2 then
|
||||
return source .. ": " .. name .. ": "
|
||||
else
|
||||
return source .. ": " .. name .. ": " .. lineno .. ":"
|
||||
end
|
||||
else
|
||||
return "callback:"
|
||||
end
|
||||
@@ -182,7 +200,7 @@ function dtutils_log.msg(level, ...)
|
||||
end
|
||||
local log_msg = level.label
|
||||
if level.engine ~= dt_screen and call_level ~= 0 then
|
||||
log_msg = log_msg .. dtutils_log.caller(call_level) .. " "
|
||||
log_msg = log_msg .. dtutils_log.caller(call_level, level.caller_info) .. " "
|
||||
elseif log_msg:len() > 2 then
|
||||
log_msg = log_msg .. " "
|
||||
end
|
||||
|
||||
@@ -269,5 +269,31 @@ function dtutils_string.sanitize(str)
|
||||
end
|
||||
end
|
||||
|
||||
dtutils_string.libdoc.functions["sanitize_lua"] = {
|
||||
Name = [[sanitize_lua]],
|
||||
Synopsis = [[escape lua 'magic' characters from a pattern string]],
|
||||
Usage = [[local ds = require "lib/dtutils.string"
|
||||
|
||||
local result = ds.sanitize_lua(str)
|
||||
str - string - the string that needs to be made safe]],
|
||||
Description = [[sanitize_lua escapes lua 'magic' characters so that
|
||||
a string may be used in lua string/patten matching.]],
|
||||
Return_Value = [[result - string - a lua pattern safe string]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_string.sanitize_lua(str)
|
||||
str = string.gsub(str, "%-", "%%-")
|
||||
str = string.gsub(str, "%(", "%%(")
|
||||
str = string.gsub(str, "%)", "%%)")
|
||||
return str
|
||||
end
|
||||
|
||||
|
||||
|
||||
return dtutils_string
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
local dtutils_system = {}
|
||||
|
||||
local dt = require "darktable"
|
||||
require "official/yield" -- necessary for dt.control.execute()
|
||||
|
||||
dtutils_system.libdoc = {
|
||||
Name = [[dtutils.system]],
|
||||
|
||||
@@ -1,39 +1,78 @@
|
||||
# OpenInExplorer Darktable Plug-In.
|
||||
# Copyright (C) 2020 Volker Lenhardt
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Volker Lenhardt <volker.lenhardt@unitybox.de>, 2020.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenInExplorer\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-04-19 14:43+0200\n"
|
||||
"POT-Creation-Date: 2020-06-11 19:07+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Volker Lenhardt <volker.lenhardt@unitybox.de>\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: OpenInExplorer.lua:64
|
||||
#: OpenInExplorer.lua:71
|
||||
msgid ""
|
||||
"OpenInExplorer plug-in only supports Linux, macOS, and Windows at this time"
|
||||
msgstr "OpenInExplorer-Plug-in kann nur auf macOS, Linux oder Windows laufen"
|
||||
"OpenInExplorer plug-in only supports Linux and macOS, and Windows at this time"
|
||||
msgstr "OpenInExplorer-Plug-in unterstützt zur Zeit nur Linux, macOS oder Windows"
|
||||
|
||||
#: OpenInExplorer.lua:79
|
||||
#: OpenInExplorer.lua:87
|
||||
msgid ""
|
||||
"No links directory selected.\n"
|
||||
"Please check the dt preferences (lua options)"
|
||||
msgstr "Kein Verknüpfungs-Verzeichnis ausgewählt.\nBitte die dt-Voreinstellungen überprüfen (Lua-Optionen)"
|
||||
|
||||
#: OpenInExplorer.lua:91
|
||||
#, lua-format
|
||||
msgid ""
|
||||
"Links directory '%s' not found.\n"
|
||||
"Please check the dt preferences (lua options)"
|
||||
msgstr "Das Verknüpfungs-Verzeichnis '%s' konnte nicht gefunden werden.\nBitte die dt-Voreinstellungen überprüfen (Lua-Optionen)"
|
||||
|
||||
#: OpenInExplorer.lua:148
|
||||
msgid "Failed to create links. Missing rights?"
|
||||
msgstr "Die Verknüpfungen konnten nicht erstellt werden. Fehlende Rechte?"
|
||||
|
||||
#: OpenInExplorer.lua:164
|
||||
msgid "Please select an image"
|
||||
msgstr "Es wurde kein Bild ausgewählt"
|
||||
|
||||
#: OpenInExplorer.lua:98
|
||||
msgid "Please select fewer images (max 15)"
|
||||
#: OpenInExplorer.lua:170
|
||||
msgid "Please select fewer images (max. 15)"
|
||||
msgstr "Bitte nicht mehr als 15 Bilder auswählen"
|
||||
|
||||
#: OpenInExplorer.lua:105
|
||||
#: OpenInExplorer.lua:186
|
||||
msgid "show in file explorer"
|
||||
msgstr "im Dateimanager anzeigen"
|
||||
|
||||
#: OpenInExplorer.lua:107
|
||||
msgid "Opens the file manager at the selected image's location"
|
||||
#: OpenInExplorer.lua:188
|
||||
msgid "Open the file manager at the selected image's location"
|
||||
msgstr "Öffnet den Dateimanager an der Position des ausgewählten Bildes"
|
||||
|
||||
#: OpenInExplorer.lua:193
|
||||
msgid "OpenInExplorer: linked files directory"
|
||||
msgstr "OpenInExplorer: Verknüpfungs-Verzeichnis"
|
||||
|
||||
#: OpenInExplorer.lua:194
|
||||
msgid ""
|
||||
"Directory to store the links to the file names. Requires restart to take "
|
||||
"effect"
|
||||
msgstr "Verzeichnis für die Verknüpfungen zu den Dateinamen. Erfordert dt-Neustart"
|
||||
|
||||
#: OpenInExplorer.lua:197
|
||||
msgid "Select directory"
|
||||
msgstr "Verzeichnis auswählen"
|
||||
|
||||
#: OpenInExplorer.lua:203
|
||||
msgid "OpenInExplorer: use links"
|
||||
msgstr "OpenInExplorer: Verknüpfungen nutzen"
|
||||
|
||||
#: OpenInExplorer.lua:204
|
||||
msgid "Use links instead of multiple windows. Requires restart to take effect"
|
||||
msgstr "Verknüpfungen statt einzelner Fenster nutzen. Erfordert dt-Neustart"
|
||||
|
||||
73
locale/de_DE/LC_MESSAGES/photils.po
Normal file
73
locale/de_DE/LC_MESSAGES/photils.po
Normal file
@@ -0,0 +1,73 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Lua photils\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-12 13:12+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "get tags"
|
||||
msgstr "hole stichwörter"
|
||||
|
||||
msgid "requires a restart to be applied"
|
||||
msgstr "erfordert einen Neustart um angewendet zu werden"
|
||||
|
||||
msgid "min confidence value"
|
||||
msgstr "min vertrauenswert"
|
||||
|
||||
msgid ""
|
||||
"The suggested tags were not generated\n"
|
||||
" for the currently selected image!"
|
||||
msgstr ""
|
||||
"Die vorgeschlagenen Stichwörter wurden für das\n"
|
||||
"aktuell ausgewählte Bild nicht generiert!"
|
||||
|
||||
#, lua-format
|
||||
msgid " page %s of %s "
|
||||
msgstr " seite %s von %s "
|
||||
|
||||
msgid "Tags successfully attached to image"
|
||||
msgstr "Stichwörter erfolgreich an Bild angefügt"
|
||||
|
||||
#, lua-format
|
||||
msgid "Error writing to `%s`"
|
||||
msgstr "Fehler beim Schreiben in `%s`"
|
||||
|
||||
#, lua-format
|
||||
msgid "%s failed, see terminal output for details"
|
||||
msgstr "%s fehlgeschlagen, siehe Terminal-Ausgabe für Details"
|
||||
|
||||
#, lua-format
|
||||
msgid "%s found %d tags for your image"
|
||||
msgstr "%s gefunden %d-Stichwörter für Ihr Bild"
|
||||
|
||||
msgid "No image selected."
|
||||
msgstr "Kein Bild ausgewählt."
|
||||
|
||||
msgid "This plugin can only handle a single image."
|
||||
msgstr "Dieses Plugin kann nur ein einziges Bild verarbeiten."
|
||||
|
||||
#, lua-format
|
||||
msgid "attach %d tags"
|
||||
msgstr "%d stichwörter anhängen"
|
||||
|
||||
msgid "photils-cli not found"
|
||||
msgstr "photils-cli nicht gefunden"
|
||||
|
||||
msgid ""
|
||||
"Select an image, click \"Get Tags\" and get \n"
|
||||
"suggestions for tags."
|
||||
msgstr ""
|
||||
"Wählen Sie ein Bild aus, drücken Sie \"Hole Stichwörter\"\n"
|
||||
" und erhalten Sie Vorschläge für Stichwörter."
|
||||
@@ -7,21 +7,29 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-09-07 22:25-0400\n"
|
||||
"PO-Revision-Date: 2016-10-03 14:55+0200\n"
|
||||
"Last-Translator: Pascal Obry <pascal@obry.net>\n"
|
||||
"POT-Creation-Date: 2020-12-27 17:55+0100\n"
|
||||
"PO-Revision-Date: 2020-12-27 17:55+0100\n"
|
||||
"Last-Translator: Christophe Agathon <christophe.agathon@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.9\n"
|
||||
"Language: fr_FR\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: gettext;dgettext:2;dcgettext:2ngettext:1,2;"
|
||||
"X-Poedit-KeywordsList: _;gettext;dgettext:2;dcgettext:2ngettext:1,2;"
|
||||
"dngettext:2,3\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Language-Team: \n"
|
||||
"X-Poedit-Basepath: ../../../contrib\n"
|
||||
"X-Poedit-SearchPath-0: clear_GPS.lua\n"
|
||||
|
||||
#: clear_GPS.lua:62
|
||||
#: clear_GPS.lua:67
|
||||
msgid "clear GPS data"
|
||||
msgstr "effacer données GPS"
|
||||
|
||||
#: clear_GPS.lua:69
|
||||
msgid "Clear GPS data from selected images"
|
||||
msgstr "Effacer les données GPS des images sélectionnées"
|
||||
|
||||
#: clear_GPS.lua:75
|
||||
msgid "Clear GPS data"
|
||||
msgstr "Effacer les données GPS"
|
||||
|
||||
78
locale/fr_FR/LC_MESSAGES/copy_attach_detach_tags.po
Normal file
78
locale/fr_FR/LC_MESSAGES/copy_attach_detach_tags.po
Normal file
@@ -0,0 +1,78 @@
|
||||
# French messages for copy_attach_detach_tags.lua
|
||||
# Christophe Agathon <christophe.agathon@gmail.com>, 2021
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-01-10 19:39+0100\n"
|
||||
"PO-Revision-Date: 2021-01-10 19:43+0100\n"
|
||||
"Last-Translator: Christophe Agathon <christophe.agathon@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"X-Poedit-Basepath: ../../../contrib\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Poedit-KeywordsList: _\n"
|
||||
"X-Poedit-SearchPath-0: copy_attach_detach_tags.lua\n"
|
||||
|
||||
#: copy_attach_detach_tags.lua:93
|
||||
msgid "Image tags copied ..."
|
||||
msgstr "Mots-clés de l'image copiés ..."
|
||||
|
||||
#: copy_attach_detach_tags.lua:115
|
||||
msgid "No tag to attach, please copy tags first."
|
||||
msgstr "Pas de mot-clé à attacher, veuillez d'abord copier les mots-clés."
|
||||
|
||||
#: copy_attach_detach_tags.lua:139
|
||||
msgid "Tags attached ..."
|
||||
msgstr "Mots-clés attachés ..."
|
||||
|
||||
#: copy_attach_detach_tags.lua:155
|
||||
msgid "Tags removed from image(s)."
|
||||
msgstr "Mots-clés supprimés des images."
|
||||
|
||||
#: copy_attach_detach_tags.lua:161
|
||||
msgid "Tags replaced"
|
||||
msgstr "Mots-clés remplacés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:166
|
||||
msgid "tagging addon"
|
||||
msgstr "mots-clés extra"
|
||||
|
||||
#: copy_attach_detach_tags.lua:189
|
||||
msgid "tag clipboard"
|
||||
msgstr "presse-papier des mots-clés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:197
|
||||
msgid "multi copy tags"
|
||||
msgstr "copier mots-clés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:198 copy_attach_detach_tags.lua:252
|
||||
msgid "copy tags from selected image(s)"
|
||||
msgstr "copier les mots-clés des images sélectionnnées"
|
||||
|
||||
#: copy_attach_detach_tags.lua:201 copy_attach_detach_tags.lua:257
|
||||
msgid "paste tags to selected image(s)"
|
||||
msgstr "coller les mots clés dans les images sélectionnées"
|
||||
|
||||
#: copy_attach_detach_tags.lua:202
|
||||
msgid "paste tags"
|
||||
msgstr "coller mots-clés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:210
|
||||
msgid "replace tags"
|
||||
msgstr "remplacer mots-clés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:211 copy_attach_detach_tags.lua:267
|
||||
msgid "replace tags from selected image(s)"
|
||||
msgstr "remplacer les mots-clés des images sélectionnées"
|
||||
|
||||
#: copy_attach_detach_tags.lua:214
|
||||
msgid "remove all tags"
|
||||
msgstr "supprimer tous mots-clés"
|
||||
|
||||
#: copy_attach_detach_tags.lua:215 copy_attach_detach_tags.lua:262
|
||||
msgid "remove tags from selected image(s)"
|
||||
msgstr "supprimer les mots-clés des images sélectionnées"
|
||||
35
locale/fr_FR/LC_MESSAGES/copy_paste_metadata.po
Normal file
35
locale/fr_FR/LC_MESSAGES/copy_paste_metadata.po
Normal file
@@ -0,0 +1,35 @@
|
||||
# French messages for copy_paste_metadata.lua
|
||||
# Christophe Agathon <christophe.agathon@gmail.com>, 2020
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: copy_paste_metadata\n"
|
||||
"POT-Creation-Date: 2020-12-26 12:49+0100\n"
|
||||
"PO-Revision-Date: 2020-12-26 12:52+0100\n"
|
||||
"Last-Translator: Christophe Agathon <christophe.agathon@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"X-Poedit-Basepath: ../../../official\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: _\n"
|
||||
"X-Poedit-SearchPath-0: copy_paste_metadata.lua\n"
|
||||
|
||||
#: copy_paste_metadata.lua:115
|
||||
msgid "copy metadata"
|
||||
msgstr "copier les métadonnées"
|
||||
|
||||
#: copy_paste_metadata.lua:117
|
||||
msgid "copy metadata of the first selected image"
|
||||
msgstr "copier les métadonnées de la première image sélectionnée"
|
||||
|
||||
#: copy_paste_metadata.lua:121
|
||||
msgid "paste metadata"
|
||||
msgstr "coller les métadonnées"
|
||||
|
||||
#: copy_paste_metadata.lua:123
|
||||
msgid "paste metadata to the selected images"
|
||||
msgstr "coller les métadonnées vers les images sélectionnées"
|
||||
117
locale/fr_FR/LC_MESSAGES/photils.po
Normal file
117
locale/fr_FR/LC_MESSAGES/photils.po
Normal file
@@ -0,0 +1,117 @@
|
||||
# French messages for photils.lua
|
||||
# Christophe Agathon <christophe.agathon@gmail.com>, 2021
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-08-13 09:04+0200\n"
|
||||
"PO-Revision-Date: 2021-08-13 09:49+0200\n"
|
||||
"Last-Translator: Christophe Agathon <christophe.agathon@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"X-Poedit-Basepath: ../../../contrib\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Poedit-SearchPath-0: photils.lua\n"
|
||||
|
||||
#: photils.lua:117
|
||||
msgid "get tags"
|
||||
msgstr "trouver des mots-clés"
|
||||
|
||||
#: photils.lua:148
|
||||
msgid "requires a restart to be applied"
|
||||
msgstr "nécessite un redémarrage pour être pris en compte"
|
||||
|
||||
#: photils.lua:163
|
||||
msgid "min confidence value"
|
||||
msgstr "niveau de confiance minimum"
|
||||
|
||||
#: photils.lua:180
|
||||
msgid ""
|
||||
"The suggested tags were not generated\n"
|
||||
" for the currently selected image!"
|
||||
msgstr ""
|
||||
"La proposition de mots-clés n'a pas été générée\n"
|
||||
" pour l'image sélectionnée actuellement !"
|
||||
|
||||
#: photils.lua:186
|
||||
#, lua-format
|
||||
msgid " page %s of %s "
|
||||
msgstr " page %s de %s "
|
||||
|
||||
#: photils.lua:237
|
||||
msgid "Apply tag to image"
|
||||
msgstr "Appliquer les mots-clés à l'image"
|
||||
|
||||
#: photils.lua:249
|
||||
msgid "Tags successfully attached to image"
|
||||
msgstr "Les mots-clés ont bien été ajoutés à l'image"
|
||||
|
||||
#: photils.lua:299
|
||||
#, lua-format
|
||||
msgid "%s found %d tags for your image"
|
||||
msgstr "%s a trouvé %d mots-clés pour votre image"
|
||||
|
||||
#: photils.lua:315
|
||||
msgid "No image selected."
|
||||
msgstr "Pas d'image sélectionnée."
|
||||
|
||||
#: photils.lua:319
|
||||
msgid "This plugin can only handle a single image."
|
||||
msgstr "Ce plugin ne peut gérer qu'une seule image."
|
||||
|
||||
#: photils.lua:326
|
||||
#, lua-format
|
||||
msgid "%s failed, see terminal output for details"
|
||||
msgstr ""
|
||||
"%s a échoué, consultez les messages sur le terminal pour plus de détails"
|
||||
|
||||
#: photils.lua:334
|
||||
#, lua-format
|
||||
msgid "no tags where found"
|
||||
msgstr "aucun mot-clé n'a été trouvé"
|
||||
|
||||
#: photils.lua:365
|
||||
#, lua-format
|
||||
msgid "attach %d tags"
|
||||
msgstr "ajouter %d mots-clés"
|
||||
|
||||
#: photils.lua:429 photils.lua:430
|
||||
msgid "photils-cli not found"
|
||||
msgstr "photils-cli non trouvé"
|
||||
|
||||
#: photils.lua:432
|
||||
msgid ""
|
||||
"Select an image, click \"get tags\" and get \n"
|
||||
"suggestions for tags."
|
||||
msgstr ""
|
||||
"Sélectionnez une image, cliquez sur « trouver des mots-clés » \n"
|
||||
"pour obtenir une proposition de mots-clés."
|
||||
|
||||
#: photils.lua:467
|
||||
msgid "photils: show confidence value"
|
||||
msgstr "photils: afficher le niveau de confiance"
|
||||
|
||||
# Original message should begin with capital I
|
||||
#: photils.lua:468
|
||||
msgid "if enabled, the confidence value for each tag is displayed"
|
||||
msgstr "Si activé, le niveau de confiance de chaque mot-clé est affiché"
|
||||
|
||||
#: photils.lua:474
|
||||
msgid "photils: use exported image for tag request"
|
||||
msgstr "photils: utiliser l'image exportée pour la recherche de mots-clés"
|
||||
|
||||
#: photils.lua:475
|
||||
msgid ""
|
||||
"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."
|
||||
msgstr ""
|
||||
"Si activé, l'image passée à photils pour la proposition de mots-clés est "
|
||||
"basée sur l'export de l'image déjà éditée. Sinon, c'est la vignette "
|
||||
"encapsulée dans le fichier RAW qui sera utilisée. La vignette encapsulée "
|
||||
"pourra accélérer la proposition des mots-clés mais la recherche échouera si "
|
||||
"le fichier RAW n'est pas supporté."
|
||||
188
locale/fr_FR/LC_MESSAGES/script_manager.po
Normal file
188
locale/fr_FR/LC_MESSAGES/script_manager.po
Normal file
@@ -0,0 +1,188 @@
|
||||
# French messages for script_manager.lua
|
||||
# Christophe Agathon <christophe.agathon@gmail.com>, 2020
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2020-12-28 10:22+0100\n"
|
||||
"PO-Revision-Date: 2020-12-28 10:24+0100\n"
|
||||
"Last-Translator: Christophe Agathon <christophe.agathon@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"X-Poedit-Basepath: ../../../tools\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Poedit-KeywordsList: _\n"
|
||||
"X-Poedit-SearchPath-0: script_manager.lua\n"
|
||||
|
||||
#: script_manager.lua:190
|
||||
msgid "Cant read from "
|
||||
msgstr "Ne peut pas lire "
|
||||
|
||||
#: script_manager.lua:204
|
||||
msgid "Loaded "
|
||||
msgstr "Script chargé : "
|
||||
|
||||
#: script_manager.lua:207
|
||||
msgid " failed to load"
|
||||
msgstr " non chargé"
|
||||
|
||||
#: script_manager.lua:223
|
||||
msgid " will not start when darktable is restarted"
|
||||
msgstr " ne démarrera pas lorsque darktable sera redémarré"
|
||||
|
||||
#: script_manager.lua:281 script_manager.lua:345
|
||||
msgid "find command is "
|
||||
msgstr "la commande find est "
|
||||
|
||||
#: script_manager.lua:321
|
||||
msgid "lua scripts successfully updated"
|
||||
msgstr "mise à jour des scripts lua réussie"
|
||||
|
||||
#: script_manager.lua:381
|
||||
msgid "category "
|
||||
msgstr "la catégorie "
|
||||
|
||||
#: script_manager.lua:381
|
||||
msgid " is already in use. Please specify a different category name."
|
||||
msgstr " est déjà utilisée. Indiquez un autre nom de catégorie SVP."
|
||||
|
||||
#: script_manager.lua:410
|
||||
msgid "scripts successfully installed into category "
|
||||
msgstr "les scripts ont été installés dans la catégorie "
|
||||
|
||||
#: script_manager.lua:426
|
||||
msgid "No scripts found to install"
|
||||
msgstr "Nous n'avons pas trouvé de script à installer"
|
||||
|
||||
#: script_manager.lua:430
|
||||
msgid "failed to download scripts"
|
||||
msgstr "impossible de télécharger les scripts"
|
||||
|
||||
# Peut-être que « activé » serait mieux, mais ce n'est pas la traduction de « started »
|
||||
#: script_manager.lua:458
|
||||
msgid " started"
|
||||
msgstr " démarré"
|
||||
|
||||
# Peut-être que « désactivé » serait mieux, mais ce n'est pas la traduction de « stopped »
|
||||
#: script_manager.lua:460
|
||||
msgid " stopped"
|
||||
msgstr " arrêté"
|
||||
|
||||
#: script_manager.lua:545
|
||||
msgid "Page "
|
||||
msgstr "Page "
|
||||
|
||||
#: script_manager.lua:545
|
||||
msgid " of "
|
||||
msgstr " sur "
|
||||
|
||||
#: script_manager.lua:674
|
||||
msgid "scripts to update"
|
||||
msgstr "scripts à mettre à jour"
|
||||
|
||||
#: script_manager.lua:675
|
||||
msgid "select the scripts installation to update"
|
||||
msgstr "sélectionnez les scripts à mettre à jour"
|
||||
|
||||
#: script_manager.lua:684 script_manager.lua:742
|
||||
msgid "update scripts"
|
||||
msgstr "mettre à jour les scripts"
|
||||
|
||||
#: script_manager.lua:685
|
||||
msgid "update the lua scripts from the repository"
|
||||
msgstr "metre à jour les scripts depuis le dépôt"
|
||||
|
||||
#: script_manager.lua:696
|
||||
msgid "enter the URL of the git repository containing the scripts you wish to add"
|
||||
msgstr "indiquez l'URL du dépôt git contenant les scripts que vous souhaitez ajouter"
|
||||
|
||||
#: script_manager.lua:701
|
||||
msgid "name of new category"
|
||||
msgstr "nom de la nouvelle catégorie"
|
||||
|
||||
#: script_manager.lua:702
|
||||
msgid "enter a category name for the additional scripts"
|
||||
msgstr "indiquez un nom de catégorie pour les scripts supplémentaires"
|
||||
|
||||
#: script_manager.lua:707
|
||||
msgid "URL to download additional scripts from"
|
||||
msgstr "URL d'où seront téléchargés les scripts"
|
||||
|
||||
#: script_manager.lua:709
|
||||
msgid "new category to place scripts in"
|
||||
msgstr "nouvelle catégorie où seront placés les scripts"
|
||||
|
||||
#: script_manager.lua:712
|
||||
msgid "install additional scripts"
|
||||
msgstr "installer les scripts supplémentaires"
|
||||
|
||||
#: script_manager.lua:720
|
||||
msgid "Enable \"Disable Scripts\" button"
|
||||
msgstr "Activer le bouton « Désactiver les Scripts »"
|
||||
|
||||
#: script_manager.lua:730
|
||||
msgid "Disable Scripts"
|
||||
msgstr "Désactiver les scripts"
|
||||
|
||||
#: script_manager.lua:736
|
||||
msgid "lua scripts will not run the next time darktable is started"
|
||||
msgstr "les scripts lua ne seront pas lancés au prochain démarrage de darktable"
|
||||
|
||||
#: script_manager.lua:745
|
||||
msgid "add more scripts"
|
||||
msgstr "ajouter des scripts"
|
||||
|
||||
#: script_manager.lua:747
|
||||
msgid "disable scripts"
|
||||
msgstr "désactiver les scripts"
|
||||
|
||||
#: script_manager.lua:755
|
||||
msgid "category"
|
||||
msgstr "catégorie"
|
||||
|
||||
#: script_manager.lua:756
|
||||
msgid "select the script category"
|
||||
msgstr "sélectionner la catégorie"
|
||||
|
||||
#: script_manager.lua:780
|
||||
msgid "Page:"
|
||||
msgstr "Page :"
|
||||
|
||||
#: script_manager.lua:808
|
||||
msgid "Scripts"
|
||||
msgstr "Scripts"
|
||||
|
||||
#: script_manager.lua:817
|
||||
msgid "scripts per page"
|
||||
msgstr "scripts par page"
|
||||
|
||||
#: script_manager.lua:818
|
||||
msgid "select number of start/stop buttons to display"
|
||||
msgstr "sélectionner le nombre de boutons marche/arrêt à afficher"
|
||||
|
||||
#: script_manager.lua:829
|
||||
msgid "change number of buttons"
|
||||
msgstr "changer le nombre de boutons"
|
||||
|
||||
#: script_manager.lua:837
|
||||
msgid "Configuration"
|
||||
msgstr "Configuration"
|
||||
|
||||
#: script_manager.lua:858
|
||||
msgid "action"
|
||||
msgstr "action"
|
||||
|
||||
#: script_manager.lua:864
|
||||
msgid "install/update scripts"
|
||||
msgstr "installer/mettre à jour des scripts"
|
||||
|
||||
#: script_manager.lua:864
|
||||
msgid "configure"
|
||||
msgstr "configurer"
|
||||
|
||||
#: script_manager.lua:864
|
||||
msgid "start/stop scripts"
|
||||
msgstr "démarrer/arrêter des scripts"
|
||||
46
locale/pt_BR/LC_MESSAGES/AutoGrouper.po
Normal file
46
locale/pt_BR/LC_MESSAGES/AutoGrouper.po
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:54-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:144
|
||||
msgid "auto group"
|
||||
msgstr "grupo automático"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:173
|
||||
msgid "group gap [sec.]"
|
||||
msgstr "intervalo de agrupamento [seg]"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:174
|
||||
msgid "minimum gap, in seconds, between groups"
|
||||
msgstr "intervalo mínimo, em segundos, entre os grupos"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:187
|
||||
msgid "auto group: selected"
|
||||
msgstr "grupo automático: selecionado"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:188
|
||||
msgid "auto group selected images"
|
||||
msgstr "agrupa automaticamente as imagens selecionadas"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:192
|
||||
msgid "auto group: collection"
|
||||
msgstr "grupo automático: coleção"
|
||||
|
||||
#: ../contrib/AutoGrouper.lua:193
|
||||
msgid "auto group the entire collection"
|
||||
msgstr "agrupa automaticamente toda a coleção"
|
||||
97
locale/pt_BR/LC_MESSAGES/CollectHelper.po
Normal file
97
locale/pt_BR/LC_MESSAGES/CollectHelper.po
Normal file
@@ -0,0 +1,97 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 20:02-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:74
|
||||
msgid "Please select a single image"
|
||||
msgstr "Por favor, selecione uma única imagem"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:124
|
||||
msgid "select an image with an active color label"
|
||||
msgstr "selecione uma imagem com uma etiqueta de cor ativa"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:205
|
||||
msgid "collect: previous"
|
||||
msgstr "colecionar: anterior"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:207
|
||||
msgid "Sets the Collect parameters to be the previously active parameters"
|
||||
msgstr "Define os parâmetros da coleção para os ativos anteriormente"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:211
|
||||
msgid "collect: folder"
|
||||
msgstr "colecionar: pasta"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:213
|
||||
msgid "Sets the Collect parameters to be the selected images's folder"
|
||||
msgstr "Define os parâmetros da coleção para a pasta de imagens selecionada"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:218
|
||||
msgid "collect: color label(s)"
|
||||
msgstr "colecionar: etiqueta(s) de cor"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:220
|
||||
msgid "Sets the Collect parameters to be the selected images's color label(s)"
|
||||
msgstr ""
|
||||
"Define os parâmetros da coleção para a(s) etiqueta(s) de cor das imagens"
|
||||
" selecionadas"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:225
|
||||
msgid "collect: all (AND)"
|
||||
msgstr "colecionar: tudo (E)"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:227
|
||||
msgid ""
|
||||
"Sets the Collect parameters based on all activated CollectHelper options"
|
||||
msgstr "Define os parâmetros da coleção baseado em todas as opções do script"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:234
|
||||
msgid "CollectHelper: All"
|
||||
msgstr "CollectHelper: Tudo"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:235
|
||||
msgid ""
|
||||
"Will create a collect parameter set that utilizes all enabled CollectHelper "
|
||||
"types (AND)"
|
||||
msgstr ""
|
||||
"Criará um conjunto de parâmetros de coleção que utilizará todos os tipos "
|
||||
"habilitados do CollectHelper (E)"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:240
|
||||
msgid "CollectHelper: Color Label(s)"
|
||||
msgstr "CollectHelper: Etiqueta(s) de Cor"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:241
|
||||
msgid ""
|
||||
"Enable the button that allows you to swap to a collection based on selected "
|
||||
"image's COLOR LABEL(S)"
|
||||
msgstr ""
|
||||
"Habilita o botão que permite que você alterna para uma coleção baseada na "
|
||||
"ETIQUETA(S) DE COR da imagem selecionada"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:246
|
||||
msgid "CollectHelper: Folder"
|
||||
msgstr "CollectHelper: Pasta"
|
||||
|
||||
#: ../contrib/CollectHelper.lua:247
|
||||
msgid ""
|
||||
"Enable the button that allows you to swap to a collection based on selected "
|
||||
"image's FOLDER location"
|
||||
msgstr ""
|
||||
"Habilita o botão que permite que você alterne para uma coleção baseada na "
|
||||
"PASTA da imagem selecionada"
|
||||
163
locale/pt_BR/LC_MESSAGES/HDRMerge.po
Normal file
163
locale/pt_BR/LC_MESSAGES/HDRMerge.po
Normal file
@@ -0,0 +1,163 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:40-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:175
|
||||
msgid "please update you binary location"
|
||||
msgstr "por favor, atualize a localização do binário"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:194
|
||||
msgid "update successful"
|
||||
msgstr "atualização bem sucedida"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:196
|
||||
msgid "update unsuccessful, please try again"
|
||||
msgstr "atualização mau sucedida, tente de novo"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:210
|
||||
msgid "HDRMerge install issue"
|
||||
msgstr "problema com a instalação do HDRMerge"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:211
|
||||
msgid "HDRMerge install issue, please ensure the binary path is proper"
|
||||
msgstr ""
|
||||
"problema com a instalação do HDRMerge, certifique-se de que o caminho do"
|
||||
" binário esteja correto"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:216
|
||||
msgid "not enough images selected, select at least 2 images to merge"
|
||||
msgstr ""
|
||||
"imagens selecionadas insuficientes, selecione apenas 2 imagens para mesclar"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:277
|
||||
msgid "HDRMerge completed successfully"
|
||||
msgstr "HDRMerge completado com sucesso"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:279 ../contrib/HDRMerge.lua:280
|
||||
msgid "HDRMerge failed"
|
||||
msgstr "HDRMerge falhou"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:289
|
||||
msgid "HDRMerge"
|
||||
msgstr "HDRMerge"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:312
|
||||
msgid "HDRMerge options"
|
||||
msgstr "opções do HDRMerge"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:317
|
||||
msgid "bits per sample"
|
||||
msgstr "bits por amostra"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:318
|
||||
msgid "number of bits per sample in the output image"
|
||||
msgstr "número de bits por amostra na imagem de saída"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:334
|
||||
msgid "embedded preview size"
|
||||
msgstr "tamanho da pré-visualização embutida"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:335
|
||||
msgid "size of the embedded preview in output image"
|
||||
msgstr "tamanho da pré-visualização embutida na imagem de saída"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:337 ../contrib/HDRMerge.lua:382
|
||||
msgid "none"
|
||||
msgstr "nenhum"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:337
|
||||
msgid "half"
|
||||
msgstr "metade"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:337
|
||||
msgid "full"
|
||||
msgstr "completo"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:349
|
||||
msgid "batch mode"
|
||||
msgstr "modo em lote"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:351
|
||||
msgid ""
|
||||
"enable batch mode operation \n"
|
||||
"NOTE: resultant files will NOT be auto-imported"
|
||||
msgstr ""
|
||||
"ativar a operação em modo em lote\n"
|
||||
"NOTA: arquivos resultantes NÃO serão importados automaticamente"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:361
|
||||
msgid "batch gap [sec.]"
|
||||
msgstr "intervalo do lote [seg.]"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:362
|
||||
msgid "gap, in seconds, between batch mode groups"
|
||||
msgstr "intervalo, em segundos, entre os grupos do modo em lote"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:376
|
||||
msgid "import options"
|
||||
msgstr "opções de importação"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:379
|
||||
msgid "apply style on import"
|
||||
msgstr "aplicar estilo ao importar"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:380
|
||||
msgid "Apply selected style on auto-import to newly created image"
|
||||
msgstr ""
|
||||
"Aplica o estilo selecionado ao importar automaticamente para novas imagens"
|
||||
" criadas"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:400
|
||||
msgid "copy tags"
|
||||
msgstr "copiar etiquetas"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:402
|
||||
msgid "copy tags from first source image"
|
||||
msgstr "copia etiquetas da primeira imagem fonte"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:409
|
||||
msgid ""
|
||||
"Additional tags to be added on import. Seperate with commas, all spaces will "
|
||||
"be removed"
|
||||
msgstr ""
|
||||
"Etiquetas adicionais a serem anexadas ao importar. Separar com vírgulas,"
|
||||
" todos os espaços serão removidos"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:411
|
||||
msgid "Enter tags, seperated by commas"
|
||||
msgstr "Insira as etiquetas, separadas por vírgulas"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:415
|
||||
msgid "merge"
|
||||
msgstr "mesclar"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:416
|
||||
msgid "run HDRMerge with the above specified settings"
|
||||
msgstr "rodar o HDRMerge com as configurações especificadas acima"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:420
|
||||
msgid "Select HDRmerge executable"
|
||||
msgstr "Selecionar o executável do HDRmerge"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:425
|
||||
msgid "update"
|
||||
msgstr "atualizar"
|
||||
|
||||
#: ../contrib/HDRMerge.lua:426
|
||||
msgid "update the binary path with current value"
|
||||
msgstr "atualiza o caminho do binário com o valor atual"
|
||||
86
locale/pt_BR/LC_MESSAGES/OpenInExplorer.po
Normal file
86
locale/pt_BR/LC_MESSAGES/OpenInExplorer.po
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 23:40-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:79
|
||||
msgid ""
|
||||
"OpenInExplorer plug-in only supports Linux, macOS, and Windows at this time"
|
||||
msgstr ""
|
||||
"Atualmente, o plugin OpenInExplorer somente suporta Linux, macOS e Windows"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:95
|
||||
msgid ""
|
||||
"No links directory selected.\n"
|
||||
"Please check the dt preferences (lua options)"
|
||||
msgstr ""
|
||||
"Nenhum link para pasta selecionado.\n"
|
||||
"Verifique as preferências do darktable (opções lua)"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:99
|
||||
#, lua-format
|
||||
msgid ""
|
||||
"Links directory '%s' not found.\n"
|
||||
"Please check the dt preferences (lua options)"
|
||||
msgstr ""
|
||||
"Links para pasta '%s' não encontrados.\n"
|
||||
"Verifique as preferências do darktable (opções lua)"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:156
|
||||
msgid "Failed to create links. Missing rights?"
|
||||
msgstr "Falha ao criar links. Possui permissões adequadas?"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:172
|
||||
msgid "Please select an image"
|
||||
msgstr "Por favor, selecione uma imagem"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:178
|
||||
msgid "Please select fewer images (max. 15)"
|
||||
msgstr "Por favor, selecione menos imagens (máx 15)"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:203
|
||||
msgid "show in file explorer"
|
||||
msgstr "mostrar no navegador de arquivos"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:205
|
||||
msgid "Open the file manager at the selected image's location"
|
||||
msgstr "Abre o gerenciador de arquivos na localização das imagens selecionadas"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:212
|
||||
msgid "OpenInExplorer: linked files directory"
|
||||
msgstr "OpenInExplorer: pasta de arquivos linkada"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:213
|
||||
msgid ""
|
||||
"Directory to store the links to the file names. Requires restart to take "
|
||||
"effect"
|
||||
msgstr ""
|
||||
"Pasta para armazenar os links para os nomes de arquivo. Precisa reiniciar"
|
||||
" para ter efeito"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:216
|
||||
msgid "Select directory"
|
||||
msgstr "Selecione a pasta"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:222
|
||||
msgid "OpenInExplorer: use links"
|
||||
msgstr "OpenInExplorer: usar links"
|
||||
|
||||
#: ../contrib/OpenInExplorer.lua:223
|
||||
msgid "Use links instead of multiple windows. Requires restart to take effect"
|
||||
msgstr ""
|
||||
"Usa links ao invés de janelas múltiplas. Precisa reiniciar para ter efeito"
|
||||
74
locale/pt_BR/LC_MESSAGES/RL_out_sharp.po
Normal file
74
locale/pt_BR/LC_MESSAGES/RL_out_sharp.po
Normal file
@@ -0,0 +1,74 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:31-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:119
|
||||
msgid "GMic executable not configured"
|
||||
msgstr "executável GMic não configurado"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:139
|
||||
msgid "sharpening image "
|
||||
msgstr "melhorar nitidez da imagem "
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:154
|
||||
msgid "sharpening error"
|
||||
msgstr "erro ao melhorar nitidez"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:163
|
||||
msgid "finished exporting"
|
||||
msgstr "exportação finalizada"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:175 ../contrib/RL_out_sharp.lua:176
|
||||
msgid "select output folder"
|
||||
msgstr "selecionar pasta de saída"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:185
|
||||
msgid "sigma"
|
||||
msgstr "sigma"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:186
|
||||
msgid "controls the width of the blur that's applied"
|
||||
msgstr "controla a largura do desfoque que é aplicada"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:197
|
||||
msgid "iterations"
|
||||
msgstr "iterações"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:198
|
||||
msgid "increase for better sharpening, but slower"
|
||||
msgstr "aumente para melhor efeito, mas diminui velocidade"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:209
|
||||
msgid "output jpg quality"
|
||||
msgstr "qualidade do jpg de saída"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:210
|
||||
msgid "quality of the output jpg file"
|
||||
msgstr "qualidade do arquivo jpg de saída"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:229
|
||||
msgid "RL output sharpen"
|
||||
msgstr "melhoria de nitidez na saída RL"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:233
|
||||
msgid "executable for GMic CLI"
|
||||
msgstr "executável para o GMic CLI"
|
||||
|
||||
#: ../contrib/RL_out_sharp.lua:234
|
||||
msgid "select executable for GMic command line version"
|
||||
msgstr "selecione o executável para a versão de linha de comando do GMic"
|
||||
30
locale/pt_BR/LC_MESSAGES/clear_GPS.po
Normal file
30
locale/pt_BR/LC_MESSAGES/clear_GPS.po
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:53-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/clear_GPS.lua:81
|
||||
msgid "clear GPS data"
|
||||
msgstr "limpar dados de GPS"
|
||||
|
||||
#: ../contrib/clear_GPS.lua:83
|
||||
msgid "Clear GPS data from selected images"
|
||||
msgstr "Limpa os dados de GPS das imagens selecionadas"
|
||||
|
||||
#: ../contrib/clear_GPS.lua:89
|
||||
msgid "Clear GPS data"
|
||||
msgstr "Limpar dados de GPS"
|
||||
90
locale/pt_BR/LC_MESSAGES/color_profile_manager.po
Normal file
90
locale/pt_BR/LC_MESSAGES/color_profile_manager.po
Normal file
@@ -0,0 +1,90 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-30 19:05-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:122
|
||||
msgid "added color profile "
|
||||
msgstr "perfil de cor adicionado "
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:128
|
||||
msgid "removed color profile "
|
||||
msgstr "perfil de cor removido "
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:146
|
||||
msgid "ERROR: color profile must be an icc or icm file"
|
||||
msgstr "ERRO: perfil de cor deve ser um arquivo icm ou icc"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:229
|
||||
msgid "color profile manager"
|
||||
msgstr "gerenciador de perfil de cor"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:270
|
||||
msgid "initialize color profiles"
|
||||
msgstr "inicializar perfis de cor"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:271
|
||||
msgid "create the directory structure to contain the color profiles"
|
||||
msgstr "cria a estrutura de pasta para conter os perfis de cor"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:286
|
||||
msgid "select profile set"
|
||||
msgstr "selecionar definição de perfil"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:287
|
||||
msgid "select input or output profiles"
|
||||
msgstr "selecionar perfis de entrada ou saída"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:294
|
||||
msgid "input"
|
||||
msgstr "entrada"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:294
|
||||
msgid "output"
|
||||
msgstr "saída"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:298
|
||||
msgid "select color profile to add"
|
||||
msgstr "selecionar perfil de cor a adicionar"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:299
|
||||
msgid "select the .icc or .icm file to add"
|
||||
msgstr "selecionar arquivo icc ou icm a adicionar"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:306
|
||||
msgid "add profile"
|
||||
msgstr "adicionar perfil"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:309
|
||||
msgid "add selected color profile"
|
||||
msgstr "adicionar perfil de cor selecionado"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:310
|
||||
msgid "add selected file to profiles"
|
||||
msgstr "adicionar arquivo selecionado aos perfis"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:320
|
||||
msgid "remove profile"
|
||||
msgstr "remover perfil"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:323
|
||||
msgid "remove selected profile(s)"
|
||||
msgstr "remover perfil(s) selecionado(s)"
|
||||
|
||||
#: ../contrib/color_profile_manager.lua:324
|
||||
msgid "remove the checked profile(s)"
|
||||
msgstr "remover o(s) perfil(s) marcado(s)"
|
||||
86
locale/pt_BR/LC_MESSAGES/copy_attach_detach_tags.po
Normal file
86
locale/pt_BR/LC_MESSAGES/copy_attach_detach_tags.po
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:52-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:101
|
||||
msgid "Image tags copied ..."
|
||||
msgstr "Etiquetas de imagem copiadas ..."
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:123
|
||||
msgid "No tag to attach, please copy tags first."
|
||||
msgstr "Nenhuma etiqueta anexada, por favor copie as etiquetas primeiro."
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:147
|
||||
msgid "Tags attached ..."
|
||||
msgstr "Etiquetas anexadas ..."
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:163
|
||||
msgid "Tags removed from image(s)."
|
||||
msgstr "Etiquetas removidas da(s) imagem(ns) "
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:169
|
||||
msgid "Tags replaced"
|
||||
msgstr "Etiquetas substituídas"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:174
|
||||
msgid "tagging addon"
|
||||
msgstr "addon de etiquetas"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:204
|
||||
#: ../contrib/copy_attach_detach_tags.lua:241
|
||||
#: ../contrib/copy_attach_detach_tags.lua:294
|
||||
msgid "copy tags from selected image(s)"
|
||||
msgstr "copiar etiquetas da(s) imagem(ns) selecionada(s)"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:209
|
||||
#: ../contrib/copy_attach_detach_tags.lua:244
|
||||
#: ../contrib/copy_attach_detach_tags.lua:299
|
||||
msgid "paste tags to selected image(s)"
|
||||
msgstr "colar etiquetas para a(s) imagem(ns) selecionada(s)"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:214
|
||||
#: ../contrib/copy_attach_detach_tags.lua:257
|
||||
#: ../contrib/copy_attach_detach_tags.lua:304
|
||||
msgid "remove tags from selected image(s)"
|
||||
msgstr "remover etiquetas da(s) imagem(ns) selecionada(s)"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:219
|
||||
#: ../contrib/copy_attach_detach_tags.lua:253
|
||||
#: ../contrib/copy_attach_detach_tags.lua:309
|
||||
msgid "replace tags from selected image(s)"
|
||||
msgstr "substituir etiquetas a partir da(s) imagem(ns) selecionada(s)"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:232
|
||||
msgid "tag clipboard"
|
||||
msgstr "área de transferência de etiqueta"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:240
|
||||
msgid "multi copy tags"
|
||||
msgstr "copiar etiquetas múltiplas"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:245
|
||||
msgid "paste tags"
|
||||
msgstr "colar etiquetas"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:252
|
||||
msgid "replace tags"
|
||||
msgstr "substituir etiquetas"
|
||||
|
||||
#: ../contrib/copy_attach_detach_tags.lua:256
|
||||
msgid "remove all tags"
|
||||
msgstr "remover todas as etiquetas"
|
||||
34
locale/pt_BR/LC_MESSAGES/copy_paste_metadata.po
Normal file
34
locale/pt_BR/LC_MESSAGES/copy_paste_metadata.po
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 14:57-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:38-0300\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: copy_paste_metadata.lua:131
|
||||
msgid "copy metadata"
|
||||
msgstr "copiar metadados"
|
||||
|
||||
#: copy_paste_metadata.lua:133
|
||||
msgid "copy metadata of the first selected image"
|
||||
msgstr "copiar metadados da primeira imagem selecionada"
|
||||
|
||||
#: copy_paste_metadata.lua:139
|
||||
msgid "paste metadata"
|
||||
msgstr "colar metadados"
|
||||
|
||||
#: copy_paste_metadata.lua:141
|
||||
msgid "paste metadata to the selected images"
|
||||
msgstr "colar metadados para as imagens selecionadas"
|
||||
61
locale/pt_BR/LC_MESSAGES/enfuse.po
Normal file
61
locale/pt_BR/LC_MESSAGES/enfuse.po
Normal file
@@ -0,0 +1,61 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 15:19-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:39-0300\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: enfuse.lua:187
|
||||
#, lua-format
|
||||
msgid "Error writing to `%s`"
|
||||
msgstr "Erro ao salvar `%s`"
|
||||
|
||||
#: enfuse.lua:210
|
||||
#, lua-format
|
||||
msgid "Converting raw file '%s' to tiff..."
|
||||
msgstr "Converter arquivo raw `%s` para tiff..."
|
||||
|
||||
#: enfuse.lua:220
|
||||
#, lua-format
|
||||
msgid "Skipping %s..."
|
||||
msgstr "Pulando %s..."
|
||||
|
||||
#: enfuse.lua:227
|
||||
msgid "No suitable images selected, nothing to do for enfuse"
|
||||
msgstr "Nenhuma imagem adequada selecionado, nada a fazer para o script"
|
||||
|
||||
#: enfuse.lua:233
|
||||
#, lua-format
|
||||
msgid "%d image(s) skipped"
|
||||
msgstr "%d imagem(ns) pulada(s)"
|
||||
|
||||
#: enfuse.lua:253
|
||||
msgid "Enfuse failed, see terminal output for details"
|
||||
msgstr "Script falhou, veja a saída do terminal para detalhes"
|
||||
|
||||
#: enfuse.lua:265
|
||||
msgid "enfuse was successful, resulting image has been imported"
|
||||
msgstr "script foi bem sucedido, imagem resultante foi importada"
|
||||
|
||||
#: enfuse.lua:267
|
||||
#, lua-format
|
||||
msgid "enfuse: done, resulting image '%s' has been imported with id %d"
|
||||
msgstr "enfuse: feito, imagem '%s' resultante foi importada com o id %d"
|
||||
|
||||
#: enfuse.lua:301
|
||||
msgid "Could not find enfuse executable. Not loading enfuse exporter..."
|
||||
msgstr ""
|
||||
"Não foi possível encontrar o executável do enfuse. Exportador do enfuse não"
|
||||
" carregado..."
|
||||
555
locale/pt_BR/LC_MESSAGES/enfuseAdvanced.po
Normal file
555
locale/pt_BR/LC_MESSAGES/enfuseAdvanced.po
Normal file
@@ -0,0 +1,555 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:03-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:250
|
||||
msgid "please update your binary locations"
|
||||
msgstr "por favor, atualiza suas localizações de binários"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:262
|
||||
msgid "issue with "
|
||||
msgstr "problema com "
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:262
|
||||
msgid " executable"
|
||||
msgstr " executável"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:271
|
||||
msgid "update successful"
|
||||
msgstr "atualização bem sucedida"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:273
|
||||
msgid "update unsuccessful, please try again"
|
||||
msgstr "atualização mau sucedida, tente novamente"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:379
|
||||
msgid "saved to "
|
||||
msgstr "salvar para "
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:395
|
||||
msgid "loaded from "
|
||||
msgstr "carregado de "
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:430
|
||||
msgid "export for image fusion "
|
||||
msgstr "exportar para fusão de imagem "
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:435
|
||||
msgid "too few images selected, please select at least 2 images"
|
||||
msgstr "muito poucas imagens selecionadas, selecione pelo menos 2 imagens"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:438
|
||||
msgid "installation error, please verify binary paths are proper"
|
||||
msgstr ""
|
||||
"erro de instalação, verifique se as localizações dos binários estão corretas"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:458 ../contrib/enfuseAdvanced.lua:459
|
||||
#: ../contrib/enfuseAdvanced.lua:485 ../contrib/enfuseAdvanced.lua:486
|
||||
msgid " failed"
|
||||
msgstr " falhou"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:534
|
||||
msgid "image align options"
|
||||
msgstr "opções de alinhamento de imagem"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:537
|
||||
msgid "align images"
|
||||
msgstr "alinhar imagens"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:539
|
||||
msgid "automatically align images prior to enfuse"
|
||||
msgstr "alinha automaticamente as imagens antes de fundir"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:549
|
||||
msgid "optimize radial distortion"
|
||||
msgstr "otimizar distorção radial"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:551
|
||||
msgid ""
|
||||
"optimize radial distortion for all images, \n"
|
||||
"except for first"
|
||||
msgstr ""
|
||||
"otimiza a distorção radial para todas as imagens, \n"
|
||||
"exceto para a primeira"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:556
|
||||
msgid "optimize field of view"
|
||||
msgstr "otimizar o campo de visão"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:558
|
||||
msgid ""
|
||||
"optimize field of view for all images, except for first. \n"
|
||||
"Useful for aligning focus stacks (DFF) with slightly \n"
|
||||
"different magnification."
|
||||
msgstr ""
|
||||
"otimizar o campo de visão para todas as imagens, exceto para a primeira. \n"
|
||||
"Útil para alinhar foco empilhado (DFF, sigla em inglês) com ampliação \n"
|
||||
"ligeiramente diferente."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:563
|
||||
msgid "optimize image center shift"
|
||||
msgstr "otimizar deslocamento do centro da imagem"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:565
|
||||
msgid ""
|
||||
"optimize image center shift for all images, \n"
|
||||
"except for first."
|
||||
msgstr ""
|
||||
"otimiza o deslocamento do centro da imagem para\n"
|
||||
"todas as imagens, exceto a primeira."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:570
|
||||
msgid "auto crop"
|
||||
msgstr "recorte automático"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:572
|
||||
msgid "auto crop the image to the area covered by all images."
|
||||
msgstr ""
|
||||
"recorta automaticamente a imagem para a área coberta por todas\n"
|
||||
"as imagens."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:577
|
||||
msgid "load distortion from lens database"
|
||||
msgstr "carregar distorção a partir da base de dados de lentes"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:579
|
||||
msgid "try to load distortion information from lens database"
|
||||
msgstr "tenta carregar informações de distorção da base de dados de lentes"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:584
|
||||
msgid "use gpu"
|
||||
msgstr "usar gpu"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:586
|
||||
msgid "use gpu during alignment"
|
||||
msgstr "usa a gpu durante o alinhamento"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:593
|
||||
msgid "image grid size"
|
||||
msgstr "tamanho da grade de imagem"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:594
|
||||
msgid ""
|
||||
"break image into a rectangular grid \n"
|
||||
"and attempt to find num control points in each section.\n"
|
||||
"default: (5x5)"
|
||||
msgstr ""
|
||||
"quebra a imagem em uma grade retangular e \n"
|
||||
"tenta encontrar um número de pontos de controle\n"
|
||||
"em cada seção.\n"
|
||||
"padrão: (5x5)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:610
|
||||
msgid "control points/grid"
|
||||
msgstr "pontos de controle/grade"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:611
|
||||
msgid ""
|
||||
"number of control points (per grid, see option -g) \n"
|
||||
"to create between adjacent images \n"
|
||||
"default: (8)."
|
||||
msgstr ""
|
||||
"número de pontos de controle (por grade, veja a opção -g)\n"
|
||||
"para criar entre imagens adjacentes \n"
|
||||
"padrão: (8)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:627
|
||||
msgid "remove control points with error"
|
||||
msgstr "remover pontos de controle com erro"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:628
|
||||
msgid ""
|
||||
"remove all control points with an error higher \n"
|
||||
"than num pixels \n"
|
||||
"default: (3)"
|
||||
msgstr ""
|
||||
"remove todos os pontos de controle com um erro superior\n"
|
||||
"que um número de pixels\n"
|
||||
"padrão: (3)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:644
|
||||
msgid "correlation threshold for control points"
|
||||
msgstr "limiar de correlação para pontos de controle"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:645
|
||||
msgid ""
|
||||
"correlation threshold for identifying \n"
|
||||
"control points \n"
|
||||
"default: (0.9)."
|
||||
msgstr ""
|
||||
"limiar de correlação para identificar pontos\n"
|
||||
"de controle\n"
|
||||
"padrão: (0,9)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:659
|
||||
msgid "image fusion options"
|
||||
msgstr "opções de fusão de imagem"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:664
|
||||
msgid "exposure weight"
|
||||
msgstr "peso da exposição"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:665
|
||||
msgid ""
|
||||
"set the relative weight of the well-exposedness criterion \n"
|
||||
"as defined by the chosen exposure weight function. \n"
|
||||
"increasing this weight relative to the others will\n"
|
||||
" make well-exposed pixels contribute more to\n"
|
||||
" the final output. \n"
|
||||
"default: (1.0)"
|
||||
msgstr ""
|
||||
"configura o peso relativo do critério de boa exposição como\n"
|
||||
"definido pela função de peso de exposição.\n"
|
||||
"aumentar este peso relativo para outros fará com que\n"
|
||||
"os pixels bem expostos contribuam mais para a saída\n"
|
||||
"final.\n"
|
||||
"padrão: (1,0)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:676
|
||||
msgid "saturation weight"
|
||||
msgstr "peso da saturação"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:677
|
||||
msgid ""
|
||||
"set the relative weight of high-saturation pixels. \n"
|
||||
"increasing this weight makes pixels with high \n"
|
||||
"saturation contribute more to the final output. \n"
|
||||
"default: (0.2)"
|
||||
msgstr ""
|
||||
"configura o peso relativo dos pixels altamente saturados.\n"
|
||||
"aumentar este peso fará com que os pixels com alta saturação\n"
|
||||
"contribuam mais para a saída final. "
|
||||
"padrão: (0,2)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:688
|
||||
msgid "contrast weight"
|
||||
msgstr "peso do contraste"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:689
|
||||
msgid ""
|
||||
"sets the relative weight of high local-contrast pixels. \n"
|
||||
"default: (0.0)."
|
||||
msgstr ""
|
||||
"configura o peso relativo dos pixels com alto contraste local.\n"
|
||||
"padrão: (0,0)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:700
|
||||
msgid "exposure optimum"
|
||||
msgstr "exposição ótima"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:701
|
||||
msgid ""
|
||||
"determine at what normalized exposure value\n"
|
||||
" the optimum exposure of the input images\n"
|
||||
" is. this is, set the position of the maximum\n"
|
||||
" of the exposure weight curve. use this \n"
|
||||
"option to fine-tune exposure weighting. \n"
|
||||
"default: (0.5)"
|
||||
msgstr ""
|
||||
"determina qual valor de exposição normalizado\n"
|
||||
"é a exposição ótima da imagem de entrada.\n"
|
||||
"isto é, define a posição do máximo de exposição\n"
|
||||
"da curva de peso. use esta opção para ajustar o\n"
|
||||
"peso da exposição.\n"
|
||||
"padrão: (0,5)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:712
|
||||
msgid "exposure width"
|
||||
msgstr "largura da exposição"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:713
|
||||
msgid ""
|
||||
"set the characteristic width (FWHM) of the exposure \n"
|
||||
"weight function. low numbers give less weight to \n"
|
||||
"pixels that are far from the user-defined \n"
|
||||
"optimum and vice versa. use this option to \n"
|
||||
"fine-tune exposure weighting. \n"
|
||||
"default: (0.2)"
|
||||
msgstr ""
|
||||
"configura a largura característica (FWHM) da função de peso\n"
|
||||
"da exposição. números baixos atribuem menos peso para os\n"
|
||||
"pixels que estão longe do ótimo definido pelo usuário e vice-\n"
|
||||
"versa. use esta opção para ajustar o peso da exposição.\n"
|
||||
"padrão: (0,2)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:722
|
||||
msgid "hard mask"
|
||||
msgstr "máscara dura"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:724
|
||||
msgid ""
|
||||
"force hard blend masks on the finest scale. this avoids \n"
|
||||
"averaging of fine details (only), at the expense \n"
|
||||
"of increasing the noise. this improves the \n"
|
||||
"sharpness of focus stacks considerably.\n"
|
||||
"default (soft mask)"
|
||||
msgstr ""
|
||||
"força máscaras de mesclagem duras na escala mais fina. isto\n"
|
||||
"previne aproximação dos detalhes mais finos (somente), ao\n"
|
||||
"custo de aumentar o ruído. isto melhora a nitidez do empilha-\n"
|
||||
"mento de foco consideravelmente.\n"
|
||||
"padrão (máscara suave)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:729
|
||||
msgid "save masks"
|
||||
msgstr "salvar máscaras"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:731
|
||||
msgid ""
|
||||
"Save the generated weight masks to your home directory,\n"
|
||||
"enblend saves masks as 8 bit grayscale, \n"
|
||||
"i.e. single channel images. \n"
|
||||
"for accuracy we recommend to choose a lossless format."
|
||||
msgstr ""
|
||||
"Salva as máscaras de peso geradas para sua pasta pessoal,\n"
|
||||
"mescla máscaras salvas como tons de cinza de 8 bits, isto é,\n"
|
||||
"imagens de canal simples.\n"
|
||||
"para maior precisão, nós recomendamos escolher um formato\n"
|
||||
"sem perdas."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:738
|
||||
msgid "contrast window size"
|
||||
msgstr "tamanho da janela de contraste"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:739
|
||||
msgid ""
|
||||
"set the window size for local contrast analysis. \n"
|
||||
"the window will be a square of size × size pixels. \n"
|
||||
"if given an even size, Enfuse will \n"
|
||||
"automatically use the next odd number.\n"
|
||||
"for contrast analysis size values larger \n"
|
||||
"than 5 pixels might result in a \n"
|
||||
"blurry composite image. values of 3 and \n"
|
||||
"5 pixels have given good results on \n"
|
||||
"focus stacks. \n"
|
||||
"default: (5) pixels"
|
||||
msgstr ""
|
||||
"configura o tamanho da janela para a análise de contraste local.\n"
|
||||
"a janela será um quadrado de tamanho x tamanho em pixels.\n"
|
||||
"se fornecido um tamanho par, o script usará automaticamente\n"
|
||||
"o próximo número ímpar.\n"
|
||||
"valores de tamanho para análise de contraste maiores que\n"
|
||||
"5 pixels podem resultar em uma imagem composta borrada.\n"
|
||||
"valores de 3 e 5 pixels produzem bons resultados para empi-\n"
|
||||
"lhamento de foco.\n"
|
||||
"padrão: (5) pixels"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:755
|
||||
msgid "contrast edge scale"
|
||||
msgstr "escala de borda de contraste"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:756
|
||||
msgid ""
|
||||
"a non-zero value for EDGE-SCALE switches on the \n"
|
||||
"Laplacian-of-Gaussian (LoG) edge detection algorithm.\n"
|
||||
" edage-scale is the radius of the Gaussian used \n"
|
||||
"in the search for edges. a positive LCE-SCALE \n"
|
||||
"turns on local contrast enhancement (LCE) \n"
|
||||
"before the LoG edge detection. \n"
|
||||
"Default: (0.0) pixels."
|
||||
msgstr ""
|
||||
"um valor diferente de zero para a ESCALA DE BORDA alterna\n"
|
||||
"o algoritmo de detecção de borda Laplaciano-de-Gaussiano (LoG).\n"
|
||||
"a escala de borda é o raio do Gaussiano usado na busca por bordas.\n"
|
||||
"uma escala LCE positiva ativa o melhoramento de contraste local (LCE)\n"
|
||||
"antes da detecção de borda LoG.\n"
|
||||
"Padrão: (0,0) pixels"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:772
|
||||
msgid "contrast min curvature [%]"
|
||||
msgstr "curvatura mín de contraste [%]"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:773
|
||||
msgid ""
|
||||
"define the minimum curvature for the LoG edge detection. Append a ‘%’ to "
|
||||
"specify the minimum curvature relative to maximum pixel value in the source "
|
||||
"image. Default: (0.0%)"
|
||||
msgstr ""
|
||||
"configura a curvatura mínima para a detecção de borda LoG. Adicionar um '%'"
|
||||
" para "
|
||||
"definir a curvatura mínima em relação ao valor máximo de pixel na imagem"
|
||||
" fonte. "
|
||||
"Padrão: (0,0%)"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:787
|
||||
msgid "target file"
|
||||
msgstr "arquivo alvo"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:792
|
||||
msgid "tiff compression"
|
||||
msgstr "compressão tiff"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:793
|
||||
msgid "compression method for tiff files"
|
||||
msgstr "método de compressão para arquivos tiff"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:809
|
||||
msgid "jpeg compression"
|
||||
msgstr "compressão jpeg"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:810
|
||||
msgid "jpeg compression level"
|
||||
msgstr "nível de compressão jpeg"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:832
|
||||
msgid "file format"
|
||||
msgstr "formato de arquivo"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:833
|
||||
msgid "file format of the enfused final image"
|
||||
msgstr "formato de arquivo da imagem final fundida"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:853
|
||||
msgid "bit depth"
|
||||
msgstr "profundidade de bits"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:854
|
||||
msgid "bit depth of the enfused file"
|
||||
msgstr "profundidade de bits do arquivo fundido"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:868
|
||||
msgid "directory"
|
||||
msgstr "pasta"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:877
|
||||
msgid ""
|
||||
"select the target directory for the fused image. \n"
|
||||
"the filename is created automatically."
|
||||
msgstr ""
|
||||
"seleciona a pasta alvo para a imagem fundida.\n"
|
||||
"o nome do arquivo é criado automaticamente."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:882
|
||||
msgid "save to source image location"
|
||||
msgstr "salvar para a localização da imagem fonte"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:884
|
||||
msgid ""
|
||||
"If checked ignores the location above and saves output image(s) to the same "
|
||||
"location as the source images."
|
||||
msgstr ""
|
||||
"Se selecionado, ignora a localização acima e salva a(s) imagem(ns) de saída"
|
||||
" na mesma "
|
||||
"localização das imagens fonte."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:891
|
||||
msgid "on conflict"
|
||||
msgstr "no caso de conflito"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:905
|
||||
msgid "auto import"
|
||||
msgstr "importar automaticamente"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:907
|
||||
msgid "import the image into darktable database when enfuse completes"
|
||||
msgstr ""
|
||||
"importa a imagem para a base de dados do darktable quando a fusão for"
|
||||
" completada"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:918
|
||||
msgid "Apply Style on Import"
|
||||
msgstr "Aplicar estilo ao importar"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:919
|
||||
msgid "Apply selected style on auto-import to newly created blended image"
|
||||
msgstr ""
|
||||
"Aplica o estilo selecionado ao importar automaticamente para a nova imagem"
|
||||
" fundida criada"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:938
|
||||
msgid "copy tags"
|
||||
msgstr "copiar etiquetas"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:940
|
||||
msgid "Copy tags from first image."
|
||||
msgstr "Copia as etiquetas da primeira imagem."
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:947
|
||||
msgid ""
|
||||
"Additional tags to be added on import. Seperate with commas, all spaces will "
|
||||
"be removed"
|
||||
msgstr ""
|
||||
"Etiquetas adicionais a serem adicionadas ao importar. Separe-as com vírgulas,"
|
||||
" todos "
|
||||
"os espaços serão removidos"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:955
|
||||
msgid "active preset"
|
||||
msgstr "predefinição ativa"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:956
|
||||
msgid "preset to be loaded from or saved to"
|
||||
msgstr "predefinição a ser carregada de ou salvada para"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:970
|
||||
msgid "load fusion preset"
|
||||
msgstr "carregar predefinição de fusão"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:971
|
||||
msgid "load current fusion parameters from selected preset"
|
||||
msgstr ""
|
||||
"carrega parâmetros de fusão atuais a partir da predefinição selecionada"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:975
|
||||
msgid "save to fusion preset"
|
||||
msgstr "salvar para predefinição de fusão"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:976
|
||||
msgid "save current fusion parameters to selected preset"
|
||||
msgstr "salva os parâmetros de fusão atuais para a predefinição selecionada"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:980
|
||||
msgid "create image variants from presets"
|
||||
msgstr "criar variantes da imagem a partir das predefinições"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:982
|
||||
msgid ""
|
||||
"create multiple image variants based on the three different presets of the "
|
||||
"specified type"
|
||||
msgstr ""
|
||||
"cria múltiplas variantes da imagem baseadas nas três diferentes predefinições"
|
||||
" do tipo "
|
||||
"especificado"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:999
|
||||
msgid "create variants type"
|
||||
msgstr "criar tipos de variantes"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1000
|
||||
msgid "preset type to be used when creating image variants"
|
||||
msgstr "tipo de predefinição a ser usado ao criar variantes de imagens"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1039
|
||||
msgid "update"
|
||||
msgstr "atualizar"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1040
|
||||
msgid "update the binary paths with current values"
|
||||
msgstr "atualiza os caminhos dos binários com os valores atuais"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1120
|
||||
msgid "show options"
|
||||
msgstr "mostrar opções"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1121
|
||||
msgid "show options for specified aspect of output"
|
||||
msgstr "mostra as opções para o aspecto de saída especificado"
|
||||
|
||||
#: ../contrib/enfuseAdvanced.lua:1142
|
||||
msgid "DRI or DFF image"
|
||||
msgstr "imagem DRI ou DFF"
|
||||
58
locale/pt_BR/LC_MESSAGES/executable_manager.po
Normal file
58
locale/pt_BR/LC_MESSAGES/executable_manager.po
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 11:50-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:39-0300\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: executable_manager.lua:144
|
||||
msgid "No executable paths found, exiting..."
|
||||
msgstr "Caminho do executável não encontrado, saindo..."
|
||||
|
||||
#: executable_manager.lua:160
|
||||
msgid "select an executable"
|
||||
msgstr "selecione um executável"
|
||||
|
||||
#: executable_manager.lua:160
|
||||
msgid "search path for executable"
|
||||
msgstr "caminho de pesquisa por executável"
|
||||
|
||||
#: executable_manager.lua:169
|
||||
msgid "select "
|
||||
msgstr "selecionar "
|
||||
|
||||
#: executable_manager.lua:169
|
||||
msgid " executable"
|
||||
msgstr " executável"
|
||||
|
||||
#: executable_manager.lua:190
|
||||
msgid "select executable to modify"
|
||||
msgstr "selecione executável a modificar"
|
||||
|
||||
#: executable_manager.lua:205
|
||||
msgid "current"
|
||||
msgstr "atual"
|
||||
|
||||
#: executable_manager.lua:207
|
||||
msgid "select"
|
||||
msgstr "selecionar"
|
||||
|
||||
#: executable_manager.lua:209
|
||||
msgid "reset"
|
||||
msgstr "reiniciar"
|
||||
|
||||
#: executable_manager.lua:212
|
||||
msgid "Clear path for "
|
||||
msgstr "Limpar caminho para "
|
||||
62
locale/pt_BR/LC_MESSAGES/exportLUT.po
Normal file
62
locale/pt_BR/LC_MESSAGES/exportLUT.po
Normal file
@@ -0,0 +1,62 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-30 19:25-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/exportLUT.lua:66
|
||||
msgid "Identity_file_chooser"
|
||||
msgstr "Selecionar_arquiv_identidade"
|
||||
|
||||
#: ../contrib/exportLUT.lua:72
|
||||
msgid "Export_location_chooser"
|
||||
msgstr "Selecionar_localização_exportação"
|
||||
|
||||
#: ../contrib/exportLUT.lua:78
|
||||
msgid "choose the identity haldclut file"
|
||||
msgstr "selecione o arquivo halclut de identidade"
|
||||
|
||||
#: ../contrib/exportLUT.lua:82
|
||||
msgid "choose the output location"
|
||||
msgstr "selecione a localização de saída"
|
||||
|
||||
#: ../contrib/exportLUT.lua:86
|
||||
msgid "WARNING: files may be silently overwritten"
|
||||
msgstr "AVISO: os arquivos podem ser sobrescritos sem confirmação"
|
||||
|
||||
#: ../contrib/exportLUT.lua:108
|
||||
msgid "Invalid identity lut file"
|
||||
msgstr "Arquivo lut de identidade inválido"
|
||||
|
||||
#: ../contrib/exportLUT.lua:110
|
||||
msgid "Exporting styles as haldCLUTs"
|
||||
msgstr "Exportar estilos como haldCLUTs"
|
||||
|
||||
#: ../contrib/exportLUT.lua:129
|
||||
msgid "Exported: "
|
||||
msgstr "Exportado: "
|
||||
|
||||
#: ../contrib/exportLUT.lua:131
|
||||
msgid "Done exporting haldCLUTs"
|
||||
msgstr "Exportação de haldCLUTs feita"
|
||||
|
||||
#: ../contrib/exportLUT.lua:141
|
||||
msgid "export haldclut"
|
||||
msgstr "exportar haldclut"
|
||||
|
||||
#: ../contrib/exportLUT.lua:166
|
||||
msgid "export"
|
||||
msgstr "exportar"
|
||||
129
locale/pt_BR/LC_MESSAGES/ext_editor.po
Normal file
129
locale/pt_BR/LC_MESSAGES/ext_editor.po
Normal file
@@ -0,0 +1,129 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:07-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/ext_editor.lua:158
|
||||
msgid " editors configured"
|
||||
msgstr " editores configurados"
|
||||
|
||||
#: ../contrib/ext_editor.lua:167
|
||||
msgid "not a valid choice"
|
||||
msgstr "não é uma escolha válida"
|
||||
|
||||
#: ../contrib/ext_editor.lua:173
|
||||
msgid "please select one image"
|
||||
msgstr "por favor, selecione uma imagem"
|
||||
|
||||
#: ../contrib/ext_editor.lua:197
|
||||
msgid "file type not allowed"
|
||||
msgstr "tipo de arquivo não permitido"
|
||||
|
||||
#: ../contrib/ext_editor.lua:225
|
||||
msgid "error copying file "
|
||||
msgstr "erro ao copiar arquivo "
|
||||
|
||||
#: ../contrib/ext_editor.lua:232
|
||||
msgid "launching "
|
||||
msgstr "iniciando "
|
||||
|
||||
#: ../contrib/ext_editor.lua:235
|
||||
msgid "error launching "
|
||||
msgstr "erro ao lançar "
|
||||
|
||||
#: ../contrib/ext_editor.lua:328
|
||||
msgid "error moving file "
|
||||
msgstr "erro ao mover arquivo "
|
||||
|
||||
#: ../contrib/ext_editor.lua:337
|
||||
msgid "finished exporting"
|
||||
msgstr "exportação terminada"
|
||||
|
||||
#: ../contrib/ext_editor.lua:354
|
||||
msgid "external editors"
|
||||
msgstr "editores externos"
|
||||
|
||||
#: ../contrib/ext_editor.lua:380 ../contrib/ext_editor.lua:493
|
||||
msgid "edit with program "
|
||||
msgstr "editar com programa "
|
||||
|
||||
#: ../contrib/ext_editor.lua:382 ../contrib/ext_editor.lua:472
|
||||
msgid "collection"
|
||||
msgstr "coleção"
|
||||
|
||||
#: ../contrib/ext_editor.lua:393
|
||||
msgid "choose program"
|
||||
msgstr "selecionar programa"
|
||||
|
||||
#: ../contrib/ext_editor.lua:394
|
||||
msgid "select the external editor from the list"
|
||||
msgstr "selecione o editor externo a partir da lista"
|
||||
|
||||
#: ../contrib/ext_editor.lua:404
|
||||
msgid "edit"
|
||||
msgstr "editar"
|
||||
|
||||
#: ../contrib/ext_editor.lua:405
|
||||
msgid "open the selected image in external editor"
|
||||
msgstr "abre a imagem selecionada no editor externo"
|
||||
|
||||
#: ../contrib/ext_editor.lua:415
|
||||
msgid "edit a copy"
|
||||
msgstr "editar uma cópia"
|
||||
|
||||
#: ../contrib/ext_editor.lua:416
|
||||
msgid "create a copy of the selected image and open it in external editor"
|
||||
msgstr "cria uma cópia da imagem selecionada e abre-a no editor externo"
|
||||
|
||||
#: ../contrib/ext_editor.lua:425
|
||||
msgid "update list"
|
||||
msgstr "atualizar lista"
|
||||
|
||||
#: ../contrib/ext_editor.lua:426
|
||||
msgid "update list of programs if lua preferences are changed"
|
||||
msgstr "atualiza lista de programas se as preferências do lua forem alteradas"
|
||||
|
||||
#: ../contrib/ext_editor.lua:478
|
||||
msgid "executable for external editor "
|
||||
msgstr "executável para o editor externo "
|
||||
|
||||
#: ../contrib/ext_editor.lua:479
|
||||
msgid "select executable for external editor"
|
||||
msgstr "seleciona o executável para o editor externo"
|
||||
|
||||
#: ../contrib/ext_editor.lua:479
|
||||
msgid "(None)"
|
||||
msgstr "(Nenhum)"
|
||||
|
||||
#: ../contrib/ext_editor.lua:482
|
||||
msgid "name of external editor "
|
||||
msgstr "nome do editor externo "
|
||||
|
||||
#: ../contrib/ext_editor.lua:483
|
||||
msgid "friendly name of external editor"
|
||||
msgstr "nome amigável do editor externo"
|
||||
|
||||
#: ../contrib/ext_editor.lua:486
|
||||
msgid "show external editors in darkroom"
|
||||
msgstr "mostrar editores externos na sala escura"
|
||||
|
||||
#: ../contrib/ext_editor.lua:487
|
||||
msgid ""
|
||||
"check to show external editors module also in darkroom (requires restart)"
|
||||
msgstr ""
|
||||
"ative para mostrar o módulo de editores externos também na sala escura"
|
||||
" (precisa reiniciar)"
|
||||
135
locale/pt_BR/LC_MESSAGES/face_recognition.po
Normal file
135
locale/pt_BR/LC_MESSAGES/face_recognition.po
Normal file
@@ -0,0 +1,135 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:12-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/face_recognition.lua:131
|
||||
msgid "export images"
|
||||
msgstr "exportar imagens"
|
||||
|
||||
#: ../contrib/face_recognition.lua:137
|
||||
#, lua-format
|
||||
msgid "Exporting image %i of %i images"
|
||||
msgstr "Exportando imagem %i de %i imagens"
|
||||
|
||||
#: ../contrib/face_recognition.lua:207
|
||||
msgid "Face recognition not found"
|
||||
msgstr "Reconhecimento de rosto não encontrado"
|
||||
|
||||
#: ../contrib/face_recognition.lua:259
|
||||
msgid "Starting face recognition..."
|
||||
msgstr "Iniciando reconhecimento de rosto..."
|
||||
|
||||
#: ../contrib/face_recognition.lua:267
|
||||
msgid "Face recognition failed"
|
||||
msgstr "Reconhecimento de rosto falhou"
|
||||
|
||||
#: ../contrib/face_recognition.lua:269
|
||||
msgid "Face recognition finished"
|
||||
msgstr "Reconhecimento de rosto terminado"
|
||||
|
||||
#: ../contrib/face_recognition.lua:274
|
||||
msgid "processing results..."
|
||||
msgstr "processando resultados..."
|
||||
|
||||
#: ../contrib/face_recognition.lua:338
|
||||
msgid "face recognition complete"
|
||||
msgstr "reconhecimento de rosto completo"
|
||||
|
||||
#: ../contrib/face_recognition.lua:340
|
||||
msgid "image export failed"
|
||||
msgstr "exportação da imagem falhou"
|
||||
|
||||
#: ../contrib/face_recognition.lua:344
|
||||
msgid "no images selected"
|
||||
msgstr "nenhuma imagem selecionada"
|
||||
|
||||
#: ../contrib/face_recognition.lua:353
|
||||
msgid "face recognition"
|
||||
msgstr "reconhecimento de rosto"
|
||||
|
||||
#: ../contrib/face_recognition.lua:377
|
||||
msgid "tag to be used for unknown person"
|
||||
msgstr "etiqueta a ser usada para pessoa desconhecida"
|
||||
|
||||
#: ../contrib/face_recognition.lua:383
|
||||
msgid "tag to be used when no persons are found"
|
||||
msgstr "etiqueta a ser usada quando nenhuma pessoa for encontrada"
|
||||
|
||||
#: ../contrib/face_recognition.lua:389 ../contrib/face_recognition.lua:467
|
||||
msgid "tags of images to ignore"
|
||||
msgstr "etiquetas de imagens para ignorar"
|
||||
|
||||
#: ../contrib/face_recognition.lua:395 ../contrib/face_recognition.lua:469
|
||||
msgid "tag category"
|
||||
msgstr "categoria da etiqueta"
|
||||
|
||||
#: ../contrib/face_recognition.lua:400
|
||||
msgid "tolerance"
|
||||
msgstr "tolerância"
|
||||
|
||||
#: ../contrib/face_recognition.lua:412
|
||||
msgid "processor cores"
|
||||
msgstr "núcleos de processador"
|
||||
|
||||
#: ../contrib/face_recognition.lua:413
|
||||
msgid "number of processor cores to use, 0 for all"
|
||||
msgstr "número de núcleos de processador a usar, 0 para todos"
|
||||
|
||||
#: ../contrib/face_recognition.lua:424
|
||||
msgid "known image directory"
|
||||
msgstr "pasta de imagem conhecida"
|
||||
|
||||
#: ../contrib/face_recognition.lua:425 ../contrib/face_recognition.lua:471
|
||||
msgid "face data directory"
|
||||
msgstr "pasta de dados de rosto"
|
||||
|
||||
#: ../contrib/face_recognition.lua:434
|
||||
msgid "export image format"
|
||||
msgstr "formato de exportação da imagem"
|
||||
|
||||
#: ../contrib/face_recognition.lua:435
|
||||
msgid "format for exported images"
|
||||
msgstr "formato para as imagens exportadas"
|
||||
|
||||
#: ../contrib/face_recognition.lua:445
|
||||
msgid "maximum exported image width"
|
||||
msgstr "largura máxima das imagens exportadas"
|
||||
|
||||
#: ../contrib/face_recognition.lua:451
|
||||
msgid "maximum exported image height"
|
||||
msgstr "altura máxima das imagens exportada"
|
||||
|
||||
#: ../contrib/face_recognition.lua:463
|
||||
msgid "unknown person tag"
|
||||
msgstr "etiqueta de pessoa desconhecida"
|
||||
|
||||
#: ../contrib/face_recognition.lua:465
|
||||
msgid "no persons found tag"
|
||||
msgstr "etiqueta de nenhuma pessoa encontrada"
|
||||
|
||||
#: ../contrib/face_recognition.lua:478
|
||||
msgid "processing options"
|
||||
msgstr "opções de processamento"
|
||||
|
||||
#: ../contrib/face_recognition.lua:484
|
||||
msgid "width "
|
||||
msgstr "largura "
|
||||
|
||||
#: ../contrib/face_recognition.lua:489
|
||||
msgid "height "
|
||||
msgstr "altura "
|
||||
30
locale/pt_BR/LC_MESSAGES/fujifilm_ratings.po
Normal file
30
locale/pt_BR/LC_MESSAGES/fujifilm_ratings.po
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-30 19:26-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/fujifilm_ratings.lua:49
|
||||
msgid "exiftool not found"
|
||||
msgstr "exiftool não encontrado"
|
||||
|
||||
#: ../contrib/fujifilm_ratings.lua:62
|
||||
msgid "Using JPEG Rating: "
|
||||
msgstr "Usar classificação JPEG: "
|
||||
|
||||
#: ../contrib/fujifilm_ratings.lua:73
|
||||
msgid "Using RAF Rating: "
|
||||
msgstr "Usar classificação RAF: "
|
||||
77
locale/pt_BR/LC_MESSAGES/geoJSON_export.po
Normal file
77
locale/pt_BR/LC_MESSAGES/geoJSON_export.po
Normal file
@@ -0,0 +1,77 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:16-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:82
|
||||
#, lua-format
|
||||
msgid "Export Image %i/%i"
|
||||
msgstr "Exportar Imagem %i/%i"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:87
|
||||
msgid "mkdir not found"
|
||||
msgstr "mkdir não encontrado"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:91
|
||||
msgid "convert not found"
|
||||
msgstr "convert não encontrado"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:95
|
||||
msgid "xdg-open not found"
|
||||
msgstr "xdg-open não encontrado"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:99
|
||||
msgid "xdg-user-dir not found"
|
||||
msgstr "xdg-user-dir não encontrado"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:310
|
||||
msgid "geoJSON export: Create an additional HTML file"
|
||||
msgstr "exportar geoJSON: Criar um arquivo HTML adicional"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:311
|
||||
msgid "Creates a HTML file, that loads the geoJASON file. (Needs a MapBox key"
|
||||
msgstr ""
|
||||
"Cria um arquivo HTML que carrega o arquivo geoJSON. (Precisa de uma chave"
|
||||
" MapBox)"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:316
|
||||
msgid "geoJSON export: MapBox Key"
|
||||
msgstr "exportar geoJSON : chave MapBox"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:317
|
||||
msgid "https://www.mapbox.com/studio/account/tokens"
|
||||
msgstr "https://www.mapbox.com/studio/account/tokens"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:322
|
||||
msgid "geoJSON export: Open geoJSON file after export"
|
||||
msgstr "exportar geoJSON: Abrir o arquivo geoJSON após exportar"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:323
|
||||
msgid ""
|
||||
"Opens the geoJSON file after the export with the standard program for "
|
||||
"geoJSON files"
|
||||
msgstr ""
|
||||
"Abre o arquivo geoJSON após a exportação com o programa padrão para arquivos"
|
||||
" geoJSON"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:335
|
||||
msgid "geoJSON export: Export directory"
|
||||
msgstr "exportar geoJSON: Pasta de exportação"
|
||||
|
||||
#: ../contrib/geoJSON_export.lua:336
|
||||
msgid "A directory that will be used to export the geoJSON files"
|
||||
msgstr "Uma pasta que será usada para exportar os arquivos geoJSON"
|
||||
166
locale/pt_BR/LC_MESSAGES/geoToolbox.po
Normal file
166
locale/pt_BR/LC_MESSAGES/geoToolbox.po
Normal file
@@ -0,0 +1,166 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:23-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:58
|
||||
msgid "Distance:"
|
||||
msgstr "Distância:"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:62
|
||||
msgid "latitude:"
|
||||
msgstr "latitude:"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:67
|
||||
msgid "longitude:"
|
||||
msgstr "longitude:"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:72
|
||||
msgid "elevation:"
|
||||
msgstr "elevação:"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:79 ../contrib/geoToolbox.lua:99
|
||||
msgid "GPS selection"
|
||||
msgstr "seleção do GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:302
|
||||
msgid "latitude: "
|
||||
msgstr "latitude: "
|
||||
|
||||
#: ../contrib/geoToolbox.lua:303
|
||||
msgid "longitude: "
|
||||
msgstr "longitude: "
|
||||
|
||||
#: ../contrib/geoToolbox.lua:304
|
||||
msgid "elevation: "
|
||||
msgstr "elevação: "
|
||||
|
||||
#: ../contrib/geoToolbox.lua:329
|
||||
msgid "gnome-maps not found"
|
||||
msgstr "gnome-maps não encontrado"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:367
|
||||
msgid "curl not found"
|
||||
msgstr "curl não encontrado"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:372
|
||||
msgid "jq not found"
|
||||
msgstr "jq não encontrado"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:490
|
||||
msgid "m"
|
||||
msgstr "m"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:492
|
||||
msgid "km"
|
||||
msgstr "km"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:495
|
||||
#, lua-format
|
||||
msgid "Distance: %.2f %s"
|
||||
msgstr "Distância: %.2f %s"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:508
|
||||
msgid "export altitude CSV"
|
||||
msgstr "exportar altitude para CSV"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:518
|
||||
msgid "Name of the exported file"
|
||||
msgstr "Nome do arquivo exportado"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:523
|
||||
msgid "Start export"
|
||||
msgstr "Iniciar exportação"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:584
|
||||
msgid "File created in "
|
||||
msgstr "Arquivo criado em "
|
||||
|
||||
#: ../contrib/geoToolbox.lua:614 ../contrib/geoToolbox.lua:746
|
||||
msgid "Calculate the distance from latitude and longitude in km"
|
||||
msgstr "Calcula a distância da latitude e longitude em km"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:619 ../contrib/geoToolbox.lua:644
|
||||
#: ../contrib/geoToolbox.lua:751
|
||||
msgid "Select all images with GPS information"
|
||||
msgstr "Selecionar todas as imagens com informação de GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:621 ../contrib/geoToolbox.lua:650
|
||||
#: ../contrib/geoToolbox.lua:753
|
||||
msgid "Select all images without GPS information"
|
||||
msgstr "Selecionar todas as imagens sem informação de GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:643
|
||||
msgid "select geo images"
|
||||
msgstr "selecionar imagens geoetiquetadas"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:649
|
||||
msgid "select non-geo images"
|
||||
msgstr "selecionar imagens sem geoetiquetas"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:656
|
||||
msgid "copy GPS data"
|
||||
msgstr "copiar dados do GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:657
|
||||
msgid "Copy GPS data"
|
||||
msgstr "Copiar dados do GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:665
|
||||
msgid "paste GPS data"
|
||||
msgstr "colar dados do GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:666
|
||||
msgid "Paste GPS data"
|
||||
msgstr "Colar dados do GPS"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:695
|
||||
msgid "open in Gnome Maps"
|
||||
msgstr "abrir no Gnome Maps"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:696
|
||||
msgid "Open location in Gnome Maps"
|
||||
msgstr "Abrir localização no Gnome Maps"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:702
|
||||
msgid "reverse geocode"
|
||||
msgstr "geocódigo reverso"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:703
|
||||
msgid "This just shows the name of the location, but doesn't add it as tag"
|
||||
msgstr ""
|
||||
"Isto apenas mostra o nome da localização, mas não adiciona-a como uma etiqueta"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:707
|
||||
msgid "altitude CSV export"
|
||||
msgstr "exportar altitude em CSV"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:712
|
||||
msgid "export altitude CSV file"
|
||||
msgstr "exporta o arquivo CSV de altitude"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:713
|
||||
msgid "Create an altitude profile using the GPS data in the metadata"
|
||||
msgstr "Cria um perfil de altitude usando os dados GPS nos metadados"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:740
|
||||
msgid "geoToolbox export: MapBox Key"
|
||||
msgstr "exportar geoToolbox: chave MapBox"
|
||||
|
||||
#: ../contrib/geoToolbox.lua:741
|
||||
msgid "https://www.mapbox.com/studio/account/tokens"
|
||||
msgstr "https://www.mapbox.com/studio/account/tokens"
|
||||
43
locale/pt_BR/LC_MESSAGES/gimp.po
Normal file
43
locale/pt_BR/LC_MESSAGES/gimp.po
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:18-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/gimp.lua:111
|
||||
#, lua-format
|
||||
msgid "Export Image %i/%i"
|
||||
msgstr "Exportar Imagem %i/%i"
|
||||
|
||||
#: ../contrib/gimp.lua:121
|
||||
msgid "GIMP not found"
|
||||
msgstr "GIMP não encontrado"
|
||||
|
||||
#: ../contrib/gimp.lua:144
|
||||
msgid "Launching GIMP..."
|
||||
msgstr "Iniciando GIMP..."
|
||||
|
||||
#: ../contrib/gimp.lua:207
|
||||
msgid "run detached"
|
||||
msgstr "executar desassociado"
|
||||
|
||||
#: ../contrib/gimp.lua:208
|
||||
msgid "don't import resulting image back into darktable"
|
||||
msgstr "não importar a imagem resultante de volta para o darktable"
|
||||
|
||||
#: ../contrib/gimp.lua:215
|
||||
msgid "Edit with GIMP"
|
||||
msgstr "Editar com o GIMP"
|
||||
54
locale/pt_BR/LC_MESSAGES/gpx_export.po
Normal file
54
locale/pt_BR/LC_MESSAGES/gpx_export.po
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:48-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/gpx_export.lua:59
|
||||
msgid "gpx file path"
|
||||
msgstr "caminho do arquivo gpx"
|
||||
|
||||
#: ../contrib/gpx_export.lua:72
|
||||
msgid "exporting gpx file..."
|
||||
msgstr "exportar arquivo gpx..."
|
||||
|
||||
#: ../contrib/gpx_export.lua:74
|
||||
msgid "gpx export"
|
||||
msgstr "exportar gpx"
|
||||
|
||||
#: ../contrib/gpx_export.lua:93 ../contrib/gpx_export.lua:94
|
||||
msgid " does not have date information and won't be processed"
|
||||
msgstr " não possui informações de data e não será processado"
|
||||
|
||||
#: ../contrib/gpx_export.lua:134
|
||||
msgid "invalid path: "
|
||||
msgstr "caminho inválido: "
|
||||
|
||||
#: ../contrib/gpx_export.lua:138
|
||||
msgid "gpx file created: "
|
||||
msgstr "arquivo gpx criado: "
|
||||
|
||||
#: ../contrib/gpx_export.lua:171
|
||||
msgid "export"
|
||||
msgstr "exportar"
|
||||
|
||||
#: ../contrib/gpx_export.lua:172
|
||||
msgid "export gpx file"
|
||||
msgstr "exportar arquivo gpx"
|
||||
|
||||
#: ../contrib/gpx_export.lua:180
|
||||
msgid "file:"
|
||||
msgstr "arquivo:"
|
||||
22
locale/pt_BR/LC_MESSAGES/harmonic_armature_guide.po
Normal file
22
locale/pt_BR/LC_MESSAGES/harmonic_armature_guide.po
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-30 19:26-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/harmonic_armature_guide.lua:76
|
||||
msgid "harmonic armature"
|
||||
msgstr "armadura harmônica"
|
||||
67
locale/pt_BR/LC_MESSAGES/hugin.po
Normal file
67
locale/pt_BR/LC_MESSAGES/hugin.po
Normal file
@@ -0,0 +1,67 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:26-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/hugin.lua:109
|
||||
msgid "hugin is not found, did you set the path?"
|
||||
msgstr "hugin não encontrado, você configurou o caminho?"
|
||||
|
||||
#: ../contrib/hugin.lua:165
|
||||
msgid "will try to stitch now"
|
||||
msgstr "tentará pregar agora"
|
||||
|
||||
#: ../contrib/hugin.lua:170
|
||||
msgid "creating pto file"
|
||||
msgstr "criar arquivo pto"
|
||||
|
||||
#: ../contrib/hugin.lua:174
|
||||
msgid "running assistant"
|
||||
msgstr "rodar assistente"
|
||||
|
||||
#: ../contrib/hugin.lua:182
|
||||
msgid "launching hugin"
|
||||
msgstr "iniciar o hugin"
|
||||
|
||||
#: ../contrib/hugin.lua:184
|
||||
msgid "unable to find command line tools, launching hugin"
|
||||
msgstr ""
|
||||
"não foi possível encontrar as ferramentas de linha de comando, iniciar o hugin"
|
||||
|
||||
#: ../contrib/hugin.lua:192
|
||||
msgid "hugin isn't available."
|
||||
msgstr "hugin não está disponível."
|
||||
|
||||
#: ../contrib/hugin.lua:197
|
||||
msgid "hugin failed ..."
|
||||
msgstr "hugin falhou..."
|
||||
|
||||
#: ../contrib/hugin.lua:203
|
||||
msgid "importing file "
|
||||
msgstr "importar arquivo "
|
||||
|
||||
#: ../contrib/hugin.lua:229
|
||||
msgid " launch hugin gui"
|
||||
msgstr " iniciar interface gráfica do hugin"
|
||||
|
||||
#: ../contrib/hugin.lua:231
|
||||
msgid "launch hugin in gui mode"
|
||||
msgstr "inicia o hugin no modo de interface gráfica"
|
||||
|
||||
#: ../contrib/hugin.lua:237
|
||||
msgid "hugin panorama"
|
||||
msgstr "hugin panorama"
|
||||
273
locale/pt_BR/LC_MESSAGES/image_stack.po
Normal file
273
locale/pt_BR/LC_MESSAGES/image_stack.po
Normal file
@@ -0,0 +1,273 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 23:35-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/image_stack.lua:96
|
||||
msgid "image align options"
|
||||
msgstr "opções de alinhamento da imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:100
|
||||
msgid "image stack options"
|
||||
msgstr "opções de empilhamento da imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:104
|
||||
msgid "executable locations"
|
||||
msgstr "localizações dos executáveis"
|
||||
|
||||
#: ../contrib/image_stack.lua:129
|
||||
msgid "perform image alignment"
|
||||
msgstr "realizar o alinhamento da imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:131
|
||||
msgid "align the image stack before processing"
|
||||
msgstr "alinha a pilha de imagem antes de processar"
|
||||
|
||||
#: ../contrib/image_stack.lua:135
|
||||
msgid "optimize radial distortion for all images"
|
||||
msgstr "otimizar a distorção radial para todas as imagens"
|
||||
|
||||
#: ../contrib/image_stack.lua:137
|
||||
msgid ""
|
||||
"optimize radial distortion for all images, \n"
|
||||
"except for first"
|
||||
msgstr ""
|
||||
"otimiza a distorção radial para todas as imagens,\n"
|
||||
"exceto para a primeira"
|
||||
|
||||
#: ../contrib/image_stack.lua:141
|
||||
msgid "optimize field of view for all images"
|
||||
msgstr "otimizar campo de visão para todas as imagens"
|
||||
|
||||
#: ../contrib/image_stack.lua:143
|
||||
msgid ""
|
||||
"optimize field of view for all images, except for first. \n"
|
||||
"Useful for aligning focus stacks (DFF) with slightly \n"
|
||||
"different magnification."
|
||||
msgstr ""
|
||||
"otimiza o campo de visão para todas as imagens, exceto para a primeira.\n"
|
||||
"Útil para alinhar o empilhamento de foco (DFF) com uma ampliação \n"
|
||||
"levemente diferente."
|
||||
|
||||
#: ../contrib/image_stack.lua:147
|
||||
msgid "optimize image center shift for all images"
|
||||
msgstr "otimizar o deslocamento do centro da imagem para todas as imagens"
|
||||
|
||||
#: ../contrib/image_stack.lua:149
|
||||
msgid ""
|
||||
"optimize image center shift for all images, \n"
|
||||
"except for first."
|
||||
msgstr ""
|
||||
"otimiza o deslocamento do centro da imagem para todas as imagens, \n"
|
||||
"exceto para a primeira."
|
||||
|
||||
#: ../contrib/image_stack.lua:153
|
||||
msgid "auto crop the image"
|
||||
msgstr "cortar automaticamente a imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:155
|
||||
msgid "auto crop the image to the area covered by all images."
|
||||
msgstr ""
|
||||
"corta automaticamente a imagem para a área coberta por todas as imagens."
|
||||
|
||||
#: ../contrib/image_stack.lua:159
|
||||
msgid "load distortion from lens database"
|
||||
msgstr "carregar a distorção a partir da base de dados de lentes"
|
||||
|
||||
#: ../contrib/image_stack.lua:161
|
||||
msgid "try to load distortion information from lens database"
|
||||
msgstr "tenta carregar as informações de distorção da base de dados de lentes"
|
||||
|
||||
#: ../contrib/image_stack.lua:165
|
||||
msgid "image grid size"
|
||||
msgstr "tamanho da grade da imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:166
|
||||
msgid ""
|
||||
"break image into a rectangular grid \n"
|
||||
"and attempt to find num control points in each section.\n"
|
||||
"default: (5x5)"
|
||||
msgstr ""
|
||||
"quebra a imagem em uma grade retangular \n"
|
||||
"e tenta encontrar o número de pontos de controle\n"
|
||||
"em cada seção.\n"
|
||||
"padrão: (5x5)"
|
||||
|
||||
#: ../contrib/image_stack.lua:175
|
||||
msgid "control points/grid"
|
||||
msgstr "grade/pontos de controle"
|
||||
|
||||
#: ../contrib/image_stack.lua:176
|
||||
msgid ""
|
||||
"number of control points (per grid, see option -g) \n"
|
||||
"to create between adjacent images \n"
|
||||
"default: (8)."
|
||||
msgstr ""
|
||||
"número de pontos de controle (por grade, veja a opção -g) \n"
|
||||
"a criar entre imagens adjacentes\n"
|
||||
"padrão: (8)"
|
||||
|
||||
#: ../contrib/image_stack.lua:185
|
||||
msgid "remove control points with error"
|
||||
msgstr "remover pontos de controle com erro"
|
||||
|
||||
#: ../contrib/image_stack.lua:186
|
||||
msgid ""
|
||||
"remove all control points with an error higher \n"
|
||||
"than num pixels \n"
|
||||
"default: (3)"
|
||||
msgstr ""
|
||||
"remove todos os pontos de controle com um erro maior \n"
|
||||
"que um número de pixels \n"
|
||||
"padrão: (3)"
|
||||
|
||||
#: ../contrib/image_stack.lua:195
|
||||
msgid "correlation threshold for control points"
|
||||
msgstr "limiar de correlação para pontos de controle"
|
||||
|
||||
#: ../contrib/image_stack.lua:196
|
||||
msgid ""
|
||||
"correlation threshold for identifying \n"
|
||||
"control points \n"
|
||||
"default: (0.9)."
|
||||
msgstr ""
|
||||
"limiar de correlação para identificar pontos\n"
|
||||
"de controle\n"
|
||||
"padrão: (0,9)"
|
||||
|
||||
#: ../contrib/image_stack.lua:205
|
||||
msgid "select stack function"
|
||||
msgstr "função de seleção de pilha"
|
||||
|
||||
#: ../contrib/image_stack.lua:206
|
||||
msgid ""
|
||||
"select function to be \n"
|
||||
"applied to image stack"
|
||||
msgstr ""
|
||||
"função de seleção a ser aplicada\n"
|
||||
"à pilha de imagens"
|
||||
|
||||
#: ../contrib/image_stack.lua:215
|
||||
msgid "select output format"
|
||||
msgstr "selecionar formato de saída"
|
||||
|
||||
#: ../contrib/image_stack.lua:216
|
||||
msgid "choose the format for the resulting image"
|
||||
msgstr "seleciona o formato para a imagem resultante"
|
||||
|
||||
#: ../contrib/image_stack.lua:224
|
||||
msgid "tag source images used?"
|
||||
msgstr "etiquetas das imagens fonte usadas?"
|
||||
|
||||
#: ../contrib/image_stack.lua:226
|
||||
msgid "tag the source images used to create the output file?"
|
||||
msgstr "etiquetas das imagens fonte usadas para criar o arquivo de saída?"
|
||||
|
||||
#: ../contrib/image_stack.lua:261
|
||||
#, lua-format
|
||||
msgid "Export Image %i/%i"
|
||||
msgstr "Exportar Imagem %i/%i"
|
||||
|
||||
#: ../contrib/image_stack.lua:454
|
||||
msgid "Unrecognized option to copy_image_attributes: "
|
||||
msgstr "Opção não reconhecida para copy_image_attributes: "
|
||||
|
||||
#: ../contrib/image_stack.lua:497
|
||||
msgid "ERROR: at least 2 images required for image stacking, exiting..."
|
||||
msgstr ""
|
||||
"ERRO: pelo menos 2 imagens são necessárias para empilhamento de imagens,"
|
||||
" saindo..."
|
||||
|
||||
#: ../contrib/image_stack.lua:498
|
||||
msgid " image(s) selected, at least 2 required"
|
||||
msgstr " imagem(ns) selecionada(s), pelo menos 2 necessárias"
|
||||
|
||||
#: ../contrib/image_stack.lua:512
|
||||
msgid "aligning images..."
|
||||
msgstr "alinhar imagens..."
|
||||
|
||||
#: ../contrib/image_stack.lua:515
|
||||
msgid "images aligned"
|
||||
msgstr "imagens alinhadas"
|
||||
|
||||
#: ../contrib/image_stack.lua:521
|
||||
msgid "ERROR: image alignment failed"
|
||||
msgstr "ERRO: alinhamento de imagem falhou"
|
||||
|
||||
#: ../contrib/image_stack.lua:522
|
||||
msgid "image alignment failed"
|
||||
msgstr "alinhamento de imagem falhou"
|
||||
|
||||
#: ../contrib/image_stack.lua:527
|
||||
msgid "ERROR: align_image_stack not found"
|
||||
msgstr "ERRO: align_image_stack não encontrado"
|
||||
|
||||
#: ../contrib/image_stack.lua:528
|
||||
msgid "align_image_stack not found"
|
||||
msgstr "align_image_stack não encontrado"
|
||||
|
||||
#: ../contrib/image_stack.lua:542
|
||||
msgid "convert command is "
|
||||
msgstr "comando convert é "
|
||||
|
||||
#: ../contrib/image_stack.lua:543
|
||||
msgid "processing image stack"
|
||||
msgstr "processar empilhamento de imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:546
|
||||
msgid "image stack processed"
|
||||
msgstr "empilhamento de imagem processado"
|
||||
|
||||
#: ../contrib/image_stack.lua:551
|
||||
msgid "importing result"
|
||||
msgstr "importar resultado"
|
||||
|
||||
#: ../contrib/image_stack.lua:556
|
||||
msgid "Created with|image_stack"
|
||||
msgstr "Criado com|image_stack"
|
||||
|
||||
#: ../contrib/image_stack.lua:569
|
||||
msgid "tagging source images"
|
||||
msgstr "etiquetando imagens fonte"
|
||||
|
||||
#: ../contrib/image_stack.lua:570
|
||||
msgid "Source file|"
|
||||
msgstr "Arquivo fonte |"
|
||||
|
||||
#: ../contrib/image_stack.lua:577
|
||||
msgid "ERROR: image stack processing failed"
|
||||
msgstr "ERRO: processamento de empilhamento de imagem falhou"
|
||||
|
||||
#: ../contrib/image_stack.lua:581
|
||||
msgid "ERROR: convert executable not found"
|
||||
msgstr "ERRO: executável do convert não encontrado"
|
||||
|
||||
#: ../contrib/image_stack.lua:582
|
||||
msgid "convert executable not found"
|
||||
msgstr "executável do convert não encontrado"
|
||||
|
||||
#: ../contrib/image_stack.lua:594
|
||||
msgid "align image stack: use GPU for remaping"
|
||||
msgstr "alinhar pilha de imagens: usar GPU para remapear"
|
||||
|
||||
#: ../contrib/image_stack.lua:595
|
||||
msgid "set the GPU remapping for image align"
|
||||
msgstr "definir o remapeamento de GPU para alinhamento de imagem"
|
||||
|
||||
#: ../contrib/image_stack.lua:598
|
||||
msgid "image stack"
|
||||
msgstr "empilhamento de imagem"
|
||||
244
locale/pt_BR/LC_MESSAGES/image_time.po
Normal file
244
locale/pt_BR/LC_MESSAGES/image_time.po
Normal file
@@ -0,0 +1,244 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:09-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/image_time.lua:177
|
||||
msgid "Error: 2 images must be selected"
|
||||
msgstr "Erro: 2 imagens devem ser selecionadas"
|
||||
|
||||
#: ../contrib/image_time.lua:230
|
||||
msgid "unable to detect exiv2"
|
||||
msgstr "não foi possível detectar exiv2"
|
||||
|
||||
#: ../contrib/image_time.lua:251 ../contrib/image_time.lua:268
|
||||
msgid "unable to get information for "
|
||||
msgstr "não foi possível obter informações para "
|
||||
|
||||
#: ../contrib/image_time.lua:316
|
||||
msgid "reset time: no images selected"
|
||||
msgstr "reiniciar tempo: nenhuma imagem selecionada"
|
||||
|
||||
#: ../contrib/image_time.lua:317
|
||||
msgid "please select the images that need their time reset"
|
||||
msgstr ""
|
||||
"por favor, selecione as imagens que precisam que seu tempo seja reiniciado"
|
||||
|
||||
#: ../contrib/image_time.lua:330 ../contrib/image_time.lua:355
|
||||
msgid "please select some images and try again"
|
||||
msgstr "por favor, selecione algumas imagens e tente novamente"
|
||||
|
||||
#: ../contrib/image_time.lua:334 ../contrib/image_time.lua:437
|
||||
#: ../contrib/image_time.lua:444
|
||||
msgid "subtract"
|
||||
msgstr "subtrair"
|
||||
|
||||
#: ../contrib/image_time.lua:407
|
||||
msgid "image time"
|
||||
msgstr "tempo da imagem"
|
||||
|
||||
#: ../contrib/image_time.lua:431
|
||||
msgid "years"
|
||||
msgstr "anos"
|
||||
|
||||
#: ../contrib/image_time.lua:431
|
||||
msgid "years to adjust by, 0 - ?"
|
||||
msgstr "anos a ajustar, 0 - ?"
|
||||
|
||||
#: ../contrib/image_time.lua:432
|
||||
msgid "months"
|
||||
msgstr "meses"
|
||||
|
||||
#: ../contrib/image_time.lua:433
|
||||
msgid "days"
|
||||
msgstr "dias"
|
||||
|
||||
#: ../contrib/image_time.lua:434
|
||||
msgid "hours"
|
||||
msgstr "horas"
|
||||
|
||||
#: ../contrib/image_time.lua:434
|
||||
msgid "hours to adjust by, 0-23"
|
||||
msgstr "horas a ajustar, 0-23"
|
||||
|
||||
#: ../contrib/image_time.lua:435
|
||||
msgid "minutes"
|
||||
msgstr "minutos"
|
||||
|
||||
#: ../contrib/image_time.lua:435
|
||||
msgid "minutes to adjust by, 0-59"
|
||||
msgstr "minutos a ajustar, 0-59"
|
||||
|
||||
#: ../contrib/image_time.lua:436 ../contrib/image_time.lua:443
|
||||
msgid "seconds"
|
||||
msgstr "segundos"
|
||||
|
||||
#: ../contrib/image_time.lua:436
|
||||
msgid "seconds to adjust by, 0-59"
|
||||
msgstr "segundos a ajustar, 0-59"
|
||||
|
||||
#: ../contrib/image_time.lua:437 ../contrib/image_time.lua:444
|
||||
msgid "add/subtract"
|
||||
msgstr "adicionar/subtrair"
|
||||
|
||||
#: ../contrib/image_time.lua:437 ../contrib/image_time.lua:444
|
||||
msgid "add or subtract time"
|
||||
msgstr "adicionar ou subtrair tempo"
|
||||
|
||||
#: ../contrib/image_time.lua:437 ../contrib/image_time.lua:444
|
||||
msgid "add"
|
||||
msgstr "adicionar"
|
||||
|
||||
#: ../contrib/image_time.lua:438
|
||||
msgid "year"
|
||||
msgstr "ano"
|
||||
|
||||
#: ../contrib/image_time.lua:438
|
||||
msgid "year to set, 1900 - now"
|
||||
msgstr "ano a definir, 1900 - agora"
|
||||
|
||||
#: ../contrib/image_time.lua:439
|
||||
msgid "month"
|
||||
msgstr "mês"
|
||||
|
||||
#: ../contrib/image_time.lua:439
|
||||
msgid "month to set, 1-12"
|
||||
msgstr "mês a definir, 1-12"
|
||||
|
||||
#: ../contrib/image_time.lua:440
|
||||
msgid "day"
|
||||
msgstr "dia"
|
||||
|
||||
#: ../contrib/image_time.lua:440
|
||||
msgid "day to set, 1-31"
|
||||
msgstr "dia a definir, 1-31"
|
||||
|
||||
#: ../contrib/image_time.lua:441
|
||||
msgid "hour"
|
||||
msgstr "hora"
|
||||
|
||||
#: ../contrib/image_time.lua:441
|
||||
msgid "hour to set, 0-23"
|
||||
msgstr "hora a definir, 0-23"
|
||||
|
||||
#: ../contrib/image_time.lua:442
|
||||
msgid "minute"
|
||||
msgstr "minuto"
|
||||
|
||||
#: ../contrib/image_time.lua:442
|
||||
msgid "minutes to set, 0-59"
|
||||
msgstr "minuto a definir, 0-59"
|
||||
|
||||
#: ../contrib/image_time.lua:443
|
||||
msgid "seconds to set, 0-59"
|
||||
msgstr "segundos a definir, 0-59"
|
||||
|
||||
#: ../contrib/image_time.lua:459
|
||||
msgid "Time difference between images in seconds"
|
||||
msgstr "Diferença de tempo entre as imagens em segundos"
|
||||
|
||||
#: ../contrib/image_time.lua:460
|
||||
msgid "Select 2 images and use the calculate button"
|
||||
msgstr "Selecione 2 imagens e use o botão para calcular"
|
||||
|
||||
#: ../contrib/image_time.lua:465
|
||||
msgid "Calculate"
|
||||
msgstr "Calcular"
|
||||
|
||||
#: ../contrib/image_time.lua:466
|
||||
msgid "calculate time difference between 2 images"
|
||||
msgstr "calcula a diferença de tempo entre 2 imagens"
|
||||
|
||||
#: ../contrib/image_time.lua:473
|
||||
msgid "synchronize image times"
|
||||
msgstr "sincronizar tempos da imagem"
|
||||
|
||||
#: ../contrib/image_time.lua:474
|
||||
msgid "apply the time difference from selected images"
|
||||
msgstr "aplica a diferença de tempo a partir das imagens selecionadas"
|
||||
|
||||
#: ../contrib/image_time.lua:484 ../contrib/image_time.lua:550
|
||||
msgid "adjust time"
|
||||
msgstr "ajustar tempo"
|
||||
|
||||
#: ../contrib/image_time.lua:485
|
||||
msgid "days, months, years"
|
||||
msgstr "dias, meses, anos"
|
||||
|
||||
#: ../contrib/image_time.lua:489
|
||||
msgid "hours, minutes, seconds"
|
||||
msgstr "horas, minutos, segundos"
|
||||
|
||||
#: ../contrib/image_time.lua:493
|
||||
msgid "adjustment direction"
|
||||
msgstr "direção de ajuste"
|
||||
|
||||
#: ../contrib/image_time.lua:496
|
||||
msgid "adjust"
|
||||
msgstr "ajustar"
|
||||
|
||||
#: ../contrib/image_time.lua:504 ../contrib/image_time.lua:551
|
||||
msgid "set time"
|
||||
msgstr "definir tempo"
|
||||
|
||||
#: ../contrib/image_time.lua:505
|
||||
msgid "date: "
|
||||
msgstr "data: "
|
||||
|
||||
#: ../contrib/image_time.lua:509
|
||||
msgid "time:"
|
||||
msgstr "tempo: "
|
||||
|
||||
#: ../contrib/image_time.lua:514
|
||||
msgid "set"
|
||||
msgstr "definir"
|
||||
|
||||
#: ../contrib/image_time.lua:522
|
||||
msgid "synchronize image time"
|
||||
msgstr "sincronizar tempo da imagem"
|
||||
|
||||
#: ../contrib/image_time.lua:523
|
||||
msgid "calculate difference between images"
|
||||
msgstr "calcular a diferença entre imagens"
|
||||
|
||||
#: ../contrib/image_time.lua:526
|
||||
msgid "apply difference"
|
||||
msgstr "aplicar diferença"
|
||||
|
||||
#: ../contrib/image_time.lua:532
|
||||
msgid "reset to original time"
|
||||
msgstr "reiniciar para o tempo original"
|
||||
|
||||
#: ../contrib/image_time.lua:535
|
||||
msgid "reset"
|
||||
msgstr "reiniciar"
|
||||
|
||||
#: ../contrib/image_time.lua:544
|
||||
msgid "mode"
|
||||
msgstr "modo"
|
||||
|
||||
#: ../contrib/image_time.lua:545
|
||||
msgid "select mode"
|
||||
msgstr "selecionar modo"
|
||||
|
||||
#: ../contrib/image_time.lua:552
|
||||
msgid "synchronize time"
|
||||
msgstr "sincronizar tempo"
|
||||
|
||||
#: ../contrib/image_time.lua:553
|
||||
msgid "reset time"
|
||||
msgstr "reiniciar tempo"
|
||||
90
locale/pt_BR/LC_MESSAGES/kml_export.po
Normal file
90
locale/pt_BR/LC_MESSAGES/kml_export.po
Normal file
@@ -0,0 +1,90 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:14-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/kml_export.lua:64
|
||||
#, lua-format
|
||||
msgid "Export Image %i/%i"
|
||||
msgstr "Exportar Imagem %i/%i"
|
||||
|
||||
#: ../contrib/kml_export.lua:91
|
||||
msgid "magick not found"
|
||||
msgstr "magick não encontrado"
|
||||
|
||||
#: ../contrib/kml_export.lua:96
|
||||
msgid "xdg-user-dir not found"
|
||||
msgstr "xdg-user-dir não encontrado"
|
||||
|
||||
#: ../contrib/kml_export.lua:106
|
||||
msgid "zip not found"
|
||||
msgstr "zip não encontrado"
|
||||
|
||||
#: ../contrib/kml_export.lua:321
|
||||
msgid "KML export: Open KML file after export"
|
||||
msgstr "exportar KML: Abrir arquivo Open KML após a exportação"
|
||||
|
||||
#: ../contrib/kml_export.lua:322 ../contrib/kml_export.lua:329
|
||||
msgid ""
|
||||
"Opens the KML file after the export with the standard program for KML files"
|
||||
msgstr ""
|
||||
"Abre o arquivo KML após a exportação com o programa padrão para arquivos KML"
|
||||
|
||||
#: ../contrib/kml_export.lua:328
|
||||
msgid "KML export: Open KML/KMZ file after export"
|
||||
msgstr "exportar KML: Abre arquivo KML/KMZ após a exportação"
|
||||
|
||||
#: ../contrib/kml_export.lua:348
|
||||
msgid "KML export: Export directory"
|
||||
msgstr "exportar KML: Pasta de exportação"
|
||||
|
||||
#: ../contrib/kml_export.lua:349
|
||||
msgid "A directory that will be used to export the KML/KMZ files"
|
||||
msgstr "Uma pasta que será usada para exportar os arquivos KML/KMZ"
|
||||
|
||||
#: ../contrib/kml_export.lua:356
|
||||
msgid "KML export: ImageMagick binary Location"
|
||||
msgstr "exportar KML: Localização do binário do ImageMagick"
|
||||
|
||||
#: ../contrib/kml_export.lua:357
|
||||
msgid "Install location of magick[.exe]. Requires restart to take effect."
|
||||
msgstr ""
|
||||
"Localização de instalação do magick[.exe]. Precisa reiniciar para ter efeito."
|
||||
|
||||
#: ../contrib/kml_export.lua:364
|
||||
msgid "KML export: Connect images with path"
|
||||
msgstr "exportar KML: Conectar imagens com caminho"
|
||||
|
||||
#: ../contrib/kml_export.lua:365
|
||||
msgid "connect all images with a path"
|
||||
msgstr "conecta todas as imagens com um caminho"
|
||||
|
||||
#: ../contrib/kml_export.lua:372
|
||||
msgid "KML export: Create KMZ file"
|
||||
msgstr "exportar KML: Criar arquivo KMZ"
|
||||
|
||||
#: ../contrib/kml_export.lua:373
|
||||
msgid "Compress all imeges to one KMZ file"
|
||||
msgstr "Comprime todas as imagens para um arquivo KMZ"
|
||||
|
||||
#: ../contrib/kml_export.lua:379
|
||||
msgid "KML Export"
|
||||
msgstr "Exportar KML"
|
||||
|
||||
#: ../contrib/kml_export.lua:381
|
||||
msgid "KML/KMZ Export"
|
||||
msgstr "Exportar KML/KMZ"
|
||||
22
locale/pt_BR/LC_MESSAGES/passport_guide.po
Normal file
22
locale/pt_BR/LC_MESSAGES/passport_guide.po
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-01 19:26-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/passport_guide.lua:90
|
||||
msgid "ISO 19794-5/ICAO 9309 passport"
|
||||
msgstr "passaporte ISO 19794-5/ICAO 9309"
|
||||
70
locale/pt_BR/LC_MESSAGES/pdf_slideshow.po
Normal file
70
locale/pt_BR/LC_MESSAGES/pdf_slideshow.po
Normal file
@@ -0,0 +1,70 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:16-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:55
|
||||
msgid "pdflatex not found"
|
||||
msgstr "pdflatex não encontrado"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:71
|
||||
msgid "a pdf viewer"
|
||||
msgstr "um visualizador de pdf"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:72
|
||||
msgid "can be an absolute pathname or the tool may be in the PATH"
|
||||
msgstr "pode ser um caminho absoluto ou a ferramenta pode estar no PATH"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:76 ../contrib/pdf_slideshow.lua:103
|
||||
msgid "slideshow title"
|
||||
msgstr "título da apresentação"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:80
|
||||
msgid "transition delay (s)"
|
||||
msgstr "atraso da transição (s)"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:91
|
||||
msgid "include image title"
|
||||
msgstr "incluir título da imagem"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:93
|
||||
msgid "whether to include the image title (if defined) into the slide"
|
||||
msgstr "se deve ser incluído o título da imagem (se definido) no slide"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:97
|
||||
msgid "include image author"
|
||||
msgstr "incluir autor da imagem"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:99
|
||||
msgid "whether to include the image author (if defined) into the slide"
|
||||
msgstr "se deve ser incluído o autor da imagem (se definido) no slide"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:179
|
||||
msgid "pdf slideshow"
|
||||
msgstr "apresentação do pdf"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:232
|
||||
msgid "problem running pdflatex"
|
||||
msgstr "problema ao executar o pdflatex"
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:233 ../contrib/pdf_slideshow.lua:243
|
||||
msgid "problem running "
|
||||
msgstr "problema ao executar "
|
||||
|
||||
#: ../contrib/pdf_slideshow.lua:242
|
||||
msgid "problem running pdf viewer"
|
||||
msgstr "problema ao executar o visualizador de pdf"
|
||||
118
locale/pt_BR/LC_MESSAGES/photils.po
Normal file
118
locale/pt_BR/LC_MESSAGES/photils.po
Normal file
@@ -0,0 +1,118 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:22-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/photils.lua:117
|
||||
msgid "get tags"
|
||||
msgstr "obter etiquetas"
|
||||
|
||||
#: ../contrib/photils.lua:148
|
||||
msgid "requires a restart to be applied"
|
||||
msgstr "precisa reiniciar para ser aplicado"
|
||||
|
||||
#: ../contrib/photils.lua:163
|
||||
msgid "min confidence value"
|
||||
msgstr "valor mín de confiança"
|
||||
|
||||
#: ../contrib/photils.lua:180
|
||||
msgid ""
|
||||
"The suggested tags were not generated\n"
|
||||
" for the currently selected image!"
|
||||
msgstr ""
|
||||
"As etiquetas sugeridas não serão geradas\n"
|
||||
"para a imagem atualmente selecionada!"
|
||||
|
||||
#: ../contrib/photils.lua:186
|
||||
#, lua-format
|
||||
msgid " page %s of %s "
|
||||
msgstr " página %s de %s "
|
||||
|
||||
#: ../contrib/photils.lua:237
|
||||
msgid "Apply tag to image"
|
||||
msgstr "Aplicar etiqueta à imagem"
|
||||
|
||||
#: ../contrib/photils.lua:249
|
||||
msgid "Tags successfully attached to image"
|
||||
msgstr "Etiquetas anexadas com sucesso à imagem"
|
||||
|
||||
#: ../contrib/photils.lua:299
|
||||
#, lua-format
|
||||
msgid "%s found %d tags for your image"
|
||||
msgstr "%s encontrado %d etiquetas para sua imagem"
|
||||
|
||||
#: ../contrib/photils.lua:315
|
||||
msgid "No image selected."
|
||||
msgstr "Nenhuma imagem selecionada."
|
||||
|
||||
#: ../contrib/photils.lua:319
|
||||
msgid "This plugin can only handle a single image."
|
||||
msgstr "Este plugin pode manipular somente uma imagem por vez."
|
||||
|
||||
#: ../contrib/photils.lua:326
|
||||
#, lua-format
|
||||
msgid "%s failed, see terminal output for details"
|
||||
msgstr "%s falhou, veja a saída do terminal para detalhes"
|
||||
|
||||
#: ../contrib/photils.lua:334
|
||||
#, lua-format
|
||||
msgid "no tags where found"
|
||||
msgstr "nenhuma etiqueta encontrada"
|
||||
|
||||
#: ../contrib/photils.lua:365
|
||||
#, lua-format
|
||||
msgid "attach %d tags"
|
||||
msgstr "anexar %d etiquetas"
|
||||
|
||||
#: ../contrib/photils.lua:429 ../contrib/photils.lua:430
|
||||
msgid "photils-cli not found"
|
||||
msgstr "photils-cli não encontrado"
|
||||
|
||||
#: ../contrib/photils.lua:432
|
||||
msgid ""
|
||||
"Select an image, click \"get tags\" and get \n"
|
||||
"suggestions for tags."
|
||||
msgstr ""
|
||||
"Selecione uma imagem, clique em \"obter etiquetas\"\n"
|
||||
"e obtenha sugestões para etiquetas."
|
||||
|
||||
#: ../contrib/photils.lua:467
|
||||
msgid "photils: show confidence value"
|
||||
msgstr "photils: mostrar valor de confiança"
|
||||
|
||||
#: ../contrib/photils.lua:468
|
||||
msgid "if enabled, the confidence value for each tag is displayed"
|
||||
msgstr "se ativo, o valor de confiança para cada etiqueta é exibido"
|
||||
|
||||
#: ../contrib/photils.lua:474
|
||||
msgid "photils: use exported image for tag request"
|
||||
msgstr "photils: usar imagem exportada para pedido de etiqueta"
|
||||
|
||||
#: ../contrib/photils.lua:475
|
||||
msgid ""
|
||||
"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."
|
||||
msgstr ""
|
||||
"Se ativo, a imagem passada para o photils para a sugestão de etiquetas é"
|
||||
" baseada na "
|
||||
"exportada, a imagem já editada. Caso contrário, a miniatura embutida no"
|
||||
" arquivo RAW "
|
||||
"será usada para sugestão de etiquetas. A miniatura embutida pode acelerar a"
|
||||
" sugestão "
|
||||
"de etiqueta mas pode falhar se o arquivo RAW não for suportado."
|
||||
82
locale/pt_BR/LC_MESSAGES/quicktag.po
Normal file
82
locale/pt_BR/LC_MESSAGES/quicktag.po
Normal file
@@ -0,0 +1,82 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:25-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/quicktag.lua:78
|
||||
msgid "max. length of button labels"
|
||||
msgstr "comprimento máximo dos rótulos de botão"
|
||||
|
||||
#: ../contrib/quicktag.lua:79
|
||||
msgid "may range from 15 to 60 - needs a restart"
|
||||
msgstr "pode ir de 16 à 60 - precisa reiniciar"
|
||||
|
||||
#: ../contrib/quicktag.lua:92
|
||||
msgid "number of quicktag fields"
|
||||
msgstr "número de campos de quicktag"
|
||||
|
||||
#: ../contrib/quicktag.lua:93
|
||||
msgid "may range from 2 to 20 - needs a restart"
|
||||
msgstr "pode ir de 2 à 20 - precisa reiniciar"
|
||||
|
||||
#: ../contrib/quicktag.lua:133
|
||||
#, lua-format
|
||||
msgid "quicktag %i is empty, please set a tag"
|
||||
msgstr "quicktag %i está vazio, por favor defina uma etiqueta"
|
||||
|
||||
#: ../contrib/quicktag.lua:148
|
||||
msgid "no images selected"
|
||||
msgstr "nenhuma imagem selecionada"
|
||||
|
||||
#: ../contrib/quicktag.lua:158
|
||||
#, lua-format
|
||||
msgid "tag \"%s\" attached to %i image(s)"
|
||||
msgstr "etiqueta \"%s\" anexada a %i imagem(ns)"
|
||||
|
||||
#: ../contrib/quicktag.lua:179
|
||||
msgid "old tag"
|
||||
msgstr "etiqueta antiga"
|
||||
|
||||
#: ../contrib/quicktag.lua:180
|
||||
msgid "select the quicktag to replace"
|
||||
msgstr "selecione a quicktag para substituir"
|
||||
|
||||
#: ../contrib/quicktag.lua:225 ../contrib/quicktag.lua:303
|
||||
#, lua-format
|
||||
msgid "quicktag %i"
|
||||
msgstr "quicktag %i"
|
||||
|
||||
#: ../contrib/quicktag.lua:240 ../contrib/quicktag.lua:264
|
||||
msgid "new tag"
|
||||
msgstr "nova etiqueta"
|
||||
|
||||
#: ../contrib/quicktag.lua:243
|
||||
msgid "enter your tag here"
|
||||
msgstr "insira sua etiqueta aqui"
|
||||
|
||||
#: ../contrib/quicktag.lua:247
|
||||
msgid "set tag"
|
||||
msgstr "definir etiqueta"
|
||||
|
||||
#: ../contrib/quicktag.lua:251
|
||||
msgid "new quicktag is empty!"
|
||||
msgstr "nova quicktag está vazia!"
|
||||
|
||||
#: ../contrib/quicktag.lua:255
|
||||
#, lua-format
|
||||
msgid "quicktag \"%s\" replaced by \"%s\""
|
||||
msgstr "quicktag \"%s\" substituída por \"%s\""
|
||||
234
locale/pt_BR/LC_MESSAGES/rename_images.po
Normal file
234
locale/pt_BR/LC_MESSAGES/rename_images.po
Normal file
@@ -0,0 +1,234 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:45-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:123
|
||||
msgid "unrecognized variable "
|
||||
msgstr "variável não reconhecida "
|
||||
|
||||
#: ../contrib/rename_images.lua:124
|
||||
msgid "unknown variable "
|
||||
msgstr "variável desconhecida "
|
||||
|
||||
#: ../contrib/rename_images.lua:143
|
||||
msgid "rename images"
|
||||
msgstr "renomear imagens"
|
||||
|
||||
#: ../contrib/rename_images.lua:175
|
||||
msgid "pattern is "
|
||||
msgstr "padrão é "
|
||||
|
||||
#: ../contrib/rename_images.lua:179
|
||||
msgid "renaming images"
|
||||
msgstr "renomeando images"
|
||||
|
||||
#: ../contrib/rename_images.lua:186
|
||||
msgid "unable to do variable substitution, exiting..."
|
||||
msgstr "não foi possível a substituição de variável, saindo..."
|
||||
|
||||
#: ../contrib/rename_images.lua:215
|
||||
msgid "renamed "
|
||||
msgstr "renomeado "
|
||||
|
||||
#: ../contrib/rename_images.lua:218
|
||||
msgid "please enter the new name or pattern"
|
||||
msgstr "por favor, insira o novo nome ou padrão"
|
||||
|
||||
#: ../contrib/rename_images.lua:222
|
||||
msgid "please select some images and try again"
|
||||
msgstr "por favor, selecione algumas imagens e tente novamente"
|
||||
|
||||
#: ../contrib/rename_images.lua:235
|
||||
msgid "$(ROLL_NAME) - film roll name\n"
|
||||
msgstr "$(ROLL_NAME) - nome do rolo de filme\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:236
|
||||
msgid "$(FILE_FOLDER) - image file folder\n"
|
||||
msgstr "$(FILE_FOLDER) - pasta do arquivo de imagem\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:237
|
||||
msgid "$(FILE_NAME) - image file name\n"
|
||||
msgstr "$(FILE_NAME) - nome do arquivo de imagem\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:238
|
||||
msgid "$(FILE_EXTENSION) - image file extension\n"
|
||||
msgstr "$(FILE_EXTENSION) - extensão do arquivo de imagem\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:239
|
||||
msgid "$(ID) - image id\n"
|
||||
msgstr "$(ID) - id da imagem\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:240
|
||||
msgid "$(VERSION) - version number\n"
|
||||
msgstr "$(VERSION) - número de versão\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:241
|
||||
msgid "$(SEQUENCE) - sequence number of selection\n"
|
||||
msgstr "$(SEQUENCE) - número de sequência da seleção\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:242
|
||||
msgid "$(YEAR) - current year\n"
|
||||
msgstr "$(YEAR) - ano atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:243
|
||||
msgid "$(MONTH) - current month\n"
|
||||
msgstr "$(MONTH) - mês atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:244
|
||||
msgid "$(DAY) - current day\n"
|
||||
msgstr "$(DAY) - dia atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:245
|
||||
msgid "$(HOUR) - current hour\n"
|
||||
msgstr "$(HOUR) - hora atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:246
|
||||
msgid "$(MINUTE) - current minute\n"
|
||||
msgstr "$(MINUTE) - minuto atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:247
|
||||
msgid "$(SECOND) - current second\n"
|
||||
msgstr "$(SECOND) - segundo atual\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:248
|
||||
msgid "$(EXIF_YEAR) - EXIF year\n"
|
||||
msgstr "$(EXIF_YEAR) - ano EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:249
|
||||
msgid "$(EXIF_MONTH) - EXIF month\n"
|
||||
msgstr "$(EXIF_MONTH) - mês EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:250
|
||||
msgid "$(EXIF_DAY) - EXIF day\n"
|
||||
msgstr "$(EXIF_DAY) - dia EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:251
|
||||
msgid "$(EXIF_HOUR) - EXIF hour\n"
|
||||
msgstr "$(EXIF_HOUR) - hora EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:252
|
||||
msgid "$(EXIF_MINUTE) - EXIF minute\n"
|
||||
msgstr "$(EXIF_MINUTE) - minuto EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:253
|
||||
msgid "$(EXIF_SECOND) - EXIF seconds\n"
|
||||
msgstr "$(EXIF_SECOND) - segundo EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:254
|
||||
msgid "$(EXIF_ISO) - EXIF ISO\n"
|
||||
msgstr "$(EXIF_ISO) - ISO EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:255
|
||||
msgid "$(EXIF_EXPOSURE) - EXIF exposure\n"
|
||||
msgstr "$(EXIF_EXPOSURE) - exposição EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:256
|
||||
msgid "$(EXIF_EXPOSURE_BIAS) - EXIF exposure bias\n"
|
||||
msgstr "$(EXIF_EXPOSURE_BIAS) - viés de exposição EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:257
|
||||
msgid "$(EXIF_APERTURE) - EXIF aperture\n"
|
||||
msgstr "$(EXIF_APERTURE) - abertura EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:258
|
||||
msgid "$(EXIF_FOCAL_LENGTH) - EXIF focal length\n"
|
||||
msgstr "$(EXIF_FOCAL_LENGTH) - distância focal EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:259
|
||||
msgid "$(EXIF_FOCUS_DISTANCE) - EXIF focus distance\n"
|
||||
msgstr "$(EXIF_FOCUS_DISTANCE) - distância do foco EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:260
|
||||
msgid "$(EXIF_CROP) - EXIF crop\n"
|
||||
msgstr "$(EXIF_CROP) - corte EXIF\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:261
|
||||
msgid "$(LONGITUDE) - longitude\n"
|
||||
msgstr "$(LONGITUDE) - longitude\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:262
|
||||
msgid "$(LATITUDE) - latitude\n"
|
||||
msgstr "$(LATITUDE) - latitude\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:263
|
||||
msgid "$(ELEVATION) - elevation\n"
|
||||
msgstr "$(ELEVATION) - elevação\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:264
|
||||
msgid "$(STARS) - star rating\n"
|
||||
msgstr "$(STARS) - classificação de estrelas\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:265
|
||||
msgid "$(LABELS) - color labels\n"
|
||||
msgstr "$(LABELS) - etiquetas de cor\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:266
|
||||
msgid "$(MAKER) - camera maker\n"
|
||||
msgstr "$(MAKER) - fabricante da câmera\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:267
|
||||
msgid "$(MODEL) - camera model\n"
|
||||
msgstr "$(MODEL) - modelo da câmera\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:268
|
||||
msgid "$(LENS) - lens\n"
|
||||
msgstr "$(LENS) - lente\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:269
|
||||
msgid "$(TITLE) - title from metadata\n"
|
||||
msgstr "$(TITLE) - título a partir dos metadados\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:270
|
||||
msgid "$(DESCRIPTION) - description from metadata\n"
|
||||
msgstr "$(DESCRIPTION) - descrição a partir dos metadados\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:271
|
||||
msgid "$(CREATOR) - creator from metadata\n"
|
||||
msgstr "$(CREATOR) - autor a partir dos metadados\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:272
|
||||
msgid "$(PUBLISHER) - publisher from metadata\n"
|
||||
msgstr "$(PUBLISHER) - editor a partir dos metadados\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:273
|
||||
msgid "$(RIGHTS) - rights from metadata\n"
|
||||
msgstr "$(RIGHTS) - direitos autorais a partir dos metadados\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:274
|
||||
msgid "$(USERNAME) - username\n"
|
||||
msgstr "$(USERNAME) - nome do usuário\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:275
|
||||
msgid "$(PICTURES_FOLDER) - pictures folder\n"
|
||||
msgstr "$(PICTURES_FOLDER) - pasta de imagens\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:276
|
||||
msgid "$(HOME) - user's home directory\n"
|
||||
msgstr "$(HOME) - pasta pessoal do usuário\n"
|
||||
|
||||
#: ../contrib/rename_images.lua:277
|
||||
msgid "$(DESKTOP) - desktop directory"
|
||||
msgstr "$(DESKTOP) - pasta da área de trabalho"
|
||||
|
||||
#: ../contrib/rename_images.lua:278
|
||||
msgid "enter pattern $(FILE_FOLDER)/$(FILE_NAME)"
|
||||
msgstr "insira o padrão $(FILE_FOLDER)/$(FILE_NAME)"
|
||||
|
||||
#: ../contrib/rename_images.lua:288
|
||||
msgid "rename"
|
||||
msgstr "renomear"
|
||||
199
locale/pt_BR/LC_MESSAGES/script_manager.po
Normal file
199
locale/pt_BR/LC_MESSAGES/script_manager.po
Normal file
@@ -0,0 +1,199 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 11:49-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:41-0300\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: script_manager.lua:314
|
||||
msgid "Cant read from "
|
||||
msgstr "Não foi possível ler de "
|
||||
|
||||
#: script_manager.lua:332
|
||||
msgid "Loaded "
|
||||
msgstr "Carregado "
|
||||
|
||||
#: script_manager.lua:344
|
||||
msgid " failed to load"
|
||||
msgstr " falhou ao carregar"
|
||||
|
||||
#: script_manager.lua:379 script_manager.lua:634 script_manager.lua:657
|
||||
msgid " stopped"
|
||||
msgstr " parado"
|
||||
|
||||
#: script_manager.lua:383
|
||||
msgid " will not start when darktable is restarted"
|
||||
msgstr " não iniciará quando o darktable for reiniciado"
|
||||
|
||||
#: script_manager.lua:443 script_manager.lua:507
|
||||
msgid "find command is "
|
||||
msgstr "encontrar comando é "
|
||||
|
||||
#: script_manager.lua:469 script_manager.lua:553
|
||||
msgid ""
|
||||
"ERROR: git not found. Install or specify the location of the git executable."
|
||||
msgstr ""
|
||||
"ERRO: git não encontrado. Instale ou defina a localização do executável do"
|
||||
" git."
|
||||
|
||||
#: script_manager.lua:483
|
||||
msgid "lua scripts successfully updated"
|
||||
msgstr "scripts lua atualizados com sucesso"
|
||||
|
||||
#: script_manager.lua:543
|
||||
msgid "category "
|
||||
msgstr "categoria "
|
||||
|
||||
#: script_manager.lua:543
|
||||
msgid " is already in use. Please specify a different category name."
|
||||
msgstr " já está em uso. Por favor, defina um nome de categoria diferente."
|
||||
|
||||
#: script_manager.lua:572
|
||||
msgid "scripts successfully installed into category "
|
||||
msgstr "scripts instalados com sucesso na categoria "
|
||||
|
||||
#: script_manager.lua:588
|
||||
msgid "No scripts found to install"
|
||||
msgstr "Nenhum script para instalação encontrado"
|
||||
|
||||
#: script_manager.lua:592
|
||||
msgid "failed to download scripts"
|
||||
msgstr "falha ao baixar scripts"
|
||||
|
||||
#: script_manager.lua:627
|
||||
msgid " started"
|
||||
msgstr " iniciado"
|
||||
|
||||
#: script_manager.lua:732
|
||||
msgid "Page "
|
||||
msgstr "Página "
|
||||
|
||||
#: script_manager.lua:732
|
||||
msgid " of "
|
||||
msgstr " de "
|
||||
|
||||
#: script_manager.lua:934
|
||||
msgid "scripts to update"
|
||||
msgstr "scripts a atualizar"
|
||||
|
||||
#: script_manager.lua:935
|
||||
msgid "select the scripts installation to update"
|
||||
msgstr "selecione as instalações de scripts a atualizar"
|
||||
|
||||
#: script_manager.lua:944 script_manager.lua:1002
|
||||
msgid "update scripts"
|
||||
msgstr "atualizar scripts"
|
||||
|
||||
#: script_manager.lua:945
|
||||
msgid "update the lua scripts from the repository"
|
||||
msgstr "atualizar os scripts lua a partir do repositório"
|
||||
|
||||
#: script_manager.lua:956
|
||||
msgid ""
|
||||
"enter the URL of the git repository containing the scripts you wish to add"
|
||||
msgstr ""
|
||||
"insira a URL do repositório git contendo os scripts que deseja adicionar"
|
||||
|
||||
#: script_manager.lua:961
|
||||
msgid "name of new category"
|
||||
msgstr "nome da nova categoria"
|
||||
|
||||
#: script_manager.lua:962
|
||||
msgid "enter a category name for the additional scripts"
|
||||
msgstr "insira um nome de categoria para os scripts adicionais"
|
||||
|
||||
#: script_manager.lua:967
|
||||
msgid "URL to download additional scripts from"
|
||||
msgstr "URL da qual baixar os scripts adicionais"
|
||||
|
||||
#: script_manager.lua:969
|
||||
msgid "new category to place scripts in"
|
||||
msgstr "nova categoria para colocar os scripts"
|
||||
|
||||
#: script_manager.lua:972
|
||||
msgid "install additional scripts"
|
||||
msgstr "instalar scripts adicionais"
|
||||
|
||||
#: script_manager.lua:980
|
||||
msgid "Enable \"Disable Scripts\" button"
|
||||
msgstr "Ativar botão \"Desabilitar Scripts\""
|
||||
|
||||
#: script_manager.lua:990
|
||||
msgid "Disable Scripts"
|
||||
msgstr "Desabilitar Scripts"
|
||||
|
||||
#: script_manager.lua:996
|
||||
msgid "lua scripts will not run the next time darktable is started"
|
||||
msgstr "scripts lua não rodarão na próxima vez que o darktable for iniciado"
|
||||
|
||||
#: script_manager.lua:1005
|
||||
msgid "add more scripts"
|
||||
msgstr "adicionar mais scripts"
|
||||
|
||||
#: script_manager.lua:1007
|
||||
msgid "disable scripts"
|
||||
msgstr "desabilitar scripts"
|
||||
|
||||
#: script_manager.lua:1015
|
||||
msgid "category"
|
||||
msgstr "categoria"
|
||||
|
||||
#: script_manager.lua:1016
|
||||
msgid "select the script category"
|
||||
msgstr "selecione a categoria do script"
|
||||
|
||||
#: script_manager.lua:1036
|
||||
msgid "Page:"
|
||||
msgstr "Página:"
|
||||
|
||||
#: script_manager.lua:1064
|
||||
msgid "Scripts"
|
||||
msgstr "Scripts"
|
||||
|
||||
#: script_manager.lua:1073
|
||||
msgid "scripts per page"
|
||||
msgstr "scripts por página"
|
||||
|
||||
#: script_manager.lua:1074
|
||||
msgid "select number of start/stop buttons to display"
|
||||
msgstr "selecione o número de botões de iniciar/parar a exibir"
|
||||
|
||||
#: script_manager.lua:1085
|
||||
msgid "change number of buttons"
|
||||
msgstr "mudar o número de botões"
|
||||
|
||||
#: script_manager.lua:1093
|
||||
msgid "Configuration"
|
||||
msgstr "Configuração"
|
||||
|
||||
#: script_manager.lua:1099
|
||||
msgid "use color interface?"
|
||||
msgstr "usar interface colorida?"
|
||||
|
||||
#: script_manager.lua:1122
|
||||
msgid "action"
|
||||
msgstr "ação"
|
||||
|
||||
#: script_manager.lua:1128
|
||||
msgid "install/update scripts"
|
||||
msgstr "instalar/atualizar scripts"
|
||||
|
||||
#: script_manager.lua:1128
|
||||
msgid "configure"
|
||||
msgstr "configurar"
|
||||
|
||||
#: script_manager.lua:1128
|
||||
msgid "start/stop scripts"
|
||||
msgstr "iniciar/parar scripts"
|
||||
32
locale/pt_BR/LC_MESSAGES/select_untagged.po
Normal file
32
locale/pt_BR/LC_MESSAGES/select_untagged.po
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:47-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/select_untagged.lua:47
|
||||
msgid "select untagged images"
|
||||
msgstr "selecionar imagens sem etiqueta"
|
||||
|
||||
#: ../contrib/select_untagged.lua:79
|
||||
msgid "select untagged"
|
||||
msgstr "selecionar sem etiqueta"
|
||||
|
||||
#: ../contrib/select_untagged.lua:81
|
||||
msgid "select all images containing no tags or only tags added by darktable"
|
||||
msgstr ""
|
||||
"seleciona todas as imagens que não possuam etiqueta ou somente etiquetas"
|
||||
" adicionadas pelo darktable"
|
||||
34
locale/pt_BR/LC_MESSAGES/slideshowMusic.po
Normal file
34
locale/pt_BR/LC_MESSAGES/slideshowMusic.po
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-09-28 19:50-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/slideshowMusic.lua:56
|
||||
msgid "rhythmbox-client not found"
|
||||
msgstr "cliente rhythmbox não encontrado"
|
||||
|
||||
#: ../contrib/slideshowMusic.lua:85
|
||||
msgid "Slideshow background music file"
|
||||
msgstr "Arquivo de música de fundo da apresentação"
|
||||
|
||||
#: ../contrib/slideshowMusic.lua:89
|
||||
msgid "Play slideshow background music"
|
||||
msgstr "Exibe uma apresentação com música de fundo"
|
||||
|
||||
#: ../contrib/slideshowMusic.lua:90
|
||||
msgid "Plays music with rhythmbox if a slideshow starts"
|
||||
msgstr "Toca música com o rhytmbox se uma apresentação inicia"
|
||||
75
locale/pt_BR/LC_MESSAGES/transfer_hierarchy.po
Normal file
75
locale/pt_BR/LC_MESSAGES/transfer_hierarchy.po
Normal file
@@ -0,0 +1,75 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:28-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:153
|
||||
msgid "Lowest directory containing all selected images"
|
||||
msgstr "Pasta de nível mais baixa contendo todas as imagens selecionadas"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:256
|
||||
msgid ""
|
||||
"transfer hierarchy: ERROR: existing root is out of sync -- click 'calculate' "
|
||||
"to update"
|
||||
msgstr ""
|
||||
"transferir hierarquia: ERRO: raiz existente está fora de sincronia -- clique"
|
||||
" 'calcular' para atualizar"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:260
|
||||
msgid "transfer hierarchy: ERROR: destination not specified"
|
||||
msgstr "transferir hierarquia: ERRO: destino não especificado"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:270
|
||||
msgid "transfer hierarchy: ERROR: could not create directory: "
|
||||
msgstr "transferir hierarquia: ERRO: não foi possível criar a pasta: "
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:275
|
||||
msgid "transfer hierarchy: ERROR: not a directory: "
|
||||
msgstr "transferir hierarquia: ERRO: não é uma pasta: "
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:280
|
||||
msgid "transfer hierarchy: ERROR: could not create film: "
|
||||
msgstr "transferir hierarquia: ERRO: não foi possível criar um filme: "
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:289
|
||||
#, lua-format
|
||||
msgid "transfer hierarchy"
|
||||
msgstr "transferir hierarquia"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:327
|
||||
msgid "calculate"
|
||||
msgstr "calcular"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:331
|
||||
msgid "existing root"
|
||||
msgstr "raiz existente"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:336
|
||||
msgid "root of destination"
|
||||
msgstr "raiz do destino"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:341
|
||||
msgid "move"
|
||||
msgstr "mover"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:346
|
||||
msgid "copy"
|
||||
msgstr "copiar"
|
||||
|
||||
#: ../contrib/transfer_hierarchy.lua:347
|
||||
msgid "Copy all selected images"
|
||||
msgstr "Copia todas as imagens selecionadas"
|
||||
135
locale/pt_BR/LC_MESSAGES/video_ffmpeg.po
Normal file
135
locale/pt_BR/LC_MESSAGES/video_ffmpeg.po
Normal file
@@ -0,0 +1,135 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marcus Gama <marcus.gama@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-28 19:37-0300\n"
|
||||
"PO-Revision-Date: 2021-10-02 05:38-0300\n"
|
||||
"Last-Translator: Marcus Gama <marcus.gama@gmail.com>\n"
|
||||
"Language-Team: Portuguese <darktable-dev@lists.darktable.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 21.08.1\n"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:243
|
||||
msgid "framerate"
|
||||
msgstr "taxa de quadros"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:244
|
||||
msgid "select framerate of output video"
|
||||
msgstr "seleciona a taxa de quadros da saída de vídeo"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:251
|
||||
msgid "resolution"
|
||||
msgstr "resolução"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:252
|
||||
msgid "select resolution of output video"
|
||||
msgstr "seleciona a resolução da saída de vídeo"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:259
|
||||
msgid "codec"
|
||||
msgstr "codec"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:260
|
||||
msgid "select codec"
|
||||
msgstr "seleciona o codec"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:267
|
||||
msgid "format container"
|
||||
msgstr "formato"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:268
|
||||
msgid "select format of output video"
|
||||
msgstr "seleciona o formato da saída de vídeo"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:280
|
||||
msgid "output file destination"
|
||||
msgstr "destino do arquivo de saída"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:281
|
||||
msgid "settings of output file destination and name"
|
||||
msgstr "configurações do destino e nome do arquivo de saída"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:296
|
||||
msgid "Select export path"
|
||||
msgstr "Selecionar caminho de exportação"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:298
|
||||
msgid ""
|
||||
"select the target directory for the timelapse. \n"
|
||||
"the filename is created automatically."
|
||||
msgstr ""
|
||||
"selecione a pasta alvo para o timelapse.\n"
|
||||
"o nome do arquivo é criado automaticamente."
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:305
|
||||
msgid ""
|
||||
"if selected, output video will be placed in the same directory as first of "
|
||||
"selected images"
|
||||
msgstr ""
|
||||
"se selecionado, o vídeo de saída será colocado na mesma pasta da primeira das"
|
||||
" imagens "
|
||||
"selecionadas"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:320
|
||||
msgid "override output file on conflict"
|
||||
msgstr "sobrescrever arquivo de saída em caso de conflito"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:321
|
||||
msgid "if checked, in case of file name conflict, the file will be overwritten"
|
||||
msgstr "se ativo, em caso de conflito de nome, o arquivo será sobrescrito"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:329
|
||||
msgid ""
|
||||
"enter output file name without extension.\n"
|
||||
"\n"
|
||||
"You can use some placeholders:\n"
|
||||
"- {time} - time in format HH-mm-ss\n"
|
||||
"- {date} - date in foramt YYYY-mm-dd\n"
|
||||
"- {first_file} - name of first input file\n"
|
||||
"- {last_file} - name of last last_file"
|
||||
msgstr ""
|
||||
"insira o nome do arquivo de saída sem extensão.\n"
|
||||
"\n"
|
||||
"Você pode usar alguns coringas:\n"
|
||||
"- {time} - tempo no formato HH-mm-ss\n"
|
||||
"- {date} - data no formato AAAA-mm-dd\n"
|
||||
"- {first_file} - nome do primeiro arquivo de entrada\n"
|
||||
"- {last_file} - nome do último last_file"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:349
|
||||
msgid " open after export"
|
||||
msgstr " abrir após exportar"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:350
|
||||
msgid "open video file after successful export"
|
||||
msgstr "abre o arquivo de vídeo após ser exportado com sucesso"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:377
|
||||
msgid "export "
|
||||
msgstr "exportar "
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:433
|
||||
msgid "prepare merge process"
|
||||
msgstr "preparar o processo de mesclagem"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:436
|
||||
msgid "ERROR: cannot create temp directory"
|
||||
msgstr "ERRO: não foi possível criar a pasta temporária"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:448
|
||||
msgid "ERROR: cannot build image, see console for more info"
|
||||
msgstr ""
|
||||
"ERRO: não foi possível construir a imagem, veja o console para mais"
|
||||
" informações"
|
||||
|
||||
#: ../contrib/video_ffmpeg.lua:450
|
||||
msgid "SUCCESS"
|
||||
msgstr "SUCESSO"
|
||||
@@ -34,6 +34,14 @@ local cjson = require "cjson"
|
||||
|
||||
du.check_min_api_version("2.0.0", "check_for_updates")
|
||||
|
||||
-- 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
|
||||
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
|
||||
|
||||
-- compare two version strings of the form "major.minor.patch"
|
||||
-- returns -1, 0, 1 if the first version is smaller, equal, greater than the second version,
|
||||
-- or nil if one or both are of the wrong format
|
||||
@@ -80,6 +88,10 @@ local function compare_versions(a, b)
|
||||
end
|
||||
end
|
||||
|
||||
local function destroy()
|
||||
-- nothing to destroy
|
||||
end
|
||||
|
||||
|
||||
-- local function test(a, b, r)
|
||||
-- local cmp = compare_versions(a, b)
|
||||
@@ -134,3 +146,6 @@ if now > (back_then + 60 * 60 * 24 * 7) then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
return script_data
|
||||
|
||||
@@ -27,8 +27,17 @@ USAGE
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local gettext = dt.gettext
|
||||
|
||||
du.check_min_api_version("3.0.0", "copy_paste_metadata")
|
||||
du.check_min_api_version("7.0.0", "copy_paste_metadata")
|
||||
|
||||
-- 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
|
||||
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
|
||||
|
||||
-- set this to "false" if you don't want to overwrite metadata fields
|
||||
-- (title, description, creator, publisher and rights) that are already set
|
||||
@@ -48,6 +57,13 @@ 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)
|
||||
end
|
||||
|
||||
local function copy(image)
|
||||
if not image then
|
||||
have_data = false
|
||||
@@ -104,26 +120,41 @@ local function paste(images)
|
||||
end
|
||||
end
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
"copy metadata",
|
||||
function(event, images) copy(images[1]) end,
|
||||
"copy metadata of the first selected image"
|
||||
)
|
||||
local function destroy()
|
||||
dt.gui.libs.image.destroy_action("metadata_copy")
|
||||
dt.gui.libs.image.destroy_action("metadata_paste")
|
||||
dt.destroy_event("capmd1", "shortcut")
|
||||
dt.destroy_event("capmd2", "shortcut")
|
||||
end
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
"paste metadata",
|
||||
function(event, images) paste(images) end,
|
||||
"paste metadata to the selected images"
|
||||
"metadata_copy", _("copy metadata"),
|
||||
function(event, images) copy(images[1]) end,
|
||||
_("copy metadata of the first selected image")
|
||||
)
|
||||
|
||||
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
"metadata_paste", _("paste metadata"),
|
||||
function(event, images) paste(images) end,
|
||||
_("paste metadata to the selected images")
|
||||
)
|
||||
|
||||
|
||||
|
||||
dt.register_event(
|
||||
"shortcut",
|
||||
"capmd1", "shortcut",
|
||||
function(event, shortcut) copy(dt.gui.action_images[1]) end,
|
||||
"copy metadata"
|
||||
)
|
||||
|
||||
dt.register_event(
|
||||
"shortcut",
|
||||
"capmd2", "shortcut",
|
||||
function(event, shortcut) paste(dt.gui.action_images) end,
|
||||
"paste metadata"
|
||||
)
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
@@ -33,11 +33,23 @@ local du = require "lib/dtutils"
|
||||
|
||||
du.check_min_api_version("2.0.0", "delete_long_tags")
|
||||
|
||||
-- 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
|
||||
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
|
||||
|
||||
dt.preferences.register("delete_long_tags", "length", "integer",
|
||||
"maximum length of tags to keep",
|
||||
"tags longer than this get deleted on start",
|
||||
666, 0, 65536)
|
||||
|
||||
local function destroy()
|
||||
-- noting to destroy
|
||||
end
|
||||
|
||||
local max_length = dt.preferences.read("delete_long_tags", "length", "integer")
|
||||
|
||||
-- deleting while iterating the tags list seems to break the iterator!
|
||||
@@ -55,3 +67,7 @@ for _,name in pairs(long_tags) do
|
||||
tag = dt.tags.find(name)
|
||||
tag:delete()
|
||||
end
|
||||
|
||||
script_data.destroy = destroy
|
||||
|
||||
return script_data
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user