Autosave für Word-Plus

Viele Textverarbeitungen haben ein Feature namens Autosave: In gewissen Zeitabständen wird der eingegebene Text automatisch gesichert, um bei Systemabstürzen möglichst wenig Verlust zu haben. Wordplus fehlt, wie so vieles mehr, diese Möglichkeit, das kleine Accessory AUTOSAVE setzt auf Wordplus auf und übernimmt diese Funktion.

Wenn Sie in Wordplus arbeiten und einen Text geöffnet haben, können Sie durch Aufruf des Accessories und Auswahl von “AN” den Autosave aktivieren (Bild 1). Alle fünf Minuten (Voreinstellung) wird Wordplus zur Durchführung von “Speichern & weiter” veranlaßt. Der gerade bearbeitete Text wird dann auf Platte oder Diskette geschrieben und ist somit bei Abstürzen gerettet. Während des Sicherns wird die Texteingabe unterbrochen und die “busy bee” erscheint. Zeichen gehen dabei nicht verloren; sie werden gepuffert.

Aktivieren von Autosave

Ein erneuter Aufruf von AUTOSAVE ergibt eine etwas andere Alertbox (Bild 2). Sie zeigt den Zeitabstand zwischen den Sicherungsvorgängen an, der in Minutenschritten erhöht bzw. erniedrigt werden kann. Der kürzeste Abstand ist eine Minute. Mit “AUS” wird AUTOSAVE abgeschaltet.

Ist AUTOSAVE aktiviert, wenn Wordplus nicht geladen ist, erscheint beim Versuch, Wordplus zum Sichern zu veranlassen, eine Alertbox (Bild 3), und AUTOSAVE wird automatisch abgeschaltet, um das System nicht unnötig zu belasten.

Im Kampf mit den Wanzen

Leider gibt es einige Fehler im GEM und eine schlecht programmierte Stelle in Wordplus, die Einschränkungen im Umgang mit AUTOSAVE erfordern. Der GEM-Fehler besteht darin, daß das System dem Accessory auch dann meldet, Wordplus wäre geladen, wenn dies garnicht der Fall ist. Dieser Bug tritt immer dann auf, wenn das letzte gelaufene Programm die Textverarbeitung war, und kein anderes in der Zwischenzeit gestartet wurde. Wordplus reagiert leider auch dann auf den “Speichern & weiter”- Aufruf, wenn kein Dokument geöffnet ist (Der entsprechende Menüeintrag wird dann deaktiviert; anscheinend kamen die Programmierer nicht auf die Idee, daß eines Tages ein anderes Programm Funktionen aufrufen würde, und fangen dies nicht ab). Wordplus versucht dann einen nicht vorhandenen Text zu sichern, kommt mit der Speicherverwaltung durcheinander und erzeugt einen Busfehler, der wiederum einen Systemabsturz mit Neubooten auslöst.

Da sich diese Fehler nicht von AUTOSAVE aus verhindern lassen, dürfen Sie das Accessory nur dann benutzen, wenn Wordplus geladen und mindestens ein Dokument geöffnet ist. Ärgerlich, aber nicht zu ändern.

Einstellen des Zeilenabstands

Im Programm

Das in Modula-2 geschriebene Programm ist im Listing abgedruckt. Beim Link-Vorgang muß, da es sich um ein Accessory handelt, die Option “QUERY” eingeschaltet und für “GEMX.LNK” das Linkmodul -GEMACCX.LNK” ausgewählt werden. Die Option "OPT” sollte auch eingesetzt werden, damit das Accessory nur ca. 3,5 KByte belegt.

Die Autosave-Funktion wird ermöglicht, indem an Wordplus eine Mitteilung geschickt wird, laut der der Eintrag "Speichern & weiter” im "File”-Menü ausgewählt wurde. Normalerweise verschickt nur GEM solche Mitteilungen, mit der “Appl-Write”-Funktion kann das aber jede Applikation. Dazu muß zunächst mit “ApplFind " die Applikations-Kennzahl von Wordplus ermittelt werden, damit der Empfänger der Nachricht benannt werden kann. “ApplFind” hat den oben beschriebenen Fehler, nicht immer -1 zu liefern, wenn das gesuchte Programm nicht im Speicher steht. Die Mitteilung wird wie eine Standardmessage zusammengestellt und im Gerten und fünften Wert die Indizes des ausgewählten Menütitels und -eintrags abgelegt. Diese Werte sind in dem Programm für die Version 2.02 von Wordplus enthalten (Prozedur “Init”). Wenn Sie eine andere Version benutzen, müssen Sie mit einem Resource-Construction-Set an den Titel “File” und den Eintrag “Sichern & weiter” einen Namen vergeben und die Resource speichern. Aus dem dann erzeugten Headerfile lassen sich die Indizes auslesen. Wenn Sie den Umgang mit einem RCS nicht gewohnt sind, sollten Sie sich von einem “Experten” helfen lassen.

Automatisches Ausschalten

Durch einen “EventMultiple” wird bei eingeschaltetem AUTOSAVE auch auf ein Timer-Ereignis gewartet, das dann den Sicherungsvorgang auslöst. Auch hier soll es einen GEM-Bug geben, durch den der Timerevent bei Accessories nicht immer funktioniert. Allerdings konnte ich dies noch nicht beobachten. Bei einem Mitteilungs-Ereignis werden die Alerts ausgeführt, durch die AUTOSAVE ein-und ausgeschaltet sowie das Sicherungsintervall verändert wird.

Aufbauend auf das gleiche Schema kann : man z.B. ein Autosave für andere Programme schreiben oder andere Funktionen “fernsteuern". Die Möglichkeiten sind dabei praktisch unbegrenzt.

MODULE AutoSave ;
	(*$A+*)	(*	optimieren *)

FROM M2Conversions	IMPORT ConvertCardinal ;
FROM Strings	IMPORT String, Concat ;
FROM SYSTEM	IMPORT ADR ;
FROM GEMAESbase	IMPORT AccessoryOpen, MenuSelected, MesageEvent, TimerEvent ;
FROM AESApplications	IMPORT	ApplInitialise, ApplFind, ApplWrite ;
FROM AESEvents	IMPORT	EventMultiple ;
FROM AESForms	IMPORT	FormAlert ;
FROM AESMenus	IMPORT	MenuRegister ;

CONST
	WORDPLUSVERSION	=	2.02 ;
	OnAlert	= '[2][Autosave für Wordplus! by Robert Tolksdorf][AN|ABBRUCH]';
	OffAlert1 = ' [2] [Autosave für Wordplus| by Robert Tolksdorf|Intervall:' ;
	OffAlert2 =	'	Min] [+1 Min|-1	Min|AUS]';
	SetOff1	=	'[3][Autosave für Wordplus! by Robert Tolksdorf!';
	SetOff2	=	'Autosave ausgeschaltet,|da nicht mehr in WORDPLUS][OK]';
	AMinute = 60000 ;	(*	eine Minute = 60000 ms *)

VAR ApplID, AccID, WordPlusID	:	INTEGER;
	MessBuffer	:	ARRAY [0..7] OF CARDINAL ;
		SichernUndWeiterlndex, Fileindex ; CARDINAL ;
	Saveinterval	:	LONGCARD;
	dummy, AwaitedEvents, Event	:	INTEGER;
	Alert	:	ARRAY	[0..132] OF CHAR;
	Interval	:	String;

PROCEDURE Init;
BEGIN
	IF WORDPLUSVERSION = 2.02 THEN 
		SichernUndWeiterIndex:=28;
		Fileindex:=4;
	END;
	(* hier andere Versionen einsetzen:	IF WORDPLUSVERSION = ... *)
	AwaitedEvents:=MesageEvent; (* ausgeschaltet *)
	Saveinterval :=5*AMinute;	(*	auf	5 Min voreinstellen *)
END Init;

BEGIN
	Init ;	(* Initialisieren *)
	ApplID:=ApplInitialis	(* Applikation anmelden *)
	AccID:=MenuRegister(ApplID,' AutoSave'); (* ACC anmelden *)
LOOP
		Event:=EventMultiple(AwaitedEvents,0,0,0,0,0,0,0,0,0,0,0,0,0, 
			ADR(MessBuffer),
			INTEGER(Saveinterval MOD 10000H),
			INTEGER(Saveinterval DIV 10000H), 
			dummy,dummy,dummy,dummy,dummy,dummy);
	IF (4 IN BITSET(Event)) AND (MessBuffer[0]=AccessoryOpen)
	THEN
		IF AwaitedEvents=MesageEvent THEN (* Messageevent *)
			IF FormAlert(1,OnAlert)=1 THEN (* ist ausgeschaltet *)
				AwaitedEvents:=MesageEvent+TimerEvent; (* einschalten *)
		END;
	ELSE
		ConvertCardinal(CARDINAL(Saveinterval DIV 
		AMinute),3,Interval);
		Concat(OffAlert1,Interval,Alert);	(* Intervall einfügen *)
		Concat(Alert,OffAlert2,Alert);
		CASE FormAlert(3,Alert) OF
			1:	Saveinterval:=SaveInterval+AMinute; (* + 1 Min *)
			|	2:	IF SaveInterval>AMinute THEN
				SaveInterval:=SaveInterval-AMinute; (* -1 Min *)
			END;
			|	3: AwaitedEvents:=MesageEvent;	(* ausschalten *)
		END;
	END;
END;
IF 5 IN BITSET(Event) THEN	(* Timerevent *)
	WordPlusID:=ApplFind('WORDPLUS');	(*	ID holen *)
	IF WordPlusID#-l THEN
		MessBuffer[0]:=MenuSelected; (* Message zusammenbauen *) 
		MessBuffer[1]:=ApplID;
		MessBuffer[2]:=0;
		MessBuffer[3]:=FileIndex;
		MessBuffer[4]:=SichernUndWeiterIndex;
		MessBuffer[5]:=0; MessBuffer[6] :=0; MessBuffer[7]:=0; 
		ApplWrite(WordPlusID,16,ADR(MessBuffer));	(* Message schicken *)
	ELSE
		AwaitedEvents:=MesageEvent;	(*	nicht geladen *)
		Concat(SetOff1,SetOff2,Alert); dummy:=FormAlert(1,Alert);
	END;
END;

END; (* und von vorne ...	*)

END AutoSave.

Robert Tolksdorf
Aus: ST-Computer 02 / 1988, Seite 40

Links

Copyright-Bestimmungen: siehe Über diese Seite