This button will show a dialog (if you have selected files) to enter a timeshift string and picking a reference date (https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Time_Shifting.htm).
It does syntax checking for the timeshift string. If it is valid, it will apply the timeshift with the selected reference date with the SetAttr
command to the selected files.
- If you dont want the help text feel free to edit the dialogsize in the buttons resources.
- The syntax check for the value for year is arbitrary (3000, was just the next millenial from now)
- Leading 0s are allowed
Installation
Edit your menu (via context menu "customize") and copy the code below and paste into your menu (contextmenu "paste")
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
<label>Time Shift</label>
<icon1>#setdate</icon1>
<function type="script">
<instruction>@disablenosel</instruction>
<instruction>@script JScript</instruction>
<instruction>function OnClick(clickData)</instruction>
<instruction>{</instruction>
<instruction> ShowDialog(clickData, "", -1);</instruction>
<instruction>}</instruction>
<instruction />
<instruction>//Show the dialog and do syntax check</instruction>
<instruction>//Is an extra function because dialog can be closed with wrong data and needs to be shown again</instruction>
<instruction>function ShowDialog(clickData, pickedTimeshift, pickedSourceDate)</instruction>
<instruction>{</instruction>
<instruction> var dlg = DOpus.Dlg;</instruction>
<instruction> dlg.window = clickData.func.sourcetab;</instruction>
<instruction> dlg.template = "timeshiftdialog";</instruction>
<instruction> dlg.detach = true;</instruction>
<instruction> dlg.Create();</instruction>
<instruction> </instruction>
<instruction> if(pickedTimeshift != "")</instruction>
<instruction> dlg.Control("editTimeShift").value = pickedTimeshift;</instruction>
<instruction> dlg.Control("comboSourceDate").value = pickedSourceDate == -1 ? 2 : pickedSourceDate; // Default is datetaken</instruction>
<instruction />
<instruction> dlg.Show();</instruction>
<instruction />
<instruction> while (true) </instruction>
<instruction> {</instruction>
<instruction> var msg = dlg.GetMsg();</instruction>
<instruction> if (!msg.result) </instruction>
<instruction> break;</instruction>
<instruction />
<instruction> var timeShift = String(dlg.Control("editTimeShift").value);</instruction>
<instruction> if(TestTimeshiftString(timeShift))</instruction>
<instruction> dlg.Control("staticSyntax").bg = "0,255,0";</instruction>
<instruction />
<instruction> else</instruction>
<instruction> dlg.Control("staticSyntax").bg = "255,0,0";</instruction>
<instruction> </instruction>
<instruction> if (msg.event == "click")</instruction>
<instruction> {</instruction>
<instruction> if(msg.control == "buttonApply")</instruction>
<instruction> {</instruction>
<instruction> if(TestTimeshiftString(timeShift))</instruction>
<instruction> dlg.EndDlg(0);</instruction>
<instruction> } </instruction>
<instruction> if(msg.control == "buttonDocs") </instruction>
<instruction> DOpus.NewCommand.RunCommand("https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Time_Shifting.htm");</instruction>
<instruction> if(msg.control == "buttonCancel")</instruction>
<instruction> dlg.EndDlg(1);</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction> </instruction>
<instruction> if(dlg.result == 0)</instruction>
<instruction> {</instruction>
<instruction> var sourceDateIndex = dlg.Control("comboSourceDate").value;</instruction>
<instruction> var timeShift = String(dlg.Control("editTimeShift").value);</instruction>
<instruction />
<instruction> if(!TestTimeshiftString(timeShift)) //</instruction>
<instruction> {</instruction>
<instruction> var errorDlg = clickData.func.Dlg;</instruction>
<instruction> errorDlg.message = "The timeshift string you entered is wrong";</instruction>
<instruction> errorDlg.buttons = "OK";</instruction>
<instruction> errorDlg.title = "Wrong timeshift string";</instruction>
<instruction> errorDlg.Show();</instruction>
<instruction> ShowDialog(clickData);</instruction>
<instruction> }</instruction>
<instruction> else if(sourceDateIndex == -1)</instruction>
<instruction> {</instruction>
<instruction> var errorDlg = clickData.func.Dlg;</instruction>
<instruction> errorDlg.message = "Pick date for timeshift origin";</instruction>
<instruction> errorDlg.buttons = "OK";</instruction>
<instruction> errorDlg.title = "Incomplete data";</instruction>
<instruction> errorDlg.Show();</instruction>
<instruction> if(TestTimeshiftString(timeShift))</instruction>
<instruction> ShowDialog(clickData, timeShift, -1);</instruction>
<instruction> else</instruction>
<instruction> ShowDialog(clickData, "", -1);</instruction>
<instruction> }</instruction>
<instruction> else//all correct</instruction>
<instruction> {</instruction>
<instruction> var dates = ["createdate", "datedigitized", "datetaken", "lastmodifieddate"];</instruction>
<instruction> ShiftTime(clickData, dates[sourceDateIndex], timeShift);</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction> else if(dlg.result == 1)</instruction>
<instruction> return;</instruction>
<instruction>}</instruction>
<instruction />
<instruction>// Test for syntax</instruction>
<instruction>function TestTimeshiftString(timeShift)</instruction>
<instruction>{</instruction>
<instruction> var regex = /^((\+|\-)?((0{0,3}[0-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|[12][0-9]{3}|3000):(0?[1-9]|1[0-2]):(0?[1-9]|[12][0-9]|3[01])|(0?[1-9]|1[0-2]):(0?[1-9]|[12][0-9]|3[01])|(0?[1-9]|[12][0-9]|3[01])) )?(\+|\-)?((0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9]):(0?[0-9]|[1-5][0-9])|(0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9])|(0?[0-9]|1[0-9]|2[0-3]))$/;</instruction>
<instruction> var matches = timeShift.match(regex);</instruction>
<instruction> return matches != null;</instruction>
<instruction>}</instruction>
<instruction />
<instruction>//Apply Timeshift to selected files</instruction>
<instruction>function ShiftTime(clickData, sourceDate, timeShift)</instruction>
<instruction>{</instruction>
<instruction> var selectedFiles = clickData.func.sourcetab.selected_files;</instruction>
<instruction> var cmd = DOpus.Create.Command;</instruction>
<instruction> cmd.AddLine("SetAttr META \"" + sourceDate + ":" + timeShift + "\"");</instruction>
<instruction> Log("SetAttr META \"" + sourceDate + ":" + timeShift + "\"");</instruction>
<instruction> cmd.SetModifier("nodeselect");</instruction>
<instruction> cmd.AddFiles(selectedFiles);</instruction>
<instruction> cmd.Run();</instruction>
<instruction>}</instruction>
<instruction />
<instruction>function Log(msg)</instruction>
<instruction>{</instruction>
<instruction> DOpus.output(String(msg));</instruction>
<instruction>}</instruction>
<instruction>==SCRIPT RESOURCES</instruction>
<instruction><resources></instruction>
<instruction> <resource name="timeshiftdialog" type="dialog"></instruction>
<instruction> <dialog fontsize="8" height="276" lang="english" title="Timeshift selected files" width="306"></instruction>
<instruction> <control halign="left" height="8" name="static1" title="Timeshift string" type="static" valign="top" width="56" x="6" y="6" /></instruction>
<instruction> <control halign="left" height="12" name="editTimeShift" tip="&lt;date-shift&gt; &lt;time-shift&gt; or &lt;time-shift&gt;" type="edit" width="174" x="66" y="6" /></instruction>
<instruction> <control halign="left" height="8" name="static2" title="Date source" type="static" valign="top" width="48" x="6" y="24" /></instruction>
<instruction> <control height="40" name="comboSourceDate" sort="yes" type="combo" width="228" x="66" y="24"></instruction>
<instruction> <contents></instruction>
<instruction> <item text="createdate" /></instruction>
<instruction> <item text="datedigitized" /></instruction>
<instruction> <item text="datetaken" /></instruction>
<instruction> <item text="lastmodifieddate" /></instruction>
<instruction> </contents></instruction>
<instruction> </control></instruction>
<instruction> <control height="204" name="group1" title="Help" type="group" width="294" x="6" y="66" /></instruction>
<instruction> <control default="yes" height="14" name="buttonApply" title="Apply" type="button" width="50" x="6" y="42" /></instruction>
<instruction> <control height="14" name="buttonDocs" title="Bring me to the docs" type="button" width="90" x="108" y="42" /></instruction>
<instruction> <control height="14" name="buttonCancel" title="Cancel" type="button" width="50" x="246" y="42" /></instruction>
<instruction> <control halign="left" height="8" name="static3" title="The format of the time shift string is either:" type="static" valign="top" width="150" x="12" y="78" /></instruction>
<instruction> <control halign="left" height="8" name="st" title="&lt;date-shift&gt; &lt;time-shift&gt; or &lt;time-shift&gt;" type="static" valign="top" width="144" x="12" y="90" /></instruction>
<instruction> <control halign="left" height="12" name="static5" title="The &lt;date-shift&gt; portion has three allowable formats:" type="static" valign="top" width="186" x="12" y="108" /></instruction>
<instruction> <control halign="left" height="12" name="static6" title="[+-]Y:M:D - year:month:day, with an optional positive or negative modifier" type="static" valign="top" width="255" x="18" y="120" /></instruction>
<instruction> <control halign="left" height="12" name="static7" title="[+-]M:D - month:day, with an optional positive or negative modifier" type="static" valign="top" width="231" x="18" y="132" /></instruction>
<instruction> <control halign="left" height="12" name="static8" title="[+-]D - day, with an optional positive or negative modifier" type="static" valign="top" width="201" x="18" y="144" /></instruction>
<instruction> <control halign="left" height="12" name="static9" title="[+-]H:M:S - hours:minutes:seconds, with an optional positive or negative modifier" type="static" valign="top" width="282" x="18" y="174" /></instruction>
<instruction> <control halign="left" height="12" name="static10" title="[+-]H:M - hours:minutes, with an optional positive or negative modifier" type="static" valign="top" width="246" x="18" y="186" /></instruction>
<instruction> <control halign="left" height="12" name="static11" title="[+-]H - hours, with an optional positive or negative modifier" type="static" valign="top" width="210" x="18" y="198" /></instruction>
<instruction> <control halign="left" height="12" name="static12" title="The &lt;time-shift&gt; portion has three allowable formats as well:" type="static" valign="top" width="213" x="12" y="162" /></instruction>
<instruction> <control halign="left" height="8" name="static13" title="Here are a few other examples:" type="static" valign="top" width="132" x="12" y="222" /></instruction>
<instruction> <control halign="left" height="8" name="static14" title="-1:0:0 0 - subtract one year from the timestamps" type="static" valign="top" width="174" x="18" y="234" /></instruction>
<instruction> <control halign="left" height="8" name="static15" title="+8:30 - add eight and a half hours to the timestamp" type="static" valign="top" width="180" x="18" y="246" /></instruction>
<instruction> <control halign="left" height="8" name="static16" title="+3 -0:45 - add three days, subtract 45 minutes from the timestamp" type="static" valign="top" width="228" x="18" y="258" /></instruction>
<instruction> <control halign="left" height="8" name="staticSyntax" title="Syntax Check" type="static" valign="top" width="48" x="246" y="6" /></instruction>
<instruction> </dialog></instruction>
<instruction> </resource></instruction>
<instruction></resources></instruction>
</function>
</button>