Subject: How to insert version nr of current project [Print This Page] Author:
Edelcom Time: 2008-7-8 20:50 Subject: How to insert version nr of current project
Hi,
I installed both CNPack and GExperts in to my Delphi 7 environent.
However, I suspect them both of doing all sorts of things in the background when I start a program from with in the IDE, and certainly doing all sorts of things when a program started from the IDE is finished (it takes a long time for the IDE to show the source code again. Certainly I see a lot of forms being displayed after a program is finished.
I disabled GExperts at the moment (just to see if this makes a difference), but am now missing the main thing I used GExperts in the first place (or at least the important thing I started using GExperts for).
In GExperts I had the ability to insert my version information string into the editor.
Like:
var
i : integer;
iNew : integer; //!2.0.0.3
begin
iNew := SomeFunction(); //!2.0.0.3
if iNew > 10 //!08.07.08
then
DoSomethingUseful();
end;
After assigning this to a key (Ctrl-Num +), I could very easily mark new or changed lines in my source.
Also, I did the same with te date (also in the example above), which I use to mark new lines in global libraries and global routines.
Can I achieve the same thing somewhere using CnPack ? I know about the date insert, but that's one enter too many, in my opinion, since the user is almost always going to use the same date format over and over again.
The version string, however, I could not find.
I looked at the Script Wizard but have no clue to see if it is possible to insert the versionstring.Author:
Edelcom Time: 2008-7-9 16:59
To answer my own question (played around with the scripting freature of cn-pack). This can be done using the following script (to which I assigned the shift-ctrl+num + key).
program edlInsetVersionInfo;
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ToolsAPI, CnCommon, CnWizUtils;
var
Options: IOTAProjectOptions;
Project: IOTAProject;
MajorVer, MinorVer, ReleaseNo, BuildNo: Integer;
sVersion: string;
iCol,iLine : integer;
begin
Options := CnOtaGetActiveProjectOptions(nil);
if Options = nil then Exit;
Project := CnOtaGetCurrentProject;
if Project = nil then Exit;
// Get the Versions
MajorVer := Options.GetOptionValue('MajorVersion');
MinorVer := Options.GetOptionValue('MinorVersion');
ReleaseNo := Options.GetOptionValue('Release');
BuildNo := Options.GetOptionValue('Build');
I still have two problems (looking at the following line):
IdeEditorGotoEditPos(81-Length(sVersion), iLine, True);
1/ Last parameter centers this line when set to True, and moves the current line to the top of the edit window when set to False. This is very annoying.
2/ Is there a way to move the cursor to the end of the current line before I use IdeInsertTextIntoEditor(...)
thanksAuthor:
Passion Time: 2008-7-9 21:28
Well done. I just wanna reply with "refer to IncProjBuild.pas" in Demo, and soon see that you found the answer.
About your moving cursor questions, you can use some TOOLSAPI functions in the script.
var
EditView: IOTAEditView;
EditView := CnOtaGetTopMostEditView;
if EditView <> nil then
EditView.GetPosition.MoveEOL; // it can move cursor to the end of current line.
Please try it? To use GetPosition rather than Position is by reason that Script Wizard does not support interface property.Author:
Edelcom Time: 2008-7-9 22:47
Thanks for the tip, the final working version is below.
I
t now has the added capability (which I did not have when I used the GExperts version), that the inserted text will be right-aligned at the 80-column boundery. If the text to insert would not fit in this space, it is just appended at the end of the line.
{*******************************************************}
{ }
{ Pascal Script Source File }
{ Run by RemObjects Pascal Script in CnWizards }
{ }
{ Generated by CnPack IDE Wizards }
{ }
{*******************************************************}
Options := CnOtaGetActiveProjectOptions(nil);
if Options = nil then Exit;
Project := CnOtaGetCurrentProject;
if Project = nil then Exit;
Editor := CnOtaGetCurrentSourceEditor
if Editor = Nil then Exit;
EditView := CnOtaGetTopMostEditView(Editor);
if EditView = Nil then Exit;
// Get the Versions
MajorVer := Options.GetOptionValue('MajorVersion');
MinorVer := Options.GetOptionValue('MinorVersion');
ReleaseNo := Options.GetOptionValue('Release');
BuildNo := Options.GetOptionValue('Build');
// build string to insert
sVersion := '//!' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer) + '.' + IntToStr(ReleaseNo) + '.' + IntToStr(BuildNo);
// move to end of line
EditView.GetPosition.MoveEOL;
// get current position
IdeEditorGetEditPos(iCol,iLine);
sFiller := '';
if iCol + Length(sVersion) < 80
then begin
for i := 1 to 80-Length(sVersion)-iCol+1 do
sFiller := sFiller + ' ';
end;
//IdeEditorGotoEditPos(81-Length(sVersion), iLine, True);
IdeInsertTextIntoEditor(sFiller+sVersion);
end.Author:
Passion Time: 2008-7-10 14:50
Nice work.
Could you allow us to add this script to our Demo?Author:
Edelcom Time: 2008-7-10 15:18
Of course, feel free to add it to the demo's section of your marvelous products.
I would be gratefull if you could mention my name some where : Erik De Laet and/or my company E.De.L.Com bvba.
Thanks for the help.
ErikAuthor:
Passion Time: 2008-7-10 16:15
OK. You'll in our credits list and the comments of this script will also include your information. Author:
Edelcom Time: 2008-7-12 17:04
There is a problem with the script as it is now.
If I use the script, and than close the file from within the IDE (D7), I get the following standard error box:
Instance of Class TEditSource has dangling reference count of 2.
As far as I can tell, that is not a class I have access to, so it must be instantiated by one of the CnOtaGet... routines at the start of the script, or by the IdeEditor... routines towards the end of the script.
Anyone any idea what could be causing this problem ?
thanks, ErikAuthor:
Passion Time: 2008-7-12 20:15
I also see a similiar problem, but just an AV box, not the error message described by you.
It seems caused by the Length function call.
In my environment, If I remove the Length(sVersion), no error appears.
Could you try this?Author:
Passion Time: 2008-7-12 20:54
In another workstation I reproduced your problem with the same error message.
It's caused by :
Editor := CnOtaGetCurrentSourceEditor
if Editor = Nil then Exit;
EditView := CnOtaGetTopMostEditView(Editor);
But I'm also not clear why it happens. In fact, we can use
EditView := CnOtaGetTopMostEditView(nil);
to get current EditView simply.
I'll commit the modified source at 412 unstable version of CnWizards.Author:
Edelcom Time: 2008-7-13 16:03
Thanks very much Liu,
This fix eliminates the error.
For your intrest: I modified the script in such a way that, when the script is called on an empty line, the text is inserted at the current cursor position. This makes more sence if you are inserting the version string in a comment block before or after some Delphi source code.
Is there any documentation on the "CnOta..."routines ?
Erik
{*******************************************************}
{ }
{ Pascal Script Source File }
{ Run by RemObjects Pascal Script in CnWizards }
{ }
{ Generated by CnPack IDE Wizards }
{ }
{ Script created by : }
{ - Erik De Laet - E.De.L.Com bvba }
{ 'Programmer by choice and profession!' }
{ www.edelcom.be - Belgium }
{ }
{ Thanks to Passion (LiuXiao) of the CnPack team }
{ for the necessary and appreciated help and }
{ insight in the CnPack routines. }
{ }
{*******************************************************}
program edlInsetVersionInfo;
uses
Windows, SysUtils, CnWizUtils;
var
EditView: IOTAEditView;
Options: IOTAProjectOptions;
Project: IOTAProject;
MajorVer, MinorVer, ReleaseNo, BuildNo: Integer;
sVersion: string;
iColInSource,iCol,iLine : integer;
sFiller: string;
i: integer;
begin
Options := CnOtaGetActiveProjectOptions(nil);
if Options = nil then Exit;
Project := CnOtaGetCurrentProject;
if Project = nil then Exit;
EditView := CnOtaGetTopMostEditView(Nil);
if EditView = Nil then Exit;
// Get the Versions
MajorVer := Options.GetOptionValue('MajorVersion');
MinorVer := Options.GetOptionValue('MinorVersion');
ReleaseNo := Options.GetOptionValue('Release');
BuildNo := Options.GetOptionValue('Build');
// build string to insert
sVersion := '//!' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer) + '.' + IntToStr(ReleaseNo) + '.' + IntToStr(BuildNo);
// get and keep de current cursor position
IdeEditorGetEditPos(iColInSource,iLine);
// move to end of line
EditView.GetPosition.MoveEOL;
// get current position again
IdeEditorGetEditPos(iCol,iLine);
if iCol = 1
then begin
// if we are at the beginning of the line, the line was empty, so insert
// the text at the saved position (by inserting spaces - see note below)
sFiller := '';
for i := 1 to iColInSource-1 do
sFiller := sFiller + ' ';
// we cannot use "IdeEditorGotoEditPos" because this takes a third parameter
// and this will move the current line to the top or the middle of the
// editor window (don't know why this third parameter is needed ???)
// IdeEditorGotoEditPos(iColInSource,iLine,True);
end
else begin
// else try to position the text right aligned at 80 chars (unless we don't
// have room there, in which case the text is inserted after the line
sFiller := '';
if iCol + Length(sVersion) < 80
then begin
for i := 1 to 80-Length(sVersion)-iCol+1 do
sFiller := sFiller + ' ';
end;
end;
// insert the text (including the filler)
IdeInsertTextIntoEditor(sFiller+sVersion);
end.Author:
Passion Time: 2008-7-13 16:12
Sorry, the CnOta... routines help is in chinese language in our comments of CnWizUtils.pas in PSDeclEx directory. And it's not so detailed, just a function description.
Other routines's comments also lies in PSDecl and PSDeclEx directory. But most are in chinese language, too.
In fact the loop:
sFiller := '';
for i := 1 to iColInSource-1 do
sFiller := sFiller + ' ';
can be replaced by a routine Spc in CnCommon.pas as in 412 version. It use StringOfChar function to generate a fixed length string with a certain char, but StringOfChar is not imported by Pascal Script Engine, so we write a wrapper function to do it.Author:
Edelcom Time: 2008-7-13 16:48
Liu, as you might have guessed: I don't speak Chinese .
Modified script below:
{*******************************************************}
{ }
{ Pascal Script Source File }
{ Run by RemObjects Pascal Script in CnWizards }
{ }
{ Generated by CnPack IDE Wizards }
{ }
{ Script created by : }
{ - Erik De Laet - E.De.L.Com bvba }
{ 'Programmer by choice and profession!' }
{ www.edelcom.be - Belgium }
{ }
{ Thanks to Passion (LiuXiao) of the CnPack team }
{ for the necessary and appreciated help and }
{ insight in the CnPack routines. }
{ }
{*******************************************************}
program edlInsetVersionInfo;
uses
Windows, SysUtils, CnCommon, CnWizUtils;
var
EditView: IOTAEditView;
Options: IOTAProjectOptions;
Project: IOTAProject;
MajorVer, MinorVer, ReleaseNo, BuildNo: Integer;
sVersion: string;
iColInSource,iCol,iLine : integer;
sFiller: string;
begin
Options := CnOtaGetActiveProjectOptions(nil);
if Options = nil then Exit;
Project := CnOtaGetCurrentProject;
if Project = nil then Exit;
EditView := CnOtaGetTopMostEditView(Nil);
if EditView = Nil then Exit;
// Get the Versions
MajorVer := Options.GetOptionValue('MajorVersion');
MinorVer := Options.GetOptionValue('MinorVersion');
ReleaseNo := Options.GetOptionValue('Release');
BuildNo := Options.GetOptionValue('Build');
// build string to insert
sVersion := '//!' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer) + '.' + IntToStr(ReleaseNo) + '.' + IntToStr(BuildNo);
// get and keep de current cursor position
IdeEditorGetEditPos(iColInSource,iLine);
// move to end of line
EditView.GetPosition.MoveEOL;
// get current position again
IdeEditorGetEditPos(iCol,iLine);
if iCol = 1
then begin
// if we are at the beginning of the line, the line was empty, so insert
// the text at the saved position (by inserting spaces - see note below)
sFiller := Spc(iColInSource-1);
// we cannot use "IdeEditorGotoEditPos" because this takes a third parameter
// and this will move the current line to the top or the middle of the
// editor window (don't know why this third parameter is needed ???)
// IdeEditorGotoEditPos(iColInSource,iLine,True);
end
else begin
// else try to position the text right aligned at 80 chars (unless we don't
// have room there, in which case the text is inserted after the line)
sFiller := Spc(80-Length(sVersion)-iCol+1);
end;
// insert the text (including the filler)
IdeInsertTextIntoEditor(sFiller+sVersion);
end.