What about
Paste, i.e. read the content stored in the clipboard?
I have tried two versions:
Code: Select all
PROCEDURE PasteFromClipboard* (): POINTER TO ARRAY OF CHAR;
VAR i: INTEGER; T: TextModels.Model; S: TextMappers.Scanner;
v: Views.View; w, h: INTEGER; isSingle: BOOLEAN;
str: POINTER TO ARRAY OF CHAR; ch: CHAR;
BEGIN
HostClipboard.GetClipView("", v, w, h, isSingle);
IF (v # NIL) & (v.ThisModel() # NIL) & (v.ThisModel() IS TextModels.Model) THEN
(* Views.OpenView(v); *)
T := v.ThisModel()(TextModels.Model);
S.ConnectTo(T);
NEW(str, T.Length() + 1);
i := 0; S.rider.ReadChar(ch);
WHILE ~S.rider.eot DO
IF S.rider.view = NIL THEN str^[i] := ch; INC(i) END;
S.rider.ReadChar(ch)
END;
str^[i] := 0X
ELSE
NEW(str, 1); str^[0] := 0X
END;
RETURN str
END PasteFromClipboard;
PROCEDURE PasteFromClipboard* (OUT str: ARRAY OF CHAR);
VAR i: INTEGER; T: TextModels.Model; S: TextMappers.Scanner;
v: Views.View; w, h: INTEGER; isSingle: BOOLEAN;
ch: CHAR;
BEGIN
HostClipboard.GetClipView("", v, w, h, isSingle);
IF (v # NIL) & (v.ThisModel() # NIL) & (v.ThisModel() IS TextModels.Model) THEN
(* Views.OpenView(v); *)
T := v.ThisModel()(TextModels.Model);
S.ConnectTo(T);
i := 0; S.rider.ReadChar(ch);
WHILE (i < LEN(str) - 1) & ~S.rider.eot DO
IF S.rider.view = NIL THEN str[i] := ch; INC(i) END;
S.rider.ReadChar(ch)
END;
str[i] := 0X
ELSE
str[0] := 0X
END
END PasteFromClipboard;
At first I felt a bit unable to decide which interface was better, whether a or b:
a) PROCEDURE PasteFromClipboard* (): POINTER TO ARRAY OF CHAR
b) PROCEDURE PasteFromClipboard* (OUT str: ARRAY OF CHAR)
Interface "a" seems more usable because can be called directly even without having a destination array, e.g.:
Code: Select all
StdLog.String("Content = '" + PasteFromClipboard() + "'")
Also it is fine that the client does not need to worry about the size of the array, but ... caution should be taken if the clipboard has got a large amount of data; otherwise execution traps with "stack overflow" or "illegal memory write". I also have noticed that if the clipboard, instead of chars, has got a file, then there is no problem because
HostClipboard.GetClipView gives value NIL to variable v, and nothing is returned.
I reckon that interface "b" can be more efficient because the procedure does not need to allocate the array, but a truncation will be produced if the content of the clipboard is greater than the VAR parameter received.
Because of the possible traps, I favour "b" over "a".
On the other hand ... the client can be interested in reading the content of the clipboard in other ways, rather than as bare chars. I mean, he might want to read the list of numbers stored in the clipboard, for example. In that case, to read the clipboard it is better to use "S.Scan, S.type and S.int", instead of "S.rider.ReadChar(ch)".
What I want to say is that the above procedure
PasteFromClipboard (returning chars) is not a general utility function, and that the client will have to write his ad hoc procedure to read the clipboard.
Anyway, it is useful to have at hand a procedure like
PasteFromClipboard (returning chars), because it gives clues about how to read the clipboard.
Regards