├── README.md ├── creatorfilter.lrdevplugin ├── CreatorExternalToolFilterProvider.lua ├── Info.lua ├── mac │ └── LightroomCreatorXMP └── win │ └── LightroomCreatorXMP.exe ├── custommetadatasample.lrdevplugin ├── AllMetadataTagset.lua ├── CustomMetadataDefinition.lua ├── CustomMetadataTagset.lua ├── DisplayMetadata.lua ├── Info.lua ├── PluginInfoProvider.lua ├── PluginInit.lua └── strings │ └── en │ └── TranslatedStrings.txt ├── flickr.lrdevplugin ├── FlickrAPI.lua ├── FlickrExportServiceProvider.lua ├── FlickrMetadataDefinition.lua ├── FlickrPublishSupport.lua ├── FlickrUser.lua ├── Info.lua ├── small_flickr.png └── small_flickr@2x.png ├── ftp_upload.lrdevplugin ├── FtpUploadExportDialogSections.lua ├── FtpUploadServiceProvider.lua ├── FtpUploadTask.lua └── Info.lua ├── helloworld.lrdevplugin ├── CustomDialogWithMultipleBind.lua ├── CustomDialogWithObserver.lua ├── ExportMenuItem.lua ├── Info.lua ├── RadioButtons.lua └── ShowCustomDialog.lua ├── languagefilter.lrdevplugin ├── Info.lua ├── LanguageExternalToolFilterProvider.lua ├── mac │ └── LightroomLanguageXMP └── win │ └── LightroomLanguageXMP.exe ├── metaexportfilter.lrdevplugin ├── Info.lua └── MetadataExportFilterProvider.lua ├── mymetadata.lrdevplugin ├── Info.lua ├── MyMetadataDefinitionFile.lua ├── MyMetadataTagset.lua └── MyMetadataTagsetAll.lua ├── mysample.lrwebengine ├── footer.html ├── galleryInfo.lrweb ├── grid.html ├── header.html ├── large.html ├── manifest.lrweb ├── myExampleTags.lrweb └── resources │ └── live_update.js └── websample.lrwebengine ├── footer.html ├── galleryInfo.lrweb ├── grid.html ├── header.html ├── manifest.lrweb ├── readme.txt ├── resources ├── blank.JPG ├── css │ ├── ie6.css │ ├── ie7.css │ └── stylesheet.css └── js │ ├── live_update.js │ └── pngfix.js └── strings └── en └── TranslatedStrings.txt /README.md: -------------------------------------------------------------------------------- 1 | # Adobe Photoshop Lightroom SDK 8.0 - Official Samples 2 | 3 | All content of this repository is copied from [Adobe sources](https://console.adobe.io/downloads/lr) and not created or owned by me. 4 | 5 | ### Official notice from Adobe 6 | 7 | ``` 8 | Welcome to the Adobe® Lightroom® Classic 8.0 Software Development Kit 9 | _____________________________________________________________________________ 10 | 11 | This file contains the latest information for the Adobe Lightroom SDK (8.0 Release). 12 | The information applies to Adobe Lightroom Classic and includes the following sections: 13 | 14 | 1. Introduction 15 | 2. SDK content overview 16 | 3. Development environment 17 | 4. Sample plug-ins 18 | 5. Running the plug-ins 19 | 6. Adobe Add-ons 20 | 21 | ********************************************** 22 | 1. Introduction 23 | ********************************************** 24 | 25 | The SDK provides information and examples for the scripting interface to Adobe 26 | Lightroom Classic. The SDK defines a scripting interface for the Lua language. 27 | 28 | A number of new features have been added in the 7.4 SDK release. Please see the API 29 | Reference for more information about each of the namespaces: 30 | 31 | 1. LrApplicationView: 32 | - New APIs to support Screen Modes, Grid and Loupe View Styles have been added 33 | 34 | 2. LrPhoto: 35 | - NEW API support to change quick develop settings from Library module have been added. 36 | - API support has been added for various actions to overcome locale issues. 37 | 38 | 3. LrDevelopController: 39 | - Support added for setting Auto Tone, White Balance, Clipping is added. 40 | - New API support for Radial, Spot and Graduated Filter. 41 | 42 | Key Bug Fixes: 43 | 44 | 1. Incosistencies between process versions are rectified 45 | 2. Docs have been updated to correct a number of issues. 46 | 47 | ********************************************** 48 | 3. Development environment 49 | ********************************************** 50 | 51 | You can use any text editor to write your Lua scripts, and you can 52 | use the LrLogger namespace to write debugging information to a console. 53 | See the section on "Debugging your Plug-in" in the Lightroom SDK Guide. 54 | 55 | ********************************************** 56 | 4. Sample Plugins 57 | ********************************************** 58 | 59 | The SDK provides the following samples: 60 | 61 | - /Sample Plugins/flickr.lrdevplugin/: 62 | Sample plug-in that demonstrates creating a plug-in which allows 63 | images to be directly exported to a Flickr account. 64 | 65 | - /Sample Plugins/ftp_upload.lrdevplugin/: 66 | Sample plug-in that demonstrates how to export images to an FTP server. 67 | 68 | - /Sample Plugins/helloworld.lrdevplugin/: 69 | Sample code that accompanies the Getting Started section of the 70 | Lightroom SDK Guide. 71 | 72 | /Sample Plugins/custommetadatasample.lrdevplugin/: 73 | Sample code that accompanies the custommetadatasample plug-in that 74 | demonstrates custom metadata. 75 | 76 | - /Sample Plugins/metaexportfilter.lrdevplugin/: 77 | Sample code that demonstrates using the metadata stored in a file 78 | to filter the files exported via the export dialog. 79 | 80 | - /Sample Plugins/websample.lrwebengine/: 81 | Sample code that creates a new style of web gallery template 82 | using the Web SDK. 83 | 84 | ********************************************** 85 | 5. Running the plug-ins 86 | ********************************************** 87 | 88 | To run the sample code, load the plug-ins using the Plug-in Manager 89 | available within Lightroom. See the Lightroom SDK Guide for more information. 90 | 91 | ********************************************************* 92 | 6. Adobe Add-ons 93 | ********************************************************* 94 | 95 | To learn more about Adobe Add-ons, point your browser to: 96 | 97 | https://creative.adobe.com/addons 98 | 99 | _____________________________________________________________________________ 100 | 101 | Copyright 2018 Adobe Systems Incorporated. All rights reserved. 102 | 103 | Adobe, Lightroom, and Photoshop are registered trademarks or trademarks of 104 | Adobe Systems Incorporated in the United States and/or other countries. 105 | Windows is either a registered trademark or a trademark of Microsoft Corporation 106 | in the United States and/or other countries. Macintosh is a trademark of 107 | Apple Computer, Inc., registered in the United States and other countries. 108 | ``` -------------------------------------------------------------------------------- /creatorfilter.lrdevplugin/CreatorExternalToolFilterProvider.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | CreatorExternalToolFilterProvider.lua 4 | Export service provider description for Creator external tool sample 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Lightroom SDK 20 | local LrView = import 'LrView' 21 | local bind = LrView.bind 22 | local LrPathUtils = import 'LrPathUtils' 23 | local LrTasks = import "LrTasks" 24 | 25 | 26 | --============================================================================-- 27 | 28 | local CreatorExternalToolFilterProvider = {} 29 | 30 | ------------------------------------------------------------------------------- 31 | 32 | CreatorExternalToolFilterProvider.exportPresetFields = { 33 | { key = 'creatorName', default = 'Lightroom' }, 34 | { key = 'metachoice', default = 'Title' }, 35 | { key = 'metavalue', default = '' }, 36 | } 37 | 38 | ------------------------------------------------------------------------------- 39 | 40 | function CreatorExternalToolFilterProvider.sectionForFilterInDialog( viewFactory, propertyTable ) 41 | 42 | return { 43 | title = 'Creator External Tool Sample', 44 | 45 | viewFactory:row { 46 | spacing = viewFactory:control_spacing(), 47 | viewFactory:static_text { 48 | title = "Export Images that match the following", 49 | }, 50 | }, 51 | viewFactory:row { 52 | spacing = viewFactory:control_spacing(), 53 | viewFactory:popup_menu { 54 | value = bind 'metachoice', 55 | items = { 56 | { title = "Title", value = "title" }, 57 | { title = "Creator", value = "creator" }, 58 | { title = "Copyright Status", value = "copyright" }, 59 | { title = "File Name", value = "fileName" }, 60 | { title = "Folder", value = "folderName" }, 61 | }, 62 | }, 63 | 64 | viewFactory:edit_field { 65 | value = bind 'metavalue', 66 | }, 67 | }, 68 | viewFactory:row { 69 | spacing = viewFactory:control_spacing(), 70 | viewFactory:static_text { 71 | title = "Set the Creator Name metadata field to match the following", 72 | }, 73 | }, 74 | viewFactory:row { 75 | spacing = viewFactory:control_spacing(), 76 | viewFactory:static_text { 77 | title = "Creator Name", 78 | }, 79 | viewFactory:edit_field { 80 | value = bind 'creatorName', 81 | }, 82 | } 83 | } 84 | end 85 | 86 | ------------------------------------------------------------------------------- 87 | 88 | function CreatorExternalToolFilterProvider.postProcessRenderedPhotos( functionContext, filterContext ) 89 | 90 | 91 | local renditionOptions = { 92 | plugin = _PLUGIN, 93 | renditionsToSatisfy = filterContext.renditionsToSatisfy, 94 | filterSettings = function( renditionToSatisfy, exportSettings ) 95 | 96 | -- This hook function gives you the opportunity to change the render 97 | -- settings for each photo before Lightroom renders it. 98 | -- For example, if you wanted Lightroom to generate TIFF files. 99 | -- You can add below statements: 100 | -- exportSettings.LR_format = TIFF 101 | -- return os.tmpname() 102 | -- By doing so, you assume responsibility for creating 103 | -- the file type that was originally requested and placing it 104 | -- in the location that was originally requested in your filter loop below. 105 | 106 | end, 107 | } 108 | 109 | local command 110 | local quotedCommand 111 | local targetCreator = filterContext.propertyTable.creatorName 112 | 113 | for sourceRendition, renditionToSatisfy in filterContext:renditions( renditionOptions ) do 114 | 115 | -- Wait for the upstream task to finish its work on this photo. 116 | 117 | local success, _ = sourceRendition:waitForRender() 118 | 119 | if success then 120 | 121 | local path = sourceRendition.destinationPath 122 | 123 | -- Now that the photo is completed and available to this filter, you can do your work on the photo here. 124 | -- In this example, the renditions are passed to an external application that updates the Creator metadata 125 | -- with the entry added in the export dialog section. 126 | 127 | if WIN_ENV == true then 128 | command = '"' .. LrPathUtils.child( LrPathUtils.child( _PLUGIN.path, "win" ), "LightroomCreatorXMP.exe" ) .. '" ' .. '"' .. path .. '" ' .. '"' .. targetCreator .. '"' 129 | quotedCommand = '"' .. command .. '"' 130 | else 131 | command = '"' .. LrPathUtils.child( LrPathUtils.child( _PLUGIN.path, "mac" ), "LightroomCreatorXMP" ) .. '" ' .. '"' .. path .. '" ' .. '"' .. targetCreator .. '"' 132 | quotedCommand = command 133 | end 134 | 135 | if LrTasks.execute( quotedCommand ) ~= 0 then 136 | renditionToSatisfy:renditionIsDone( false, "Failed to contact XMP Application" ) 137 | end 138 | 139 | end 140 | 141 | end 142 | 143 | end 144 | 145 | ------------------------------------------------------------------------------- 146 | 147 | function CreatorExternalToolFilterProvider.shouldRenderPhoto( exportSettings, photo ) 148 | 149 | -- This function should return either: 150 | -- true, photo gets included in export, or 151 | -- false, photo should be removed from the export. 152 | -- The photo represents an LrPhoto object. 153 | 154 | local targetField = exportSettings.metachoice 155 | local targetValue = exportSettings.metavalue 156 | 157 | -- Now that the user has filled in this section we need to filter through the images and only 158 | -- choose the ones that match the required metadata. 159 | 160 | local sourceMetaValue = photo:getFormattedMetadata( targetField ) 161 | 162 | local shouldRender = sourceMetaValue == targetValue 163 | 164 | return shouldRender 165 | 166 | end 167 | 168 | -------------------------------------------------------------------------------- 169 | 170 | return CreatorExternalToolFilterProvider 171 | -------------------------------------------------------------------------------- /creatorfilter.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | Summary information for creator filter plug-in 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | 18 | ------------------------------------------------------------------------------]] 19 | 20 | return { 21 | 22 | LrSdkVersion = 3.0, 23 | LrSdkMinimumVersion = 2.0, 24 | 25 | LrPluginName = "Creator External Tool", 26 | LrToolkitIdentifier = 'com.adobe.lightroom.sdk.export.creator', 27 | 28 | LrExportFilterProvider = { 29 | title = "Creator External Tool", 30 | file = 'CreatorExternalToolFilterProvider.lua', 31 | }, 32 | 33 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 34 | 35 | } 36 | -------------------------------------------------------------------------------- /creatorfilter.lrdevplugin/mac/LightroomCreatorXMP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/creatorfilter.lrdevplugin/mac/LightroomCreatorXMP -------------------------------------------------------------------------------- /creatorfilter.lrdevplugin/win/LightroomCreatorXMP.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/creatorfilter.lrdevplugin/win/LightroomCreatorXMP.exe -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/AllMetadataTagset.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | AllMetadataTagset.lua 4 | This tagset shows examples of displaying different types of metadata available within Lightroom 5 | When in Lightroom choose "All Metadata" from the drop down menu in the Metadata panel. 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ------------------------------------------------------------------------------]] 19 | 20 | return { 21 | 22 | title = LOC "$$$/CustomMetadata/Fields/AllPreset=All Metadata", 23 | id = "all", 24 | 25 | items = { 26 | "com.adobe.filename", 27 | "com.adobe.originalFilename.ifDiffers", 28 | "com.adobe.sidecars", 29 | "com.adobe.copyname", 30 | "com.adobe.folder", 31 | "com.adobe.filesize", 32 | "com.adobe.fileFormat", 33 | "com.adobe.metadataStatus", 34 | "com.adobe.metadataDate", 35 | "com.adobe.audioAnnotation", 36 | 37 | "com.adobe.allPluginMetadata", 38 | 39 | "com.adobe.separator", 40 | 41 | "com.adobe.rating", 42 | 43 | "com.adobe.separator", 44 | 45 | "com.adobe.colorLabels", 46 | 47 | "com.adobe.separator", 48 | 49 | "com.adobe.title", 50 | { "com.adobe.caption", height_in_lines = 3 }, 51 | 52 | "com.adobe.separator", 53 | { 54 | formatter = "com.adobe.label", 55 | label = LOC "$$$/CustomMetadata/Fields/ExifLabel=EXIF", 56 | }, 57 | 58 | "com.adobe.imageFileDimensions", -- dimensions 59 | "com.adobe.imageCroppedDimensions", 60 | 61 | "com.adobe.exposure", -- exposure factors 62 | "com.adobe.brightnessValue", 63 | "com.adobe.exposureBiasValue", 64 | "com.adobe.flash", 65 | "com.adobe.exposureProgram", 66 | "com.adobe.meteringMode", 67 | "com.adobe.ISOSpeedRating", 68 | 69 | "com.adobe.focalLength", -- lens info 70 | "com.adobe.focalLength35mm", 71 | "com.adobe.lens", 72 | "com.adobe.subjectDistance", 73 | 74 | "com.adobe.dateTimeOriginal", 75 | "com.adobe.dateTimeDigitized", 76 | "com.adobe.dateTime", 77 | 78 | "com.adobe.make", -- camera 79 | "com.adobe.model", 80 | "com.adobe.serialNumber", 81 | 82 | "com.adobe.userComment", 83 | 84 | "com.adobe.artist", 85 | "com.adobe.software", 86 | 87 | "com.adobe.GPS", -- gps 88 | "com.adobe.GPSAltitude", 89 | "com.adobe.GPSImgDirection", 90 | 91 | "com.adobe.separator", 92 | { 93 | formatter = "com.adobe.label", 94 | label = LOC "$$$/CustomMetadata/Fields/CreatorInfoLabel=Contact", 95 | }, 96 | 97 | "com.adobe.creator", 98 | { formatter = "com.adobe.creatorJobTitle", form = "shortTitle" }, 99 | { formatter = "com.adobe.creatorAddress", form = "shortTitle" }, 100 | { formatter = "com.adobe.creatorCity", form = "shortTitle" }, 101 | { formatter = "com.adobe.creatorState", form = "shortTitle" }, 102 | { formatter = "com.adobe.creatorZip", form = "shortTitle" }, 103 | { formatter = "com.adobe.creatorCountry", form = "shortTitle" }, 104 | { formatter = "com.adobe.creatorWorkPhone", form = "shortTitle" }, 105 | { formatter = "com.adobe.creatorWorkEmail", form = "shortTitle" }, 106 | { formatter = "com.adobe.creatorWorkWebsite", form = "shortTitle" }, 107 | 108 | "com.adobe.separator", 109 | { 110 | formatter = "com.adobe.label", 111 | label = LOC "$$$/CustomMetadata/Fields/IPTCLabel=IPTC", 112 | }, 113 | 114 | "com.adobe.headline", 115 | "com.adobe.iptcSubjectCode", 116 | "com.adobe.descriptionWriter", 117 | "com.adobe.category", 118 | "com.adobe.supplementalCategories", 119 | 120 | { 121 | formatter = "com.adobe.label", 122 | label = LOC "$$$/CustomMetadata/Fields/FormalDescriptiveInfo=Image", 123 | }, 124 | "com.adobe.dateCreated", 125 | "com.adobe.intellectualGenre", 126 | "com.adobe.scene", 127 | "com.adobe.location", 128 | "com.adobe.city", 129 | "com.adobe.state", 130 | "com.adobe.country", 131 | "com.adobe.isoCountryCode", 132 | { 133 | formatter = "com.adobe.label", 134 | label = LOC "$$$/CustomMetadata/Fields/Workflow=Workflow", 135 | }, 136 | "com.adobe.jobIdentifier", 137 | "com.adobe.instructions", 138 | "com.adobe.provider", 139 | "com.adobe.source", 140 | { 141 | formatter = "com.adobe.label", 142 | label = LOC "$$$/CustomMetadata/Fields/Copyright=Copyright", 143 | }, 144 | { "com.adobe.copyrightState", pruneRedundantFields = false }, 145 | "com.adobe.copyright", 146 | "com.adobe.rightsUsageTerms", 147 | "com.adobe.copyrightInfoURL", 148 | 149 | }, 150 | 151 | } 152 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/CustomMetadataDefinition.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | CustomMetadataDefinition.lua 4 | Sample custom metadata definition 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | require "PluginInit" 20 | 21 | return { 22 | 23 | metadataFieldsForPhotos = { 24 | 25 | { 26 | id = 'siteId', 27 | 28 | -- This field will not be available in the metadata browser because 29 | -- it does not have a title field. You might use a field like this 30 | -- to store a photo ID from an external database or web service. 31 | 32 | }, 33 | { 34 | id = 'randomString', 35 | title = LOC "$$$/CustomMetadata/Fields/RandomString=Random String", 36 | dataType = 'string', -- Specifies the data type for this field. 37 | browsable = true, 38 | searchable = true, 39 | }, 40 | { 41 | id = 'readonlyString', 42 | title = LOC "$$$/CustomMetadata/Fields/ReadOnlyString=Another String", 43 | dataType = 'string', -- Specifies the data type for this field. 44 | searchable = true 45 | }, 46 | 47 | { 48 | id = 'displayImage', 49 | title = LOC "$$$/CustomMetadata/Fields/Display=Display Image", 50 | dataType = 'enum', 51 | values = { 52 | { 53 | value = 'no', 54 | title = LOC "$$$/CustomMetadata/Fields/Display/No=No", 55 | }, 56 | { 57 | value = 'yes', 58 | title = LOC "$$$/CustomMetadata/Fields/Display/Yes=Yes", 59 | }, 60 | allowPluginToSetOtherValues = true, 61 | }, 62 | }, 63 | { 64 | id = 'url', 65 | title = LOC "$$$/CustomMetadata/Fields/Display/URL=URL", 66 | dataType = 'url', 67 | }, 68 | }, 69 | 70 | schemaVersion = 1, -- must be a number, preferably a positive integer 71 | 72 | updateFromEarlierSchemaVersion = function( catalog, previousSchemaVersion ) 73 | -- Note: This function is called from within a catalog:withPrivateWriteAccessDo 74 | -- block. You should not call any of the with___Do functions yourself. 75 | 76 | catalog:assertHasPrivateWriteAccess( "CustomMetadataDefinition.updateFromEarlierSchemaVersion" ) 77 | 78 | if previousSchemaVersion == 1 then 79 | 80 | -- Retrieve photos that have been used already with the custom metadata. 81 | 82 | local photosToMigrate = catalog:findPhotosWithProperty( PluginInit.pluginID, 'siteId' ) 83 | 84 | -- Optional: can add property version number here. 85 | 86 | for _, photo in ipairs( photosToMigrate ) do 87 | local oldSiteId = photo:getPropertyForPlugin( PluginInit.pluginID, 'siteId' ) -- add property version here if used above 88 | local newSiteId = "new:" .. oldSiteId -- replace this with whatever data transformation you need to do 89 | photo:setPropertyForPlugin( _PLUGIN, 'siteId', newSiteId ) 90 | end 91 | elseif previousSchemaVersion == 2 then 92 | 93 | -- Optional area to do further processing etc. 94 | end 95 | end, 96 | 97 | } 98 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/CustomMetadataTagset.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | CustomMetadataTagset.lua 4 | Sample custom metadata tagset 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return{ 20 | 21 | title = LOC "$$$/CustomMetadata/Tagset/Title=Custom Metadata", 22 | id = 'CustomMetadataTagset', 23 | 24 | items = { 25 | { 'com.adobe.label', label = LOC "$$$/Metadata/OrigLabel=Standard Metadata" }, 26 | 'com.adobe.filename', 27 | 'com.adobe.folder', 28 | 29 | 'com.adobe.separator', 30 | 31 | 'com.adobe.title', 32 | { 'com.adobe.caption', height_in_lines = 3 }, 33 | 34 | 'com.adobe.separator', 35 | 36 | 'com.adobe.lightroom.sdk.metadata.custommetadatasample.*', 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/DisplayMetadata.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | DisplayMetadata.lua 4 | Summary information for custom metadata dialog sample plugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | local LrApplication = import 'LrApplication' 20 | local LrDialogs = import 'LrDialogs' 21 | local catalog = LrApplication.activeCatalog() 22 | 23 | CMMenuItem = {} 24 | 25 | 26 | function CMMenuItem.sortImages() 27 | 28 | -- Get a reference to the photos within the current catalog. 29 | 30 | local catPhotos = catalog.targetPhotos 31 | 32 | local titles = {} 33 | 34 | -- Create an array that will store strings detailing the photos. 35 | 36 | for _, photo in ipairs( catPhotos ) do 37 | -- Loop through each of the photos. 38 | 39 | -- We now have access to the photo so let's try and access the custom metadata. 40 | 41 | local display = photo:getPropertyForPlugin( 'com.adobe.lightroom.sdk.metadata.custommetadatasample', 'displayImage' ) 42 | if display then 43 | 44 | -- The photo has a value for this custom metadata so let's continue. 45 | 46 | if display == 'yes' then 47 | 48 | -- We only want to display photos that have the custom metadata field displayImage set to 'yes'. 49 | 50 | local imageDetails = photo:getFormattedMetadata( 'fileName' ) 51 | local randomString = photo:getPropertyForPlugin( 'com.adobe.lightroom.sdk.metadata.custommetadatasample', 'randomString' ) 52 | if randomString then 53 | imageDetails = imageDetails .. "\t" .. randomString 54 | end 55 | 56 | -- The above code has checked the values of the custom metadata randomString and rating defined by the plugin 57 | -- customemetadatasample. see customMetadataSample.lrdevplugin in the Lightroom SDK. 58 | -- If there are valid entries the values of these fields have been appended to the variable imageDetails. 59 | 60 | titles[ #titles + 1 ] = imageDetails 61 | end 62 | end 63 | end 64 | 65 | -- Now pass the keywords to the showModalDialog method for processing. 66 | 67 | CMMenuItem.showModalDialog( titles ) 68 | 69 | end 70 | 71 | -- Now display a dialog with the new file entries. 72 | 73 | function CMMenuItem.showModalDialog( keys ) 74 | local message = "Matching Strings - " .. #keys 75 | 76 | -- We have been passed the keys so now need to loop through the items and add them to a string ready for displaying. 77 | 78 | for _, title in ipairs( keys ) do 79 | message = message .. "\n" .. title 80 | end 81 | 82 | LrDialogs.message( "Custom Metadata Dialog", message, "info" ) 83 | end 84 | 85 | import 'LrTasks'.startAsyncTask( CMMenuItem.sortImages ) 86 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | Summary information for custom metadata sample plugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | LrSdkVersion = 3.0, 22 | LrSdkMinimumVersion = 2.0, 23 | LrToolkitIdentifier = 'com.adobe.lightroom.sdk.metadata.custommetadatasample', 24 | 25 | LrPluginName = LOC "$$$/CustomMetadata/PluginName=Custom Metadata Sample", 26 | LrPluginInfoUrl = "http://www.adobe.com", 27 | 28 | -- Add the Metadata Definition File 29 | LrMetadataProvider = 'CustomMetadataDefinition.lua', 30 | 31 | -- Add the Metadata Tagset File 32 | LrMetadataTagsetFactory = { 33 | 'CustomMetadataTagset.lua', 34 | 'AllMetadataTagset.lua', 35 | }, 36 | 37 | LrLibraryMenuItems = { 38 | title = 'Custom Metadata Dialog', 39 | file = 'DisplayMetadata.lua', 40 | enabledWhen = 'photosAvailable', 41 | }, 42 | 43 | -- Add the entry for the Plug-in Manager Dialog 44 | LrPluginInfoProvider = 'PluginInfoProvider.lua', 45 | 46 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 47 | 48 | } 49 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/PluginInfoProvider.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | PluginInfoProvider.lua 4 | 5 | Responsible for managing the dialog entry in the Plugin Manager dialog window which 6 | manages the individual plug-ins installed in the Lightroom application. 7 | 8 | This will create a section in the Plugin Manager Dialog window. This example creates a 9 | label and button that when clicked launches a browser window and opens http://www.adobe.com 10 | 11 | -------------------------------------------------------------------------------- 12 | 13 | ADOBE SYSTEMS INCORPORATED 14 | Copyright 2008 Adobe Systems Incorporated 15 | All Rights Reserved. 16 | 17 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 18 | with the terms of the Adobe license agreement accompanying it. If you have received 19 | this file from a source other than Adobe, then your use, modification, or distribution 20 | of it requires the prior written permission of Adobe. 21 | 22 | ------------------------------------------------------------------------------]] 23 | 24 | require "PluginInit" 25 | 26 | local LrHttp = import "LrHttp" 27 | 28 | local function sectionsForTopOfDialog( f, _ ) 29 | return { 30 | -- Section for the top of the dialog. 31 | { 32 | title = LOC "$$$/CustomMetadata/PluginManager=Custom Metadata Sample", 33 | f:row { 34 | spacing = f:control_spacing(), 35 | 36 | f:static_text { 37 | title = LOC "$$$/CustomMetadata/Title1=Click the button to find out more about Adobe", 38 | fill_horizontal = 1, 39 | }, 40 | 41 | f:push_button { 42 | width = 150, 43 | title = LOC "$$$/CustomMetadata/ButtonTitle=Connect to Adobe", 44 | enabled = true, 45 | action = function() 46 | LrHttp.openUrlInBrowser( PluginInit.URL ) 47 | end, 48 | }, 49 | }, 50 | f:row { 51 | f:static_text { 52 | title = LOC "$$$/CustomMetadata/Title2=Global default value for displayImage: ", 53 | }, 54 | f:static_text { 55 | title = PluginInit.currentDisplayImage, 56 | fill_horizontal = 1, 57 | }, 58 | }, 59 | }, 60 | 61 | } 62 | end 63 | 64 | return{ 65 | 66 | sectionsForTopOfDialog = sectionsForTopOfDialog, 67 | 68 | } 69 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/PluginInit.lua: -------------------------------------------------------------------------------- 1 | PluginInit = { 2 | currentDisplayImage = "no", 3 | pluginID = "com.adobe.lightroom.sdk.metadata.custommetadatasample", 4 | URL = "http://www.adobe.com", 5 | } 6 | -------------------------------------------------------------------------------- /custommetadatasample.lrdevplugin/strings/en/TranslatedStrings.txt: -------------------------------------------------------------------------------- 1 | "$$$/CustomMetadata/PluginName=Custom Metadata Sample" 2 | "$$$/CustomMetadata/Fields/RandomString=Random String" 3 | "$$$/CustomMetadata/Fields/Display=Display Image" 4 | "$$$/CustomMetadata/Fields/Display/Yes=Yes" 5 | "$$$/CustomMetadata/Fields/Display/No=No" 6 | "$$$/CustomMetadata/Fields/Rating=Rating" 7 | "$$$/CustomMetadata/Tagset/Title=Custom Metadata" 8 | "$$$/Metadata/OrigLabel=Standard Metadata" 9 | "$$$/Metadata/CusLabel=Custom Metadata" 10 | "$$$/CustomMetadata/Fields/ReadOnlyString=ReadOnly String" 11 | "$$$/CustomMetadata/PluginManager=Custom Metadata Sample" 12 | "$$$/CustomMetadata/Fields/Display/URL=URL" 13 | "$$$/CustomMetadata/Fields/Copyright=Copyright" 14 | "$$$/CustomMetadata/Fields/Workflow=Workflow" 15 | "$$$/CustomMetadata/Fields/FormalDescriptiveInfo=Image" 16 | "$$$/CustomMetadata/Fields/IPTCLabel=IPTC" 17 | "$$$/CustomMetadata/Fields/CreatorInfoLabel=Contact" 18 | "$$$/CustomMetadata/Fields/ExifLabel=EXIF" 19 | "$$$/CustomMetadata/Fields/AllPreset=All Metadata" 20 | -------------------------------------------------------------------------------- /flickr.lrdevplugin/FlickrMetadataDefinition.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | FlickrMetadataDefinition.lua 4 | Custom metadata definition for Flickr publish plug-in 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2009 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | metadataFieldsForPhotos = { 22 | 23 | { 24 | id = 'previous_tags', 25 | dataType = 'string', 26 | }, 27 | 28 | }, 29 | 30 | schemaVersion = 2, -- must be a number, preferably a positive integer 31 | 32 | } 33 | -------------------------------------------------------------------------------- /flickr.lrdevplugin/FlickrUser.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | FlickrUser.lua 4 | Flickr user account management 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Lightroom SDK 20 | local LrDialogs = import 'LrDialogs' 21 | local LrFunctionContext = import 'LrFunctionContext' 22 | local LrTasks = import 'LrTasks' 23 | 24 | local logger = import 'LrLogger'( 'FlickrAPI' ) 25 | 26 | require 'FlickrAPI' 27 | 28 | 29 | --============================================================================-- 30 | 31 | FlickrUser = {} 32 | 33 | -------------------------------------------------------------------------------- 34 | 35 | local function storedCredentialsAreValid( propertyTable ) 36 | 37 | return propertyTable.username and string.len( propertyTable.username ) > 0 38 | and propertyTable.nsid 39 | and propertyTable.auth_token 40 | 41 | end 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | local function notLoggedIn( propertyTable ) 46 | 47 | propertyTable.token = nil 48 | 49 | propertyTable.nsid = nil 50 | propertyTable.username = nil 51 | propertyTable.fullname = '' 52 | propertyTable.auth_token = nil 53 | 54 | propertyTable.accountStatus = LOC "$$$/Flickr/AccountStatus/NotLoggedIn=Not logged in" 55 | propertyTable.loginButtonTitle = LOC "$$$/Flickr/LoginButton/NotLoggedIn=Log In" 56 | propertyTable.loginButtonEnabled = true 57 | propertyTable.validAccount = false 58 | 59 | end 60 | 61 | -------------------------------------------------------------------------------- 62 | 63 | local doingLogin = false 64 | 65 | function FlickrUser.login( propertyTable ) 66 | 67 | if doingLogin then return end 68 | doingLogin = true 69 | 70 | LrFunctionContext.postAsyncTaskWithContext( 'Flickr login', 71 | function( context ) 72 | 73 | -- Clear any existing login info, but only if creating new account. 74 | -- If we're here on an existing connection, that's because the login 75 | -- token was rejected. We need to retain existing account info so we 76 | -- can cross-check it. 77 | 78 | if not propertyTable.LR_editingExistingPublishConnection then 79 | notLoggedIn( propertyTable ) 80 | end 81 | 82 | propertyTable.accountStatus = LOC "$$$/Flickr/AccountStatus/LoggingIn=Logging in..." 83 | propertyTable.loginButtonEnabled = false 84 | 85 | LrDialogs.attachErrorDialogToFunctionContext( context ) 86 | 87 | -- Make sure login is valid when done, or is marked as invalid. 88 | 89 | context:addCleanupHandler( function() 90 | 91 | doingLogin = false 92 | 93 | if not storedCredentialsAreValid( propertyTable ) then 94 | notLoggedIn( propertyTable ) 95 | end 96 | 97 | -- Hrm. New API doesn't make it easy to show what operation failed. 98 | -- LrDialogs.message( LOC "$$$/Flickr/LoginFailed=Failed to log in." ) 99 | 100 | end ) 101 | 102 | -- Make sure we have an API key. 103 | 104 | FlickrAPI.getApiKeyAndSecret() 105 | 106 | -- Show request for authentication dialog. 107 | 108 | local authRequestDialogResult = LrDialogs.confirm( 109 | LOC "$$$/Flickr/AuthRequestDialog/Message=Lightroom needs your permission to upload images to Flickr.", 110 | LOC "$$$/Flickr/AuthRequestDialog/HelpText=If you click Authorize, you will be taken to a web page in your web browser where you can log in. When you're finished, return to Lightroom to complete the authorization.", 111 | LOC "$$$/Flickr/AuthRequestDialog/AuthButtonText=Authorize", 112 | LOC "$$$/LrDialogs/Cancel=Cancel" ) 113 | 114 | if authRequestDialogResult == 'cancel' then 115 | return 116 | end 117 | 118 | -- Request the frob that we need for authentication. 119 | 120 | propertyTable.accountStatus = LOC "$$$/Flickr/AccountStatus/WaitingForFlickr=Waiting for response from flickr.com..." 121 | 122 | require 'FlickrAPI' 123 | local frob = FlickrAPI.openAuthUrl() 124 | 125 | local waitForAuthDialogResult = LrDialogs.confirm( 126 | LOC "$$$/Flickr/WaitForAuthDialog/Message=Return to this window once you've authorized Lightroom on flickr.com.", 127 | LOC "$$$/Flickr/WaitForAuthDialog/HelpText=Once you've granted permission for Lightroom (in your web browser), click the Done button below.", 128 | LOC "$$$/Flickr/WaitForAuthDialog/DoneButtonText=Done", 129 | LOC "$$$/LrDialogs/Cancel=Cancel" ) 130 | 131 | if waitForAuthDialogResult == 'cancel' then 132 | return 133 | end 134 | 135 | -- User has OK'd authentication. Get the user info. 136 | 137 | propertyTable.accountStatus = LOC "$$$/Flickr/AccountStatus/WaitingForFlickr=Waiting for response from flickr.com..." 138 | 139 | local data = FlickrAPI.callRestMethod( propertyTable, { method = 'flickr.auth.getToken', frob = frob, suppressError = true, skipAuthToken = true } ) 140 | 141 | local auth = data.auth 142 | 143 | if not auth then 144 | return 145 | end 146 | 147 | -- If editing existing connection, make sure user didn't try to change user ID on us. 148 | 149 | if propertyTable.LR_editingExistingPublishConnection then 150 | 151 | if auth.user and propertyTable.nsid ~= auth.user.nsid then 152 | LrDialogs.message( LOC "$$$/Flickr/CantChangeUserID=You can not change Flickr accounts on an existing publish connection. Please log in again with the account you used when you first created this connection." ) 153 | return 154 | end 155 | 156 | end 157 | 158 | -- Now we can read the Flickr user credentials. Save off to prefs. 159 | 160 | propertyTable.nsid = auth.user.nsid 161 | propertyTable.username = auth.user.username 162 | propertyTable.fullname = auth.user.fullname 163 | propertyTable.auth_token = auth.token._value 164 | 165 | FlickrUser.updateUserStatusTextBindings( propertyTable ) 166 | 167 | end ) 168 | 169 | end 170 | 171 | -------------------------------------------------------------------------------- 172 | 173 | local function getDisplayUserNameFromProperties( propertyTable ) 174 | 175 | local displayUserName = propertyTable.fullname 176 | if ( not displayUserName or #displayUserName == 0 ) 177 | or displayUserName == propertyTable.username 178 | then 179 | displayUserName = propertyTable.username 180 | else 181 | displayUserName = LOC( "$$$/Flickr/AccountStatus/UserNameAndLoginName=^1 (^2)", 182 | propertyTable.fullname, 183 | propertyTable.username ) 184 | end 185 | 186 | return displayUserName 187 | 188 | end 189 | 190 | -------------------------------------------------------------------------------- 191 | 192 | function FlickrUser.verifyLogin( propertyTable ) 193 | 194 | -- Observe changes to prefs and update status message accordingly. 195 | 196 | local function updateStatus() 197 | 198 | logger:trace( "verifyLogin: updateStatus() was triggered." ) 199 | 200 | LrTasks.startAsyncTask( function() 201 | logger:trace( "verifyLogin: updateStatus() is executing." ) 202 | if storedCredentialsAreValid( propertyTable ) then 203 | 204 | local displayUserName = getDisplayUserNameFromProperties( propertyTable ) 205 | 206 | propertyTable.accountStatus = LOC( "$$$/Flickr/AccountStatus/LoggedIn=Logged in as ^1", displayUserName ) 207 | 208 | if propertyTable.LR_editingExistingPublishConnection then 209 | propertyTable.loginButtonTitle = LOC "$$$/Flickr/LoginButton/LogInAgain=Log In" 210 | propertyTable.loginButtonEnabled = false 211 | propertyTable.validAccount = true 212 | else 213 | propertyTable.loginButtonTitle = LOC "$$$/Flickr/LoginButton/LoggedIn=Switch User?" 214 | propertyTable.loginButtonEnabled = true 215 | propertyTable.validAccount = true 216 | end 217 | else 218 | notLoggedIn( propertyTable ) 219 | end 220 | 221 | FlickrUser.updateUserStatusTextBindings( propertyTable ) 222 | end ) 223 | 224 | end 225 | 226 | propertyTable:addObserver( 'auth_token', updateStatus ) 227 | updateStatus() 228 | 229 | end 230 | 231 | -------------------------------------------------------------------------------- 232 | 233 | function FlickrUser.updateUserStatusTextBindings( settings ) 234 | 235 | local nsid = settings.nsid 236 | 237 | if nsid and string.len( nsid ) > 0 then 238 | 239 | LrFunctionContext.postAsyncTaskWithContext( 'Flickr account status check', 240 | function( context ) 241 | 242 | context:addFailureHandler( function() 243 | 244 | -- Login attempt failed. Offer chance to re-establish connection. 245 | 246 | if settings.LR_editingExistingPublishConnection then 247 | 248 | local displayUserName = getDisplayUserNameFromProperties( settings ) 249 | 250 | settings.accountStatus = LOC( "$$$/Flickr/AccountStatus/LogInFailed=Log in failed, was logged in as ^1", displayUserName ) 251 | 252 | settings.loginButtonTitle = LOC "$$$/Flickr/LoginButton/LogInAgain=Log In" 253 | settings.loginButtonEnabled = true 254 | settings.validAccount = false 255 | 256 | settings.isUserPro = false 257 | settings.accountTypeMessage = LOC "$$$/Flickr/AccountStatus/LoginFailed/Message=Could not verify this Flickr account. Please log in again. Please note that you can not change the Flickr account for an existing publish connection. You must log in to the same account." 258 | 259 | end 260 | 261 | end ) 262 | 263 | local userinfo = FlickrAPI.getUserInfo( settings, { userId = nsid } ) 264 | if userinfo and ( not userinfo.ispro ) then 265 | settings.accountTypeMessage = LOC( "$$$/Flickr/NonProAccountLimitations=This account is not a Flickr Pro account, and is subject to limitations. Once a photo has been uploaded, it will not be automatically updated if it changes. In addition, there is an upload bandwidth limit each month." ) 266 | settings.isUserPro = false 267 | else 268 | settings.accountTypeMessage = LOC( "$$$/Flickr/ProAccountDescription=This Flickr Pro account can utilize collections, modified photos will be automatically be re-published, and there is no monthly bandwidth limit." ) 269 | settings.isUserPro = true 270 | end 271 | 272 | end ) 273 | else 274 | 275 | settings.accountTypeMessage = LOC( "$$$/Flickr/SignIn=Sign in with your Flickr account." ) 276 | settings.isUserPro = false 277 | 278 | end 279 | 280 | end 281 | -------------------------------------------------------------------------------- /flickr.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | Summary information for Flickr sample plug-in 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | LrSdkVersion = 3.0, 22 | LrSdkMinimumVersion = 3.0, -- minimum SDK version required by this plug-in 23 | 24 | LrToolkitIdentifier = 'com.adobe.lightroom.export.flickr', 25 | LrPluginName = LOC "$$$/Flickr/PluginName=Flickr", 26 | 27 | LrExportServiceProvider = { 28 | title = LOC "$$$/Flickr/Flickr-title=Flickr", 29 | file = 'FlickrExportServiceProvider.lua', 30 | }, 31 | 32 | LrMetadataProvider = 'FlickrMetadataDefinition.lua', 33 | 34 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 35 | 36 | } 37 | -------------------------------------------------------------------------------- /flickr.lrdevplugin/small_flickr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/flickr.lrdevplugin/small_flickr.png -------------------------------------------------------------------------------- /flickr.lrdevplugin/small_flickr@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/flickr.lrdevplugin/small_flickr@2x.png -------------------------------------------------------------------------------- /ftp_upload.lrdevplugin/FtpUploadExportDialogSections.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | FtpUploadExportDialogSections.lua 4 | Export dialog customization for Lightroom FTP uploader 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Lightroom SDK 20 | local LrView = import 'LrView' 21 | local LrFtp = import 'LrFtp' 22 | 23 | --============================================================================-- 24 | 25 | FtpUploadExportDialogSections = {} 26 | 27 | ------------------------------------------------------------------------------- 28 | 29 | local function updateExportStatus( propertyTable ) 30 | 31 | local message = nil 32 | 33 | repeat 34 | -- Use a repeat loop to allow easy way to "break" out. 35 | -- (It only goes through once.) 36 | 37 | if propertyTable.ftpPreset == nil then 38 | message = LOC "$$$/FtpUpload/ExportDialog/Messages/SelectPreset=Select or Create an FTP preset" 39 | break 40 | end 41 | 42 | if propertyTable.putInSubfolder and ( propertyTable.path == "" or propertyTable.path == nil ) then 43 | message = LOC "$$$/FtpUpload/ExportDialog/Messages/EnterSubPath=Enter a destination path" 44 | break 45 | end 46 | 47 | local fullPath = propertyTable.ftpPreset.path or "" 48 | 49 | if propertyTable.putInSubfolder then 50 | fullPath = LrFtp.appendFtpPaths( fullPath, propertyTable.path ) 51 | end 52 | 53 | propertyTable.fullPath = fullPath 54 | 55 | until true 56 | 57 | if message then 58 | propertyTable.message = message 59 | propertyTable.hasError = true 60 | propertyTable.hasNoError = false 61 | propertyTable.LR_cantExportBecause = message 62 | else 63 | propertyTable.message = nil 64 | propertyTable.hasError = false 65 | propertyTable.hasNoError = true 66 | propertyTable.LR_cantExportBecause = nil 67 | end 68 | 69 | end 70 | 71 | ------------------------------------------------------------------------------- 72 | 73 | function FtpUploadExportDialogSections.startDialog( propertyTable ) 74 | 75 | propertyTable:addObserver( 'items', updateExportStatus ) 76 | propertyTable:addObserver( 'path', updateExportStatus ) 77 | propertyTable:addObserver( 'putInSubfolder', updateExportStatus ) 78 | propertyTable:addObserver( 'ftpPreset', updateExportStatus ) 79 | 80 | updateExportStatus( propertyTable ) 81 | 82 | end 83 | 84 | ------------------------------------------------------------------------------- 85 | 86 | function FtpUploadExportDialogSections.sectionsForBottomOfDialog( _, propertyTable ) 87 | 88 | local f = LrView.osFactory() 89 | local bind = LrView.bind 90 | local share = LrView.share 91 | local LrFtp = import 'LrFtp' 92 | 93 | local result = { 94 | 95 | { 96 | title = LOC "$$$/FtpUpload/ExportDialog/FtpSettings=FTP Server", 97 | 98 | synopsis = bind { key = 'fullPath', object = propertyTable }, 99 | 100 | f:row { 101 | f:static_text { 102 | title = LOC "$$$/FtpUpload/ExportDialog/Destination=Destination:", 103 | alignment = 'right', 104 | width = share 'labelWidth' 105 | }, 106 | 107 | LrFtp.makeFtpPresetPopup { 108 | factory = f, 109 | properties = propertyTable, 110 | valueBinding = 'ftpPreset', 111 | itemsBinding = 'items', 112 | fill_horizontal = 1, 113 | }, 114 | }, 115 | 116 | f:row { 117 | f:spacer { 118 | width = share 'labelWidth' 119 | }, 120 | 121 | f:checkbox { 122 | title = LOC "$$$/FtpUpload/ExportDialog/PutInSubfolder=Put in Subfolder:", 123 | value = bind 'putInSubfolder', 124 | }, 125 | 126 | f:edit_field { 127 | value = bind 'path', 128 | enabled = bind 'putInSubfolder', 129 | validate = LrFtp.ftpPathValidator, 130 | truncation = 'middle', 131 | immediate = true, 132 | fill_horizontal = 1, 133 | }, 134 | }, 135 | 136 | f:column { 137 | place = 'overlapping', 138 | fill_horizontal = 1, 139 | 140 | f:row { 141 | f:static_text { 142 | title = LOC "$$$/FtpUpload/ExportDialog/FullPath=Full Path:", 143 | alignment = 'right', 144 | width = share 'labelWidth', 145 | visible = bind 'hasNoError', 146 | }, 147 | 148 | f:static_text { 149 | fill_horizontal = 1, 150 | width_in_chars = 20, 151 | title = bind 'fullPath', 152 | visible = bind 'hasNoError', 153 | }, 154 | }, 155 | 156 | f:row { 157 | f:static_text { 158 | fill_horizontal = 1, 159 | title = bind 'message', 160 | visible = bind 'hasError', 161 | }, 162 | }, 163 | }, 164 | }, 165 | } 166 | 167 | return result 168 | 169 | end 170 | -------------------------------------------------------------------------------- /ftp_upload.lrdevplugin/FtpUploadServiceProvider.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | FtpUploadExportServiceProvider.lua 4 | Export service provider description for Lightroom FtpUpload uploader 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- FtpUpload plug-in 20 | require "FtpUploadExportDialogSections" 21 | require "FtpUploadTask" 22 | 23 | 24 | --============================================================================-- 25 | 26 | return { 27 | 28 | hideSections = { 'exportLocation' }, 29 | 30 | allowFileFormats = nil, -- nil equates to all available formats 31 | 32 | allowColorSpaces = nil, -- nil equates to all color spaces 33 | 34 | exportPresetFields = { 35 | { key = 'putInSubfolder', default = false }, 36 | { key = 'path', default = 'photos' }, 37 | { key = "ftpPreset", default = nil }, 38 | { key = "fullPath", default = nil }, 39 | }, 40 | 41 | startDialog = FtpUploadExportDialogSections.startDialog, 42 | sectionsForBottomOfDialog = FtpUploadExportDialogSections.sectionsForBottomOfDialog, 43 | 44 | processRenderedPhotos = FtpUploadTask.processRenderedPhotos, 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ftp_upload.lrdevplugin/FtpUploadTask.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | FtpUploadTask.lua 4 | Upload photos via Ftp 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Lightroom API 20 | local LrPathUtils = import 'LrPathUtils' 21 | local LrFtp = import 'LrFtp' 22 | local LrFileUtils = import 'LrFileUtils' 23 | local LrErrors = import 'LrErrors' 24 | local LrDialogs = import 'LrDialogs' 25 | 26 | --============================================================================-- 27 | 28 | FtpUploadTask = {} 29 | 30 | -------------------------------------------------------------------------------- 31 | 32 | function FtpUploadTask.processRenderedPhotos( functionContext, exportContext ) 33 | 34 | -- Make a local reference to the export parameters. 35 | 36 | local exportSession = exportContext.exportSession 37 | local exportParams = exportContext.propertyTable 38 | local ftpPreset = exportParams.ftpPreset 39 | 40 | -- Set progress title. 41 | 42 | local nPhotos = exportSession:countRenditions() 43 | 44 | local progressScope = exportContext:configureProgress { 45 | title = nPhotos > 1 46 | and LOC( "$$$/FtpUpload/Upload/Progress=Uploading ^1 photos via Ftp", nPhotos ) 47 | or LOC "$$$/FtpUpload/Upload/Progress/One=Uploading one photo via Ftp", 48 | } 49 | 50 | -- Create an FTP connection. 51 | 52 | if not LrFtp.queryForPasswordIfNeeded( ftpPreset ) then 53 | return 54 | end 55 | 56 | local ftpInstance = LrFtp.create( ftpPreset, true ) 57 | 58 | if not ftpInstance then 59 | 60 | -- This really shouldn't ever happen. 61 | 62 | LrErrors.throwUserError( LOC "$$$/FtpUpload/Upload/Errors/InvalidFtpParameters=The specified FTP preset is incomplete and cannot be used." ) 63 | end 64 | 65 | -- Ensure target directory exists. 66 | 67 | local index = 0 68 | while true do 69 | 70 | local subPath = string.sub( exportParams.fullPath, 0, index ) 71 | ftpInstance.path = subPath 72 | 73 | local exists = ftpInstance:exists( '' ) 74 | 75 | if exists == false then 76 | local success = ftpInstance:makeDirectory( '' ) 77 | 78 | if not success then 79 | 80 | -- This is a possible situation if permissions don't allow us to create directories. 81 | 82 | LrErrors.throwUserError( LOC "$$$/FtpUpload/Upload/Errors/CannotMakeDirectoryForUpload=Cannot upload because Lightroom could not create the destination directory." ) 83 | end 84 | 85 | elseif exists == 'file' then 86 | 87 | -- Unlikely, due to the ambiguous way paths for directories get tossed around. 88 | 89 | LrErrors.throwUserError( LOC "$$$/FtpUpload/Upload/Errors/UploadDestinationIsAFile=Cannot upload to a destination that already exists as a file." ) 90 | elseif exists == 'directory' then 91 | 92 | -- Excellent, it exists, do nothing here. 93 | 94 | else 95 | 96 | -- Not sure if this would every really happen. 97 | 98 | LrErrors.throwUserError( LOC "$$$/FtpUpload/Upload/Errors/CannotCheckForDestination=Unable to upload because Lightroom cannot ascertain if the target destination exists." ) 99 | end 100 | 101 | if index == nil then 102 | break 103 | end 104 | 105 | index = string.find( exportParams.fullPath, "/", index + 1 ) 106 | 107 | end 108 | 109 | ftpInstance.path = exportParams.fullPath 110 | 111 | -- Iterate through photo renditions. 112 | 113 | local failures = {} 114 | 115 | for _, rendition in exportContext:renditions{ stopIfCanceled = true } do 116 | 117 | -- Wait for next photo to render. 118 | 119 | local success, pathOrMessage = rendition:waitForRender() 120 | 121 | -- Check for cancellation again after photo has been rendered. 122 | 123 | if progressScope:isCanceled() then break end 124 | 125 | if success then 126 | 127 | local filename = LrPathUtils.leafName( pathOrMessage ) 128 | 129 | local success = ftpInstance:putFile( pathOrMessage, filename ) 130 | 131 | if not success then 132 | 133 | -- If we can't upload that file, log it. For example, maybe user has exceeded disk 134 | -- quota, or the file already exists and we don't have permission to overwrite, or 135 | -- we don't have permission to write to that directory, etc.... 136 | 137 | table.insert( failures, filename ) 138 | end 139 | 140 | -- When done with photo, delete temp file. There is a cleanup step that happens later, 141 | -- but this will help manage space in the event of a large upload. 142 | 143 | LrFileUtils.delete( pathOrMessage ) 144 | 145 | end 146 | 147 | end 148 | 149 | ftpInstance:disconnect() 150 | 151 | if #failures > 0 then 152 | local message 153 | if #failures == 1 then 154 | message = LOC "$$$/FtpUpload/Upload/Errors/OneFileFailed=1 file failed to upload correctly." 155 | else 156 | message = LOC ( "$$$/FtpUpload/Upload/Errors/SomeFileFailed=^1 files failed to upload correctly.", #failures ) 157 | end 158 | LrDialogs.message( message, table.concat( failures, "\n" ) ) 159 | end 160 | 161 | end 162 | -------------------------------------------------------------------------------- /ftp_upload.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | Summary information for ftp_upload sample plug-in 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2007 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | 18 | ------------------------------------------------------------------------------]] 19 | 20 | return { 21 | 22 | LrSdkVersion = 3.0, 23 | LrSdkMinimumVersion = 1.3, -- minimum SDK version required by this plug-in 24 | 25 | LrToolkitIdentifier = 'com.adobe.lightroom.export.ftp_upload', 26 | 27 | LrPluginName = LOC "$$$/FTPUpload/PluginName=FTP Upload Sample", 28 | 29 | LrExportServiceProvider = { 30 | title = "FTP Upload", 31 | file = 'FtpUploadServiceProvider.lua', 32 | }, 33 | 34 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 35 | 36 | } 37 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/CustomDialogWithMultipleBind.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | CustomDialogMultipleBind.lua 15 | From the Hello World sample plug-in. Displays several custom dialog and writes debug info. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Access the Lightroom SDK namespaces. 20 | 21 | local LrFunctionContext = import 'LrFunctionContext' 22 | local LrBinding = import 'LrBinding' 23 | local LrDialogs = import 'LrDialogs' 24 | local LrView = import 'LrView' 25 | 26 | 27 | --[[ 28 | Demonstrates a custom dialog with a multi binding, two properties from 29 | separate tables are bound to the value of a text field. The dialog displays two 30 | sliders. Each slider's value is shown in a field next to the slider. A third text field 31 | displays the values from both sliders. 32 | 33 | Whenever either of the sliders' value changes the third text field will be updated. 34 | The binding is done by overriding the default property table for the key value that resides 35 | in the second property table. 36 | ]] 37 | local function showCustomDialogWithMultipleBind() 38 | 39 | LrFunctionContext.callWithContext( "showCustomDialogWithMultipleBind", function( context ) 40 | 41 | -- Create two observable tables. 42 | 43 | local tableOne = LrBinding.makePropertyTable( context ) -- This will be bound to the view 44 | local tableTwo = LrBinding.makePropertyTable( context ) 45 | 46 | -- Add a property to each table. 47 | 48 | tableOne.sliderOne = 0 49 | tableTwo.sliderTwo = 50 50 | 51 | local f = LrView.osFactory() 52 | 53 | local c = f:column { 54 | 55 | bind_to_object = tableOne, -- bind tableOne 56 | spacing = f:control_spacing(), 57 | 58 | f:row { 59 | f:group_box { 60 | title = "Slider One", 61 | font = "", 62 | f:slider { 63 | value = LrView.bind( "sliderOne" ), 64 | min = 0, 65 | max = 100, 66 | width = LrView.share( "slider_width" ) 67 | }, 68 | 69 | f:edit_field { 70 | place_horizontal = 0.5, 71 | value = LrView.bind( "sliderOne" ), 72 | width_in_digits = 7 73 | }, 74 | }, 75 | 76 | f:group_box { 77 | title = "Slider Two", 78 | font = "", 79 | f:slider { 80 | bind_to_object = tableTwo, 81 | value = LrView.bind( "sliderTwo" ), 82 | min = 0, 83 | max = 100, 84 | width = LrView.share( "slider_width" ) 85 | }, 86 | 87 | f:edit_field { 88 | place_horizontal = 0.5, 89 | bind_to_object = tableTwo, 90 | value = LrView.bind( "sliderTwo" ), 91 | width_in_digits = 7 92 | } 93 | }, 94 | }, 95 | 96 | f:group_box { 97 | fill_horizontal = 1, 98 | title = "Both Values", 99 | font = "", 100 | 101 | f:edit_field{ 102 | place_horizontal = 0.5, 103 | value = LrView.bind { 104 | 105 | -- Supply a table with table keys. 106 | 107 | keys = { 108 | { 109 | -- Only the key name is needed as sliderOne in tableOne and that is already bound. 110 | 111 | key = "sliderOne" 112 | }, 113 | { 114 | -- We need to supply the key and the table to which it belongs. 115 | 116 | key = "sliderTwo", 117 | bind_to_object = tableTwo 118 | } 119 | }, 120 | 121 | -- This operation will create the value for this edit_field. 122 | -- The bound values are accessed with the arg 'values'. 123 | operation = function( _, values, _ ) 124 | return values.sliderTwo + values.sliderOne 125 | end 126 | }, 127 | width_in_digits = 7 128 | }, 129 | } 130 | } 131 | 132 | LrDialogs.presentModalDialog { 133 | title = "Custom Dialog Multiple Bind", 134 | contents = c 135 | } 136 | 137 | end ) 138 | 139 | 140 | end 141 | 142 | -- Now display the dialogs. 143 | 144 | showCustomDialogWithMultipleBind() 145 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/CustomDialogWithObserver.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | CustomDialogWithObserver.lua 15 | From the Hello World sample plug-in. Displays several custom dialog and writes debug info. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Access the Lightroom SDK namespaces. 20 | 21 | local LrFunctionContext = import 'LrFunctionContext' 22 | local LrBinding = import 'LrBinding' 23 | local LrDialogs = import 'LrDialogs' 24 | local LrView = import 'LrView' 25 | local LrLogger = import 'LrLogger' 26 | local LrColor = import 'LrColor' 27 | 28 | -- Create the logger and enable the print function. 29 | 30 | local myLogger = LrLogger( 'libraryLogger' ) 31 | myLogger:enable( "print" ) -- Pass either a string or a table of actions. 32 | 33 | -- Write trace information to the logger. 34 | 35 | local function outputToLog( message ) 36 | myLogger:trace( message ) 37 | end 38 | 39 | --[[ 40 | Demonstrates a custom dialog with a simple binding. The dialog has a text field 41 | that is used to update a value in an observable table. The table has an observer 42 | attached that will be notified when a key value is updated. The observer is 43 | only interested in the props.myObservedString. When that value changes the 44 | observer will be notified. 45 | ]] 46 | local function showCustomDialogWithObserver() 47 | 48 | LrFunctionContext.callWithContext( "showCustomDialogWithObserver", function( context ) 49 | 50 | -- Create a bindable table. Whenever a field in this table changes then notifications 51 | -- will be sent. Note that we do NOT bind this to the UI. 52 | 53 | local props = LrBinding.makePropertyTable( context ) 54 | props.myObservedString = "This is my string" 55 | 56 | local f = LrView.osFactory() 57 | 58 | -- Create the UI components like this so we can access the values as vars. 59 | 60 | local staticTextValue = f:static_text { 61 | title = props.myObservedString, 62 | } 63 | 64 | local updateField = f:edit_field { 65 | immediate = true, 66 | value = "Enter some text!!" 67 | } 68 | 69 | -- This is the function that will run when the value props.myString is changed. 70 | 71 | local function myCalledFunction() 72 | outputToLog( "props.myObservedString has been updated." ) 73 | staticTextValue.title = updateField.value 74 | staticTextValue.text_color = LrColor ( 1, 0, 0 ) 75 | end 76 | 77 | -- Add an observer to the property table. We pass in the key and the function 78 | -- we want called when the value for the key changes. 79 | -- Note: Only when the value changes will there be a notification sent which 80 | -- causes the function to be invoked. 81 | 82 | props:addObserver( "myObservedString", myCalledFunction ) 83 | 84 | -- Create the contents for the dialog. 85 | 86 | local c = f:column { 87 | spacing = f:dialog_spacing(), 88 | f:row{ 89 | fill_horizontal = 1, 90 | f:static_text { 91 | alignment = "right", 92 | width = LrView.share "label_width", 93 | title = "Bound value: " 94 | }, 95 | staticTextValue, 96 | }, -- end f:row 97 | 98 | f:row { 99 | f:static_text { 100 | alignment = "right", 101 | width = LrView.share "label_width", 102 | title = "New value: " 103 | }, 104 | updateField, 105 | f:push_button { 106 | title = "Update", 107 | 108 | -- When the 'Update' button is clicked. 109 | 110 | action = function() 111 | outputToLog( "Update button clicked." ) 112 | staticTextValue.text_color = LrColor ( 0, 0, 0) 113 | 114 | -- When this property is updated, the observer is notified. 115 | 116 | props.myObservedString = updateField.value 117 | end 118 | }, 119 | }, -- end row 120 | } -- end column 121 | 122 | LrDialogs.presentModalDialog { 123 | title = "Custom Dialog Observer", 124 | contents = c 125 | } 126 | 127 | end) -- end main function 128 | 129 | 130 | end 131 | 132 | -- Now display the dialogs. 133 | 134 | showCustomDialogWithObserver() 135 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/ExportMenuItem.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | ExportMenuItem.lua 15 | From the Hello World sample plug-in. Displays a modal dialog and writes debug info. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Access the Lightroom SDK namespaces. 20 | local LrDialogs = import 'LrDialogs' 21 | local LrLogger = import 'LrLogger' 22 | 23 | -- Create the logger and enable the print function. 24 | local myLogger = LrLogger( 'exportLogger' ) 25 | myLogger:enable( "print" ) -- Pass either a string or a table of actions. 26 | 27 | -------------------------------------------------------------------------------- 28 | -- Write trace information to the logger. 29 | 30 | local function outputToLog( message ) 31 | myLogger:trace( message ) 32 | end 33 | 34 | -------------------------------------------------------------------------------- 35 | -- Display a modal information dialog. 36 | 37 | local function showModalDialog() 38 | 39 | outputToLog( "MyHWExportItem.showModalMessage function entered." ) 40 | LrDialogs.message( "ExportMenuItem Selected", "Hello World!", "info" ); 41 | outputToLog( "MyHWExportItem.showModalMessage function exiting." ) 42 | 43 | end 44 | 45 | -------------------------------------------------------------------------------- 46 | -- Display a dialog. 47 | showModalDialog() 48 | 49 | 50 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | Info.lua 15 | Summary information for Hello World sample plug-in. 16 | 17 | Adds menu items to Lightroom. 18 | 19 | ------------------------------------------------------------------------------]] 20 | 21 | return { 22 | 23 | LrSdkVersion = 3.0, 24 | LrSdkMinimumVersion = 1.3, -- minimum SDK version required by this plug-in 25 | 26 | LrToolkitIdentifier = 'com.adobe.lightroom.sdk.helloworld', 27 | 28 | LrPluginName = LOC "$$$/HelloWorld/PluginName=Hello World Sample", 29 | 30 | -- Add the menu item to the File menu. 31 | 32 | LrExportMenuItems = { 33 | title = "Hello World Dialog", 34 | file = "ExportMenuItem.lua", 35 | }, 36 | 37 | -- Add the menu item to the Library menu. 38 | 39 | LrLibraryMenuItems = { 40 | { 41 | title = LOC "$$$/HelloWorld/CustomDialog=Hello World Custom Dialog", 42 | file = "ShowCustomDialog.lua", 43 | }, 44 | { 45 | title = LOC "$$$/HelloWorld/MultiBind=Hello World Custom Dialog with MultipleBind", 46 | file = "CustomDialogWithMultipleBind.lua", 47 | }, 48 | { 49 | title = LOC "$$$/HelloWorld/RadioButtons=Hello World RadioButtons", 50 | file = "RadioButtons.lua", 51 | }, 52 | { 53 | title = LOC "$$$/HelloWorld/DialogObserver=Hello World Custom Dialog with Observer", 54 | file = "CustomDialogWithObserver.lua", 55 | }, 56 | }, 57 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 58 | 59 | } 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/RadioButtons.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | RadioButton.lua 15 | From the Hello World sample plug-in. Displays several custom dialogs and writes debug info. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Access the Lightroom SDK namespaces. 20 | local LrFunctionContext = import 'LrFunctionContext' 21 | local LrBinding = import 'LrBinding' 22 | local LrDialogs = import 'LrDialogs' 23 | local LrView = import 'LrView' 24 | local LrLogger = import 'LrLogger' 25 | local LrColor = import 'LrColor' 26 | 27 | -- Create the logger and enable the print function. 28 | 29 | local myLogger = LrLogger( 'libraryLogger' ) 30 | myLogger:enable( "print" ) -- Pass either a string or a table of actions 31 | 32 | -- Write trace information to the logger. 33 | 34 | local function outputToLog( message ) 35 | myLogger:trace( message ) 36 | end 37 | 38 | 39 | --[[ 40 | Demonstrates a custom dialog with a complex binding. The dialog displays two 41 | radio buttons and a label. The contents of the label are updated depending on 42 | which button is selected. 43 | 44 | All three controls are bound to the same value in an observed table. Whenever 45 | the property 'selectedButton' is modified then changes are reflected in the radio 46 | buttons and the label. 47 | 48 | The static_text.title value uses a binding with a transform function. The value retuned 49 | from the transform function is a string of our choosing, rather than the value of the 50 | bound property. In this case the label simply updates to whichever button is selected. 51 | 52 | ]] 53 | local function showCustomDialogWithTransform() 54 | 55 | LrFunctionContext.callWithContext( "RadioButtons", function( context ) 56 | 57 | -- Create a bindable table. Whenever a field in this table changes 58 | -- then notifications will be sent. 59 | 60 | local props = LrBinding.makePropertyTable( context ) 61 | props.selectedButton = "one" 62 | 63 | local f = LrView.osFactory() 64 | 65 | local c = f:column { 66 | bindToObject = props, 67 | spacing = f:control_spacing(), 68 | 69 | f:row{ 70 | f:column { 71 | 72 | spacing = f:control_spacing(), 73 | 74 | -- A radio button is selected when its value is equal to its checked_value. 75 | 76 | f:radio_button { 77 | title = "Button one", 78 | value = LrView.bind( "selectedButton" ), 79 | checked_value = "one", 80 | }, 81 | 82 | f:radio_button { 83 | title = "Button two", 84 | value = LrView.bind( "selectedButton" ), 85 | checked_value = "two", 86 | }, 87 | }, 88 | }, 89 | 90 | f:row { 91 | 92 | f:static_text { 93 | text_color = LrColor( 1, 0, 0 ), 94 | title = LrView.bind( 95 | { 96 | key = "selectedButton", -- the key value to bind to. The property table (props) is already bound 97 | transform = function( value, _ ) 98 | outputToLog( "showCustomDialogWithTransform" .. value ) 99 | if value == "one" then 100 | return "Button one selected" 101 | else 102 | return "Button two selected" 103 | end 104 | end 105 | }), 106 | } 107 | }, 108 | } 109 | 110 | LrDialogs.presentModalDialog { 111 | title = "Custom Dialog Transform", 112 | contents = c 113 | } 114 | 115 | end) -- end callWithContext 116 | 117 | end 118 | 119 | 120 | -- Now display the dialogs 121 | showCustomDialogWithTransform() 122 | -------------------------------------------------------------------------------- /helloworld.lrdevplugin/ShowCustomDialog.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ADOBE SYSTEMS INCORPORATED 4 | Copyright 2007 Adobe Systems Incorporated 5 | All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 8 | with the terms of the Adobe license agreement accompanying it. If you have received 9 | this file from a source other than Adobe, then your use, modification, or distribution 10 | of it requires the prior written permission of Adobe. 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | ShowCustomDialog.lua 15 | From the Hello World sample plug-in. Displays a custom dialog and writes debug info. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Access the Lightroom SDK namespaces. 20 | local LrFunctionContext = import 'LrFunctionContext' 21 | local LrBinding = import 'LrBinding' 22 | local LrDialogs = import 'LrDialogs' 23 | local LrView = import 'LrView' 24 | 25 | --[[ 26 | Demonstrates a custom dialog with a simple binding. The dialog displays a 27 | checkbox and a text field. When the check box is selected the text field becomes 28 | enabled, if the checkbox is unchecked then the text field is disabled. 29 | 30 | The check_box.value and the edit_field.enabled are bound to the same value in an 31 | observable table. When the check_box is checked/unchecked the changes are reflected 32 | in the bound property 'isChecked'. Because the edit_field.enabled value is also bound then 33 | it reflects whatever value 'isChecked' has. 34 | ]] 35 | local function showCustomDialog() 36 | 37 | LrFunctionContext.callWithContext( "showCustomDialog", function( context ) 38 | 39 | local f = LrView.osFactory() 40 | 41 | -- Create a bindable table. Whenever a field in this table changes 42 | -- then notifications will be sent. 43 | local props = LrBinding.makePropertyTable( context ) 44 | props.isChecked = false 45 | 46 | -- Create the contents for the dialog. 47 | local c = f:row { 48 | 49 | -- Bind the table to the view. This enables controls to be bound 50 | -- to the named field of the 'props' table. 51 | 52 | bind_to_object = props, 53 | 54 | -- Add a checkbox and an edit_field. 55 | 56 | f:checkbox { 57 | title = "Enable", 58 | value = LrView.bind( "isChecked" ), 59 | }, 60 | f:edit_field { 61 | value = "Some Text", 62 | enabled = LrView.bind( "isChecked" ) 63 | } 64 | } 65 | 66 | LrDialogs.presentModalDialog { 67 | title = "Custom Dialog", 68 | contents = c 69 | } 70 | 71 | 72 | end) -- end main function 73 | 74 | end 75 | 76 | 77 | -- Now display the dialogs. 78 | showCustomDialog() 79 | -------------------------------------------------------------------------------- /languagefilter.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | Summary information for language filter plug-in 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | 18 | ------------------------------------------------------------------------------]] 19 | 20 | return { 21 | 22 | LrSdkVersion = 3.0, 23 | LrSdkMinimumVersion = 2.0, 24 | 25 | LrPluginName = "Language External Tool", 26 | LrToolkitIdentifier = 'com.adobe.lightroom.sdk.export.language', 27 | 28 | LrExportFilterProvider = { 29 | title = "Language External Tool", 30 | file = 'LanguageExternalToolFilterProvider.lua', 31 | }, 32 | 33 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 34 | 35 | } 36 | -------------------------------------------------------------------------------- /languagefilter.lrdevplugin/LanguageExternalToolFilterProvider.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | LanguageExternalToolFilterProvider.lua 4 | Export service provider description for Creator external tool sample 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | -- Lightroom SDK 20 | local LrView = import 'LrView' 21 | local bind = LrView.bind 22 | local LrPathUtils = import 'LrPathUtils' 23 | local LrTasks = import "LrTasks" 24 | 25 | 26 | --============================================================================-- 27 | 28 | local LanguageExternalToolFilterProvider = {} 29 | 30 | ------------------------------------------------------------------------------- 31 | 32 | LanguageExternalToolFilterProvider.exportPresetFields = { 33 | { key = 'language', default = 'x-default' }, 34 | { key = 'title', default = '' }, 35 | } 36 | 37 | ------------------------------------------------------------------------------- 38 | 39 | function LanguageExternalToolFilterProvider.sectionForFilterInDialog( viewFactory, propertyTable ) 40 | 41 | return { 42 | title = 'Language External Tool Sample', 43 | 44 | viewFactory:row { 45 | spacing = viewFactory:control_spacing(), 46 | viewFactory:static_text { 47 | title = "Title", 48 | }, 49 | viewFactory:edit_field { 50 | value = bind 'title', 51 | }, 52 | 53 | viewFactory:popup_menu { 54 | value = bind 'language', 55 | items = { 56 | { title = "Default", value = "x-default" }, 57 | { title = "English [US]", value = "en-US" }, 58 | { title = "German [Germany]", value = "de-DE" }, 59 | { title = "German [Switzerland]", value = "de-CH" }, 60 | { title = "French [France]", value = "fr-FR" }, 61 | { title = "Italian [Italy]", value = "it-IT" }, 62 | { title = "Japanese [Japan]", value = "jp-JP" }, 63 | { title = "Arabic [U.A.E.]", value = "ar-AE" }, 64 | { title = "Bulgarian [Bulgaria]", value = "bg-BG" }, 65 | { title = "Czech [Czech Republic]", value = "cs-CZ" }, 66 | { title = "Danish [Denmark]", value = "da-DK" }, 67 | { title = "Greek [Greece]", value = "el-GR" }, 68 | { title = "English [United Kingdom]", value = "en-GB" }, 69 | { title = "Spanish [Spain]", value = "es-ES" }, 70 | { title = "Finnish [Finland]", value = "fi-FI" }, 71 | { title = "Norwegian [Norway]", value = "no-NO" }, 72 | { title = "Dutch [Netherlands]", value = "nl-NL" }, 73 | { title = "Romanian [Romania]", value = "ro-RO" }, 74 | { title = "Polish [Poland]", value = "pl-PL" }, 75 | }, 76 | }, 77 | }, 78 | } 79 | end 80 | 81 | ------------------------------------------------------------------------------- 82 | 83 | function LanguageExternalToolFilterProvider.postProcessRenderedPhotos( functionContext, filterContext ) 84 | 85 | local lang = filterContext.propertyTable.language 86 | local title = filterContext.propertyTable.title 87 | 88 | local renditionOptions = { 89 | plugin = _PLUGIN, 90 | renditionsToSatisfy = filterContext.renditionsToSatisfy, 91 | filterSettings = function( renditionToSatisfy, exportSettings ) 92 | 93 | -- This hook function gives you the opportunity to change the render 94 | -- settings for each photo before Lightroom renders it. 95 | -- For example, if you wanted Lightroom to generate TIFF files, 96 | -- you can add below statements: 97 | -- exportSettings.LR_format = TIFF 98 | -- return os.tmpname() 99 | -- By doing so, you assume responsibility for creating 100 | -- the file type that was originally requested and placing it 101 | -- in the location that was originally requested in your filter loop below. 102 | 103 | end, 104 | } 105 | 106 | local command 107 | local quotedCommand 108 | 109 | for sourceRendition, renditionToSatisfy in filterContext:renditions( renditionOptions ) do 110 | 111 | -- Wait for the upstream task to finish its work on this photo. 112 | 113 | local success, pathOrMessage = sourceRendition:waitForRender() 114 | if success then 115 | 116 | -- Now that the photo is completed and available to this filter, 117 | -- you can do your work on the photo here. This sample passes the user's settings, 118 | -- the title and language to an external application to update the metadata. 119 | 120 | local path = pathOrMessage 121 | 122 | if WIN_ENV == true then 123 | command = '"' .. LrPathUtils.child( LrPathUtils.child( _PLUGIN.path, "win" ), "LightroomLanguageXMP.exe" ) .. '" ' .. '"' .. path .. '" ' .. '"' .. lang .. '" ' .. '"' .. title .. '" ' 124 | quotedCommand = '"' .. command .. '"' 125 | else 126 | command = '"' .. LrPathUtils.child(LrPathUtils.child( _PLUGIN.path, "mac" ), "LightroomLanguageXMP" ) .. '" ' .. '"' .. path .. '" ' .. '"' .. lang .. '" ' .. '"' .. title .. '"' 127 | quotedCommand = command 128 | end 129 | 130 | if LrTasks.execute( quotedCommand ) ~= 0 then 131 | renditionToSatisfy:renditionIsDone( false, "Failed to contact Language XMP Application" ) 132 | end 133 | 134 | end 135 | 136 | end 137 | 138 | end 139 | 140 | ------------------------------------------------------------------------------- 141 | 142 | return LanguageExternalToolFilterProvider 143 | -------------------------------------------------------------------------------- /languagefilter.lrdevplugin/mac/LightroomLanguageXMP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/languagefilter.lrdevplugin/mac/LightroomLanguageXMP -------------------------------------------------------------------------------- /languagefilter.lrdevplugin/win/LightroomLanguageXMP.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/languagefilter.lrdevplugin/win/LightroomLanguageXMP.exe -------------------------------------------------------------------------------- /metaexportfilter.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | metaExportFilter Sample 5 | Summary information for Metadata Export Filter plugin sample plugin 6 | -------------------------------------------------------------------------------- 7 | ADOBE SYSTEMS INCORPORATED 8 | Copyright 2008 Adobe Systems Incorporated 9 | All Rights Reserved. 10 | 11 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 12 | with the terms of the Adobe license agreement accompanying it. If you have received 13 | this file from a source other than Adobe, then your use, modification, or distribution 14 | of it requires the prior written permission of Adobe. 15 | ------------------------------------------------------------------------------]] 16 | 17 | return { 18 | 19 | LrSdkVersion = 3.0, 20 | LrSdkMinimumVersion = 1.3, -- minimum SDK version required by this plugin 21 | 22 | LrPluginName = LOC "$$$/SDK/MetaExportFilter/Sample=Metadata Post Process Sample", 23 | LrToolkitIdentifier = 'com.adobe.lightroom.sdk.export.metaexportfilter', 24 | 25 | LrExportFilterProvider = { 26 | title = LOC "$$$/SDK/MetaExportFilter/Sample=Metadata Post Process", -- the string that appears in the export filter section of the export dialog in LR 27 | file = 'MetadataExportFilterProvider.lua', -- name of the file containing the filter definition script 28 | id = "metadata", -- unique identifier for export filter 29 | }, 30 | 31 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 32 | 33 | } 34 | -------------------------------------------------------------------------------- /metaexportfilter.lrdevplugin/MetadataExportFilterProvider.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | ExportFilterProvider.lua 4 | metaExportFilter Sample Plugin 5 | ExportFilterProvider for the Metadata Export Filter sample plugin 6 | 7 | Defines the dialog section to be displayed in the Export dialog and provides the 8 | filter process before the photos are exported. 9 | 10 | -------------------------------------------------------------------------------- 11 | ADOBE SYSTEMS INCORPORATED 12 | Copyright 2008 Adobe Systems Incorporated 13 | All Rights Reserved. 14 | 15 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 16 | with the terms of the Adobe license agreement accompanying it. If you have received 17 | this file from a source other than Adobe, then your use, modification, or distribution 18 | of it requires the prior written permission of Adobe. 19 | 20 | ------------------------------------------------------------------------------]] 21 | 22 | local LrView = import 'LrView' 23 | local bind = LrView.bind 24 | 25 | -------------------------------------------------------------------------------- 26 | -- This function will check the status of the Export Dialog to determine 27 | -- if all required fields have been populated. 28 | 29 | local function updateFilterStatus( propertyTable, ... ) 30 | 31 | -- Initialise potential error message. 32 | local message = nil 33 | 34 | if propertyTable.metachoice == nil then 35 | message = LOC "$$$/SDK/MetaExportFilter/Messages/choice=Please choose which type of metadata to filter" 36 | elseif propertyTable.metavalue == nil then 37 | message = LOC "$$$/SDK/MetaExportFilter/Messages/choice=Please enter the required matching string" 38 | end 39 | 40 | if message then 41 | -- Display error. 42 | propertyTable.message = message 43 | propertyTable.hasError = true 44 | propertyTable.hasNoError = false 45 | propertyTable.LR_canExport = false 46 | 47 | else 48 | -- All required fields have been populated so enable Export button, reset message, and set error status to false. 49 | propertyTable.message = nil 50 | propertyTable.hasError = false 51 | propertyTable.hasNoError = true 52 | propertyTable.LR_canExport = true 53 | end 54 | end 55 | 56 | -------------------------------------------------------------------------------- 57 | -- This optional function adds the observers for our required fields metachoice and metavalue so we can change 58 | -- the dialog depending on whether they have been populated. 59 | 60 | local function startDialog( propertyTable ) 61 | 62 | propertyTable:addObserver( 'metachoice', updateFilterStatus ) 63 | propertyTable:addObserver( 'metavalue', updateFilterStatus ) 64 | updateFilterStatus( propertyTable ) 65 | 66 | end 67 | 68 | -------------------------------------------------------------------------------- 69 | -- This function will create the section displayed on the export dialog 70 | -- when this filter is added to the export session. 71 | 72 | local function sectionForFilterInDialog( f, propertyTable ) 73 | 74 | return { 75 | title = LOC "$$$/SDK/MetaExportFilter/SectionTitle=Metadata Export Filter", 76 | f:row { 77 | spacing = f:control_spacing(), 78 | f:static_text { 79 | title = "Metadata Filter", 80 | fill_horizontal = 1, 81 | }, 82 | 83 | f:popup_menu { 84 | value = bind 'metachoice', 85 | items = { 86 | { title = "Title", value = "title" }, 87 | { title = "Creator", value = "creator" }, 88 | { title = "Copyright Status", value = "copyright" }, 89 | { title = "File Name", value = "fileName" }, 90 | { title = "Folder", value = "folderName" }, 91 | }, 92 | }, 93 | 94 | f:edit_field { 95 | value = bind 'metavalue', 96 | }, 97 | } 98 | } 99 | end 100 | 101 | -------------------------------------------------------------------------------- 102 | -- We specify any presets here 103 | 104 | local exportPresetFields = { 105 | { key = 'metachoice', default = "Creator" }, 106 | { key = 'metavalue', default = '' }, 107 | } 108 | 109 | -------------------------------------------------------------------------------- 110 | -- This function obtains access to the photos and removes entries that don't match the metadata filter. 111 | 112 | local function shouldRenderPhoto( exportSettings, photo ) 113 | 114 | -- This function should return either: 115 | -- true, photo gets included in export, or 116 | -- false, photo should be removed from the export. 117 | -- The photo represents an LrPhoto object. 118 | 119 | local targetField = exportSettings.metachoice 120 | local targetValue = exportSettings.metavalue 121 | 122 | -- Now that the user has filled in this section, we need to filter through the images and only 123 | -- choose the ones that match the required metadata. 124 | 125 | local sourceMetaValue = photo:getFormattedMetadata( targetField ) 126 | 127 | local shouldRender = sourceMetaValue == targetValue 128 | 129 | return shouldRender 130 | 131 | end 132 | 133 | -------------------------------------------------------------------------------- 134 | 135 | return { 136 | 137 | exportPresetFields = exportPresetFields, 138 | startDialog = startDialog, 139 | sectionForFilterInDialog = sectionForFilterInDialog, 140 | shouldRenderPhoto = shouldRenderPhoto, 141 | } 142 | -------------------------------------------------------------------------------- /mymetadata.lrdevplugin/Info.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | Info.lua 4 | MyMetadata.lrplugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | LrSdkVersion = 3.0, 22 | 23 | LrToolkitIdentifier = 'sample.metadata.mymetadatasample', 24 | LrPluginName = "My Metadata Sample", 25 | 26 | LrMetadataTagsetFactory = { 27 | 'MyMetadataTagset.lua', 28 | 'MyMetadataTagsetAll.lua' 29 | }, 30 | 31 | VERSION = { major=8, minor=0, revision=0, build=1193777, }, 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mymetadata.lrdevplugin/MyMetadataDefinitionFile.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | MyMetadataDefinitionFile.lua 4 | MyMetadata.lrplugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | metadataFieldsForPhotos = { 22 | 23 | { 24 | id = 'siteId', 25 | }, 26 | 27 | { 28 | id = 'myString', 29 | title = "My String", 30 | dataType = 'string', -- Specifies the data type for this field. 31 | searchable = true, 32 | browsable = true, 33 | version = 2, 34 | }, 35 | 36 | { 37 | id = 'myboolean', 38 | title = "My Boolean", 39 | dataType = 'enum', 40 | searchable = true, 41 | browsable = true, 42 | version = 2, 43 | values = { 44 | { 45 | value = 'true', 46 | title = "True", 47 | }, 48 | { 49 | value = 'false', 50 | title = "False", 51 | }, 52 | }, 53 | }, 54 | 55 | }, 56 | 57 | schemaVersion = 1, 58 | 59 | } 60 | -------------------------------------------------------------------------------- /mymetadata.lrdevplugin/MyMetadataTagset.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | MyMetadataTagset.lua 4 | MyMetadata.lrplugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | return { 20 | 21 | title = "My Metadata", 22 | id = 'MyMetadataTagset', 23 | 24 | items = { 25 | 'com.adobe.filename', 26 | 'com.adobe.folder', 27 | 28 | 'com.adobe.separator', 29 | 30 | 'sample.metadata.mymetadatasample.*', 31 | }, 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mymetadata.lrdevplugin/MyMetadataTagsetAll.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | MyMetadataTagsetAll.lua 4 | MyMetadata.lrplugin 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | ADOBE SYSTEMS INCORPORATED 9 | Copyright 2008 Adobe Systems Incorporated 10 | All Rights Reserved. 11 | 12 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 13 | with the terms of the Adobe license agreement accompanying it. If you have received 14 | this file from a source other than Adobe, then your use, modification, or distribution 15 | of it requires the prior written permission of Adobe. 16 | 17 | ------------------------------------------------------------------------------]] 18 | 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | -- NOTE to developers reading this sample code: This file is used to generate 23 | -- the documentation for the "metadata tagset provider" section of the API 24 | -- reference material. This means it's more verbose than it would otherwise 25 | -- be, but also means that you can match up the documentation with an actual 26 | -- working example. It is not necessary for you to preserve any of the 27 | -- documentation comments in your own code. 28 | 29 | 30 | --===========================================================================-- 31 | --[[ @sdk 32 | --- The metadata-tagset provider is a Lua file that returns a tagset 33 | -- definition for filtering metadata displayed in the Library module's Metadata 34 | -- panel. Tagset defintions available to Lightroom are selected using the 35 | -- drop-down menu at the top left of the Metadata panel. 36 | --

First supported in version 2.0 of the Lightroom SDK.

37 | -- @module_type Plug-in provided 38 | 39 | module 'SDK - Metadata tagset provider' -- not actually executed, but suffices to trick LuaDocs 40 | 41 | --]] 42 | 43 | 44 | --============================================================================-- 45 | 46 | return { 47 | 48 | -------------------------------------------------------------------------------- 49 | --- (string, required) This table member defines the localizable display name of 50 | -- the tagset, which appears in the popup menu for the Metadata panel. 51 | -- @name title 52 | -- @class property 53 | 54 | title = "EXIF and IPTC and Extensions", 55 | 56 | -------------------------------------------------------------------------------- 57 | --- (string, required) This table member defines an identifier for this tagset 58 | -- that is unique within this plug-in. The name must conform to the same naming 59 | -- conventions as Lua variables; that is, it must start with a letter, followed 60 | -- by letters or numbers. Case is significant. 61 | -- @name id 62 | -- @class property 63 | 64 | id = 'MyMetadataTagsetAll', 65 | 66 | -------------------------------------------------------------------------------- 67 | --- (table, required) This table member defines an array of metadata fields that 68 | -- appear in this tagset, in order of appearance. Each entry in the items array 69 | -- identifies a field to be included in the Metadata menu. It can be a simple 70 | -- string specifying the field name, or an array that specifies the field name 71 | -- and additional information about that field. 72 | --

If present, it should be a table containing the following elements: 73 | --

    74 | --
  • (string) The first element in the array is the unique identifying 75 | -- name of the field, or one of the special values described below.
  • 76 | --
  • height_in_lines: (number) (optional) For text-entry fields, 77 | -- the number of lines of text for the field.
  • 78 | --
  • label: (string, optional) When the field name is the special 79 | -- value 'com.adobe.label', this is the localizable string to use as the section label.
  • 80 | --

81 | --

The field names accepted within tagsets are as follows: 82 | --

    83 | --
  • com.adobe.filename: The leaf name of the file 84 | -- (for example, "myFile.jpg").
  • 85 | --
  • com.adobe.originalFilename.ifDiffers: The leaf 86 | -- name of the file (for example, "myFile.jpg") prior to renaming. 87 | -- Only displayed if differs from the current file name.
  • 88 | --
  • com.adobe.sidecars: If any "sidecar" files are 89 | -- associated with this file (for instance, .xmp or .thm files), 90 | -- this item will list the extensions of those files.
  • 91 | --
  • com.adobe.copyname: The name associated with this copy.
  • 92 | --
  • com.adobe.folder: The name of the folder the file is in.
  • 93 | --
  • com.adobe.filesize: The formatted size of the file 94 | -- (for example, "6.01 MB")
  • 95 | --
  • com.adobe.fileFormat: The user-visible file type 96 | -- (DNG, RAW, etc.).
  • 97 | --
  • com.adobe.metadataStatus: The status of the metadata 98 | -- in the file, as compared to the metadata in the Lightroom catalog. 99 | -- Typical values (in English) are "Up to date", "Has been changed", 100 | -- or "Conflict exists". (This list is not exhaustive.)
  • 101 | --
  • com.adobe.metadataDate: Date/time when Lightroom last 102 | -- updated metadata in this file.
  • 103 | --
  • com.adobe.audioAnnotation: If an audio file (typically .wav file) 104 | -- is associated with this photo, this will contain the name of that 105 | -- file. Only displayed if there is an audio file.
  • 106 | --
  • com.adobe.separator: Inserts a dividing line.
  • 107 | --
  • com.adobe.rating: The user rating of the file (number of stars).
  • 108 | --
  • com.adobe.colorLabels: The name of assigned color label. Despite 109 | -- the plural name, only one color label can be assigned to a photo.
  • 110 | --
  • com.adobe.title: The title of photo.
  • 111 | --
  • com.adobe.caption: The caption for photo.
  • 112 | --
  • com.adobe.label: This entry allows you to insert a custom 113 | -- label describing the items that follow it.
  • 114 | --
  • com.adobe.imageFileDimensions: The original dimensions of 115 | -- the file (for example, "3072 x 2304").
  • 116 | --
  • com.adobe.imageCroppedDimensions: The cropped dimensions of 117 | -- file (for example, "3072 x 2304").
  • 118 | --
  • com.adobe.exposure: The exposure summary (for example, "1/60 sec at f/2.8")
  • 119 | -- exposureTime? 120 | --
  • com.adobe.shutterSpeedValue: The shutter speed (for example, "1/60 sec")
  • 121 | --
  • com.adobe.apertureValue: The aperture (for example, "f/2.8")
  • 122 | --
  • com.adobe.brightnessValue: The brightness value
  • 123 | --
  • com.adobe.exposureBiasValue: The exposure bias/compensation (for example, "-2/3 EV")
  • 124 | --
  • com.adobe.flash: Whether the flash fired or not (for example, "Did fire")
  • 125 | --
  • com.adobe.exposureProgram: The exposure program (for example, "Aperture priority")
  • 126 | --
  • com.adobe.meteringMode: The metering mode (for example, "Pattern")
  • 127 | --
  • com.adobe.ISOSpeedRating: The ISO speed rating (for example, "ISO 200")
  • 128 | --
  • com.adobe.focalLength: The focal length of lens as shot (for example, "132 mm")
  • 129 | --
  • com.adobe.focalLength35mm: The focal length as 35mm equivalent (for example, "211 mm")
  • 130 | --
  • com.adobe.lens: The lens (for example, "28.0-135.0 mm")
  • 131 | --
  • com.adobe.subjectDistance: The subject distance (for example, "3.98 m"). Approximate value only, and some camera vendors discourage its use.
  • 132 | --
  • com.adobe.dateTimeOriginal: The date and time of capture (for example, "09/15/2005 17:32:50") 133 | -- Formatting can vary based on the user's localization settings
  • 134 | --
  • com.adobe.dateTimeDigitized: The date and time of scanning (for example, "09/15/2005 17:32:50") 135 | -- Formatting can vary based on the user's localization settings
  • 136 | --
  • com.adobe.dateTime: Adjusted date and time (for example, "09/15/2005 17:32:50") 137 | -- Formatting can vary based on the user's localization settings
  • 138 | --
  • com.adobe.make: The camera manufacturer
  • 139 | --
  • com.adobe.model: The camera model
  • 140 | --
  • com.adobe.serialNumber: The camera serial number
  • 141 | --
  • com.adobe.userComment: The comments recorded by the user in camera
  • 142 | --
  • com.adobe.artist: The artist's name
  • 143 | --
  • com.adobe.software: The software used to process/create photo
  • 144 | --
  • com.adobe.GPS: The location of this photo (for example, "37°56'10" N 27°20'42" E")
  • 145 | --
  • com.adobe.GPSAltitude: The GPS altitude for this photo (for example, "82.3 m")
  • 146 | --
  • com.adobe.GPSImgDirection: The GPS direction for this photo (for example, "South")
  • 147 | --
  • com.adobe.creator: The name of the person that created this image
  • 148 | --
  • com.adobe.creatorJobTitle: The job title of the person that created this image
  • 149 | --
  • com.adobe.creatorAddress: The address for the person that created this image
  • 150 | --
  • com.adobe.creatorCity: The city for the person that created this image
  • 151 | --
  • com.adobe.creatorState: The state or city for the person that created this image
  • 152 | --
  • com.adobe.creatorZip: The postal code for the person that created this image
  • 153 | --
  • com.adobe.creatorCountry: The country for the person that created this image
  • 154 | --
  • com.adobe.creatorWorkPhone: The phone number for the person that created this image
  • 155 | --
  • com.adobe.creatorWorkEmail: The email address for the person that created this image
  • 156 | --
  • com.adobe.creatorWorkWebsite: The web URL for the person that created this image
  • 157 | --
  • com.adobe.headline: A brief, publishable synopsis or summary of the contents of this image
  • 158 | --
  • com.adobe.iptcSubjectCode: Values from the IPTC Subject NewsCode Controlled Vocabulary (see: http://www.newscodes.org/)
  • 159 | --
  • com.adobe.descriptionWriter: The name of the person involved in writing, editing or correcting the description of the image
  • 160 | --
  • com.adobe.category: Deprecated field; included for transferring legacy metadata
  • 161 | --
  • com.adobe.supplementalCategories: Deprecated field; included for transferring legacy metadata
  • 162 | --
  • com.adobe.dateCreated: The IPTC-formatted creation date (for example, "2005-09-20T15:10:55Z")
  • 163 | --
  • com.adobe.intellectualGenre: A term to describe the nature of the image in terms of its intellectual or journalistic characteristics, such as daybook, or feature (examples at: http://www.newscodes.org/)
  • 164 | --
  • com.adobe.scene: Values from the IPTC Scene NewsCodes Controlled Vocabulary (see: http://www.newscodes.org/)
  • 165 | --
  • com.adobe.location: Details about a location which is shown in this image
  • 166 | --
  • com.adobe.city: The name of the city pictured in this image
  • 167 | --
  • com.adobe.state: The name of the state pictured in this image
  • 168 | --
  • com.adobe.country: The name of the country pictured in this image
  • 169 | --
  • com.adobe.isoCountryCode: The 2 or 3 letter ISO 3166 Country Code of the country pictured in this image
  • 170 | --
  • com.adobe.jobIdentifier: A number or identifier needed for workflow control or tracking
  • 171 | --
  • com.adobe.instructions: Information about embargoes, or other restrictions not covered by the Rights Usage field
  • 172 | --
  • com.adobe.provider: Name of person who should be credited when this image is published
  • 173 | --
  • com.adobe.source: The original owner of the copyright of this image
  • 174 | --
  • com.adobe.copyright: The copyright text for this image
  • 175 | --
  • com.adobe.rightsUsageTerms: Instructions on how this image can legally be used
  • 176 | --
  • com.adobe.copyrightInfoURL
  • 177 | --
  • com.adobe.allPluginMetadata: All metadata defined by plug-ins.
  • 178 | --
  • (plugin ID).*: All metadata defined by the plug-in with the given ID.
  • 179 | --
  • (plugin ID).(field ID): A specific plug-in provided metadata field.
  • 180 | --
181 | --

The following items are first supported in version 3.0 of the Lightroom SDK.

182 | --
    183 | --
  • com.adobe.personInImage: Name of a person shown in the image
  • 184 | --
  • com.adobe.locationCreated: The Location the photo was taken. Each element in the return table is a table which is a structure named LocationDetails as defined in the IPTC Extension spec. Definition details can be found at http://www.iptc.org/std/photometadata/2008/specification/.
  • 185 | --
  • com.adobe.locationShown: The Location shown in the image. Each element in the return table is a table which is a structure named LocationDetails as defined in the IPTC Extension spec. Definition details can be found at http://www.iptc.org/std/photometadata/2008/specification/.
  • 186 | --
  • com.adobe.organisationInImageName: Name of the organization or company which is featured in the image
  • 187 | --
  • com.adobe.organisationInImageCode: Code from a controlled vocabulary for identifying the organization or company which is featured in the image
  • 188 | --
  • com.adobe.event: Names or describes the specific event at which the photo was taken
  • 189 | --
  • com.adobe.artworkOrObject: A set of metadata about artwork or an object in the image. Each element in the return table is a table which is a structure named ArtworkOrObjectDetails as defined in the IPTC Extension spec. Definition details can be found at http://www.iptc.org/std/photometadata/2008/specification/.
  • 190 | --
  • com.adobe.additionalModelInfo: Information about the ethnicity and other facets of model(s) in a model-released image
  • 191 | --
  • com.adobe.modelAge: Age of human model(s) at the time this image was taken in a model released image
  • 192 | --
  • com.adobe.minorModelAgeDisclosure: Age of the youngest model pictured in the image, at the time that the image was made.
  • 193 | --
  • com.adobe.modelReleaseStatus: Summarizes the availability and scope of model releases authorizing usage of the likenesses of persons appearing in the photograph.
  • 194 | --
  • com.adobe.modelReleaseID: A PLUS-ID identifying each Model Release
  • 195 | --
  • com.adobe.imageSupplier: Identifies the most recent supplier of item, who is not necessarily its owner or creator. Each element in the return table is a table which is a structure named ImageSupplierDetail defined in PLUS. Definition details can be found at http://ns.useplus.org/LDF/ldf-XMPReference.
  • 196 | --
  • com.adobe.imageSupplierImageId: Identifier assigned by the Image Supplier. Definition details can be found at http://ns.useplus.org/LDF/ldf-XMPReference.
  • 197 | --
  • com.adobe.registryId: Both a Registry Item Id and a Registry Organization Id to record any registration of this item with a registry. Each element in the return table is a table which is a structure named RegistryEntryDetail as defined in the IPTC Extension spec. Definition details can be found at http://www.iptc.org/std/photometadata/2008/specification/.
  • 198 | --
  • com.adobe.maxAvailWidth: The maximum available width in pixels of the original photo from which this photo has been derived by downsizing
  • 199 | --
  • com.adobe.maxAvailHeight: The maximum available height in pixels of the original photo from which this photo has been derived by downsizing
  • 200 | --
  • com.adobe.digitalSourceType: The type of the source of this digital image, selected from a controlled vocabulary
  • 201 | --
  • com.adobe.imageCreator: Creator or creators of the image. Each element in the return table is a table which is a structure named ImageCreatorDetail defined in PLUS. Definition details can be found at http://ns.useplus.org/LDF/ldf-XMPReference.
  • 202 | --
  • com.adobe.copyrightOwner: Owner or owners of the copyright in the licensed image. Each element in the return table is a table which is a structure named CopyrightOwnerDetail defined in PLUS. Definition details can be found at http://ns.useplus.org/LDF/ldf-XMPReference.
  • 203 | --
  • com.adobe.licensor: A person or company that should be contacted to obtain a license for using the item or who has licensed the item. Each element in the return table is a table which is a structure named LicensorDetail defined in PLUS. Definition details can be found at http://ns.useplus.org/LDF/ldf-XMPReference.
  • 204 | --
  • com.adobe.propertyReleaseID: A PLUS-ID identifying each Property Release
  • 205 | --
  • com.adobe.propertyReleaseStatus: Summarizes the availability and scope of property releases authorizing usage of the likenesses of persons appearing in the photograph.
  • 206 | --
  • com.adobe.digImageGUID: Globally unique identifier for the item, created and applied by the creator of the item at the time of its creation
  • 207 | --
  • com.adobe.plusVersion: The version number of the PLUS standards in place at the time of the transaction
  • 208 | --
209 | --

The following items are first supported in version 4.0 of the Lightroom SDK.

210 | --
    211 | --
  • com.adobe.duration: The duration of the media file in minutes and seconds. (for example, 01:59.0)
  • 212 | --
  • com.adobe.duration.combined.optional: The duration of the media file, and the duration of the trimmed media file (if trimmed).
  • 213 | --
  • com.adobe.trimmed_duration.optional: The duration of the trimmed media file (if trimmed).
  • 214 | --
  • com.adobe.videoFrameRate: The video frame rate, in frames per second.
  • 215 | --
  • com.adobe.videoAlphaMode: The alpha mode (for example, straight, pre-multiplied or none).
  • 216 | --
  • com.adobe.videoFrameSize: The frame size in pixels. For example: 640 x 480.
  • 217 | --
  • com.adobe.audioChannelType: The audio channel type. Valid text values are predefined in the XMP Dynamic Media namespace. Details can be found at http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf
  • 218 | --
  • com.adobe.audioSampleRate: The audio sample rate. Can be any value, but commonly 32000, 44100, or 48000 Hz.
  • 219 | --
  • com.adobe.audioSampleType: The audio sample type.
  • 220 | --
  • com.adobe.speakerPlacement: A description of the speaker angles from centre front in degrees. For example: "Left = -30, Right = 30, Centre = 0, LFE = 45, Left Surround = -110, Right Surround = 110"
  • 221 | --
  • com.adobe.tapeName: The name of the tape from which the clip was captured, as set during the capture process.
  • 222 | --
  • com.adobe.altTapeName: An alternative tape name.
  • 223 | --
  • com.adobe.dm_scene: The name of the scene.
  • 224 | --
  • com.adobe.shotName: The name of the shot or take.
  • 225 | --
  • com.adobe.shotDate: The date and time when the video was shot.
  • 226 | --
  • com.adobe.shotLocation: The name of the location where the video was shot. For example: "Oktoberfest, Munich Germany"
  • 227 | --
  • com.adobe.logComment: User&rs_quot;s log comments.
  • 228 | --
  • com.adobe.dm_artist: The name of the artist or artists.
  • 229 | --
  • com.adobe.album: The name of the album.
  • 230 | --
  • com.adobe.genre: The name of the genre.
  • 231 | --
  • com.adobe.releaseDate: The date the title was released.
  • 232 | --
  • com.adobe.composer: The composer&rs_quot;s name.
  • 233 | --
  • com.adobe.engineer: The engineer&rs_quot;s name.
  • 234 | --
  • com.adobe.instrument: The musical instrument.
  • 235 | --
  • com.adobe.comment: A user&rs_quot;s comments
  • 236 | --
  • com.adobe.client: The client for the job of which this shot or take is a part.
  • 237 | --
  • com.adobe.good: A selection for tracking whether a shot is a keeper.
  • 238 | --
  • com.adobe.projectName: The name of the project of which this file is a part.
  • 239 | --
  • com.adobe.director: The director of the scene.
  • 240 | --
  • com.adobe.directorPhotography: The director of photography for the scene.
  • 241 | --
  • com.adobe.cameraModel: The make and model of the camera used for a shoot.
  • 242 | --
  • com.adobe.cameraAngle: The orientation of the camera to the subject in a static shot, from a fixed set of industry standard terminology. A selection from values are predefined in the XMP Dynamic Media namespace. Details can be found at http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf
  • 243 | --
  • com.adobe.cameraMove: The movement of the camera during the shot, from a fixed set of industry standard terminology. A selection from values are predefined in the XMP Dynamic Media namespace. Details can be found at http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf
  • 244 | --
  • com.adobe.shotDay: The day in a multiday shoot. For example: "Day 2", "Friday".
  • 245 | --
  • com.adobe.dng.version: The version of the DNG standard used by the image.
  • 246 | --
  • com.adobe.dng.backwardVersion: The version of the DNG standard this image is backwards compatible with.
  • 247 | --
  • com.adobe.dng.compatibility: The earliest version of Lightroom this image is compatible with.
  • 248 | --
  • com.adobe.dng.hasFastLoadData: Whether the DNG has fast load data embedded or not (for example, "Embedded").
  • 249 | --
  • com.adobe.dng.lossyCompression: Whether the DNG uses lossy compression or not (for example, "No").
  • 250 | --
  • com.adobe.dng.hasEmbeddedOriginalRawFile: Whether the DNG has the original raw file embedded or not (for example, "None Embedded").
  • 251 | --
  • com.adobe.dng.hasMosaicData: Whether the DNG contains mosaic data or not (for example, "Yes").
  • 252 | --
  • com.adobe.dng.hasTransparency: Whether the DNG contains transparency data or not (for example, "No").
  • 253 | --
  • com.adobe.dng.floatingPointType: Whether the DNG uses integer or floating point pixel data (for example, "Integer").
  • 254 | --
  • com.adobe.dng.bitsPerSample: The number of bits used per DNG data sample.
  • 255 | --
  • com.adobe.dng.originalRawFileName: The name of the original raw file used when creating the DNG.
  • 256 | --
  • com.adobe.dng.originalImageDimensions: The dimensions of the original raw file used when creating the DNG (for example, "4288 x 2848").
  • 257 | --
  • com.adobe.dng.imageDimensions: The dimensions of the DNG image file (for example, "4288 x 2848").
  • 258 | --
  • com.adobe.dng.previewDimensions: The dimensions of the embedded preview within this DNG image file (for example, "3882 x 2579").
  • 259 | --
260 | -- @name items 261 | -- @class property 262 | 263 | items = { 264 | "com.adobe.separator", 265 | { 266 | formatter = "com.adobe.label", 267 | label = "keywordTags", 268 | }, 269 | 270 | "com.adobe.keywordTags", -- does this work? 271 | 272 | "com.adobe.separator", 273 | { 274 | formatter = "com.adobe.label", 275 | label = "kwTagsForExport", 276 | }, 277 | 278 | "com.adobe.keywordTagsForExport", -- does this work? 279 | 280 | "com.adobe.separator", 281 | 282 | "com.adobe.filename", 283 | "com.adobe.originalFilename.ifDiffers", 284 | "com.adobe.sidecars", 285 | "com.adobe.copyname", 286 | "com.adobe.folder", 287 | "com.adobe.filesize", 288 | "com.adobe.fileFormat", 289 | "com.adobe.metadataStatus", 290 | "com.adobe.metadataDate", 291 | "com.adobe.audioAnnotation", 292 | 293 | "com.adobe.separator", 294 | 295 | "com.adobe.rating", 296 | 297 | "com.adobe.separator", 298 | 299 | "com.adobe.colorLabels", 300 | 301 | "com.adobe.separator", 302 | 303 | "com.adobe.title", 304 | { "com.adobe.caption", height_in_lines = 3 }, 305 | 306 | "com.adobe.separator", 307 | { 308 | formatter = "com.adobe.label", 309 | label = "EXIF", 310 | }, 311 | 312 | "com.adobe.imageFileDimensions", -- dimensions 313 | "com.adobe.imageCroppedDimensions", 314 | 315 | "com.adobe.exposure", -- exposure factors 316 | "com.adobe.brightnessValue", 317 | "com.adobe.exposureBiasValue", 318 | "com.adobe.flash", 319 | "com.adobe.exposureProgram", 320 | "com.adobe.meteringMode", 321 | "com.adobe.ISOSpeedRating", 322 | 323 | "com.adobe.focalLength", -- lens info 324 | "com.adobe.focalLength35mm", 325 | "com.adobe.lens", 326 | "com.adobe.subjectDistance", 327 | 328 | "com.adobe.dateTimeOriginal", 329 | "com.adobe.dateTimeDigitized", 330 | "com.adobe.dateTime", 331 | 332 | "com.adobe.make", -- camera 333 | "com.adobe.model", 334 | "com.adobe.serialNumber", 335 | 'com.adobe.userComment', 336 | 337 | "com.adobe.artist", 338 | "com.adobe.software", 339 | 340 | "com.adobe.GPS", -- gps 341 | "com.adobe.GPSAltitude", 342 | "com.adobe.GPSImgDirection", 343 | 344 | "com.adobe.separator", 345 | { 346 | formatter = "com.adobe.label", 347 | label = "Contact", 348 | }, 349 | 350 | "com.adobe.creator", 351 | { formatter = "com.adobe.creatorJobTitle", form = "short_title" }, 352 | { formatter = "com.adobe.creatorAddress", form = "short_title" }, 353 | { formatter = "com.adobe.creatorCity", form = "short_title" }, 354 | { formatter = "com.adobe.creatorState", form = "short_title" }, 355 | { formatter = "com.adobe.creatorZip", form = "short_title" }, 356 | { formatter = "com.adobe.creatorCountry", form = "short_title" }, 357 | { formatter = "com.adobe.creatorWorkPhone", form = "short_title" }, 358 | { formatter = "com.adobe.creatorWorkEmail", form = "short_title" }, 359 | { formatter = "com.adobe.creatorWorkWebsite", form = "short_title" }, 360 | 361 | "com.adobe.separator", 362 | { formatter = "com.adobe.label", 363 | label = "IPTC", 364 | }, 365 | 366 | "com.adobe.headline", 367 | "com.adobe.iptcSubjectCode", 368 | "com.adobe.descriptionWriter", 369 | "com.adobe.category", 370 | "com.adobe.supplementalCategories", 371 | 372 | { 373 | formatter = "com.adobe.label", 374 | label = "Image", 375 | }, 376 | "com.adobe.dateCreated", 377 | "com.adobe.intellectualGenre", 378 | "com.adobe.scene", 379 | "com.adobe.location", 380 | "com.adobe.city", 381 | "com.adobe.state", 382 | "com.adobe.country", 383 | "com.adobe.isoCountryCode", 384 | { 385 | formatter = "com.adobe.label", 386 | label = "Workflow", 387 | }, 388 | "com.adobe.jobIdentifier", 389 | "com.adobe.instructions", 390 | "com.adobe.provider", 391 | "com.adobe.source", 392 | { 393 | formatter = "com.adobe.label", 394 | label = "Copyright", 395 | }, 396 | { "com.adobe.copyrightState", pruneRedundantFields = false }, 397 | "com.adobe.copyright", 398 | "com.adobe.rightsUsageTerms", 399 | "com.adobe.copyrightInfoURL", 400 | 401 | "com.adobe.separator", 402 | { formatter = "com.adobe.label", 403 | label = "IPTC Extension", 404 | }, 405 | 406 | -- might want to enable this if the user can ever do anything useful with it 407 | -- for example, he might want to look the photo up in a global db of some sort 408 | "com.adobe.digImageGUID", 409 | 410 | "com.adobe.separator", 411 | { 412 | formatter = "com.adobe.label", 413 | label = "Description", 414 | }, 415 | 416 | { formatter = "com.adobe.personInImage", form = "short_title" }, 417 | 418 | { formatter = "com.adobe.locationCreated", form = "short_title" }, 419 | { formatter = "com.adobe.locationShown", form = "short_title" }, 420 | 421 | { formatter = "com.adobe.organisationInImageName", form = "short_title" }, 422 | { formatter = "com.adobe.organisationInImageCode", form = "short_title" }, 423 | "com.adobe.event", 424 | 425 | "com.adobe.separator", 426 | { 427 | formatter = "com.adobe.label", 428 | label = "Artworks", 429 | }, 430 | 431 | { formatter = "com.adobe.artworkOrObject", form = "short_title" }, 432 | 433 | "com.adobe.separator", 434 | { 435 | formatter = "com.adobe.label", 436 | label = "Models", 437 | }, 438 | 439 | { formatter = "com.adobe.additionalModelInfo", form = "short_title" }, 440 | "com.adobe.modelAge", 441 | { formatter = "com.adobe.minorModelAgeDisclosure", form = "short_title" }, 442 | "com.adobe.modelReleaseStatus", 443 | "com.adobe.modelReleaseID", 444 | 445 | "com.adobe.separator", 446 | { 447 | formatter = "com.adobe.label", 448 | label = "Admin", 449 | }, 450 | 451 | "com.adobe.imageSupplier", 452 | "com.adobe.imageSupplierImageId", 453 | "com.adobe.registryId", 454 | "com.adobe.maxAvailHeight", 455 | "com.adobe.maxAvailWidth", 456 | { formatter = "com.adobe.digitalSourceType", form = "short_title" }, 457 | 458 | "com.adobe.separator", 459 | { 460 | formatter = "com.adobe.label", 461 | label = "Rights", 462 | }, 463 | 464 | "com.adobe.imageCreator", 465 | "com.adobe.copyrightOwner", 466 | "com.adobe.licensor", 467 | { formatter = "com.adobe.propertyReleaseID", form = "short_title" }, 468 | { formatter = "com.adobe.propertyReleaseStatus", form = "short_title" }, 469 | 470 | "com.adobe.separator", 471 | { 472 | formatter = "com.adobe.label", 473 | label = "Video", 474 | }, 475 | 476 | "com.adobe.duration.combined.optional", 477 | "com.adobe.duration", 478 | "com.adobe.trimmed_duration.optional", 479 | "com.adobe.videoFrameRate", 480 | "com.adobe.videoAlphaMode", 481 | "com.adobe.videoFrameSize", 482 | "com.adobe.audioChannelType", 483 | "com.adobe.audioSampleRate", 484 | "com.adobe.audioSampleType", 485 | 486 | "com.adobe.separator", 487 | 488 | "com.adobe.speakerPlacement", 489 | "com.adobe.tapeName", 490 | "com.adobe.altTapeName", 491 | "com.adobe.dm_scene", 492 | "com.adobe.shotName", 493 | "com.adobe.shotDate", 494 | "com.adobe.shotLocation", 495 | "com.adobe.logComment", 496 | 497 | "com.adobe.separator", 498 | 499 | "com.adobe.dm_artist", 500 | "com.adobe.album", 501 | "com.adobe.genre", 502 | "com.adobe.releaseDate", 503 | "com.adobe.composer", 504 | "com.adobe.engineer", 505 | "com.adobe.instrument", 506 | 507 | "com.adobe.separator", 508 | 509 | "com.adobe.comment", 510 | "com.adobe.client", 511 | "com.adobe.good", 512 | "com.adobe.projectName", 513 | "com.adobe.director", 514 | "com.adobe.directorPhotography", 515 | "com.adobe.cameraModel", 516 | "com.adobe.cameraAngle", 517 | "com.adobe.cameraMove", 518 | "com.adobe.shotDay", 519 | 520 | "com.adobe.separator", 521 | { 522 | formatter = "com.adobe.label", 523 | label = "DNG Info", 524 | }, 525 | "com.adobe.dng.version", 526 | "com.adobe.dng.backwardVersion", 527 | "com.adobe.dng.compatibility", 528 | 529 | "com.adobe.separator", 530 | 531 | "com.adobe.dng.hasFastLoadData", 532 | "com.adobe.dng.lossyCompression", 533 | "com.adobe.dng.hasEmbeddedOriginalRawFile", 534 | "com.adobe.dng.hasMosaicData", 535 | "com.adobe.dng.hasTransparency", 536 | "com.adobe.dng.floatingPointType", 537 | "com.adobe.dng.bitsPerSample", 538 | 539 | "com.adobe.separator", 540 | 541 | "com.adobe.dng.originalRawFileName", 542 | "com.adobe.dng.originalImageDimensions", 543 | "com.adobe.dng.imageDimensions", 544 | "com.adobe.dng.previewDimensions", 545 | 546 | "com.adobe.separator", 547 | { 548 | formatter = "com.adobe.label", 549 | label = "Others", 550 | }, 551 | 552 | "com.adobe.plusVersion", 553 | 554 | "com.adobe.allPluginMetadata", 555 | -- separator and label will be added automatically for each plug-in 556 | }, 557 | } 558 | -------------------------------------------------------------------------------- /mysample.lrwebengine/footer.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | footer.html 5 | This file adds closure to the html file. 6 | By separating the pages the footer can be used with the large.html and grid.html pages 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ]] 19 | %> 20 | 21 | 22 | -------------------------------------------------------------------------------- /mysample.lrwebengine/galleryInfo.lrweb: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | galleryInfo.lrweb 4 | This file specifies the development environment within Lightroom. 5 | For this sample we have defined sizes for large and thumbnail images which will be used in the large.html 6 | and grid.html pages when displaying the selected photos. 7 | 8 | The views table creates the panel entries available within the Lightroom UI. For this sample the 9 | user can dynamically edit the site title of the website before it is published. 10 | 11 | -------------------------------------------------------------------------------- 12 | 13 | ADOBE SYSTEMS INCORPORATED 14 | Copyright 2008 Adobe Systems Incorporated 15 | All Rights Reserved. 16 | 17 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 18 | with the terms of the Adobe license agreement accompanying it. If you have received 19 | this file from a source other than Adobe, then your use, modification, or distribution 20 | of it requires the prior written permission of Adobe. 21 | 22 | ]] 23 | 24 | 25 | return { 26 | LrSdkVersion = 2.0, 27 | LrSdkMinimumVersion = 2.0, -- minimum SDK version required by this plugin 28 | 29 | title = "My Sample Plug-in", 30 | id = "com.adobe.wpg.templates.mysample", -- unique id for this plug-in 31 | galleryType = "lua", -- lua or flash 32 | 33 | model = { 34 | 35 | ["metadata.siteTitle.value"] = "MySample", -- default value for the siteTitle variable 36 | ["appearance.sitetitle.cssID"] = "#sitetitle", 37 | 38 | ["nonCSS.tracking"] = false, 39 | 40 | ["photoSizes.large.width"] = 450, -- width of the large image as used in large.html 41 | ["photoSizes.large.height"] = 450, -- height of the large image as used in large.html 42 | 43 | ["photoSizes.thumb.height"] = 150, -- height of the thumbnail image used in grid.html 44 | ["photoSizes.thumb.width"] = 150, -- width of the thumbnail image used in grid.html 45 | ["photoSizes.thumb.metadataExportMode"] = "copyright", -- add copyright to images when published 46 | ["appearance.thumb.cssID"] = ".thumb", -- CSS Id. In grid.html the images with id 'thumb' will be set with the thumb.height and thumb.width defined above. 47 | 48 | ["nonCSS.imageBase"] = "content", -- when translated to html, the images will be in a root folder 'content' 49 | 50 | }, 51 | 52 | views = function( controller, f ) 53 | local LrView = import "LrView" 54 | local bind = LrView.bind 55 | local multibind = f.multibind 56 | return { 57 | -- this panel will appear in the Lightroom UI to enable a user to dynamically change the site title from the application without modifying any of this code. 58 | labels = f:panel_content { 59 | bindToObject = controller, 60 | f:subdivided_sections { 61 | f:labeled_text_input { 62 | title = "MySample", 63 | value = bind "metadata.siteTitle.value", 64 | }, 65 | }, 66 | }, 67 | } 68 | end, 69 | 70 | } 71 | -------------------------------------------------------------------------------- /mysample.lrwebengine/grid.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | grid.html 5 | This file displays a thumbnail grid of the images with dimensions specified in the galleryInfo.lrweb file. 6 | The Pagination tagsets have been used to assist with navigation through the photos. 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ]] 19 | %> 20 | <% 21 | --[[ Define some variables to make locating other resources easier.]] 22 | 23 | local mySize = "thumb" 24 | local others = "content" 25 | local theRoot = "." 26 | 27 | %> 28 | 29 | <% --[[ Include the page header]] %> 30 | <%@ include file="header.html" %> 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | <% if numGridPages > 1 then %> 41 | 65 | <% end %> 66 | 67 | <% --[[ Include the page footer]] %> 68 | <%@ include file="footer.html" %> 69 | -------------------------------------------------------------------------------- /mysample.lrwebengine/header.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | header.html 5 | This file begins the html file. 6 | By separating the pages, the header can be used with the large.html and grid.html pages 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ]] 19 | %> 20 | 21 | 22 | 23 | 24 | 25 | My Sample Plugin 26 | 27 | 28 | 29 | 30 |

$model.metadata.siteTitle.value

31 | -------------------------------------------------------------------------------- /mysample.lrwebengine/large.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | large.html 5 | This file displays the larger image with dimensions specified in the galleryInfo.lrweb file 6 | The Pagination tagsets have been used to assist with navigation through the photos with 7 | a mechanism Index enabling the user to return to the thumbnail view. 8 | 9 | The lower section demonstrates the use of the custom tagsets defined in myExampleTags.lrweb 10 | -------------------------------------------------------------------------------- 11 | 12 | ADOBE SYSTEMS INCORPORATED 13 | Copyright 2008 Adobe Systems Incorporated 14 | All Rights Reserved. 15 | 16 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 17 | with the terms of the Adobe license agreement accompanying it. If you have received 18 | this file from a source other than Adobe, then your use, modification, or distribution 19 | of it requires the prior written permission of Adobe. 20 | 21 | ]] 22 | %> 23 | <% 24 | --[[ Define some variables to make locating other resources easier.]] 25 | 26 | local image = getImage( index ) 27 | local theRoot = ".." 28 | local others = "." 29 | local mySize = "large" 30 | %> 31 | 32 | <% --[[ Include the page header]] %> 33 | <%@ include file="header.html" %> 34 |
35 |
    36 | 37 | 38 |
  • Previous
  • 39 |
    40 | 41 |
  • Previous
  • 42 |
    43 |
  • Index
  • 44 | 45 |
  • Next
  • 46 |
    47 | 48 |
  • Next
  • 49 |
    50 |
    51 |
52 |
53 | 54 | 55 | 56 | 57 | You know what they say:
58 |
....how interesting!
59 |
60 | 61 | <% --[[ Include the page footer]] %> 62 | <%@ include file="footer.html" %> 63 | -------------------------------------------------------------------------------- /mysample.lrwebengine/manifest.lrweb: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | manifest.lrweb 4 | Sample web template 5 | 6 | Lightroom Web Gallery manifest. This file maps various template files to actual 7 | files to be produced for your website. 8 | 9 | -------------------------------------------------------------------------------- 10 | 11 | ADOBE SYSTEMS INCORPORATED 12 | Copyright 2008 Adobe Systems Incorporated 13 | All Rights Reserved. 14 | 15 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 16 | with the terms of the Adobe license agreement accompanying it. If you have received 17 | this file from a source other than Adobe, then your use, modification, or distribution 18 | of it requires the prior written permission of Adobe. 19 | 20 | ]] 21 | 22 | importTags( "lr", "com.adobe.lightroom.default" ) 23 | importTags( "xmpl", "myExampleTags.lrweb" ) 24 | 25 | AddGridPages { 26 | template="grid.html", 27 | rows=3, 28 | columns=3, 29 | } 30 | 31 | AddCustomCSS { 32 | filename='content/custom.css', 33 | } 34 | AddPhotoPages { 35 | template="large.html", 36 | variant="_large", 37 | destination="content", 38 | } 39 | AddResources { 40 | source='resources', 41 | destination='resources', 42 | } -------------------------------------------------------------------------------- /mysample.lrwebengine/myExampleTags.lrweb: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | myExampleTags.lrweb 4 | This file specifies custom tagsets that can then be used within a web plug-in as 5 | shown in this tutorial supplied with the Lightroom SDK. 6 | 7 | Two tags are created; saying and aQuote. These are then added to the large.html 8 | page so that each time an image is selected a new saying is displayed in the lower 9 | section of the page. 10 | 11 | -------------------------------------------------------------------------------- 12 | 13 | ADOBE SYSTEMS INCORPORATED 14 | Copyright 2008 Adobe Systems Incorporated 15 | All Rights Reserved. 16 | 17 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 18 | with the terms of the Adobe license agreement accompanying it. If you have received 19 | this file from a source other than Adobe, then your use, modification, or distribution 20 | of it requires the prior written permission of Adobe. 21 | 22 | ]] 23 | 24 | -- use local upvalues to declare tables or variables 25 | local sayings = { 26 | "A dish fit for the gods - Julius Caesar, Shakespeare", 27 | "Oh, that way madness lies - King Lear, Shakespeare", 28 | "A multitude of sins - James 5:20", 29 | "A knight in shining armour - The Ancient Ballad of Prince Baldwin", 30 | "Blood is thicker than water - Guy Mannering; or the astrologer, Sir Walter Scott" 31 | } 32 | local randomSayingCount = 0 33 | 34 | -- define a variable 'globals' to add functions or variables 35 | -- to the global environment of every luapage 36 | globals = { 37 | randomSaying = function() 38 | randomSayingCount = math.mod( randomSayingCount + 1, #sayings ) 39 | 40 | return sayings[ randomSayingCount ] 41 | end, 42 | } 43 | 44 | -- define tags by creating a 'tags' table 45 | tags = { 46 | -- each entry becomes a pair of tags: 47 | -- and 48 | -- the actual prefix used depends on what is used in the importTags statement. 49 | saying = { 50 | startTag = "write( 'Here is a saying: ' ) write( randomSaying() )", 51 | endTag = "write( [[And that's all.]] ) ", 52 | }, 53 | 54 | aQuote = { 55 | startTag = 'write( [[
]] )', 56 | endTag = 'write( [[
]] )', 57 | } 58 | } -------------------------------------------------------------------------------- /mysample.lrwebengine/resources/live_update.js: -------------------------------------------------------------------------------- 1 | // a constant used to indicate a function that does nothing 2 | var NOOP = function() {} 3 | 4 | // ------------------------------------------------------------------------ 5 | // Find the font family, size and face for the provided node in the 6 | // HTML dom. The result object contains fontSize, fontFamily and 7 | // fontFace entries. 8 | // 9 | function findFont( obj ) 10 | { 11 | var result = new Object(); 12 | if ( obj.currentStyle ) { 13 | result.fontSize = obj.currentStyle[ 'fontSize' ]; 14 | result.fontFamily = obj.currentStyle[ 'fontFamily' ]; 15 | result.fontFace = obj.currentStyle[ 'fontFace' ]; 16 | } else if ( document.defaultView && document.defaultView.getComputedStyle ) { 17 | var computedStyle = document.defaultView.getComputedStyle( obj, "" ); 18 | result.fontSize = computedStyle.getPropertyValue( 'font-size' ); 19 | result.fontFamily = computedStyle.getPropertyValue( 'font-family' ); 20 | result.fontFace = computedStyle.getPropertyValue( 'font-face' ); 21 | } 22 | return result; 23 | } 24 | 25 | // --------------------------------------------------------------------------- 26 | 27 | /* 28 | Find the bounds of the specified node in the DOM. This returns 29 | an objct with x,y, height and width fields 30 | */ 31 | function findBounds( obj ) 32 | { 33 | var bounds = new Object(); 34 | bounds.x = 0; 35 | bounds.y = 0; 36 | bounds.width = obj.scrollWidth; 37 | bounds.height = obj.scrollHeight; 38 | if( obj.x != null ) { 39 | bounds.x = obj.x; 40 | bounds.y = obj.y; 41 | } 42 | else { 43 | while( obj.offsetLeft != null ) { 44 | bounds.x += obj.offsetLeft; 45 | bounds.y += obj.offsetTop; 46 | if( obj.offsetParent ) { 47 | obj = obj.offsetParent; 48 | } 49 | else { 50 | break; 51 | } 52 | } 53 | } 54 | 55 | // subtract the amount the page is scrolled from position 56 | if (self.pageYOffset) // all except Explorer 57 | { 58 | bounds.x -= self.pageXOffset; 59 | bounds.y -= self.pageYOffset; 60 | } 61 | else if (document.documentElement && document.documentElement.scrollTop) 62 | // Explorer 6 Strict 63 | { 64 | bounds.x -= document.documentElement.scrollLeft; 65 | bounds.y -= document.documentElement.scrollTop; 66 | } 67 | else if (document.body) // all other Explorers 68 | { 69 | bounds.x -= document.body.scrollLeft; 70 | bounds.y -= document.body.scrollTop; 71 | } 72 | 73 | return bounds; 74 | } 75 | 76 | // --------------------------------------------------------------------------- 77 | 78 | var isFirefoxPat = /Firefox\/([0-9]+)[.]([0-9]+)[.]([0-9]+)/; 79 | var firFoxArr = isFirefoxPat.exec( navigator.userAgent ); 80 | var isSafariPat = /AppleWebKit\/([0-9]+)[.]([0-9]+)/; 81 | var safariArr = isSafariPat.exec( navigator.userAgent ); 82 | 83 | // --------------------------------------------------------------------------- 84 | 85 | /* 86 | Default implementation does nothing when viewing the webpage normally 87 | */ 88 | var clickTarget = NOOP; 89 | var tellLightroomWhatImagesWeAreUsing = NOOP; 90 | var setActiveImageSize = NOOP; 91 | var callCallback = NOOP; 92 | var pushresult = NOOP; 93 | 94 | // --------------------------------------------------------------------------- 95 | 96 | callCallback = function() { 97 | var javascript = 'myCallback.' + arguments[ 0 ] + "( "; 98 | var j = arguments.length; 99 | var c = j - 1; 100 | for( var i = 1; i < j; i++ ) { 101 | var arg = arguments[ i ]; 102 | if( typeof( arg ) == 'string' ) { 103 | javascript = javascript + '"' + arg + '"'; 104 | } 105 | if( typeof( arg ) == 'number' ) { 106 | javascript = javascript + arg 107 | } 108 | if( typeof( arg ) == 'undefined' ) { 109 | javascript = javascript + 'undefined' 110 | } 111 | if( i < c ) { 112 | javascript = javascript + ", " 113 | } 114 | } 115 | javascript = javascript + " )" 116 | hosteval( javascript ) 117 | } 118 | 119 | pushresult = function( result ) { 120 | callCallback( "pushresult", result ) 121 | } 122 | 123 | // --------------------------------------------------------------------------- 124 | 125 | /* 126 | Set up live feedback between Lightroom and the previewed web page. 127 | */ 128 | if( callCallback != NOOP ) { 129 | setActiveImageSize = function( size ) { 130 | document.activeImageSize = size; 131 | callCallback( "setActiveImageSize", size ); 132 | } 133 | 134 | tellLightroomWhatImagesWeAreUsing = function() { 135 | 136 | if( window.myCallback != null ) { 137 | var imgElements = document.getElementsByTagName( "img" ); 138 | var elsLen = imgElements.length; 139 | var result = new Array() 140 | for( i = 0; i < elsLen; i++ ) { 141 | var element = imgElements[ i ]; 142 | var imageID = element.id; 143 | // for html validation purposes, we've prepended "ID" to the GUID for this 144 | // image, so now we strip that off. 145 | imageID = imageID.substring( 2 ); 146 | result[ i ] = imageID; 147 | } 148 | myCallback.setUsedFiles( result ); 149 | } 150 | } 151 | 152 | clickTarget = function( obj, target, imageID ) { 153 | if( imageID != null ) { 154 | // for html validation purposes, we've prepended "ID" to the GUID for this 155 | // image, so now we strip that off. 156 | imageID = imageID.substring( 2 ); 157 | } 158 | var bounds = findBounds( obj ); 159 | var font = findFont( obj ); 160 | callCallback( 'inPlaceEdit', target, bounds.x, bounds.y, bounds.width, bounds.height, font.fontFamily, font.fontSize, imageID ) 161 | } 162 | 163 | AgDebugPrint = function( message ) { 164 | callCallback( 'AgDebugPrint', message ); 165 | } 166 | } 167 | 168 | // --------------------------------------------------------------------------- 169 | 170 | if( firFoxArr && ( firFoxArr[1] > 1 || firFoxArr[2] > 4 ) || 171 | safariArr ) { 172 | window.gridOn = NOOP; 173 | window.gridOff= NOOP; 174 | } 175 | else { 176 | window.gridOn = function( t, id ) { 177 | t.agOriginalClassName = t.className; 178 | t.className = "selectedThumbnail " + t.className; 179 | }; 180 | window.gridOff= function( t ) { 181 | t.className = t.agOriginalClassName; 182 | }; 183 | } 184 | 185 | var needThumbImgLink = !isFirefoxPat; 186 | 187 | 188 | var oldOnLoad = window.onload; 189 | window.onload = function() { 190 | if( window.AgOnLoad ) { 191 | window.AgOnLoad(); 192 | } 193 | if( oldOnLoad ) { 194 | oldOnLoad(); 195 | } 196 | }; 197 | 198 | //------------------------------------------------------------ 199 | 200 | document.liveUpdateImageMaxSize = function( id, value ) { 201 | var targetArr = id.split(/[ \t\r\n]*,[ \t\r\n]*/); 202 | for( i = 0; i < targetArr.length; i++ ) { 203 | var target = targetArr[i]; 204 | var idRegex = new RegExp( "^[#](.+$)" ); 205 | var theId = idRegex.exec( target ); 206 | if( theId && theId[ 1 ] ) { 207 | var item = document.getElementById( theId[ 1 ] ); 208 | if( item ) { 209 | 210 | // scale image size 211 | var max = item.width; 212 | if( item.height > max ) { 213 | max = item.height; 214 | } 215 | item.width = item.width * value / max; 216 | item.height = item.height * value / max; 217 | } 218 | } 219 | } 220 | 221 | 222 | return "invalidateAllContent"; 223 | } 224 | 225 | //------------------------------------------------------------ 226 | 227 | document.liveUpdatePropertyMac = function( id, property, value ) { 228 | 229 | var targetArr = id.split(/[ \t\r\n]*,[ \t\r\n]*/); 230 | var clasRegex = new RegExp( "^[.](.+$)" ) 231 | var idRegex = new RegExp( "^[#](.+$)" ) 232 | var comboRegex = new RegExp( "[ \t\r\n]" ); 233 | 234 | for( i = 0; i < targetArr.length; i++ ) { 235 | var target = targetArr[i]; 236 | var theClass = clasRegex.exec( target ); 237 | var theId = idRegex.exec( target ); 238 | if( comboRegex.exec( target ) ) { 239 | return "failed"; 240 | } 241 | else if( theClass) { 242 | var pattern = new RegExp( "(^|\\s)" + theClass[1] + "(\\s|$)" ); 243 | var items = document.getElementsByTagName( '*' ); 244 | for( o = 0; o < items.length; o++ ) { 245 | var item = items[ o ]; 246 | if( pattern.test( item.className ) ){ 247 | item.style.setProperty( property, value, "important" ); 248 | } 249 | } 250 | return "invalidateAllContent"; 251 | } 252 | else if( theId ) { 253 | if( property == "maxSize" ) { 254 | return document.liveUpdateImageMaxSize( id, value ); 255 | } 256 | var item = document.getElementById( theId[ 1 ] ); 257 | if( item ) { 258 | item.style.setProperty( property, value, "important"); 259 | } 260 | return "invalidateAllContent"; 261 | } 262 | else { 263 | var items = document.getElementsByTagName( target); 264 | for( i = 0; i < items.length; i++ ) { 265 | var item = items[i]; 266 | item.style.setProperty( property, value, "important" ); 267 | } 268 | return "invalidateAllContent"; 269 | } 270 | } 271 | }; 272 | 273 | //------------------------------------------------------------ 274 | 275 | document.liveUpdatePropertyWin = function( id, property, value ) { 276 | // AgDebugPrint( "document.liveUpdatePropertyWin( " + id + ", " + property + ", " + value + " )\n" ); 277 | if( property == "maxSize" ) { 278 | return document.liveUpdateImageMaxSize( id, value ); 279 | } 280 | if( property == 'display' || value == 'inherit' ) { 281 | return "failed" 282 | } 283 | var x = document.styleSheets[0]; 284 | x.addRule(id, property + ": " + value + " !important"); 285 | return "invalidateAllContent"; 286 | } 287 | if( MAC_ENV ) { 288 | document.liveUpdateProperty = document.liveUpdatePropertyMac 289 | } 290 | if( WIN_ENV ) { 291 | document.liveUpdateProperty = document.liveUpdatePropertyWin 292 | } 293 | 294 | //------------------------------------------------------------ 295 | 296 | document.liveUpdate = function( path, newValue, cssId, property ) { 297 | // AgDebugPrint( "document.liveUpdate( " + path + ", " + newValue + ", " + cssId + " , " + property + " ) " ); 298 | var success = "failed"; 299 | var reg = /(^[^.]+)\./; 300 | var ar = reg.exec( path ); 301 | if( ar == null ) { 302 | 303 | // override result if we drove this change ourselves 304 | if( document.LR_modelManipulation ) { 305 | return "invalidateOldHTML"; 306 | } 307 | return "failed"; 308 | } 309 | var area = ar[1]; 310 | if( area == "metadata" ) { 311 | // our html is built so that the HTML ids are the metadata path 312 | var a = document.getElementById( path ); 313 | while(a.hasChildNodes()) { 314 | a.removeChild(a.firstChild); 315 | } 316 | a.innerHTML = newValue; 317 | success = "invalidateOldHTML"; 318 | } 319 | else if( area == "appearance" ) { 320 | success = document.liveUpdateProperty( cssId, property, newValue ); 321 | } 322 | else if( path == "nonCSS.tracking" ) { 323 | if( newValue == null || newValue == "null") { 324 | // force reload by signalling failure to update 325 | // because we don't properly layout all the nuiances of 326 | // detail image placement during tracking, we reload at the 327 | // end to make sure it is correct when mouseup 328 | success = "failed"; 329 | } 330 | else { 331 | // FIX_ME, image won't layout properly during drag w/o this 332 | success = "invalidateOldHTML"; 333 | } 334 | } 335 | else if( path == "nonCSS.imageBorderWidth" ) { 336 | // FIX_ME, not yet implemented, so image won't layout properly during drag 337 | // as a workaround, we're reloading on tracking up (see previous block) 338 | success = "invalidateOldHTML"; 339 | } 340 | else { 341 | // AgDebugPrint("How do I update " + path + " to " + newValue ) 342 | } 343 | 344 | // override result if we drove this change ourselves 345 | if( document.LR_modelManipulation ) { 346 | return "invalidateOldHTML"; 347 | } 348 | return success; 349 | } 350 | 351 | //------------------------------------------------------------ 352 | 353 | document.liveUpdateImageSize = function( imageID, width, height ) { 354 | 355 | var img = document.getElementById( 'ID' + imageID ); 356 | img.style.width = width + 'px'; 357 | img.style.height = height + 'px'; 358 | return "invalidateAllContent"; 359 | } 360 | 361 | //------------------------------------------------------------ 362 | 363 | -------------------------------------------------------------------------------- /websample.lrwebengine/footer.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | footer.html 5 | This file adds closure to the html file. 6 | By separating the pages the footer can be used with other html pages 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ]] 19 | %> 20 |
21 |
22 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /websample.lrwebengine/galleryInfo.lrweb: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | galleryInfo.lrweb 4 | This file specifies the development environment within Lightroom. 5 | 6 | The views table creates the panel entries available within the Lightroom UI. 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | ADOBE SYSTEMS INCORPORATED 11 | Copyright 2008 Adobe Systems Incorporated 12 | All Rights Reserved. 13 | 14 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 15 | with the terms of the Adobe license agreement accompanying it. If you have received 16 | this file from a source other than Adobe, then your use, modification, or distribution 17 | of it requires the prior written permission of Adobe. 18 | 19 | ]] 20 | 21 | local useMultiBind = false 22 | return { 23 | LrSdkVersion = 2.0, 24 | LrSdkMinimumVersion = 2.0, -- minimum SDK version required by this plugin 25 | 26 | title = "A Web Sample", 27 | id = "com.adobe.lightroom.wpg.templates.sdk.luawebsample", -- unique plug-in id 28 | galleryType = "lua", -- lua 29 | maximumGallerySize = 50000, 30 | model = { 31 | 32 | -- The following metadata are located in the header of the sample and can be edited by the user using the Site Info panel. 33 | ["metadata.siteTitle.value"] = LOC "$$$/AgWPG/Templates/HTML/DefaultValues/properties/SiteTitle=Site Title", 34 | ["metadata.collectionTitle.value"] = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/CollectionTitle=My Photographs", 35 | ["metadata.collectionDescription.value"] = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/CollectionDescription=Web Photo Gallery created by Adobe Lightroom.", 36 | 37 | -- Contact details that are currently displayed in the footer section of the sample. The 'link' is the valid email address and 'value' the text representation of the link 38 | ["metadata.contactInfo.link"] = { 39 | value = LOC "$$$/AgWPG/Templates/HTML/Defaults/ContactLink=mailto:user@domain", 40 | metadata = { [ "ag:dataType" ] = "webLink" }, 41 | }, 42 | ["metadata.contactInfo.value"] = LOC "$$$/AgWPG/Templates/HTML/DefaultValues/properties/ContactInfo=Contact Name", 43 | 44 | -- The name of the homepage file when published 45 | ["metadata.homePage.value"] = { 46 | value = "index.html", 47 | metadata = { [ "ag:dataType" ] = "webLink" }, 48 | }, 49 | -- the large properties are used to display the main image in the centre panel of the page 50 | ["photoSizes.large.height"] = useMultiBind and 450 51 | or function() return photoSizes.large.width end, 52 | ["photoSizes.large.maxHeight"] = 2701, 53 | ["photoSizes.large.maxWidth"] = 2701, 54 | ["photoSizes.large.metadataExportMode"] = useMultiBind and "copyright" 55 | or function() return photoSizes.thumb.metadataExportMode end, 56 | ["photoSizes.large.width"] = 550, 57 | -- the thumb properties are responsible for displaying the thumbnails in the left-hand panel of the page. 58 | ["photoSizes.thumb.height"] = 130, 59 | ["photoSizes.thumb.metadataExportMode"] = "copyright", 60 | ["photoSizes.thumb.width"] = 130, 61 | ["photoSizes.tracking"] = false, 62 | ["nonCSS.tracking"] = false, 63 | 64 | ["lightroomApplication.identityPlateExport"] = "(main)", -- optional entry displaying identity plate 65 | ["lightroomApplication.jpegQuality"] = 70, -- quality of images when published 66 | ["lightroomApplication.sizeBeingViewed"] = "thumb", 67 | ["lightroomApplication.useWatermark"] = true, 68 | ["lightroomApplication.watermarkID"] = "", 69 | 70 | ["nonCSS.imageBase"] = "content", 71 | ["nonCSS.identityPlateAbsolutePath"] = "", 72 | ["nonCSS.numCols"] = 1, -- as we are using a scrollbar panel, 1 column is sufficient. 73 | ["nonCSS.numRows"] = 50, 74 | 75 | ["appearance.textColor.color"] = "#A1A1A1", 76 | ["appearance.textColor.cssID"] = ".textColor", 77 | 78 | ["appearance.siteTitle.cssID"] = "#liveUpdateSiteTitle", 79 | ["appearance.sitetitle.cssID"] = "#sitetitle", 80 | ["appearance.logo.cssID"] = ".logo", 81 | ["appearance.logo.display"] = false, 82 | ["appearance.body.background-color"] = "#4C4C4C", 83 | ["appearance.body.cssID"] = "body", 84 | 85 | -- this will sort out the updating of the labels that display the metadata 86 | ["appearance.metalabel.color"] = function() return appearance.textColor.color end, 87 | ["appearance.metalabel.background-color"] = "#4C4C4C", 88 | ["appearance.metalabel.cssID"] = ".metalabel", 89 | 90 | --[[ Adding the functionality to change the scroll bar colours ]] 91 | ["appearance.body.scrollbar-base-color"] = "#4C4C4C", 92 | ["appearance.body.scrollbar-arrow-color"] = "#A1A1A1", 93 | ["appearance.body.scrollbar-highlight-color"] = "#4C4C4C", 94 | ["appearance.body.scrollbar-face-color"] = "#A1A1A1", 95 | 96 | --[[thumbnail panel background]] 97 | ["appearance.leftpanel.background-color"] = "#4C4C4C", 98 | ["appearance.leftpanel.cssID"] = ".leftpanel", 99 | 100 | --[[ Header Area ]] 101 | ["appearance.header.border-color"] = "#A1A1A1", 102 | ["appearance.header.background-color"] = "#4C4C4C", 103 | ["appearance.header.cssID"] = ".header", 104 | 105 | --[[ Footer Area]] 106 | ["appearance.footer.border-color"] = "#A1A1A1", 107 | ["appearance.footer.background-color"] = "#4C4C4C", 108 | ["appearance.footer.cssID"] = ".footer", 109 | 110 | ["perImageSetting.description"] = { 111 | enabled = true, 112 | value = "{{com.adobe.caption}}", 113 | }, 114 | ["perImageSetting.title"] = { 115 | enabled = true, 116 | value = "{{com.adobe.title}}", 117 | }, 118 | 119 | }, 120 | properties = { 121 | perImage = { 122 | { 123 | id = "title", 124 | title = LOC "$$$/WPG/HTML/CSS/properties/ImageTitle=Title", 125 | }, 126 | { 127 | id = "description", 128 | title = LOC "$$$/WPG/HTML/CSS/properties/ImageCaption=Caption", 129 | }, 130 | }, 131 | }, 132 | views = function( controller, f ) 133 | local LrView = import "LrView" 134 | local bind = LrView.bind 135 | local multibind = f.multibind 136 | 137 | return { 138 | labels = f:panel_content { 139 | bindToObject = controller, 140 | f:subdivided_sections { 141 | -- Site Info panel for user to change site title, collection and description entries. 142 | f:labeled_text_input { 143 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/SiteTitle=Site Title", 144 | value = bind "metadata.siteTitle.value", 145 | }, 146 | f:labeled_text_input { 147 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/CollectionTitle=Collection Title", 148 | value = bind "metadata.groupTitle.value", 149 | }, 150 | f:labeled_text_input { 151 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/CollectionDescription=Collection Description", 152 | value = bind "metadata.collectionDescription.value", 153 | }, 154 | }, 155 | f:subdivided_sections { 156 | -- update the contact details displayed in the footer of the page 157 | f:labeled_text_input { 158 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/ContactInfo=Contact Info", 159 | value = bind "metadata.contactInfo.value", 160 | }, 161 | f:labeled_text_input { 162 | title = LOC "$$$/AgWPG/Templates/HTML/link=Web or Mail Link", 163 | value = bind "metadata.contactInfo.link", 164 | wraps = false, 165 | }, 166 | }, 167 | f:subdivided_sections { 168 | f:header_section { 169 | f:checkbox_row { 170 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/IdentityPlate=Identity Plate", 171 | value = bind "appearance.logo.display", 172 | }, 173 | }, 174 | f:identity_plate { 175 | value = bind "lightroomApplication.identityPlateExport", 176 | enabled = bind "appearance.logo.display", 177 | }, 178 | f:labeled_text_input { 179 | title = LOC "$$$/AgWPG/Templates/HTML/IdentityPlate/Link=Web or Mail Link", 180 | value = bind "metadata.homePage.value", 181 | wraps = false, 182 | }, 183 | }, 184 | }, 185 | colorPalette = f:panel_content { 186 | bindToObject = controller, 187 | f:subdivided_sections{ 188 | -- colour adjustments of the header panel 189 | f:header_section_label { 190 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Header=Header", 191 | }, 192 | f:color_content_column { 193 | f:label_and_color_row { 194 | color = bind "appearance.header.border-color", 195 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/HeaderBorder=Header Border", 196 | }, 197 | }, 198 | f:color_content_column { 199 | f:label_and_color_row { 200 | color = bind "appearance.header.background-color", 201 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/HeaderBackground=Header Background", 202 | }, 203 | }, 204 | }, 205 | f:subdivided_sections { 206 | -- colour adjustments of the centre panel 207 | f:header_section_label { 208 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Main=Main Section", 209 | }, 210 | f:color_content_column { 211 | f:label_and_color_row { 212 | color = bind "appearance.textColor.color", 213 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/TextColor=Text", 214 | }, 215 | }, 216 | f:color_content_column { 217 | f:label_and_color_row { 218 | color = bind "appearance.body.background-color", 219 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/BackgroundColors=Background", 220 | }, 221 | }, 222 | f:color_content_column { 223 | f:label_and_color_row { 224 | color = bind "appearance.metalabel.background-color", 225 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/LabelBackground=Label Background", 226 | }, 227 | }, 228 | }, 229 | f:subdivided_sections{ 230 | -- colour adjustments of the footer panel 231 | f:header_section_label { 232 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Footer=Footer", 233 | }, 234 | f:color_content_column { 235 | f:label_and_color_row { 236 | color = bind "appearance.footer.border-color", 237 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/FooterBorder=Footer Border", 238 | }, 239 | }, 240 | f:color_content_column { 241 | f:label_and_color_row { 242 | color = bind "appearance.footer.background-color", 243 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/FooterBackground=Footer Background", 244 | }, 245 | }, 246 | }, 247 | f:subdivided_sections{ 248 | -- colour adjustments of the thumbnail panel including the scrollbars. feature not available on the Mac. 249 | f:header_section_label { 250 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/ThumbnailViewer=Thumbnail Panel", 251 | }, 252 | f:color_content_column { 253 | f:label_and_color_row { 254 | color = bind "appearance.body.scrollbar-base-color", 255 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarColor=ScrollBar Base", 256 | }, 257 | }, 258 | f:color_content_column { 259 | f:label_and_color_row { 260 | color = bind "appearance.body.scrollbar-arrow-color", 261 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarArrowColor=ScrollBar Arrow", 262 | }, 263 | }, 264 | f:color_content_column { 265 | f:label_and_color_row { 266 | color = bind "appearance.body.scrollbar-highlight-color", 267 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarHighlight=ScrollBar Highlight", 268 | }, 269 | }, 270 | f:color_content_column { 271 | f:label_and_color_row { 272 | color = bind "appearance.body.scrollbar-face-color", 273 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarFace=ScrollBar Face", 274 | }, 275 | }, 276 | f:color_content_column { 277 | f:label_and_color_row { 278 | color = bind "appearance.leftpanel.background-color", 279 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ThumbBackground=Background", 280 | }, 281 | }, 282 | }, 283 | }, 284 | appearanceConfiguration = f:panel_content { 285 | bindToObject = controller, 286 | f:subdivided_sections { 287 | -- adjust large image sizes 288 | f:header_section_label { 289 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Images=Images", 290 | }, 291 | f:slider_content_column { 292 | f:slider_row { 293 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/MaximumImageSizeLabel/LargePreview=Size", 294 | value = useMultiBind and multibind { 295 | "photoSizes.large.width", 296 | "photoSizes.large.height", 297 | "appearance.liveUpdateImageSize.maxSize", 298 | } 299 | or bind "photoSizes.large.width", 300 | tracking = bind "nonCSS.tracking", 301 | unit = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/ImageSizeUnit=px", 302 | max = 2071, 303 | min = 300, 304 | width_in_digits = 4, 305 | precision = 0, 306 | }, 307 | }, 308 | }, 309 | }, 310 | outputSettings = f:panel_content { 311 | bindToObject = controller, 312 | f:subdivided_sections { 313 | f:slider_content_column { 314 | f:metadataModeControl { 315 | value = useMultiBind and multibind { 316 | "photoSizes.thumb.metadataExportMode", 317 | "photoSizes.large.metadataExportMode", 318 | } 319 | or bind "photoSizes.thumb.metadataExportMode", 320 | }, 321 | }, 322 | }, 323 | f:subdivided_sections { 324 | f:header_section_label { 325 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/ImageHandling=Large Images", 326 | }, 327 | f:slider_content_column { 328 | f:slider_row { 329 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Labels/MaximumImageSizeLabel/JPEGQualityLabel=Quality", 330 | value = bind "lightroomApplication.jpegQuality", 331 | tracking = bind "lightroomApplication.jpegQuality.tracking", 332 | tracking_value = "qualityTracking", 333 | unit = "", 334 | max = 100, 335 | min = 0, 336 | width_in_digits = 4, 337 | precision = 0, 338 | }, 339 | f:metadataModeControl { 340 | value = useMultiBind and multibind { 341 | "photoSizes.thumb.metadataExportMode", 342 | "photoSizes.large.metadataExportMode", 343 | } 344 | or bind "photoSizes.thumb.metadataExportMode", 345 | }, 346 | }, 347 | f:slider_content_column { 348 | f:checkbox_row { 349 | title = LOC "$$$/AgWPG/Templates/HTML/Panel/Checkbox/UseWatermark=Add Copyright Watermark", 350 | value = bind "lightroomApplication.useWatermark", 351 | indent_with_sliders = true, 352 | }, 353 | }, 354 | f:watermark_section( controller ), 355 | }, 356 | }, 357 | } 358 | end, 359 | } -------------------------------------------------------------------------------- /websample.lrwebengine/grid.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | grid.html 5 | This file displays a thumbnail grid of the images with dimensions specified in the galleryInfo.lrweb file. 6 | 7 | The image_viewer displays the clicked thumbnail as a larger image in the centre panel of the page. Below, 8 | if available, the title and caption of the image are displayed. 9 | 10 | -------------------------------------------------------------------------------- 11 | 12 | ADOBE SYSTEMS INCORPORATED 13 | Copyright 2008 Adobe Systems Incorporated 14 | All Rights Reserved. 15 | 16 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 17 | with the terms of the Adobe license agreement accompanying it. If you have received 18 | this file from a source other than Adobe, then your use, modification, or distribution 19 | of it requires the prior written permission of Adobe. 20 | 21 | ]] 22 | %> 23 | <% 24 | --[[ Define some variables to make locating other resources easier 25 | firstPage was defined in our manifest.]] 26 | 27 | local others = "content" 28 | local theRoot = "." 29 | local mySize = "large" 30 | local firstImage 31 | local title 32 | local caption 33 | local width 34 | local height 35 | %> 36 | 37 | <% --[[ Include the page header]] %> 38 | <%@ include file="header.html" %> 39 | 40 | <% 41 | --[[ determine the first image within the gallery ]] 42 | if numImages > 0 then 43 | firstImage = others .. "/bin/images/large/" .. getImage(1).exportFilename .. ".jpg" 44 | title = getImage(1).metadata.title 45 | caption = getImage(1).metadata.description 46 | height = getImage(1).renditions.large.height 47 | width = getImage(1).renditions.large.width 48 | else 49 | firstImage = "blank.jpg" 50 | title = "Add some images to LightRoom to display metadata here" 51 | caption = "Add some images to LightRoom to display metadata here" 52 | end 53 | %> 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 |
65 |
66 |
67 |
68 | 69 | 70 | 71 |
72 | 73 |
74 | 75 | 76 |
77 |
78 | <% --[[ Include the page footer]] %> 79 | <%@ include file="footer.html" %> 80 | -------------------------------------------------------------------------------- /websample.lrwebengine/header.html: -------------------------------------------------------------------------------- 1 | <% 2 | --[[ 3 | 4 | header.html 5 | This file begins the html file. 6 | By separating the pages, the header can be used with more than one html page 7 | -------------------------------------------------------------------------------- 8 | 9 | ADOBE SYSTEMS INCORPORATED 10 | Copyright 2008 Adobe Systems Incorporated 11 | All Rights Reserved. 12 | 13 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 14 | with the terms of the Adobe license agreement accompanying it. If you have received 15 | this file from a source other than Adobe, then your use, modification, or distribution 16 | of it requires the prior written permission of Adobe. 17 | 18 | ]] 19 | %> 20 | 21 | 22 | 23 | 24 | 25 | 26 | $model.metadata.siteTitle.value 27 | 28 | 29 | 30 | <% --[[ Scripting support for rollovers and (when previewed in Lightroom) live Update, photobin syncing ]] %> 31 | 32 | 60 | 61 | 62 | 63 | 64 | <% 65 | local function fixUrlIfRelative( url ) 66 | url = tostring( url ) or "" 67 | if string.find( url, "[a-z]+:" ) then 68 | -- this url starts with something like http: or mailto:, so leave it alone 69 | else 70 | -- this url is probably relative, so we need to tack on theRoot to the beginning 71 | -- of it, so no matter where the page were currently viewing is placed in the 72 | -- output hierarchy, this link will still point to the same page 73 | url = theRoot .. "/" .. url; 74 | end 75 | return url 76 | end 77 | %> 78 |
79 |

$model.metadata.siteTitle.value

80 |

$model.metadata.collectionTitle.value

81 |

$model.metadata.collectionDescription.value

82 |
83 | -------------------------------------------------------------------------------- /websample.lrwebengine/manifest.lrweb: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | manifest.lrweb 4 | 5 | Lightroom Web Gallery manifest. This file maps various template files to actual 6 | files to be produced for your website. 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | ADOBE SYSTEMS INCORPORATED 11 | Copyright 2008 Adobe Systems Incorporated 12 | All Rights Reserved. 13 | 14 | NOTICE: Adobe permits you to use, modify, and distribute this file in accordance 15 | with the terms of the Adobe license agreement accompanying it. If you have received 16 | this file from a source other than Adobe, then your use, modification, or distribution 17 | of it requires the prior written permission of Adobe. 18 | 19 | ]] 20 | 21 | importTags( "lr", "com.adobe.lightroom.default" ) -- main lightroom tags including Pagination. 22 | 23 | 24 | -- create a GridPage called grid.html with 1 column and 50 rows as defined in the galleryInfo 25 | AddGridPages { 26 | template="grid.html", 27 | rows=model.nonCSS.numRows, 28 | columns=model.nonCSS.numCols, 29 | } 30 | -- Include custom stylesheet 31 | AddCustomCSS{ 32 | filename="content/custom.css", 33 | } 34 | -- include images and javascript resources 35 | AddResources { 36 | source='resources', 37 | destination='resources', 38 | } 39 | IdentityPlate { 40 | destination='content/logo.png', 41 | enabledBinding = [[appearance.logo.display]], 42 | } -------------------------------------------------------------------------------- /websample.lrwebengine/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/websample.lrwebengine/readme.txt -------------------------------------------------------------------------------- /websample.lrwebengine/resources/blank.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jaid/lightroom-sdk-8-examples/ffc972be7eb97329eec1afd091a445b86d83d9d1/websample.lrwebengine/resources/blank.JPG -------------------------------------------------------------------------------- /websample.lrwebengine/resources/css/ie6.css: -------------------------------------------------------------------------------- 1 | .alignmentMiddle { 2 | z-index: 3; 3 | position: absolute; 4 | top: 50%; 5 | left: 50%; 6 | } /* for explorer only*/ 7 | 8 | .alignmentInner{ 9 | z-index: 4; 10 | position: relative; 11 | top: -50%; 12 | left: -50%; 13 | } /* for explorer only */ 14 | .alignmentOuterGrid { 15 | z-index: 1; 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | width: 100%; 20 | height: 100%; 21 | overflow: hidden; 22 | } 23 | 24 | 25 | .dropShadow:before, 26 | .dropShadow:after { 27 | display: none; 28 | } 29 | 30 | .dropShadow .inner, 31 | .dropShadow { 32 | background: none; 33 | display: inline; 34 | float: none; 35 | position: static; 36 | content: inherit; 37 | margin: 0; 38 | right: 0; 39 | left: 0; 40 | top: 0; 41 | height: auto; 42 | width: auto; 43 | 44 | } 45 | 46 | .thumb, .preview { 47 | filter:progid:DXImageTransform.Microsoft.Shadow(Color=#000000, Direction=135, Strength=1); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /websample.lrwebengine/resources/css/ie7.css: -------------------------------------------------------------------------------- 1 | .alignmentMiddle { 2 | margin-top: expression((parentNode.offsetHeight - this.offsetHeight) / 2) !important; 3 | } 4 | .alignmentOuterGrid { 5 | z-index: 1; 6 | position: absolute; 7 | top: 0; 8 | left: 0; 9 | width: 100%; 10 | height: 100%; 11 | overflow: hidden; 12 | } 13 | 14 | .dropShadow { 15 | background: none; 16 | 17 | } 18 | .thumb, .preview { 19 | filter:progid:DXImageTransform.Microsoft.Shadow(Color=#000000, Direction=135, Strength=1); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /websample.lrwebengine/resources/css/stylesheet.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /* CSS Document */ 3 | body, h1, h2, h3, h4, h5, h6, p, a { 4 | background-color:inherit; 5 | color: #b3b3b3; 6 | font-size: 12px; 7 | font-family: helvetica, arial, tahoma, verdana, sans-serif; 8 | color: #b3b3b3; 9 | } 10 | /* LINKS */ 11 | a, a:link, a:hover { 12 | text-decoration:underline; 13 | color:inherit; 14 | cursor:pointer; 15 | } 16 | a:link a:visited a:hover, a:active { 17 | color:inherit; 18 | text-decoration:none; 19 | } 20 | img { 21 | border: 0; 22 | } 23 | /* end of links */ 24 | /* Page structure */ 25 | /* Header Section */ 26 | .header { 27 | position : relative; 28 | width : 100%; 29 | height : 100px; 30 | border-bottom : 2px solid #cccccc; 31 | background-color:inherit; 32 | } 33 | /* SITE TITLE */ 34 | .sitetitle { 35 | font-size:20px; 36 | } 37 | /* end of Site Title */ 38 | /* COLLECTION HEADER */ 39 | .collectionHeader { 40 | font-size: 14px; 41 | float:right; 42 | 43 | } 44 | /* end of collection header */ 45 | /* end of header section */ 46 | /* Left panel */ 47 | .leftpanel { 48 | height : 600px; 49 | width : 170px; 50 | padding : 5px; 51 | margin-top:10px; 52 | overflow:auto; 53 | position:relative; 54 | float:left; 55 | } 56 | /* end of left panel */ 57 | .footer { 58 | position: fixed; 59 | width: 100%; 60 | height: 75px; 61 | border-top : 2px solid #cccccc; 62 | overflow:hidden; 63 | text-align:right; 64 | font-weight:bold; 65 | padding-top:20px; 66 | padding-right:20px; 67 | } 68 | #image_viewer { 69 | top : 20%; 70 | bottom : 100px; 71 | margin : 0px 0px 0px 185px; 72 | width : auto; 73 | height : auto; 74 | padding-left : 5px; 75 | padding-right : 12px; 76 | overflow : auto; 77 | float:right; 78 | position:absolute; 79 | } 80 | /* end of page structure */ 81 | .clear { 82 | clear: both; 83 | } 84 | .thumbnail { 85 | color:inherit; 86 | width: 140px; 87 | height: 140px; 88 | position:relative; 89 | padding:10px; 90 | overflow:hidden; 91 | } 92 | .thumb { 93 | border: 1px solid black; 94 | position: relative; 95 | } 96 | .selectedThumbnail, .thumbnail:hover { 97 | color:inherit; 98 | } 99 | /* LINKS */ 100 | a, a:link, a:hover { 101 | text-decoration:underline; 102 | color:inherit; 103 | cursor:pointer; 104 | } 105 | a:link a:visited a:hover, a:active { 106 | color:inherit; 107 | text-decoration:none; 108 | } 109 | /* ID PLATE */ 110 | #idplate { 111 | margin-bottom: 0px; 112 | margin-top: 0px; 113 | } 114 | #idplate .logo { 115 | } 116 | .metalabel{ 117 | border:0px; 118 | font-weight:bold; 119 | } 120 | /* end of ID Plate */ 121 | -------------------------------------------------------------------------------- /websample.lrwebengine/resources/js/live_update.js: -------------------------------------------------------------------------------- 1 | // a constant used to indicate a function that does nothing 2 | var NOOP = function() {} 3 | 4 | // ------------------------------------------------------------------------ 5 | // Find the font family, size and face for the provided node in the 6 | // HTML dom. The result object contains fontSize, fontFamily and 7 | // fontFace entries. 8 | // 9 | function findFont( obj ) 10 | { 11 | var result = new Object(); 12 | if ( obj.currentStyle ) { 13 | result.fontSize = obj.currentStyle[ 'fontSize' ]; 14 | result.fontFamily = obj.currentStyle[ 'fontFamily' ]; 15 | result.fontFace = obj.currentStyle[ 'fontFace' ]; 16 | } else if ( document.defaultView && document.defaultView.getComputedStyle ) { 17 | var computedStyle = document.defaultView.getComputedStyle( obj, "" ); 18 | result.fontSize = computedStyle.getPropertyValue( 'font-size' ); 19 | result.fontFamily = computedStyle.getPropertyValue( 'font-family' ); 20 | result.fontFace = computedStyle.getPropertyValue( 'font-face' ); 21 | } 22 | return result; 23 | } 24 | 25 | // --------------------------------------------------------------------------- 26 | 27 | /* 28 | Find the bounds of the specified node in the DOM. This returns 29 | an objct with x,y, height and width fields 30 | */ 31 | function findBounds( obj ) 32 | { 33 | var bounds = new Object(); 34 | bounds.x = 0; 35 | bounds.y = 0; 36 | bounds.width = obj.scrollWidth; 37 | bounds.height = obj.scrollHeight; 38 | if( obj.x != null ) { 39 | bounds.x = obj.x; 40 | bounds.y = obj.y; 41 | } 42 | else { 43 | while( obj.offsetLeft != null ) { 44 | bounds.x += obj.offsetLeft; 45 | bounds.y += obj.offsetTop; 46 | if( obj.offsetParent ) { 47 | obj = obj.offsetParent; 48 | } 49 | else { 50 | break; 51 | } 52 | } 53 | } 54 | 55 | // subtract the amount the page is scrolled from position 56 | if (self.pageYOffset) // all except Explorer 57 | { 58 | bounds.x -= self.pageXOffset; 59 | bounds.y -= self.pageYOffset; 60 | } 61 | else if (document.documentElement && document.documentElement.scrollTop) 62 | // Explorer 6 Strict 63 | { 64 | bounds.x -= document.documentElement.scrollLeft; 65 | bounds.y -= document.documentElement.scrollTop; 66 | } 67 | else if (document.body) // all other Explorers 68 | { 69 | bounds.x -= document.body.scrollLeft; 70 | bounds.y -= document.body.scrollTop; 71 | } 72 | 73 | return bounds; 74 | } 75 | 76 | // --------------------------------------------------------------------------- 77 | 78 | var isFirefoxPat = /Firefox\/([0-9]+)[.]([0-9]+)[.]([0-9]+)/; 79 | var firFoxArr = isFirefoxPat.exec( navigator.userAgent ); 80 | var isSafariPat = /AppleWebKit\/([0-9]+)[.]([0-9]+)/; 81 | var safariArr = isSafariPat.exec( navigator.userAgent ); 82 | 83 | // --------------------------------------------------------------------------- 84 | 85 | /* 86 | Default implementation does nothing when viewing the webpage normally 87 | */ 88 | var clickTarget = NOOP; 89 | var tellLightroomWhatImagesWeAreUsing = NOOP; 90 | var setActiveImageSize = NOOP; 91 | var callCallback = NOOP; 92 | var pushresult = NOOP; 93 | 94 | // --------------------------------------------------------------------------- 95 | 96 | callCallback = function() { 97 | var javascript = 'myCallback.' + arguments[ 0 ] + "( "; 98 | var j = arguments.length; 99 | var c = j - 1; 100 | for( var i = 1; i < j; i++ ) { 101 | var arg = arguments[ i ]; 102 | if( typeof( arg ) == 'string' ) { 103 | javascript = javascript + '"' + arg + '"'; 104 | } 105 | if( typeof( arg ) == 'number' ) { 106 | javascript = javascript + arg 107 | } 108 | if( typeof( arg ) == 'undefined' ) { 109 | javascript = javascript + 'undefined' 110 | } 111 | if( i < c ) { 112 | javascript = javascript + ", " 113 | } 114 | } 115 | javascript = javascript + " )" 116 | hosteval( javascript ) 117 | } 118 | 119 | pushresult = function( result ) { 120 | callCallback( "pushresult", result ) 121 | } 122 | 123 | // --------------------------------------------------------------------------- 124 | 125 | /* 126 | Set up live feedback between Lightroom and the previewed web page. 127 | */ 128 | if( callCallback != NOOP ) { 129 | setActiveImageSize = function( size ) { 130 | document.activeImageSize = size; 131 | callCallback( "setActiveImageSize", size ); 132 | } 133 | 134 | tellLightroomWhatImagesWeAreUsing = function() { 135 | 136 | if( window.myCallback != null ) { 137 | var imgElements = document.getElementsByTagName( "img" ); 138 | var elsLen = imgElements.length; 139 | var result = new Array() 140 | for( i = 0; i < elsLen; i++ ) { 141 | var element = imgElements[ i ]; 142 | var imageID = element.id; 143 | // for html validation purposes, we've prepended "ID" to the GUID for this 144 | // image, so now we strip that off. 145 | imageID = imageID.substring( 2 ); 146 | result[ i ] = imageID; 147 | } 148 | myCallback.setUsedFiles( result ); 149 | } 150 | } 151 | 152 | clickTarget = function( obj, target, imageID ) { 153 | if( imageID != null ) { 154 | // for html validation purposes, we've prepended "ID" to the GUID for this 155 | // image, so now we strip that off. 156 | imageID = imageID.substring( 2 ); 157 | } 158 | var bounds = findBounds( obj ); 159 | var font = findFont( obj ); 160 | callCallback( 'inPlaceEdit', target, bounds.x, bounds.y, bounds.width, bounds.height, font.fontFamily, font.fontSize, imageID ) 161 | } 162 | 163 | AgDebugPrint = function( message ) { 164 | callCallback( 'AgDebugPrint', message ); 165 | } 166 | } 167 | 168 | // --------------------------------------------------------------------------- 169 | 170 | if( firFoxArr && ( firFoxArr[1] > 1 || firFoxArr[2] > 4 ) || 171 | safariArr ) { 172 | window.gridOn = NOOP; 173 | window.gridOff= NOOP; 174 | } 175 | else { 176 | window.gridOn = function( t, id ) { 177 | t.agOriginalClassName = t.className; 178 | t.className = "selectedThumbnail " + t.className; 179 | }; 180 | window.gridOff= function( t ) { 181 | t.className = t.agOriginalClassName; 182 | }; 183 | } 184 | 185 | var needThumbImgLink = !isFirefoxPat; 186 | 187 | 188 | var oldOnLoad = window.onload; 189 | window.onload = function() { 190 | if( window.AgOnLoad ) { 191 | window.AgOnLoad(); 192 | } 193 | if( oldOnLoad ) { 194 | oldOnLoad(); 195 | } 196 | }; 197 | 198 | //------------------------------------------------------------ 199 | 200 | document.liveUpdateImageMaxSize = function( id, value ) { 201 | var targetArr = id.split(/[ \t\r\n]*,[ \t\r\n]*/); 202 | for( i = 0; i < targetArr.length; i++ ) { 203 | var target = targetArr[i]; 204 | var idRegex = new RegExp( "^[#](.+$)" ); 205 | var theId = idRegex.exec( target ); 206 | if( theId && theId[ 1 ] ) { 207 | var item = document.getElementById( theId[ 1 ] ); 208 | if( item ) { 209 | 210 | // scale image size 211 | var max = item.width; 212 | if( item.height > max ) { 213 | max = item.height; 214 | } 215 | item.width = item.width * value / max; 216 | item.height = item.height * value / max; 217 | } 218 | } 219 | } 220 | 221 | 222 | return "invalidateAllContent"; 223 | } 224 | 225 | //------------------------------------------------------------ 226 | 227 | document.liveUpdatePropertyMac = function( id, property, value ) { 228 | 229 | var targetArr = id.split(/[ \t\r\n]*,[ \t\r\n]*/); 230 | var clasRegex = new RegExp( "^[.](.+$)" ) 231 | var idRegex = new RegExp( "^[#](.+$)" ) 232 | var comboRegex = new RegExp( "[ \t\r\n]" ); 233 | 234 | for( i = 0; i < targetArr.length; i++ ) { 235 | var target = targetArr[i]; 236 | var theClass = clasRegex.exec( target ); 237 | var theId = idRegex.exec( target ); 238 | if( comboRegex.exec( target ) ) { 239 | return "failed"; 240 | } 241 | else if( theClass) { 242 | var pattern = new RegExp( "(^|\\s)" + theClass[1] + "(\\s|$)" ); 243 | var items = document.getElementsByTagName( '*' ); 244 | for( o = 0; o < items.length; o++ ) { 245 | var item = items[ o ]; 246 | if( pattern.test( item.className ) ){ 247 | item.style.setProperty( property, value, "important" ); 248 | } 249 | } 250 | return "invalidateAllContent"; 251 | } 252 | else if( theId ) { 253 | if( property == "maxSize" ) { 254 | return document.liveUpdateImageMaxSize( id, value ); 255 | } 256 | var item = document.getElementById( theId[ 1 ] ); 257 | if( item ) { 258 | item.style.setProperty( property, value, "important"); 259 | } 260 | return "invalidateAllContent"; 261 | } 262 | else { 263 | var items = document.getElementsByTagName( target); 264 | for( i = 0; i < items.length; i++ ) { 265 | var item = items[i]; 266 | item.style.setProperty( property, value, "important" ); 267 | } 268 | return "invalidateAllContent"; 269 | } 270 | } 271 | }; 272 | 273 | //------------------------------------------------------------ 274 | 275 | document.liveUpdatePropertyWin = function( id, property, value ) { 276 | if( property == "maxSize" ) { 277 | return document.liveUpdateImageMaxSize( id, value ); 278 | } 279 | if( property == 'display' || value == 'inherit' ) { 280 | return "failed" 281 | } 282 | var x = document.styleSheets[0]; 283 | x.addRule(id, property + ": " + value + " !important"); 284 | return "invalidateAllContent"; 285 | } 286 | if( MAC_ENV ) { 287 | document.liveUpdateProperty = document.liveUpdatePropertyMac 288 | } 289 | if( WIN_ENV ) { 290 | document.liveUpdateProperty = document.liveUpdatePropertyWin 291 | } 292 | 293 | //------------------------------------------------------------ 294 | 295 | document.liveUpdate = function( path, newValue, cssId, property ) { 296 | var success = "failed"; 297 | var reg = /(^[^.]+)\./; 298 | var ar = reg.exec( path ); 299 | if( ar == null ) { 300 | 301 | // override result if we drove this change ourselves 302 | if( document.LR_modelManipulation ) { 303 | return "invalidateOldHTML"; 304 | } 305 | return "failed"; 306 | } 307 | var area = ar[1]; 308 | if( area == "metadata" ) { 309 | // our html is built so that the HTML ids are the metadata path 310 | var a = document.getElementById( path ); 311 | while(a.hasChildNodes()) { 312 | a.removeChild(a.firstChild); 313 | } 314 | a.innerHTML = newValue; 315 | success = "invalidateOldHTML"; 316 | } 317 | else if( area == "appearance" ) { 318 | success = document.liveUpdateProperty( cssId, property, newValue ); 319 | } 320 | else if( path == "nonCSS.tracking" ) { 321 | if( newValue == null || newValue == "null") { 322 | // force reload by signalling failure to update 323 | // because we don't properly layout all the nuiances of 324 | // detail image placement during tracking, we reload at the 325 | // end to make sure it is correct when mouseup 326 | success = "failed"; 327 | } 328 | else { 329 | // FIX_ME, image won't layout properly during drag w/o this 330 | success = "invalidateOldHTML"; 331 | } 332 | } 333 | else if( path == "nonCSS.imageBorderWidth" ) { 334 | // FIX_ME, not yet implemented, so image won't layout properly during drag 335 | // as a workaround, we're reloading on tracking up (see previous block) 336 | success = "invalidateOldHTML"; 337 | } 338 | else { 339 | // AgDebugPrint("How do I update " + path + " to " + newValue ) 340 | } 341 | 342 | // override result if we drove this change ourselves 343 | if( document.LR_modelManipulation ) { 344 | return "invalidateOldHTML"; 345 | } 346 | return success; 347 | } 348 | 349 | //------------------------------------------------------------ 350 | 351 | document.liveUpdateImageSize = function( imageID, width, height ) { 352 | 353 | var img = document.getElementById( 'ID' + imageID ); 354 | img.style.width = width + 'px'; 355 | img.style.height = height + 'px'; 356 | return "invalidateAllContent"; 357 | } 358 | 359 | //------------------------------------------------------------ 360 | 361 | -------------------------------------------------------------------------------- /websample.lrwebengine/resources/js/pngfix.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Correctly handle PNG transparency in Win IE 5.5 & 6. 4 | http://homepage.ntlworld.com/bobosola. Updated 18-Jan-2006. 5 | 6 | Use in with DEFER keyword wrapped in conditional comments: 7 | 10 | 11 | */ 12 | 13 | var arVersion = navigator.appVersion.split("MSIE") 14 | var version = parseFloat(arVersion[1]) 15 | var re = /^agwpg/i; 16 | var workAroundIEDeadlockBug = re.exec( document.location ) == null; 17 | 18 | if ((version >= 5.5) && (document.body.filters) && workAroundIEDeadlockBug) { 19 | for(var i=0; i" 34 | img.outerHTML = strNewHTML 35 | i = i-1 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /websample.lrwebengine/strings/en/TranslatedStrings.txt: -------------------------------------------------------------------------------- 1 | "$$$/AgWPG/Templates/HTML/Title=A Basic Web SDK Plug-in" 2 | "$$$/AgWPG/Templates/HTML/Description=This HTML-driven web photo gallery is provided by Adobe with Lightroom 2.0." 3 | "$$$/AgWPG/Templates/HTML/IdentityPlate/Link=Web or Mail Link" 4 | "$$$/AgWPG/Templates/HTML/link=Web or Mail Link" 5 | 6 | "$$$/AgWPG/Templates/HTML/DefaultValues/properties/SiteTitle=Site Title" 7 | "$$$/AgWPG/Templates/HTML/DefaultValues/properties/ContactInfo=Contact Name" 8 | "$$$/AgWPG/Templates/HTML/Defaults/ContactLink=mailto:user@domain" 9 | 10 | -- [[ Main section with large image]] 11 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Main=Main Section" 12 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/BackgroundColors=Background" 13 | "$$$/AgWPG/Templates/HTML/Panel/Labels/SiteTitle=Site Title" 14 | "$$$/AgWPG/Templates/HTML/Panel/Labels/GroupTitle=Collection Title" 15 | "$$$/AgWPG/Templates/HTML/Panel/Labels/IdentityPlate=Identity Plate" 16 | "$$$/AgWPG/Templates/HTML/Panel/Labels/CollectionDescription=Collection Description" 17 | "$$$/AgWPG/Templates/HTML/Panel/Labels/ContactInfo=Contact Info" 18 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/TextColor=Text" 19 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Images=Images" 20 | "$$$/AgWPG/Templates/HTML/Panel/Labels/MaximumImageSizeLabel/LargePreview=Size" 21 | "$$$/AgWPG/Templates/HTML/Panel/Labels/ImageSizeUnit=px" 22 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/LabelBackground=Label Background" 23 | 24 | --[[Left Panel with Thumbnails]] 25 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/ThumbnailViewer=Thumbnail Viewer" 26 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarArrowColor=ScrollArrow" 27 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarColor=ScrollBar" 28 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarFace=ScrollBar Face" 29 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ScrollBarHighlight=ScrollBar Highlight" 30 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/ThumbBackground=Background" 31 | 32 | --[[ Footer Panel]] 33 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Footer=Footer" 34 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/FooterBorder=Border" 35 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/FooterBackground=Background" 36 | 37 | --[[ Header Panel]] 38 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Appearance/Header=Header" 39 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/HeaderBorder=Header Border" 40 | "$$$/AgWPG/Templates/HTML/Panel/Labels/Colors/HeaderBackground=Header Background" 41 | 42 | "$$$/AgWPG/Templates/HTML/Panel/Checkbox/ShowImageBorder=Photo Borders" 43 | "$$$/AgWPG/Templates/HTML/Panel/Checkbox/UseWatermark=Add Copyright Watermark" 44 | "$$$/AgWPG/Templates/HTML/Panel/Labels/MaximumImageSizeLabel/JPEGQualityLabel=Quality" 45 | 46 | 47 | 48 | --------------------------------------------------------------------------------