<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!ENTITY sanduhr "<application>SandUhr</application>">
<!ENTITY timerref SYSTEM "timerref.sgml">
<!ENTITY alarmref SYSTEM "alarmref.sgml">
<!ENTITY factoryref SYSTEM "factoryref.sgml">
]>

<article id="index" lang="de">

  <articleinfo>
    <title>Anleitung für SandUhr</title>
    <author>
      <firstname>Jochen</firstname> <surname>Voß</surname>
      <affiliation>
	<address>
	  <email>voss@mathematik.uni-kl.de</email>
	</address>
      </affiliation>
    </author>

    <copyright>
      <year>2000-2001</year>
      <holder>Jochen Voß</holder>
    </copyright>

    <legalnotice id="legalnotice">
      <para>
	Permission is granted to copy, distribute and/or modify this
	document under the terms of the <ulink url="gnome-help:fdl"
	type="help"><citetitle>GNU Free Documentation
	License</citetitle></ulink>, Version 1.1 or any later version
	published by the Free Software Foundation with no Invariant
	Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
	copy of the license can be found <ulink url="gnome-help:fdl"
	type="help">here</ulink> or in the file COPYING-DOCS which
	shipped as part of this package.
      </para>
    </legalnotice>

    <releaseinfo>
      Dies ist Version 1.0 der Anleitung für Sanduhr.
    </releaseinfo>

  </articleinfo>


  <sect1 id="intro">
    <title>Einleitung</title>

    <para>
      &sanduhr; ist ein Wecker, der graphisch als Sanduhr gestaltet
      ist.  Man kann zwischen verschiedenen Aktionen wählen, die nach
      Erreichen der Weckzeit ergriffen werden sollen; unter anderem
      kann man dann eine Sounddatei abspielen lassen.  Das Programm
      ist zum Beispiel eine nützliche Hilfe, wenn man am Rechner immer
      wieder die Zeit vergisst und daher fürchtet, den Tee zulange
      ziehen zu lassen.
    </para>

    <para>
      Das Programm verwendet (und benötigt) die GNOME Arbeitsumgebung.
      Es funktioniert also nur unter dem <productname>X Window
      System</productname>.  Ich habe Teile des Programs mit Hilfe
      von <application>Glade</application> (siehe <ulink
      url="http://glade.gnome.org/">glade.gnome.org</ulink>) und des
      <productname>GTK+ object builder</productname>s (see <ulink
      url="http://www.5z.com/jirka/gob.html/">http://www.5z.com/jirka/gob.html</ulink>)
      programmiert.
    </para>

    <para>
      &sanduhr; ist freie Software.  Einzelheiten kann man in <xref
      linkend="license"> nachlesen.
    </para>

    <para>
      Ich freue mich über Kommentare zu meinem Programm, insbesondere
      auch über Fehlerberichte.  Meine Email-Adresse ist
      (<email>voss@mathematik.uni-kl.de</email>).  Ihre Nachricht
      sollte die Versionsnummer des Programms enthalten.  Diese erhält
      man entweder durch den Programmaufruf <command>sanduhr
      --version</command> oder aus dem
      <guimenuitem>Info</guimenuitem>-Fenster (mit der rechten
      Maustaste erhält man ein Menü, dort wählt man <menuchoice>
      <guisubmenu>Hilfe</guisubmenu> <guimenuitem>Info</guimenuitem>
      </menuchoice>).
    </para>
  </sect1>


  <sect1 id="usage">
    <title>Bedienung</title>

    <sect2 id="invocation">
      <title>Starten des Programms</title>

      <para>
	Das Programm &sanduhr; kann man auf zwei Arten starten.  Die
	einfachere Methode ist, das Startmenü von GNOME zu verwenden.
	Dort findet sich &sanduhr; in den Systemmenüs als <menuchoice>
	<guisubmenu>Programme</guisubmenu>
	<guisubmenu>Werkzeuge</guisubmenu>
	<guimenuitem>SandUhr</guimenuitem> </menuchoice>.  Nach dem
	Start erhält man zunächst ein Fenster um die Alarmzeit
	einzustellen.  Nachdem das geschehen ist, erscheint die
	eigentliche Sanduhr.
      </para>

      <para>
	Alternativ kann man &sanduhr; auch von der
	Kommandozeile aus starten.  Das Kommando dazu lautet
	<synopsis>
<command>sanduhr</command> <optional><replaceable class="option">Optionen</replaceable></optional> <optional><replaceable class="parameter">Alarmzeit</replaceable></optional>
	</synopsis>
      </para>

      <para>
	Das Argument <replaceable
	class="parameter">Alarmzeit</replaceable> gibt an, wann die
	Uhr ablaufen soll.  Das Format dieses Parameters wird im <xref
	linkend="timespec"> erklärt.  Wenn in der Kommandozeile keine
	Alarmzeit angegeben wird, öffnet das Programm zunächst ein
	Fenster, in dem man diese Einstellen kann.  Das Programm
	versteht unter anderem folgende Optionen:

	<variablelist>
	  <varlistentry>
	    <term><parameter>-h</parameter></term>
	    <term><parameter>--help</parameter></term>
	    <listitem>
	      <para>
		Gibt eine vollstängige Liste der erlaubten Optionen aus.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><parameter>-m <replaceable class="parameter">TEXT</replaceable></parameter></term>
	    <term><parameter>--message=<replaceable class="parameter">TEXT</replaceable></parameter></term>
	    <listitem>
	      <para>
		Verwende TEXT als Alarmmeldung.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>

	<example>
	  <title>Eine Anwendung aus dem wirklichen Leben</title>
	  <para>
	    Beim Aufruf des Programms von der Kommandozeile könnte
	    <abbrev>z.B.</abbrev> folgendes Kommando sinnvoll sein.
	    Es bewirkt, dass nach zweieinhalb Minuten die Meldung
	    <quote>Tee ist fertig</quote> ausgegeben wird.
	    <screen>
<prompt>%</prompt> <userinput>sanduhr -m "Tee ist fertig" +2m30s</userinput>
	    </screen>
	  </para>
	</example>
      </para>
    </sect2>


    <sect2 id="timespec">
      <title>Die Alarmzeit</title>

      <para>
	Die Hauptfunktion des Programmes &sanduhr; ist es, bis zu
	einer bestimmten Alarmzeit zu warten.  Diese Alarmzeit gibt
	man als Text an, entweder in der Kommandozeile oder in dem
	entsprechenden Formular.  Es gibt hier zwei grundsätzlich
	unterschiedliche Arten, die Alarmzeit anzugeben.  Man kann
	entweder die Länge der Zeitspanne oder den Alarmzeitpunkt,
	<abbrev>d.h.</abbrev> das Ende der Zeitspanne, angeben.
      </para>

      <para>
	Relative Zeitangaben geben die Länge der Alarmzeitspanne an.
	Sie beginnen grundsätzlich mit einen <userinput>+</userinput>.
	Danach folgt die Länge der Zeitspanne wie
	<abbrev>z.B.</abbrev> in <userinput>+30s</userinput>
	(30&nbsp;Sekunden) oder <userinput>+1h12m</userinput> (Eine
	Stunde und 12 Minuten).  Dabei werden folgende Abkürzungen
	verwendet.
      </para>

      <variablelist>
	<varlistentry>
	  <term><userinput>d</userinput></term>
	  <term><userinput>days</userinput></term>
	  <listitem>
	    <para>Tage</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><userinput>h</userinput></term>
	  <term><userinput>hours</userinput></term>
	  <listitem>
	    <para>Stunden</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><userinput>m</userinput></term>
	  <term><userinput>min</userinput></term>
	  <listitem>
	    <para>Minuten</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><userinput>s</userinput></term>
	  <term><userinput>sec</userinput></term>
	  <listitem>
	    <para>Sekunden</para>
	  </listitem>
	</varlistentry>
      </variablelist>

      <para>
	Absolute Zeitangaben geben direkt den Alarmzeitpunkt an.  Sie
	beginnen stets mit einer Ziffer.  Beispiele sind
	<userinput>20:15</userinput> (Viertel nach Acht, abends) und
	<userinput>2003-12-31 23:59:30</userinput> (kurz vor Ende des
	Jahres 2003).
      </para>

      <tip>
	<para>
	  Wie das Beispiel zeigt, können absolute Zeitangaben Leerzeichen
	  beinhalten.  Wenn man solche Zeitangaben in der Kommandozeile macht,
	  muss man das Argument für die Alarmzeit in Anführungszeichen
	  einschließen, damit das Programm sie als ein einzelnes Argument
	  erkennt.
	</para>
      </tip>

      <example>
	<title>Ein Kommandozeilenargument mit Leerzeichen</title>
	<screen>
<prompt>%</prompt> <userinput>sanduhr "1999-12-31 23:59:30"</userinput>
	</screen>
      </example>

      <para>
	Die allgemeine Form für absolute Zeitangaben ist
	<screen>
<userinput>
<optional><replaceable>jahr</replaceable>-<replaceable>monat</replaceable>-<replaceable>tag</replaceable></optional> <replaceable>stunde</replaceable>:<replaceable>minute</replaceable><optional>:<replaceable>sekunde</replaceable></optional>
</userinput>,
	</screen>
	wobei <replaceable>jahr</replaceable> die Jahreszahl mit allen
	vier Ziffern, <replaceable>monat</replaceable> der Monat von 1
	bis 12, <replaceable>tag</replaceable> der Tag von 1 bis 31,
	<replaceable>stunde</replaceable> die Stunde von 0 bis 23,
	<replaceable>minute</replaceable> die Minute und
	<replaceable>sekunde</replaceable> die Sekunde von 0 bis 59
	ist.
      </para>
    </sect2>
  </sect1>


  <sect1 id="prefs">
    <title>Konfiguration des Programms</title>

    <sect2 id="properties">
      <title>Eigenschaften</title>

      <para>
	Während das Programm läuft, kann man mit der rechten Maustaste
	auf die Sanduhr klicken, um ein Menü zu öffnen.  Mit Hilfe
	dieses Menüs kann man <abbrev>z.B.</abbrev> das Programm
	vorzeitig beenden oder nachträglich die Alarmzeit oder
	-meldung verändern.  Der Eintrag
	<menuchoice>
	  <guimenuitem>Eigenschaften</guimenuitem>
	</menuchoice>
	öffnet den Eigenschaftendialog des Programms.
      </para>

      <para>
	Der Eigenschaftendialog besteht aus vier Seiten und die
	meisten Einträge sollten unmittelbar verständlich sein.  Zum
	Beispiel kann man auf der Seite <guilabel>Aktion</guilabel>
	einstellen, was beim Erreichen der Alarmzeit geschehen soll.
	Zur Auswahl steht das Piepsen mittels des normalen
	Tastaturpiepses, das Abspielen einer Sounddatei oder das
	Ausführen eines beliebigen Programms.
      </para>

      <para>
	Der letzte Eintrag dieser Seite, nämlich
	<quote><guilabel>Externes SandUhr::AlarmAction
	CORBA-Objekt</guilabel></quote> dient dazu, selbst programmierte
	Alarmmechanismen in das Programm einzufügen.  Dies wird
	Ausfühlich im <xref linkend="corba"> erklärt.
      </para>
    </sect2>

    <sect2 id="preferences">
      <title>Voreinstellungen</title>

      <para>
	Der Menüeintrag
	<menuchoice>
	  <guimenuitem>Globale Einstellungen</guimenuitem>
	</menuchoice>
	im Menü der SandUhr öffnet ein Fenster, in dem man die
	Vorgaben für neue Uhren wählen kann.  Die Einträge sind
	ähnlich wie die im <link
	linkend="properties">Eigenschaftendialog</link>.
      </para>
    </sect2>
  </sect1>


  <sect1 id="corba">
    <title>Steuerung mittels CORBA</title>

    <para>
      &sanduhr; besitzt eine umfangreiche
      <productname>CORBA</productname>-Schnittstelle.  Damit kann man
      auch in eigenen Skripten und Programmen neue Uhren erzeugen
      oder auf bestehende Uhren zugreifen.  Die Schnittstelle erlaubt
      es sogar, eigene Alarmmechanismen an das Programm anzuschließen.
      Unten findet sich als Beispiel eine Methode, um die Alarmmeldung
      per Email zuzustellen.
    </para>

    <sect2 id="corbaintro">
      <title>CORBA-Einführung</title>

      <para>
	<productname>CORBA</productname> ist ein komplexes Gefüge, das
	dazu dient unterschiedliche Programmteile auch dann
	miteinander verbinden zu können, wenn sie möglicherweise in
	unterschiedlichen Programmiersprachen geschrieben sind, oder
	auf unterschiedlichen Rechnern eines Netzwerkes laufen.  Die
	volle Dosis an Schlagworten findet sich auf der offiziellen
	<productname>CORBA</productname>-Webseite unter <ulink
	url="http://www.corba.org/">www.corba.org</ulink>.
      </para>

      <para>
	<productname>CORBA</productname> ist objektorientiert.  Ein
	<productname>CORBA</productname>-Server implementiert Objekte
	und Kunden können (vom Server vorgegebene) Anforderungen an
	den Server senden, um bestimme Aufgaben zu erledigen.
	&sanduhr; implementiert zwei Klassen von CORBA-Objekten:

	<itemizedlist>
	  <listitem>
	    <para>
	      <classname>SandUhr::Timer</classname>-Objekte.  Diese
	      entsprechen den sanduhrförmigen Fenstern auf dem
	      Bildschirm.  Sie stellen Anfragen zur Verfügung, um die
	      Einträge aus dem Eigenschaftendialog der Uhr zu setzen
	      oder abzufragen.
	    </para>
	  </listitem>

	  <listitem>
	    <para>
	      <classname>SandUhr::TimerFactory</classname>-Objekte.
	      Jede Kopie des &sanduhr;-Programms implementiert genau
	      ein <classname>TimerFactory</classname>-Objekt.  Das
	      entspricht im wesentlichen dem Kontrollfenster, das man
	      in dem Menü der Uhren öffnen kann.  Die Hauptaufgabe
	      dieses Objektes ist es, neue Uhren zu erzeugen.
	    </para>
	  </listitem>
	</itemizedlist>
      </para>

      <para>
	Die CORBA-Unterstützung von &sanduhr; ist mittels
	<productname>ORBit</productname> realisiert.  Dies ist der
	Standard-CORBA-ORB des GNOME-Projekts.  Informationen über
	<productname>ORBit</productname> gibt es auf der <ulink
	url="http://www.labs.redhat.com/orbit/">ORBit
	homepage</ulink>.  Die Kommunikation zwischen
	unterschiedlichen ORB-Implementationen ist standardisiert, so
	dass (zumindest in der Theorie) jede ORB-Implementation
	geeignet sein sollte, um mit &sanduhr; zusammenzuarbeiten.
	Wenn Sie mehr über <productname>CORBA</productname> lernen
	wollen, dann sollten Sie den Artikel <citetitle>CORBA
	Applications In GNOME</citetitle> von Elliot Lee lesen.
	Dieser ist auf der <ulink
	url="http://developer.gnome.org/doc/whitepapers/ORBit/index.html">GNOME
	development site</ulink> veröffentlicht.
      </para>

      <para>
	In den folgenden Beispielen werde ich die Python-Schnittstelle
	für <productname>ORBit</productname> verwenden.  Diese gibt es
	auf der Seite <ulink
	url="http://orbit-python.sault.org/">orbit-python.sault.org</ulink>.
	Außerdem wird die OAF-Bibliothek für GNOME benötigt.  Hier
	verwende ich die Python-Anbindung, die im bonobo-python Paket
	unter <ulink
	url="http://bonobo-python.lajnux.nu/">bonobo-python.lajnux.nu</ulink>
	enthalten ist.
      </para>
    </sect2>


    <sect2 id="corbasimple">
      <title>Einfache CORBA-Skripte</title>

      <para>
	Mittels <productname>CORBA</productname> eine neue Uhr zu
	erzeugen, ist leicht.  Das einzige Problem besteht darin,
	Zugriff auf ein
	<classname>SandUhr::TimerFactory</classname>-Objekt zu
	bekommen.  Wir können dann dieses Objekt einfach anweisen, für
	uns eine neue Uhr zu erzeugen.  Das Problem wird durch die
	OAF-Bibliothek von GNOME (dem <quote>Object Activation
	Framework</quote>) gelöst.  Wir können bei OAF einfach ein
	CORBA-Objekt anfordern, das die
	<classname>SandUhr::TimerFactory</classname>-Klasse
	implementiert.  Diese Technik wird durch <xref
	linkend="ex-simple1"> illustriert.
      </para>

      <example id="ex-simple1">
	<title>Erzeugen einer neuen Uhr mittels CORBA</title>
	<para>
	  Das folgende Python-Skript erzeugt eine neue Uhr, die nach
	  30 Sekunden abläuft.  Wenn man das Skript startet sollte es
	  ein neues Sanduhrfenster öffnen und sich dann sofort
	  beenden, ohne auf das Ablaufen der Uhr zu warten.  Falls Sie
	  nicht die ORBit-Python-Schnittstelle verwenden, müssen sie
	  eventuell erst mit dem IDL-Compiler das SandUhr-Modul
	  erzeugen.
	</para>

	<para>
	  Natürlich kann man diese Methode auch für jede andere
	  Programmiersprache, sofern sie nur Schnittstellen zu
	  <productname>CORBA</productname> und der OAF-Bibliothek
	  besitzt, übertragen.  Das resultierende Programm wird
	  ähnlich aufgebaut sein.
	</para>
	
	<programlisting id="ex-simple1.py">
import CORBA, oaf, SandUhr

oaf.init()
factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
factory.CreateTimer ("+30s", "Uhr abgelaufen")
	</programlisting>
      </example>

      <para>
	Wenn Sie erst einmal dieses Beispiel bewältigt haben, dann ist
	es kein Problem mehr, die Uhr weiter anzupassen.  <xref
	linkend="ex-simple2"> demonstriert, wie man einen pinkfarbenen
	Timer erzeugt, der fünfmal piept.
      </para>

      <example id="ex-simple2">
	<title>Konfigurieren der Uhren mittels CORBA</title>
	<para>
	  Das folgende Python-Skript erzeugt einen pinkfarbenen Timer,
	  der fünfmal piepst wenn der Alarm ausgelöst wird.
	</para>

	<programlisting id="ex-simple2.py">
import CORBA, oaf, SandUhr

oaf.init()
factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
timer = factory.CreateTimer ("+20s", "Pinkfarbener Timer abgelaufen")

timer.SandColor=SandUhr.Timer.Color(Red=212,Green=78,Blue=222)

alarm = factory.CreateAlarmBeep (5)
timer.Alarm = alarm
	</programlisting>
      </example>
    </sect2>


    <sect2 id="corbaadvanced">
      <title>Fortgeschrittene CORBA-Anwendungen</title>

      <para>
	Eine aufwändigere Anwendung der
	<productname>CORBA</productname>-Schnittstelle besteht darin,
	neue Alarmmechanismen an das Programm anzuschließen.  Dadurch
	können sie die Alarmmeldung mittels beliebiger Programme
	zustellen.  <xref linkend="ex-email"> zeigt exemplarisch, wie
	Sie das per Email tun.
      </para>

      <para>
	Das Programm muss hier einen CORBA-Server bereitstellen, der
	die <classname>SandUhr::AlarmAction</classname>-Schnittstelle,
	wie sie in <xref linkend="alarmref"> beschrieben ist,
	implementiert: es muss das
	<literal>SandUhr::AlarmAction::NeedsPopup</literal>-Attribut
	und die Methoden
	<literal>SandUhr::AlarmAction::Attach</literal>,
	<literal>SandUhr::AlarmAction::Detach</literal> und
	<literal>SandUhr::AlarmAction::Deliver</literal>
	bereitstellen.
      </para>

      <para>
	Für objektorientierte Programmiersprachen stellt die
	ORB-Implementation dazu gewöhnlich eine Klasse, die etwa
	<classname>SandUhr__POA::AlarmAction</classname> benannt ist,
	zur Verfügung (für Python ist der Name
	<classname>SandUhr__POA.AlarmAction</classname>).  Davon
	müssen Sie nun eine neue Klasse ableiten, die
	<literal>NeedsPopup</literal>, <literal>Attach</literal>,
	<literal>Detach</literal> und <literal>Deliver</literal>
	überlädt.
      </para>

      <para>
	&sanduhr; greift auf den Server zu, um die Alarmmeldung
	zuzustellen.  Daher müssen sie Ihr Programm am Laufen halten,
	bis der Timer abgelaufen ist.  Gewöhnlich ruft man dazu die
	Methode <literal>ORB::run</literal> des ORBs auf.
      </para>

      <example id="ex-email">
	<title>Zustellung des Alarms per Email</title>
	<para>
	  Das folgende Python-Skript implementiert eine Alarmmethode,
	  die den Alarm per Email zustellt.  Sie müssen die Variablen
	  <literal>EMAIL</literal> und <literal>SENDMAIL</literal> an
	  Ihre Situation anpassen.  Nach dem Starten sollte das Skript
	  ein Sanduhrfenster öffnen und in Schlaf verfallen.  Nach 60
	  Sekunden schickt es dann eine Email los und beendet sich
	  selbst.
	</para>

	<programlisting id="ex-email.py">
EMAIL = "Addressee &lt;some@email.address&gt;"
SENDMAIL = "/usr/sbin/sendmail"

import os
import CORBA, oaf
import SandUhr, SandUhr__POA

orb = oaf.init()

class SendMailAlarm(SandUhr__POA.AlarmAction):
    def __init__(self):
        self.NeedsPopup = CORBA.FALSE

    def Attach(self, timer):
        pass

    def Detach(self, timer):
        orb.shutdown(1)

    def Deliver(self, timespec, message):
        p = os.popen("%s -t" % SENDMAIL, "w")
        p.write("To: %s\n" % EMAIL)
        p.write("Subject: SandUhr: %s\n" % message)
        p.write("\n") # Eine Leerzeile trennt den Header vom Text
        p.write("Eine Sanduhr ist abgelaufen.\n")
        p.write("  Alarmmeldung: %s\n" % message)
        p.write("  Alarmzeit: %s\n" % timespec)
        sts = p.close()
        if sts:
            print "Sendmail exit status", sts

poa = orb.resolve_initial_references("RootPOA")
alarm = SendMailAlarm()._this()
poa._get_the_POAManager().activate()

factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
timer = factory.CreateTimer ("+60s", "Der Uhr hat die Stunde geschlagen")
timer.Alarm = alarm

orb.run()
	</programlisting>
      </example>

      <para>
	Es gibt noch eine weitere Methode, um CORBA-basierte
	Alarmmechanismen an das Programm anzuschließen: mittels
	<function>ORB::object_to_string</function> kann man den
	IOR-String des <classname>AlarmAction</classname>-Objektes
	herausfinden.  Diesen String kann man in das entsprechende
	Feld der Seite <guilabel>Aktion</guilabel> im
	Eigenschaftendialog der Uhr eintragen.  Die Uhr wird dann den
	Alarm mit Hilfe unseres Servers zustellen.  Dies wird durch
	<xref linkend="ex-ior"> demonstriert.
      </para>

      <note>
	<para>
	  Diese Technik ist manchmal nützlich, da sie im Gegensatz
	  zu den oben geschilderten Methoden nicht die OAF-Bibliothek
	  benötigt.  Man kann dieses Verfahren also auch mit
	  Programmiersprachen verwenden, für die es noch keine
	  OAF-Anbindung gibt.
	</para>
      </note>

      <example id="ex-ior">
	<title>Anschließen einer Alarmmethode mittels des IOR-Strings</title>

	<para>
	  Das folgende Python-Skript implementiert eine
	  Beispielalarmmethode.  Wenn man es startet, gibt es zunächst
	  nur den IOR-String aus und wartet ab.  Wenn man den String
	  in das entsprechende Feld der Seite
	  <guilabel>Aktion</guilabel> im Eigenschaftendialog der Uhr
	  einträgt, dann verwendet die Uhr die Funktion
	  <function>Deliver()</function> aus diesem Skript.
	</para>

	<programlisting id="ex-ior.py">
import CORBA, SandUhr, SandUhr__POA

class Wecker(SandUhr__POA.AlarmAction):
    def __init__(self):
        self.NeedsPopup = CORBA.FALSE

    def Attach(self, timer):
        pass

    def Detach(self, timer):
        orb.shutdown(1)

    def Deliver(self, timespec, message):
        print message

orb = CORBA.ORB_init()
poa = orb.resolve_initial_references("RootPOA")

ref = Wecker()._this()
print orb.object_to_string(ref)

poa.the_POAManager.activate()
orb.run()
	</programlisting>
      </example>
    </sect2>
  </sect1>


  <sect1 id="authors">
    <title>Autor</title>

    <para>
      &sanduhr; wurde von Jochen Voss
      (<email>voss@mathematik.uni-kl.de</email>) programmiert.  Sie
      können meine Homepage unter <ulink
      url="http://www.mathematik.uni-kl.de/~wwwstoch/voss/privat.html">http://www.mathematik.uni-kl.de/~wwwstoch/voss/privat.html</ulink>
      finden.  Dort gibt es auch einen Abschnitt über &sanduhr;, der
      womöglich neue Versionen des Programms oder weitere
      Informationen enthält.
    </para>

    <para>
      Ich würde mich über Kommentare und Verbesserungsvorschläge zu
      meinem Programm freuen, insbesondere auch über Fehlerberichte.
      Ihre Nachricht sollte die Versionsnummer des Programms
      enthalten.  Diese erhält man entweder durch den Programmaufruf
      <command>sanduhr --version</command> oder aus dem
      <guimenuitem>Info</guimenuitem>-Fenster.
    </para>
  </sect1>


  <sect1 id="license">
    <title>Lizenz</title>

    <para>
      &sanduhr; ist freie Software, <abbrev>d.h.</abbrev> jeder darf
      das Programm weitergeben oder verändern, solange er sich dabei
      an die Bedingungen der <ulink url="gnome-help:gpl"
      type="help"><citetitle>GNU General Public
      License</citetitle></ulink> (Version 2 oder später) der
      <citetitle>Free Software Foundation</citetitle> hält.
    </para>

    <para>
      Ich verteile das Programm in der Hoffnung, dass es nützlich ist,
      aber ich gewähre keinerlei Garantie darauf.  Näheres findet sich
      in der <citetitle>GNU General Public License</citetitle>.  Eine
      Kopie dieser Lizenz liegt dem Programm in der Datei
      <filename>COPYING</filename> bei.  Ansonsten können sie eine
      Kopie der <citetitle>GNU General Public License</citetitle> von
      der Free Software Foundation erhalten, entweder unter <ulink
      url="http://www.fsf.org" type="http">www.fsf.org</ulink> oder
      indem sie einen altmodischen Brief an folgende Adresse schreiben.
      <address>
	Free Software Foundation, Inc.
	<street>59 Temple Place</street> - Suite 330
	<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
	<country>USA</country>
      </address>
    </para>
  </sect1>


  <appendix id="idl">
    <title>Die SandUhr CORBA-Schnittstelle</title>

    <para>
      Die &sanduhr; CORBA-Schnittstelle wird durch die Datei
      <filename>sanduhr.idl</filename> definiert.  Diese Datei enthält
      eine maschinenlesbare Beschreibung der Schnittstellensyntax in
      der Beschreibungssprache IDL (Interface Description Language).
      Die folgenden Abschnitte erklären die zugehörige Semantik.
    </para>

    &timerref;
    &alarmref;
    &factoryref;

  </appendix>

</article>
