Help with copy command, distguish between file and directory

Very new user. I'm trying to create a button that will make a copy of the selected item(s) and then add a date/time stamp to the item(s).

Here is the command:

Copy DUPLICATE WHENEXISTS=rename AS "{file|noext}_{date|yyyyMMdd}_{time|HHmm}{file|ext}"

Here is the button:

<?xml version="1.0"?>
<button backcol="none" display="both" hotkey="ctrl+shift+D" textcol="none">
	<label>Copy + Timestamp File</label>
	<tip>Makes a copy of the selected item(s) and adds a date/time stamp to the name.</tip>
	<icon1>#duplicate</icon1>
	<function type="normal">
		<instruction>Copy DUPLICATE WHENEXISTS=rename AS &quot;{file|noext}_{date|yyyyMMdd}_{time|HHmm}{file|ext}&quot; </instruction>
	</function>
</button>

This works fine for files but has issues when a directories are selected:

File:

fred.txt -> fred_20071016_1215.txt

Directory:

BamBam -> BamBam_20071016_1215BamBam

The control sequece {file|ext} returns the directory name for a directory...which causes my problem.

Is there anyway to have the copy command do different things for different types (like the rename command can do) or is there some other way to have files/directories processed differently within a buttion?

Thanks for your help,

PHPBB_IMPORT_WARNING CODE_NEAR_LI

There are a couple of ways you can get this done right now. (A more direct way of doing it was requested a little while ago but I don't know when/if it'll be implemented, so these will have to do.)

[ol][li]The first method is to use a bit of VBScript glue. You make your Opus button pass the filename to a VBScript and it looks at the filename and does something different depending on whether it's a directory or a file. A VBScript which does just that can be found in this thread:

[One Hotkey for 2 commands)

In this case you could copy the file using VBScript itself, or you could have VBScript execute Opus commands via

"C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe" /cmd <your command here>
[/li]
[li]Another way of doing it is to create two User Commands which are both called by your button. One user command will start with @dironly, and only affect directories, while the other will start with @filesonly, and only affect files.

You cannot mix @dironly and @filesonly in the same command but you can have a command which calls two user commands, each of which uses one or the other. This seems to work very well and the only disadvantage is that you have to create three things instead of one.

To set this up, go to Customize, click on the Commands tab and then the User category. Add a new user command called DateDupeDirs and make it run this:

@dironly Copy DUPLICATE WHENEXISTS=rename AS "{file|noext}_{date|yyyyMMdd}_{time|HHmm}"

Now add another user command, this time called DateDupeFiles and make it run this:

@filesonly Copy DUPLICATE WHENEXISTS=rename AS "{file|noext}_{date|yyyyMMdd}_{time|HHmm}{file|ext}"

Finally, make your actual button (or hotkey or menu item) run this:

DateDupeDirs DateDupeFiles

I just tried this and it seems to work great, as shown below.[/li][/ol]


Thanks for your help. I prefer this approach, seems cleaner... But when I tried it I had some problems.

I created the two user commands and tested them by themselves - everything works good. I then added them both to the button:

DateDupeDirs 
DateDupeFiles

What I am seeing is whichever one is listed first works and the other doesn't: The above works for directories but not files. If I swap the order it will work for files but not directories...

If you happen to still have the test on your system could you see if it works for files?

Thank you,

It definitely worked for files and dirs here, see the screenshot above.

Which version of Opus are you using?

[quote="nudel"]
Which version of Opus are you using?[/quote]

I'm using version 9.0.0.9 on Windows XP.

I have the two user commands set up. As a test I created two buttons, one for each user command. The DateDupeDirs command works fine and only on directories. The DateDupeFiles works fine and only on files...

I then created a button that calls both user commands. When I test that button, only the user command listed first works...

Are there any configuration settings that could affect this?

Thank you for your help,

Not sure why it would work for me but not for you. I'm running a beta of the next version of Opus so it could be that, but I'm not aware of any changes that would affect this. Give it a try with the next version when it comes out, I guess. If I can think of anything else I'll post back.

Jon had an idea about why it works for me but not you:

If you go to Preferences - File Operations - Options do you have Postpone file deselection until end of function switched on? I do, but if you don't then it might explain why it doesn't work for you.

If you don't want to change that setting then you could probably also solve the problem by editing both of the user commands, and the main button, and adding @nodeselect to the top of all three of them (on a line by itself).

(I'm not sure if you need it in all three places, or just in some of them, but it won't hurt so adding it to all of them seems the safest bet.)

[quote="nudel"]Jon had an idea about why it works for me but not you:

If you go to Preferences - File Operations - Options do you have Postpone file deselection until end of function switched on? I do, but if you don't then it might explain why it doesn't work for you.[/quote]

Sorry for delay and thanks for your help.

That option is checked... My workaround is to have a file version on LMB and a directory version on RMB...not ideal but it works.

Thanks,

Great tip, very helpful.

Unfortunately, I am having the same problem as Indy - only the first one works. I have tried unchecking 'deselect files used in functions' , checking 'Postpone until after' and adding the @nodeselect to all called command. No dice.

Anybody else try this?

[quote="Anakha"]Great tip, very helpful.

Unfortunately, I am having the same problem as Indy - only the first one works. I have tried unchecking 'deselect files used in functions' , checking 'Postpone until after' and adding the @nodeselect to all called command. No dice.

Anybody else try this?[/quote]

Yes, I seem to have the same problem, but I've also discovered something else.

Far above Indy said [quote]The control sequece {file|ext} returns the directory name for a directory...which causes my problem. [/quote]

This is not strictly true. The control sequence {file|ext} returns the file name for a for a file the name of which does not contain a "." whether the file is or is not a directory.

If a file, not a directory, has no extension it will behave in the context of this thread as directories have been assumed to behave. Conversely, if a directory name contains a ".", it will behave as non-directories have been assumed to behave.

If one, for some reason had a directory named "abc.xyz", I don't know if the timestamp would be wanted before or after the ".xyz", but almost certainly if one had a file named only "abc", the characters "abc" would not be wanted both before and after the timestamp.

I stumbled across this while trying, so far unsuccessfully, to come up with a solution. I admit that, for practical purposes, this technicality may hardly matter.

This doesn't help add the time to the names while Copying things but, in case it's useful to anyone, you can easily solve the problem when Renaming things in-place:

Rename PATTERN="*" TO="* - {date|yyyy-MM-dd} {time|HH-mm-ss}" AUTORENAME TYPE=dirs Rename PATTERN="*.*" TO="* - {date|yyyy-MM-dd} {time|HH-mm-ss}.*" AUTORENAME TYPE=files

(Of course, you could copy normally and then rename the copies afterwards, in which case this command may be useful afterall, albeit not a one-click solution.)

So, ehm. I've decided to go with nudel's solution of first copying and then renaming, but that leaves the issue of only the first command being called unsolved.

Is this a bug in DOpus? It seems 'unexpected behaviour' at best :wink:
Should this be submitted to GP?

/Anakha

I finally have a button which performs as desired.

However, it runs runs an MS-DOS Batch Function which, in turn, runs a Rexx script since REXX is the scripting language with which I'm most familiar. I'm guessing use of Rexx may make this not of general interest.

I'm using the value of {file} being equal to or not equal to the value of {file|ext} to determine what type of rename to do.

I could, instead, base this decision on whether or not the file is actually a directory, but already having the values of {file} and {file|ext}, basing the decision on those is simpler and adequate for normal cases. Either method can have theoretical problems with unusual cases such as directories with extensions or non-directories without extensions.

My script uses "dopusrt.exe /cmd" to invoke Copy DUPLICATE WHENEXISTS=rename AS commands.

In order to make this work I had to turn off Preferences -> File Operations -> Options -> Deselect files used in functions.

With this preference in effect, apparently the selected file had been deselected bdfore the COPY command ran and the COPY command didn't do anything. At least I guess that's what happened.

Leaving the preference in effect and selecting Postpone file deselection until end of function wasn't sufficient to get the function to do anything..

I don't yet know if I will discover anything I don't like about not having Deselect files used in functions in effect.

Here is my script for anybody who may be interested:

trace ?o ProgramFiles = strip(value('ProgramFiles',,'ENVIRONMENT')) DopusPath = '"'ProgramFiles'\Directory Opus' parse arg file if substr(file,1,1) = '"' then parse arg '"' file '"' '"' noext '"' '"' ext '"' else parse arg file noext ext date = date('S') time = time('N') time = substr(time,1,2) || substr(time,4,2) || substr(time,7,2) if file = ext then '"'DopusPath'\dopusrt.exe"' '/cmd', 'Copy DUPLICATE WHENEXISTS=rename AS "'file'_'date'_'time'"' else '"'DopusPath'\dopusrt.exe"' '/cmd', 'Copy DUPLICATE WHENEXISTS=rename AS "'noext'_'date'_'time || ext'"'

[quote="Anakha"]So, ehm. I've decided to go with nudel's solution of first copying and then renaming, but that leaves the issue of only the first command being called unsolved.

Is this a bug in DOpus? It seems 'unexpected behaviour' at best :wink:
Should this be submitted to GP?

/Anakha[/quote]

I also wonder about {file|ext} giving the entire filename for a directory (file with no extension). It seems like {file|ext} should have null value in this case. If it did, all this would have been simple, I think, but I suppose changing it now would break something already in existence.

Yep... because {file} is used to identify both 'files' and 'folders' (which really are files right? just witha 'd' attribute?)... which takes us back to the opening thread mentioning Opus not distinguishing between the two types in many places...

Maybe there's an enhancement that could be requested to extend the control sequence to add modified codes like:

{ffile}
{dfile}

Or something like that which would only operate on files or directories???

[quote="steje"]Maybe there's an enhancement that could be requested to extend the control sequence to add modified codes like:

{ffile}
{dfile}

Or something like that which would only operate on files or directories???[/quote]
A while back I requested that the @filesonly and @dirsonly command modifiers be upgraded so they can be used on individual lines. I think that would do the job.

There is merit in being able to get a list of all selected files and directories (separately), which is more like your idea.

Yep... because {file} is used to identify both 'files' and 'folders' (which really are files right? just witha 'd' attribute?)... which takes us back to the opening thread mentioning Opus not distinguishing between the two types in many places...

Maybe there's an enhancement that could be requested to extend the control sequence to add modified codes like:

{ffile}
{dfile}

Or something like that which would only operate on files or directories???[/quote]

Yes, but let's not worry for the moment whether the file is a directory or not. Logically shouldn't {file|ext} have no value if the file/directory has no extension?

Above I showed my REXX script. For completeness, I should have shown that the button is invoking the script as follows: Runmode Min Rexx "E:\Bat\Directory_Opus_Filesnapshot.rex" {file} {file|noext} {file|ext}

When describing my solution above, I said:

[quote="rcoleman1943"]
In order to make this work I had to turn off Preferences -> File Operations -> Options -> Deselect files used in functions.

With this preference in effect, apparently the selected file had been deselected bdfore the COPY command ran and the COPY command didn't do anything. At least I guess that's what happened.

Leaving the preference in effect and selecting Postpone file deselection until end of function wasn't sufficient to get the function to do anything.. [/quote]

Now I just discovered that I can avoid this issue by adding @nodeselect to the function as follows:

@nodeslect Runmode Min Rexx "E:\Bat\Directory_Opus_Filesnapshot.rex" {file} {file|noext} {file|ext}

Long ago, in this thread, Indy wrote

Subsequently, I wrote

Either we were both wrong or things have changed.

Today {file|ext) returns nothing for a directory whether or not the directory name contains a ".".

On the other hand, for a non-directory file whose name contains a ".", {file|ext} returns the "."and whatever follows it (as one would expect).

For a non-directory file whose name contains no "." (has no extension), {file|ext} returns the filename. This appears to be the behavior once exhibited for any file, directory or not, whose name contained no "." (and still seems illogical).

It seems to me that if the filename contains a "." the proper value of {file|ext) would be the (last) "." and everything following it.

It further seems that if the filename contains no ".", the value of {file|ext} should be null/empty?

The current behavior of never returning the name for a directory is probably slightly better than the previous behavior of always returning the name, but is arguably wrong if the name contains a ".". The current behavior of returning the name for a non-directory file with a "." in the name still seems wrong.

Why should the value of {file|ext} depend on whether or not the file is a directory?