Command: ClipAttr (copy/paste timestamps between files)

Overview:

This script adds a ClipAttr command.

  • ClipAttr COPY will copy the Created and Modified timestamps from all selected folders & files into a variable (which acts like the clipboard, but does not modify your actual clipboard).

  • ClipAttr PASTE will set the Created and Modified timestamps on all selected folders & files to match the values copied earlier.

  • If you don't have the same number of items selected when you copy and when you paste, the list of timestamps will loop around (if needed).

    In particular, if you use ClipAttr COPY on a single item, and then select lots of items and use ClipAttr PASTE, you can paste one item's timestamps over lots of other items.

    You will usually either copy just one timestamp to apply to however many items, or copy and paste between the same number of items, but you don't have to.

Installation:

  • Download Clipboard_Attributes.vbs.txt and drag it to Preferences / Toolbars / Scripts.

    Clipboard_Attributes.vbs.txt (2.72 KB)

  • With the script installed, you can create toolbar buttons or hotkeys which use the ClipAttr command, as described in the overview section above.

  • Here are two pre-made buttons you can drag to a toolbar:

    Copy Dates.dcf (252 Bytes)
    Paste Dates.dcf (250 Bytes)

History:

  • 1.0 (18/May/2015): Initial version.

Limitations:

  • The 'clipboard' of stored timestamps does not persist if you exit and restart Opus. (This could be added if needed.)
  • Timestamp precision is only up to 1 second. Exact millisecond timestamps are not set at present.

Script code:

The script code from the download above is reproduced below. This is for people browsing the forum for scripting techniques. You do not need to care about this code if you just want to use the script.

option explicit

' Clipboard Attributes
' (C) 2015 Leo Davidson
' 
' This is a script for Directory Opus.
' See http://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.

' Called by Directory Opus to initialize the script
Function OnInit(initData)
	initData.name = "Clipboard Attributes"
	initData.desc = "Copy and paste file timestamps"
	initData.copyright = "(C) 2015 Leo Davidson"
	initData.version = "1.0"
	initData.default_enable = true

	Dim cmd

	Set cmd = initData.AddCommand
	cmd.name = "ClipAttr"
	cmd.method = "OnClipAttr"
	cmd.desc = ""
	cmd.label = "ClipAttr"
	cmd.template = "COPY/S,PASTE/S"
End Function


' Implement the ClipAttr command
Function OnClipAttr(scriptCmdData)
	If (scriptCmdData.Func.args.got_arg.COPY) Then
		OnClipAttrCopy(scriptCmdData)
	ElseIf (scriptCmdData.Func.args.got_arg.PASTE) Then
		OnClipAttrPaste(scriptCmdData)
	End If
End Function

Function ZeroPad(s,c)
	ZeroPad = s
	Do While (Len(ZeroPad) < c)
		ZeroPad = "0" & ZeroPad
	Loop
End Function

Function DateTimeForCmd(d)
	DateTimeForCmd = ZeroPad(d.year,4) & "-" & ZeroPad(d.month,2) & "-" & ZeroPad(d.day,2) & " " _
		& ZeroPad(d.hour,2) & ":" & ZeroPad(d.min,2) & ":" & ZeroPad(d.sec,2)
End Function

Function OnClipAttrCopy(scriptCmdData)

	scriptCmdData.func.command.deselect = False

	Dim vecModified, vecCreated, fileItem
	Set vecModified = DOpus.Create.Vector
	Set vecCreated = DOpus.Create.Vector
	
	For Each fileItem in scriptCmdData.func.sourcetab.selected
		vecModified.push_back( fileItem.modify )
		vecCreated.push_back( fileitem.create )
	Next

	Dim varMod, varCre
	Set varMod = Script.vars("vecModified")
	Set varCre = Script.vars("vecCreated")
	varMod.value = vecModified
'	varMod.persist = True
	varCre.value = vecCreated
'	varCre.persist = True

End Function

Function OnClipAttrPaste(scriptCmdData)

	Dim cmd, cmdLine
	Set cmd = scriptCmdData.func.command

	cmd.deselect = False

	If (Not (Script.vars.Exists("vecModified") And Script.vars.Exists("vecCreated"))) Then
		Exit Function
	End If

	Dim vecModified, vecCreated, mi, mt, ci, ct, fileItem
	Set vecModified = Script.vars.Get("vecModified")
	Set vecCreated = Script.vars.Get("vecCreated")
	mi = 0
	ci = 0
	mt = vecModified.count
	ct = vecCreated.count
	
	If (mt = 0 Or ct = 0) Then
		Exit Function
	End If
	
	For Each fileItem in scriptCmdData.func.sourcetab.selected
		cmdLine = "SetAttr MODIFIED=""" & DateTimeForCmd(vecModified(mi)) _
			& """ CREATED=""" & DateTimeForCmd(vecCreated(ci)) & """"

		cmd.ClearFiles
		cmd.AddFile fileItem
		cmd.RunCommand(cmdLine)

		mi = mi + 1
		ci = ci + 1
		If (mi >= mt) Then mi = 0
		If (ci >= ct) Then ci = 0
	Next

End Function
2 Likes

I also use it on my "All files and folders" Windows file type to create a context menu item.

Thanks so much. I'd been trying to figure this out, without a lot of success. Your script and buttons were great!!!

I took Leos code and merged existing functionality of ClipAttr into ClipboardEx.

This is not to bug you Leo and to just rewrite the things you did o). I actually wanted to combine this addin with the existing ClipboardEx addin I already have in use, too much stuff in the script addins folder already. I thought this functionality fits there quite well and I needed something which would copy (only the creation-date) by commandline, directly from A to B without an existing selection.

1 Like

Hi Leo, and thank you for this great script !

I didn't find it at first when I searched for something similar.
However, while creating a new topic, I was glad to see it appeared in the suggested existing topics !

I'm not sure why you avoided milliseconds and what are your thoughts about this, but I would think they should be included by default. They are part of the timestamp after all.

Since I wanted to clone the exact timestamp, I needed the milliseconds too.
If it can help someone else (and unless Leo advises against it), the script needs to be modified like this (replace the function DateTimeForCmd() with this one):

Function DateTimeForCmd(d)
	DateTimeForCmd = ZeroPad(d.year,4) & "-" & ZeroPad(d.month,2) & "-" & ZeroPad(d.day,2) & " " _
		& ZeroPad(d.hour,2) & ":" & ZeroPad(d.min,2) & ":" & ZeroPad(d.sec,2) & "." & ZeroPad(d.ms,3)
End Function

Basically, I only added the following to the existing line:

 & "." & ZeroPad(d.ms,3)

Thank you again Leo :muscle::+1:

2 Likes

I think milliseconds wasn’t possible back when the script was written, but is now.

1 Like