issue-#62 Unicode and Internationalization for StdStamps

Locked

Should we merge the changes of topic branch issue-#62 to master?

Yes
7
100%
No
0
No votes
Abstain
0
No votes
 
Total votes: 7

User avatar
Josef Templ
Posts: 2048
Joined: Tue Sep 17, 2013 6:50 am

issue-#62 Unicode and Internationalization for StdStamps

Post by Josef Templ »

This voting is about merging the changes of topic branch issue-#62
(Unicode and Internationalization for StdStamps) to master.
For the issue see http://redmine.blackboxframework.org/issues/62.
For the changes see http://redmine.blackboxframework.org/pr ... 2248a74eeb.

The changes are based on the proposal in CPC 1.7 rc5, change list number 28, sub-issue 3 or 3.
There are no incompatibilities introduced in the storage format unless Unicode is really used.

The changes also include the fix of a trivial typo (minutes were set twice) in GetData, which is an unused procedure.

Gentlemen, please cast your vote.

- Josef
Last edited by Josef Templ on Fri Jun 19, 2015 7:30 am, edited 1 time in total.
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Robert »

As discussed on the BlackBox mailing list earlier this year several bugs were discovered in StdStamps (some related to this Unicode support proposal). Helmut Zinn & I worked on preparing and testing the bug fixes, and a proposed solution was published there.

I would like that proposal to be considered for this issue.

I can copy the relevant postings to this topic this evening if that is helpful.


Robert
User avatar
Josef Templ
Posts: 2048
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Josef Templ »

Robert wrote:I would like that proposal to be considered for this issue.

I can copy the relevant postings to this topic this evening if that is helpful.

Robert
Sure. Let us know what has been discussed there. I was not aware of this discussion.

If it is in Helmut's CPC 1.7 rc5 version, it should already have been considered because the
changes are based on that version.

- Josef
Bernhard
Posts: 68
Joined: Tue Sep 17, 2013 6:56 am
Location: Munich, Germany

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Bernhard »

Josef Templ wrote:If it is in Helmut's CPC 1.7 rc5 version, it should already have been considered because thechanges are based on that version.
I fear the changes are only in Helmut's CPC 1.7 RC6 build 24.

As far as I can see, it was this thread:
http://forum.blackboxframework.org/view ... patibility

and the thread starting on 28. Jan 2015 on the Mailing list. Helmut added the changes to CPC 1.7-RC6 build 24.

Bobs last post (3. Feb. 2015) contained:
Robert Campbell, 3. Feb. 2015 wrote:I have also now discovered two new bugs, which have always been there.

1) If a Text contains more than 1 Stamp attempts to change the/a comment
in the second or subsequent Stamps do not work, but do change the
comment in the first Stamp.

2) If a comment is cleared (ie set to ""), and the file is then saved to
disc it cannot be read back.

I do have corrections for these bugs, but do not intend to publish them
until they have had some more testing time.
I guess/hope that Bob's Version above includes these "unpublished" changes, but I don't know.
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Robert »

The three windows below are:
1 - a copy of the list emails
2 - the source file
3 - the documentation file
followed by the Rsrc file in coded format.

I have thought, for years, that StdStamps was a good idea, but whenever I tried to use it it made no sense to me. This year I decided to investigate closer, and came to the conclusion that it made no sense because it was riddled with bugs.

Now the bugs are fixed I think it is a great tool, I use it all the time, and I strongly recommend it to others.
While these changes have an element of feature enhancement about them, I would classify them as mainly bug fixes.

Helmut Zinn helped me with the testing, and made useful suggestions.

I apologise for the delay in posting the final code. I intended to learn how to use the official tools (GitHub & Redmine), and post the issue correctly. That has not happened (yet!).

Code: Select all

From 	Robert Campbell <rdcampbell.98@gmail.com>
Subject 	The StdStamps View
Date 	Wed, 28 Jan 2015 20:08:06 +0000

[Part 1 text/plain utf-8 (13.0 kilobytes)] (View Text in a separate window)
For (* many *) years I have thought that StdStamps were a useful idea,  
but when I tried them I was never happy; their behaviour seemed to be  
erratic, unpredictable, inconsistent, and indeed undesirable. 
 
 
Finally I decided to investigate. 
 
The first thing I discovered was some helpful documentation that explained: 
- Why there are gaps in the serial numbers -  only one entry is kept for  
any one date. 
- Why early serial numbers are missing - only the most recent 25 entries  
are kept. 
 
I am happy to accept this behaviour now I understand it, but the  
documentation was not in the "Docu" file; it was unhelpfully hidden in  
the "Mod" file! I have moved it to the Docu. 
 
 
Some other behaviours I have found I regard as undesirable, maybe they  
should be considerd to be bugs. 
 
- Many Stamps add several "Empty" history entries with no fingerprint  
and a corrupt date. I have modified the code to prevent these spurious  
entries, and to delete any found internalising old Stamps. 
 
- It was impossible to edit / correct Comments with dates other than  
today. I have extended the Comment editor to allow this. It was  
irritating to see spelling mistakes, and to be unable to correct them!  
And see the next remark. 
 
- If a Comment has added in the first editting session of the day it was  
given the wrong date; it was added to the previous entry which might be  
years old. Once added to the wrong date it could not be removed. I have  
corrected this behaviour. 
 
- I have removed the code "cache". No good reason, except that I think  
it was unnecessary, and removing it simplified the code and made it  
easier to understand and correct. 
 
- I have increased the maximum history length from 25 to 35 entries. 
 
 
The revised files are below: coding for the Mod, Docu, & Rsrc files. I  
would be interested to hear any comments about the new behaviour, or any  
new bugs I might have introduced. 
(When decoding check that the paths specified suit your installation.) 
 
 
Regards 
 
Robert 
 
----------------------------------------------------------------------------------------------------------
 
From 	"Helmut Zinn" <feedback@zinnamturm.eu>
Subject 	The StdStamps View & Check Links Tool
Date 	Thu, 29 Jan 2015 19:09:35 +0100

[Part 1 text/plain utf-8 (26.2 kilobytes)] (View Text in a separate window)
Dear Robert, 
 
I received your e-mails about StdStamps & check links tool via the BlackBox mailing list. 
 
I add your changes about StdStamps to the CPC edition 1.7-RC6 build 24.  
Further I add to Std/Rsrc/Stamps.odc the missing #Std: entries for the language support. 
Also I add comments around to the annoying (* StdCmds.CloseDialog *) in the check link tools. 
All those changes will be available in the next release of CPC edition. 
 
I send my answer via the mailing list too. It is my first mail to the list. 
 
With best regards 
 
Helmut Zinn 
 
P.S.: I will look tomorrow at the subsystem Escher.   
 
----------------------------------------------------------------------------------------------------------
 
From 	=?iso-8859-1?B?TWFudWVsIE1hcnTtbiBT4W5jaGV6?= <manumart1@hotmail.com>
Subject 	Re: The StdStamps View & Check Links Tool
Date 	Fri, 30 Jan 2015 19:29:15 +0100

[Part 1 multipart/alternative]

[Part 1.1 text/plain iso-8859-1 (1.6 kilobytes)] (View Text in a separate window)
Just a comment: 
 
Menu "Info - Check Links" -> DevLinkChk 
. 
.   subsystem*: ARRAY 16 OF CHAR; 
. 
.    PROCEDURE SyntaxOK (VAR s: ARRAY OF CHAR): BOOLEAN; 
.        VAR i: INTEGER; ch: CHAR; 
.    BEGIN 
.        i := 0; ch := s[0]; 
.        WHILE (ch >= "A") & (ch <= "Z") DO INC(i); ch := s[i] END; 
.        WHILE (i # 0) & (ch >= "a") & (ch <= "z") OR (ch >= "0") & (ch <= "9") DO INC(i); ch := s[i] END; 
.        RETURN (i >= 3) & (i <= 15) & (ch = 0X) 
.    END SyntaxOK; 
 
- The loop condition is wrong, because for example the string "4ab" passes that test as a valid subsystem name. Possible quick fix:WHILE (i # 0) & ((ch >= "a") & (ch <= "z") OR (ch >= "0") & (ch <= "9")) DO 
 
- Instead of "(i <= 15)" I would put "(i < LEN(s))", or perhaps that condition is not needed at all, because if "i >= LEN(S)" then a trap would have ocurred before. 
 
- 
... Instead of fixing this function SyntaxOK, I found that already  
exists a similar function in another place, and looks better: 
 
Menu "Tool - Create Sybsystem" --> DevSubTool 
. 
.    PROCEDURE SyntaxOK (s: ARRAY OF CHAR): BOOLEAN; 
.        VAR i: INTEGER; ch: CHAR; 
.    BEGIN 
.        i := 0; ch := s[0]; 
.        WHILE Strings.IsUpper(ch) DO INC(i); ch := s[i] END; 
.        WHILE (i # 0) & Strings.IsIdent(ch) DO INC(i); ch := s[i] END; 
.        RETURN (i # 0) & (ch = 0X) 
.    END SyntaxOK; 
 
I don't know what is better: 
To keep this small piece of code duplicate in DevSubTool and DevLinkChk.To make public the function SyntaxOK of DevSubTool (and possibly change the name to something like SubsystemNameIsValid). 
Regards, 
Manuel 

----------------------------------------------------------------------------------------------------------

From 	=?iso-8859-1?B?TWFudWVsIE1hcnTtbiBT4W5jaGV6?= <manumart1@hotmail.com>
Subject 	Re: The StdStamps View & Check Links Tool
Date 	Fri, 30 Jan 2015 12:03:21 +0100

[Part 1 multipart/alternative]

[Part 1.1 text/plain iso-8859-1 (1.4 kilobytes)] (View Text in a separate window)
Just a comment: 
 
Menu "Info - Check Links" -> DevLinkChk.odc 
. 
.   subsystem*: ARRAY 16 OF CHAR; 
. 
.    PROCEDURE SyntaxOK (VAR s: ARRAY OF CHAR): BOOLEAN; 
.        VAR i: INTEGER; ch: CHAR; 
.    BEGIN 
.        i := 0; ch := s[0]; 
.        WHILE (ch >= "A") & (ch <= "Z") DO INC(i); ch := s[i] END; 
.        WHILE (i # 0) & (ch >= "a") & (ch <= "z") OR (ch >= "0") & (ch <= "9") DO INC(i); ch := s[i] END; 
.        RETURN (i >= 3) & (i <= 15) & (ch = 0X) 
.    END SyntaxOK; 
 
- I think the loop condition is wrong, because for example the subsystem name "4ab" passes that test. Possible quick fix:WHILE (i # 0) & ((ch >= "a") & (ch <= "z") OR (ch >= "0") & (ch <= "9")) DO 
 
- Instead of "(i <= 15)" I would put "(i < LEN(s))", or perhaps that condition is not needed at all, because if "i >= LEN(S)" then a trap would have ocurred before. 
 
- ... Instead of fixing this function SyntaxOK, I found that already exists a similar function in another place, and looks better: 
 
Menu "Tool - Create Sybsystem" --> DevSubTool 
. 
.    PROCEDURE SyntaxOK (s: ARRAY OF CHAR): BOOLEAN; 
.        VAR i: INTEGER; ch: CHAR; 
.    BEGIN 
.        i := 0; ch := s[0]; 
.        WHILE Strings.IsUpper(ch) DO INC(i); ch := s[i] END; 
.        WHILE (i # 0) & Strings.IsIdent(ch) DO INC(i); ch := s[i] END; 
.        RETURN (i # 0) & (ch = 0X) 
.    END SyntaxOK; 
 
Regards 
 
----------------------------------------------------------------------------------------------------------

 From 	Robert Campbell <rdcampbell.98@gmail.com>
Subject 	Re: The StdStamps View & Check Links Tool
Date 	Sun, 01 Feb 2015 21:29:48 +0000

[Part 1 multipart/alternative]

[Part 1.1 text/plain windows-1252 (1.1 kilobytes)] (View Text in a separate window)
 
A agree that this version below looks better. 
 
I think duplicating the code would be better here - there no real reason  
to make one Tool dependant on the other. 
 
 
Regards 
 
Robert 

----------------------------------------------------------------------------------------------------------

 From 	Robert Campbell <rdcampbell.98@gmail.com>
Subject 	Re: The StdStamps View & Check Links Tool
Date 	Mon, 02 Feb 2015 17:49:13 +0000

[Part 1 multipart/alternative]

[Part 1.1 text/plain windows-1252 (0.6 kilobytes)] (View Text in a separate window)
 
On 30-Jan-2015 18:29, Manuel Martín Sánchez wrote: 
... 
> .    PROCEDURE SyntaxOK (s: ARRAY OF CHAR): BOOLEAN; 
> .  ... 
> 
> I don't know what is better: 
> 
>   * To keep this small piece of code duplicate in DevSubTool and 
>     DevLinkChk. 
>   * To make public the function SyntaxOK of DevSubTool (and possibly 
>     change the name to something like SubsystemNameIsValid). 
> 
> 
> Regards, 
> Manuel 
 
Maybe a better idea is to rename it to "SubsystemNameIsValid", move it  
to Module Characters, and for both 
DevSubTool & DevLinkChk to import it? 
 
Regards 
 
Robert 
 
----------------------------------------------------------------------------------------------------------

From 	Robert Campbell <rdcampbell.98@gmail.com>
Subject 	Re: The StdStamps View - More Bugs
Date 	Tue, 03 Feb 2015 20:13:47 +0000

[Part 1 text/plain utf-8 (1.9 kilobytes)] (View Text in a separate window)
 
On 28-Jan-2015 20:08, Robert Campbell wrote: 
> For (* many *) years I have thought that StdStamps were a useful idea,  
> but when I tried them I was never happy; their behaviour seemed to be  
> erratic, unpredictable, inconsistent, and indeed undesirable. 
> 
> Finally I decided to investigate. 
> 
> The first thing I discovered was some helpful documentation that  
> explained: 
> - Why there are gaps in the serial numbers -  only one entry is kept  
> for any one date. 
> - Why early serial numbers are missing - only the most recent 25  
> entries are kept. 
> 
> I am happy to accept this behaviour now I understand it, but the  
> documentation was not in the "Docu" file; it was unhelpfully hidden in  
> the "Mod" file! I have moved it to the Docu. 
> 
> ... 
> 
> The revised files are below ... 
 
The files I sent out introduced a possible new problem. By increasing  
the history size from 25 to 35 there is now a backwards compatibility issue. 
It is possible that new Stamps can fail to be internalised by old  
versions of BlackBox software. Please don't use the files I sent out  
(unless you 
change the CONSTant "maxHistoryEntries" back from 35 to 25, which will  
avoid this problem). 
 
I have also now discovered two new bugs, which have always been there. 
 
1) If a Text contains more than 1 Stamp attempts to change the/a comment  
in the second or subsequent Stamps do not work, but do change the  
comment in the first Stamp. 
 
2) If a comment is cleared (ie set to ""), and the file is then saved to  
disc it cannot be read back. 
 
 
I do have corrections for these bugs, but do not intend to publish them  
until they have had some more testing time. 
 
Regards 
 
Robert. 
 
 
PS - Another mystery about Stamps that troubled me was why they only  
recognised some changes, but not others. This felt like some kind 
of unreliability. This, also, has a satisfactory explanation in the  
hidden documentation! 

Code: Select all

MODULE StdStamps;
(**
	project	= "BlackBox"
	organization	= "www.oberon.ch"
	contributors	= "Oberon microsystems"
	version	= "System/Rsrc/About"
	copyright	= "System/Rsrc/About"
	license	= "Docu/BB-License"
	changes	= "
	- 20110612, TemirgaleevEE, B5: change SHORTCHAR to CHAR
	- 20110613, TemirgaleevEE, B15: StdStamps.GetData: typo - 'minute' stands for the 'hour'
	- 20150124, R D Campbell. Avoid empty history entries, removed cache, and can now update any comment.
	- 20150125, R D Campbell. Option to give a comment today's date for otherwise unchanged files. Added Guards.
	- 20150128, R D Campbell. Deletes empty history entries internalizing old Stamps. MaxHistoryEntries now 35.	
	- 20150203, R D Campbell. Can now set empty comments without subsequent internalising crashing.
	- 20150203, R D Campbell. Comments set in the same Stamp as used to open the comment editor dialogue.
	- 20150203, R D Campbell. Simplified HandlePropMessage. Procedure "GetFirstInText" removed.
	- 20150204, R D Campbell. Purges uncommented history entries first.
	- 20150205, R D Campbell. Deleted obsolete "red text: to be removed soon" Oms comments.
	- 20150205, R D Campbell. Changed formal parameter qualifiers in "GetInfo" & "Stamp".
	- 20150212, R D Campbell. Simplified versions. Comments are 16-bit for versions >= 3.
	"
	issues	= ""
**)

	IMPORT
		SYSTEM, (* SYSTEM.ROT only, for fingerprint calculation *)
		Dialog, Strings, Dates, StdCmds, Ports, Models, Stores, Containers, Properties, Views, Controllers,
		Fonts, TextModels, TextSetters, TextMappers, TextViews, TextRulers ;

	CONST
		setCommentKey = "#Std:Set Comment";
		maxHistoryEntries = 35;
		minVersion = 0; origStampVersion = 0; wideCommentVersion = 3; maxVersion = 3;

	TYPE
		History = ARRAY maxHistoryEntries OF RECORD
			fprint, snr: INTEGER;	(* fingerprint, sequence number *)
			date: INTEGER;			(* days since 1/1/1 *)
			time: INTEGER;			(* min + 64 * hour *)
			comment: POINTER TO ARRAY OF CHAR	(* nil if no comment  *)
		END;

		StdView = POINTER TO RECORD (Views.View)
			nentries: INTEGER;	(* number of entries in history *)
			history: History		(* newest entry in history[0] *)
		END;

		SetCmtOp = POINTER TO RECORD (Stores.Operation)
			stamp: StdView;
			age: INTEGER;
			oldcomment: POINTER TO ARRAY OF CHAR
		END;

	VAR
		comment*: RECORD
			stamp: StdView;
			age*, snr-: INTEGER;
			date-: Dates.Date;
			s*: ARRAY 64 OF CHAR
		END;

	PROCEDURE (op: SetCmtOp) Do;
		VAR temp: POINTER TO ARRAY OF CHAR;
	BEGIN
		temp := op.stamp.history[op.age].comment;
		op.stamp.history[op.age].comment := op.oldcomment;
		op.oldcomment := temp
	END Do;

	PROCEDURE FontContext (v: StdView): Fonts.Font;
		VAR c: Models.Context;
	BEGIN
		c := v.context;
		IF (c # NIL) & (c IS TextModels.Context) THEN
			RETURN c(TextModels.Context).Attr().font
		ELSE
			RETURN Fonts.dir.Default()
		END
	END FontContext;

	PROCEDURE CalcFP (t: TextModels.Model): INTEGER;
		CONST sglQuote = "'"; dblQuote = '"';
		VAR fp: INTEGER;  rd: TextModels.Reader; ch, quoteChar: CHAR; 
	BEGIN
		quoteChar := 0X; fp := 0;
		rd := t.NewReader(NIL); rd.ReadChar(ch);
		WHILE ~rd.eot DO
			IF ch = quoteChar THEN quoteChar := 0X
			ELSIF (quoteChar = 0X) & ((ch = dblQuote) OR (ch = sglQuote)) THEN quoteChar := ch
			END;
			IF (quoteChar = 0X) & (21X <= ch) & (ch # 8BX) & (ch # 8FX) & (ch # 0A0X) (* not in string literal *)
				OR (quoteChar # 0X) & (20X <= ch) (* within string literal *)
			THEN
				fp := SYSTEM.ROT(fp, 1) + 13 * ORD(ch)
			END;
			rd.ReadChar(ch)
		END;
		RETURN fp
	END CalcFP;

	PROCEDURE Update (v: StdView; forcenew: BOOLEAN);
		VAR fp: INTEGER; k, ndays: INTEGER; d: Dates.Date; t: Dates.Time;
	BEGIN
		IF (v.context # NIL) & (v.context IS TextModels.Context) THEN
			fp := CalcFP(v.context(TextModels.Context).ThisModel());
			IF (fp # v.history[0].fprint) OR forcenew THEN
				Dates.GetDate(d); Dates.GetTime(t);
				ndays := Dates.Day(d);
				IF (ndays # v.history[0].date) OR forcenew THEN
					k := v.nentries;
					IF  k = maxHistoryEntries THEN		(* find oldest uncommented entry *)
						DEC(k);
						WHILE (k > 0) & (v.history[k].comment # NIL) DO DEC(k) END;
						IF k = 0 THEN k :=  v.nentries - 1 END
					END;
					WHILE k > 0 DO		(* move down entries in history list *)
						v.history[k] := v.history[k-1];
						DEC(k)
					END;
					v.history[0].comment := NIL;
					IF v.nentries < maxHistoryEntries THEN INC(v.nentries) END
				END;
				IF v.history[0].fprint # 0 THEN INC(v.history[0].snr) END;
				v.history[0].fprint := fp;
				v.history[0].date := ndays;
				v.history[0].time := t.minute + t.hour*64;
				Views.Update(v, Views.keepFrames)
			END
		END
	END Update;

	PROCEDURE (v: StdView) Externalize (VAR wr: Stores.Writer);
		VAR i, len: INTEGER;
	BEGIN
		Update(v, FALSE);
		v.Externalize^(wr);
		wr.WriteVersion(maxVersion);
		wr.WriteXInt(v.nentries);
		FOR i := 0 TO v.nentries-1 DO
			wr.WriteInt(v.history[i].fprint);
			wr.WriteInt(v.history[i].snr);
			wr.WriteInt(v.history[i].date);
			wr.WriteXInt(v.history[i].time);
			IF v.history[i].comment # NIL THEN
				len := LEN(v.history[i].comment$);
				wr.WriteXInt(len);
				wr.WriteString(v.history[i].comment^)
			ELSE wr.WriteXInt(0)
			END
		END
	END Externalize;

	PROCEDURE (v: StdView) Internalize (VAR rd: Stores.Reader);
		VAR thisVersion: INTEGER; format: BYTE; i, len: INTEGER;
			d: Dates.Date; t: Dates.Time;
	BEGIN
		v.Internalize^(rd);
		IF ~rd.cancelled THEN
			rd.ReadVersion(minVersion, maxVersion, thisVersion);
			IF ~rd.cancelled THEN
				IF thisVersion = origStampVersion THEN (* deal with old StdStamp format *)
					(* would like to calculate fingerprint, but hosting model not available at this time *)
					v.history[0].fprint := 0;
					v.history[0].snr := 1; v.nentries := 1;
					rd.ReadXInt(d.year); rd.ReadXInt(d.month); rd.ReadXInt(d.day);
					rd.ReadXInt(t.hour); rd.ReadXInt(t.minute); rd.ReadXInt(t.second);
					rd.ReadByte(format); (* format not used anymore *)
					v.history[0].date := Dates.Day(d);
					v.history[0].time := t.minute + t.hour*64
				ELSE
					IF thisVersion = 1 THEN rd.ReadInt(v.history[0].snr) END;
					rd.ReadXInt(v.nentries);
					FOR i := 0 TO v.nentries-1 DO
						rd.ReadInt(v.history[i].fprint);
						IF thisVersion > 1 THEN rd.ReadInt(v.history[i].snr)
						ELSIF (* (thisVersion = 1) & *) i > 0 THEN v.history[i].snr := v.history[i-1].snr - 1
						END;
						rd.ReadInt(v.history[i].date);
						rd.ReadXInt(v.history[i].time);
						rd.ReadXInt(len);
						IF len > 0 THEN
							NEW(v.history[i].comment, len + 1);
							IF thisVersion >= wideCommentVersion
								THEN rd.ReadString(v.history[i].comment^)
								ELSE rd.ReadXString(v.history[i].comment^) END
						ELSE v.history[i].comment := NIL
						END
					END;
					DEC (i); WHILE (i > 0) & (v.history[i].fprint = 0) DO  DEC (i); DEC (v.nentries) END
				END
			END
		END
	END Internalize;

	PROCEDURE (v: StdView) CopyFromSimpleView (source: Views.View);
		VAR i: INTEGER;
	BEGIN
		(* v.CopyFrom^(source); *)
		WITH source: StdView DO
			v.nentries := source.nentries;
			v.history := source.history;
			FOR i := 0 TO v.nentries - 1 DO
				IF source.history[i].comment # NIL THEN
					NEW(v.history[i].comment, LEN(source.history[i].comment$) + 1);
					v.history[i].comment^ := source.history[i].comment^$
				END
			END
		END
	END CopyFromSimpleView;

	PROCEDURE (v: StdView) Restore (f: Views.Frame; l, t, r, b: INTEGER);
		VAR a: TextModels.Attributes; color: Ports.Color; c: Models.Context; font: Fonts.Font;
			asc, dsc, fw: INTEGER; d: Dates.Date; date: ARRAY 32 OF CHAR; seq: ARRAY 8 OF CHAR;
	BEGIN
		c := v.context;
		IF (c # NIL) & (c IS TextModels.Context) THEN
			a := v.context(TextModels.Context).Attr();
			font := a.font;
			color := a.color
		ELSE font := Fonts.dir.Default(); color := Ports.black
		END;
		font.GetBounds(asc, dsc, fw);
		f.DrawLine(f.l, asc + f.dot, f.r, asc + f.dot, 1, Ports.grey25 );
		Dates.DayToDate(v.history[0].date, d);
		Dates.DateToString(d, Dates.plainAbbreviated, date);
		Strings.IntToStringForm(v.history[0].snr, Strings.decimal, 4, "0", FALSE, seq);
		f.DrawString(0, asc, color, date +  " (" + seq + ")", font)
	END Restore;

	PROCEDURE SizePref (v: StdView; VAR p: Properties.SizePref);
		VAR font: Fonts.Font; asc, dsc, w: INTEGER; d: Dates.Date; s: ARRAY 64 OF CHAR;
	BEGIN
		font := FontContext(v);
		font.GetBounds(asc, dsc, w);
		d.day := 28; d.month := 1; d.year := 2222; p.w := 0;
		WHILE d.month <= 12 DO
			Dates.DateToString(d, Dates.plainAbbreviated, s);
			s := s + " (0000)";
			w := font.StringWidth(s);
			IF w > p.w THEN p.w := w END;
			INC(d.month)
		END;
		p.h := asc + dsc
	END SizePref;

	PROCEDURE (v: StdView) HandlePropMsg (VAR msg: Properties.Message);
		VAR font: Fonts.Font; asc, w: INTEGER;
	BEGIN
		WITH msg: Properties.SizePref DO SizePref(v, msg)
		| msg: Properties.ResizePref DO msg.fixed := TRUE
		| msg: Properties.FocusPref DO msg.hotFocus := TRUE
		| msg: TextSetters.Pref DO font := FontContext(v); font.GetBounds(asc, msg.dsc, w)
		ELSE
		END
	END HandlePropMsg;

	PROCEDURE NewRuler (): TextRulers.Ruler;
		CONST mm = Ports.mm;
		VAR r: TextRulers.Ruler;
	BEGIN
		r := TextRulers.dir.New(NIL);
		TextRulers.SetRight(r, 140 * mm);
		TextRulers.AddTab(r, 15 * mm); TextRulers.AddTab(r, 35 * mm); TextRulers.AddTab(r, 75 * mm);
		RETURN r
	END NewRuler;

	PROCEDURE ShowHistory (v: StdView);
		VAR text: TextModels.Model; f: TextMappers.Formatter;
			i: INTEGER; d: Dates.Date; s: ARRAY 64 OF CHAR;
			tv: TextViews.View; attr: TextModels.Attributes;
	BEGIN
		text := TextModels.dir.New();
		f.ConnectTo(text);
		attr := f.rider.attr;
		f.rider.SetAttr(TextModels.NewStyle(attr, {Fonts.italic}));
		f.WriteString("seq nr."); f.WriteTab;
		f.WriteString("fingerprint"); f.WriteTab;
		f.WriteString("date and time"); f.WriteTab;
		f.WriteString("comment"); f.WriteLn;
		f.rider.SetAttr(attr); f.WriteLn;
		(*--n := v.snr;*)
		FOR i := 0 TO v.nentries-1 DO
			f.WriteIntForm(v.history[i].snr, 10, 4, "0", FALSE);
			(*--DEC(n);*)
			f.WriteTab;
			f.WriteIntForm(v.history[i].fprint, TextMappers.hexadecimal, 8, "0", FALSE);
			f.WriteTab;
			Dates.DayToDate(v.history[i].date, d);
			Dates.DateToString(d, Dates.plainAbbreviated, s);
			f.WriteString(s);
			f.WriteString("  ");
			f.WriteIntForm(v.history[i].time DIV 64, 10, 2, "0", FALSE);
			f.WriteString(":");
			f.WriteIntForm(v.history[i].time MOD 64, 10, 2, "0", FALSE);
			IF v.history[i].comment # NIL THEN
				f.WriteTab;
				f.WriteString( v.history[i].comment^)
			END;
			f.WriteLn
		END;
		tv := TextViews.dir.New(text);
		tv.SetDefaults(NewRuler(), TextViews.dir.defAttr);
		tv.ThisController().SetOpts({Containers.noFocus, Containers.noCaret});
		Views.OpenAux(tv, "History")
	END ShowHistory;

	PROCEDURE FillComment (v: StdView; age: INTEGER);
	BEGIN
		comment.stamp := v;
		comment.age := MIN(MAX(0, age), v.nentries - 1);
		comment.snr := v.history[comment.age].snr;
		Dates.DayToDate(v.history[comment.age].date, comment.date);
		IF  v.history[comment.age].comment = NIL THEN comment.s  :=  ''
			ELSE comment.s  :=  v.history[comment.age].comment$ END;
		Dialog.Update(comment)
	END FillComment;

	PROCEDURE Track (v: StdView; f: Views.Frame; x, y: INTEGER; buttons: SET);
		VAR c: Models.Context; w, h: INTEGER; isDown, in, in0: BOOLEAN; m: SET;
	BEGIN
		c := v.context; c.GetSize(w, h); in0 := FALSE; in := TRUE;
		REPEAT
			IF in # in0 THEN
				f.MarkRect(0, 0, w, h, Ports.fill, Ports.invert, Ports.show); in0 := in
			END;
			f.Input(x, y, m, isDown);
			in := (0 <= x) & (x < w) & (0 <= y) & (y < h)
		UNTIL ~isDown;
		IF in0 THEN
			f.MarkRect(0, 0, w, h, Ports.fill, Ports.invert, Ports.hide);
			IF Controllers.modify IN m THEN
				IF v.history[0].comment # NIL THEN comment.s := v.history[0].comment^$
				ELSE comment.s := ""
				END;
				FillComment(v, 0);
				StdCmds.OpenToolDialog("Std/Rsrc/Stamps", "#Std:Comment")
			ELSE ShowHistory(v)
			END
		END
	END Track;

	PROCEDURE (v: StdView) HandleCtrlMsg (
				f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View);
	BEGIN
		WITH msg: Controllers.TrackMsg DO
			Track(v, f, msg.x, msg.y, msg.modifiers)
		| msg: Controllers.PollCursorMsg DO
			msg.cursor := Ports.refCursor
		ELSE
		END
	END HandleCtrlMsg;

	(* ------------ programming interface: ---------------------- *)

	PROCEDURE GetActiveStamp (): StdView;
		VAR context: Models.Context;
	BEGIN
		IF comment.stamp # NIL THEN
			context := comment.stamp.context;
			IF context # NIL THEN
				IF context.ThisModel() = TextViews.FocusText() THEN RETURN comment.stamp END
			END
		END;
		RETURN NIL
	END GetActiveStamp;

	PROCEDURE IsStamp* (v: Views.View): BOOLEAN;
	BEGIN
		RETURN v IS StdView
	END IsStamp;

	PROCEDURE GetInfo* (v: Views.View; OUT snr, historylen: INTEGER);
	BEGIN
		ASSERT(v IS StdView, 20);
		WITH v: StdView DO
			snr := v.history[0].snr; historylen := v.nentries
		END
	END GetInfo;

	PROCEDURE GetData* (v: Views.View; entryno: INTEGER;
				VAR fprint: INTEGER; VAR date: Dates.Date; VAR time: Dates.Time);
	BEGIN
		ASSERT(v IS StdView, 20);
		WITH v: StdView DO
			IF entryno <= v.nentries THEN
				fprint := v.history[entryno].fprint;
				Dates.DayToDate(v.history[entryno].date, date);
				time.hour := v.history[entryno].time DIV 64;
				time.minute := v.history[entryno].time MOD 64;
				time.second := 0
			END
		END
	END GetData;

	(** Insert new history entry with comment in v. *)
	PROCEDURE Stamp* (v: Views.View; IN comment: ARRAY OF CHAR);
	BEGIN
		ASSERT(v IS StdView, 20);
		WITH v: StdView DO
			Update(v, TRUE);
			NEW(v.history[0].comment, LEN(comment$) + 1);
			v.history[0].comment^ := comment$
		END
	END Stamp;

	PROCEDURE New* (): Views.View;
		VAR v: StdView; d: Dates.Date; t: Dates.Time;
	BEGIN
		NEW(v); v.nentries := 1;
		Dates.GetDate(d); Dates.GetTime(t);
		v.history[0].date := Dates.Day(d);
		v.history[0].time := t.minute + t.hour*64;
		RETURN v
	END New;

	PROCEDURE SetComment*;
		VAR v: StdView; op: SetCmtOp; date: Dates.Date; res: INTEGER;
	BEGIN
		v := GetActiveStamp();
		IF v # NIL THEN
			res := -1;
			IF comment.age = 0 THEN
				Dates.GetDate(date);
				IF v.history[0].date # Dates.Day(date) THEN
					Dialog.GetOK("#Std:Give Comment today's date?", '', '', '', {Dialog.yes, Dialog.no}, res);
					IF res = Dialog.yes THEN Update(v, TRUE) END
				END
			END;
			NEW(op); op.stamp := v; op.age := comment.age;
			IF comment.s$ = '' THEN
				op.oldcomment := NIL
			ELSE
				NEW(op.oldcomment, LEN(comment.s$) + 1);
				op.oldcomment^ := comment.s$
			END;
			Views.Do(v, setCommentKey, op);
			IF res = Dialog.yes THEN FillComment(v, 0) END
		END
	END SetComment;

	PROCEDURE Deposit*;
	BEGIN
		Views.Deposit(New())
	END Deposit;

	PROCEDURE Guard* (VAR par: Dialog.Par);
	BEGIN
		par.disabled := GetActiveStamp() = NIL
	END Guard;

	PROCEDURE Notify* (op, from, to: INTEGER);
		VAR v: StdView;
	BEGIN
		IF op = Dialog.changed THEN
			v := GetActiveStamp();
			IF v # NIL THEN FillComment(v, comment.age) END
		END
	END Notify;

END StdStamps.

Code: Select all

StdStamps

DEFINITION StdStamps;

	PROCEDURE Deposit;

	...plus some other items used internally...

END StdStamps.


Stamps are views which indicate the date when the containing document has been saved the last time.

StdStamps are used to keep track of document changes, in particular program texts. StdStamps carry a sequence number and a fingerprint of the document with them. Each time the document (and therefore its fingerprint) is changed and stored, the sequence number is incremented. (When determining the fingerprint of the document, whitespace is ignored, except in string literals.)

Each StdStamp also keeps track of the history of most recent changes. For the last 35 sequence numbers, the date and time, and an optional one-line comment is stored. To avoid too many entries in the history while working on a module, the most recent history entry is overwritten upon the generation of a new sequence number if the current date is the same as the date in the history entry.

To avoid exceeding 35 entries the oldest uncommented entry is deleted (or the oldest if they are all commented).

Comments may now contain 16-bit characters.
BlackBox 1.6 only supported 8-bit characters in comments. However it can read these Stamps as Alien Views.


PROCEDURE Deposit
Deposit command for standard stamps.

...plus some other items used internally...

Clicking on the stamp view shows a history of when the document has been saved. Modifier-clicking on the stamp view opens a dialog box that allows to edit the comment associated with the current and previous sessions.

13 Feb 2015
PacCoder.Decode /.3sunSs6QW0T4yU6DY3bX9H41e1O181Q1cFn6L2IzYN0Ug:NxsU.d0.pG3k
jPqNEkoB7HEtE.VKzgVrR.sIzkGb/yHkyVSxjXImU4/gc3kXzk/Y/qy.wYO4jkJYUvQQKFBV9YXM
Z1iBzr0dnGVIdEEN6WWwhYl/7t7.HrYYqu.:B5e/8apBCvhPxip2NXQf4W87dapEQoOcX3hI4m7v
xE018YurzITQ16FN7/:UV.hI46G222UMcwauETad7OU8Vqc3SfIWYyszCqpOZt/DXZKCQBWmvowU
QkrEbm0/b0.Wl/Zlk5VlNXdPnlnxOM3PoMZn9q4copnznRI3isaNUjfGrP8wWIxNbNf55L2SDKFn
RD:4VVZl2tVys7on4Ogi4s:mi1nzH:EPVCL0Mi.MfU:J3k.JQDms93k32qs5TJPq9U4tLQ5PgL/S
i7DtuDkvWFSQcaVnr.UCokXsJZWf0XTex7ZDQgvCRH8emDkCx:ILswSty:29:ViFdXvQzGGNI41h
y01wcbsJ7wpyL1w:bsQDoBshYW1OiqRCfTW/zJhT9.TV4KNEpy5ETW0b:i5FylwYixGjrtqDm2SU
z7/yI1w0kz1lyP0xgmkeDtsSPWFvKsMBoD7RfYvQQTPMKZQpokt12sYdkKVEs0:sntskTdQvKYQw
u6THq3QshQuIqZvyR8:SYoZdXTvWdvaFRf3jiK5i0TUxoXh7dd3KXrxoIzyOxlR7pSzkPLnSu2jn
vWU8Qxlcxl0YkW9qZdjQf1DiGbiWviTOJUXvcNg.V7MFqWLnFyhOoFmhY7O6QfKW0cpdf3nh4z4t
yoY1Z1r2jrGq1Npd8HYKStUSt.Ss5X5us8yH5FfUYERQOWzL39/XbEvJxg4rhsVvErZ0frP44XrD
fZtfanT9zbxQW0xPfdK.Jktc/DQQ.se1b6HLGc9OUtg7EQVLjSrQOrTl/nkYTpcDFnnKstrHT5/o
pSkbIYjYqCSeS9kp6sf7uiRR5FPvsT5XmGVEtXCCQ16Q4MD3trvRJ0CvcQCPYC1K5qKlHxhu.tyo
XXXOiBXeK8/0OK:lVPN5b47aUR4r8NfDSL3Fz3o8i7Tzfbzzw.
AtEndOfEncoding
User avatar
Josef Templ
Posts: 2048
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Josef Templ »

#62 is classified as a Feature issue. Since in redmine an issue
is either a Feature or a Bug but not both, we can continue with the voting for #62
and create a new Bug fixing issue. We need to wait for working on the bug fixing issue
until #62 is committed to master because otherwise we would produce a merge conflict.

- Josef
Zinn
Posts: 476
Joined: Tue Mar 25, 2014 5:56 pm
Location: Frankfurt am Main
Contact:

Re: issue-#62 Unicode and Internationalization for StdStamps

Post by Zinn »

Some notes to Robert's version of StdStamps:
It uses maxhistoryEntry = 35 instead of 25. That is not downward compatible will create alien views in BB 1.6
It does not write the old format for BB 1.6 when ASCII is used only.
So you can't read that Stamps with BB 1.6

Some notes about Josef's version of StdStamps
It is downward compatible and has not Robert's drawbacks.
Stamps can be read and change with BB1.6
Robert's improvements is missing.

I have merge the benefits of both version.
It is not published.
I will send it on request.

Since RC5 StdStamps are changed several times.
The latest published version in RC6 needs some corrections.
It does not contain Josef's changes.
It contains Robert's change only.

Here we vote about Josef's changes and not about Robert's changes
Locked