CopyComment

Title CopyComment
File Name CopyComment.txt
Description Copy/move comment from one file to another
Author Vochomurka
Parameters see Comments
Plugins Called file, vec, miscplugin, ini
Icon
Version 1.1
Updated on 15.08.2013
local Move

if(ctrl)
	Move = 1

local Path = trim(file.folder(x9), " ", 3) ++ "\"
local Quote = esc(?+\"+, ?+\+)
Path = trim(Path, Quote, 3)
local Name = trim(file.nametype(x9), Quote, 3)
local Source = Path ++ "descript.ion"

if(not file.validpath(Source)) do
	messagebox("ok error", "File " ++ Source ++ " is missing", "No comment file")
	quit
endif

v = vec.create(1, 1)
if(v <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #1")
	quit
endif

w = vec.create(1, 1)
if(w <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #2")
	quit
endif

N = vec.create(1, 1)
if(N <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #3")
	quit
endif

local fh = file.open(Source, "r")
local i, Str, FileName, Comment, Result, Where, Ind, Comms, NotComms
local CR = esc(?+\n+, ?+\+)
local OpQuote = esc(?+\d171+, ?+\+)
local ClQuote = esc(?+\d187+, ?+\+)
local Delim = ". "
local Config = profolder ++ "scripts\ini\CopyComment.ini"

if(fh > 0) do
	for(not(file.eof(fh))) 
		Str = file.readstring(fh)
		if(not Str)
			continue

		FileName = word(Str, 1)

		if(file.validpath(Path ++ FileName)) do
			vec.insert(v, Comms, FileName)
			Comment = select(Str, length(FileName) - length(Str) + 1)
		else
			FileName = word(Str, 1, Quote)
			if(not file.validpath(Path ++ FileName)) do
				vec.insert(N, NotComms, Str)
				NotComms++
				continue
			endif

			vec.insert(v, Comms, Quote ++ FileName ++ Quote)
			Comment = select(Str, length(FileName) - length(Str) + 3)
		endif

		if(FileName == Name) do
			local mpDlgText = "File " ++ Name ++ " has the " ++ OpQuote ++ Comment
			mpDlgText = mpDlgText ++ ClQuote ++ " comment already!\n"
			mpDlgText = mpDlgText ++ "Choose where to put new comment relative "
			mpDlgText = mpDlgText ++ "to the existing one."
			local mpDlgCaption = "CopyComment Script"
			local mpIcon = "QUESTION"
			Ind = Comms

			Where = miscplugin.messagebox(1, "&Before", "&After", "&Instead", "&Cancel")
			if(Where == "&Cancel") do
				file.close(fh)
				vec.destroy(v)
				vec.destroy(w)
				vec.destroy(N)
				quit
			endif
		endif

		vec.insert(w, Comms, Comment)
		Comms++
		Result = Result ++ "File: " ++ FileName ++ ", comment: " ++ OpQuote ++ Comment
		Result = Result ++ ClQuote ++ CR
	endfor
else
	messagebox("ok error", "File not opened", "FILE plugin error #1")
	quit
endif

file.close(fh)

if(Comms == 0) do
	Str = "File " ++ Source ++ " seems to contain no file comments!"
	messagebox("ok warning", Str, "CopyComment Script")
	vec.destroy(v)
	vec.destroy(w)
	vec.destroy(N)
	quit
elseif(Comms == 1) do
	i = 0
elseif(Comms > 1) do
	Str = pickstring(Result, "Pick a comment to copy for file " ++ Name)

	if(not _pickedline_) do
		vec.destroy(v)
		vec.destroy(w)
		vec.destroy(N)
		quit
	endif

	i = _pickedline_ - 1
endif

file.delete(Source)
Str = w[i]

if(ini.check_exists(Config, "Options", "Delimiter") == 3)
	Delim = ini.get(Config, "Options", "Delimiter")

if(not Where) do
	vec.insert(v, Comms, ifelse(index(Name, " "), Quote ++ Name ++ Quote, Name))
	vec.insert(w, Comms, Str)
elseif(Where == "&Before") do
	w[Ind] = Str ++ Delim ++ w[Ind]
elseif(Where == "&After") do
	w[Ind] = w[Ind] ++ Delim ++ Str
elseif(Where == "&Instead") do
	w[Ind] = Str
endif

if(not Move && ini.check_exists(Config, "Options", "Move") == 3)
	Move = ini.get(Config, "Options", "Move")

if(Move == 1) do
	vec.delete(v, i)
	vec.delete(w, i)
elseif(Move == 2) do
	Str = "Delete comment " ++ OpQuote ++ w[i] ++ ClQuote ++ " of file "
	Str = Str ++ v[i] ++ "?"
	if(messagebox("yesno question", Str, "Move or copy comment") == 6) do
		vec.delete(v, i)
		vec.delete(w, i)
	endif
endif

if(ini.check_exists(Config, "Options", "Sort") == 3)
	vec.doublesortstring(v, w)

fh = file.open(Source, "w")

if(fh <= 0) do
	messagebox("ok error", "File not opened", "FILE plugin error #2")
	quit
endif

if(ini.check_exists(Config, "Options", "NotComments") == 3) do
	Str = ini.get(Config, "Options", "NotComments")
else
	Str = 0
endif

if(Str == 1) do
	for(i = 0; i < NotComms; i = i + 1)
		file.writeline(fh, N[i])
	endfor
	file.writeline(fh, CR)
endif

for(i = 0; i < vec.length(v); i = i + 1)
	file.writeline(fh, v[i] ++ " " ++ w[i])
endfor

if(Str == 0) do
	file.writeline(fh, CR)
	for(i = 0; i < NotComms; i = i + 1)
		file.writeline(fh, N[i])
	endfor
endif

file.close(fh)
vec.destroy(v)
vec.destroy(w)
vec.destroy(N)
Source = win.handle("c=TTOTAL_CMD")
win.sendmessage(Source, 0x400+51, 540, 0)

Comments:

Unlike the EditFileComments script that allows to create new comments, the present script copies/moves existing comment. Second difference is that the CopyComment script deals with a single file rather than a group as the EditFileComments script does.

Put the cursor on a file you need to copy comment to, and run the script. The current file can either have a comment or not. In the former case the dialog box will be first diplayed to choose where to put new comment relative to the old one: before, after, or instead.

Then, in both cases, the dialog box appears to choose the file to copy comment from. This doalog box represents descript.ion, but allows to pick one file.

If only one file is commented, the window to pick a file is not displayed.

It's important to discuss how the descript.ion stores comments for files whose names contain spaces.

Suppose there are the following files in some directory:

FileName.ext
Name with Spaces.ext
After commenting them with Total Commander the following descript.ion file is written:
FileName.ext Name without spaces
"Name with Spaces.ext" Name with spaces

Therefore, if the file name contains spaces, then it is quoted. It allows Total Commander to distinguish a space being part of the name, from a space that delimits file name and the comment. However, these quotes are seen neither in tooltip window nor in "Show Comments Ctrl+Shift+F2" view.

Total Commander undertakes to handle file names with spaces. In most cases it is very convenient for the user, but sometimes it is not. The case under consideration is the example. What are ways to overcome this problem?

First way is hadling of short name with %n parameter rather than %N. Name with Spaces.ext is thus represented by the NAMEWI~1.EXT string. If the cm_SwitchLongNames mode is switched on, the said name is presented in descript.ion, but seems to be not commented both in tooltip window and in "Show Comments Ctrl+Shift+F2" view.

Second way (pass long file name through global variable) is used in the script. But the Total Commander button to call the script must have the following fields:

Command: d:\Utils\PowerPro\powerpro.exe *script runfile CopyComment=
Parameters: %P%N

You should replace the above path to PowerPro with that valid for your computer. If you have renamed the script, the CopyComment string must be changed, too. Please note the = character in the command!

Script settings are stored in the configuration file. By default its full name is "PowerPro path"\scripts\ini\CopyComment.ini. If the configuration file is not found, the script would use default values. Otherwise you can set values of four keys:

[Options]
Delimiter=". "
Sort=1
Move=0
NotComments=0

The Delimiter key stands for string inserted between new and old comments. By default this string is "period space" (see above).

The Sort key, if present and not null string, tells the script to sort the descript.ion file alphabetically. It doesn't matter to display comments, but could be useful before the manual editing of comment file. By default, the sorting is off.

Key Move determines whether the comment is copied or moved:

  1. Copy comment (by default, that is, if the key or configuration file is absent);
  2. Move comment;
  3. Ask the user.

Another way to move comment is pressing the Ctrl key when running the script. In this case the configuration file setting is ignored.

Finally, the NotComments key is valid if, in addition to the file comments, descript.ion contains other text (for example, the custom view name used by the WDXdetect script). Key defines where to put all lines differing from the usual "filename comment" pair:

  1. After comments (default);
  2. Before comments;
  3. Nowhere (everything except file comments is removed).

Two first cases use the new line as a separator.


All Scripts Total Commander TotalCmd.net PowerPro