Kundenorientierung beim Zahnarzt

Am Montag habe ich mir beim Zahnarzt eine Füllung einsetzen lassen. Handwerklich habe ich bisher nichts zu bemängeln, das dürfte soweit alles passen. Aber die Beratung war recht dürftig …

Das ging schon mit der Routineuntersuchung vor einigen Wochen los, bei der diese behandlungsbedürftige Karies-Stelle entdeckt wurde. Da die vor ca. 5 Jahren schon im Ansatz auf einem Röntgenbild zu sehen war, wusste ich immerhin, dass jetzt wohl wirklich Bohren nötig war (und nicht nur die Zahnärztin gerne etwas verdienen wollte).

Aber schon mit der Wahl der Behandlungsmethode ging es los: Amalgam würde man grundsätzlich nicht mehr verarbeiten. Die Kasse würde ansonsten nur einfache Zementfüllungen bezahlen, bei einer Komposit-Füllung müsste ich ca. 80 € zuzahlen. Ich würde eigentlich gerne mit der für die konkrete Situation am besten passendsten (und gleichzeitig noch wirtschaftlichen) Methode behandelt werden, und nicht von vornherein eine ausschließen, weil der behandelnde Arzt die grundsätzlich nicht mehr anwendet. Und Zementfüllungen sind reine Behelfsfüllungen und nicht als Dauerlösung gedacht. Sowas allen Ernstes vorzuschlagen, grenzt schon an Unseriösität. Amalgam ist durchaus noch eine gebräuchliche Anwendungsmethode. Die Quecksilberbelastung tritt beim Anbringen der Füllung auf und bewegt sich in der Größenordnung, die man eh über die Nahrung zu sich nimmt. Was aus der fertigen Legierung (falls überhaupt …) noch austritt, dürfte Größenordnungen darunter liegen … Eine positive Eigenschaft von Amalgam ist, dass es sich beim Abbinden der Legierung ausdehnt und damit fest sitzt, wohingegen sich Kunststofffüllungen bei der Polymerisation zusammenziehen (was das Anbringen handwerklich aufwendiger macht). Es soll zwar auch Fälle geben, bei denen man die Ausdehnung von Amalgam vermeiden möchte, weil die den Zahn sprengen kann, aber das dürften wohl seltene Ausnahmen sein. Jedenfalls ein schönes Beispiel, wie sinnvolle Werkstoffe und Behandlungsmethoden verteufelt werden und daher nicht mehr in Frage kommen … Ich frage mich ja, ob ein Zahnarzt mit Kassenzulassung die Behandlung mit Amalgam (eine Kassenleistung!) überhaupt grundsätzlich verweigern darf. Wenn das tatsächlich unter “Therapiefreiheit” fällt, gerät das Sachleistungsprinzip zur Farce …

Bei der Behandlung selbst gab es dann erstmal Computerprobleme beim Aufrufen des Röntgenbildes. Das lag wohl auf einem Server, der noch nicht hochgefahren war, lol … Los ging es mit einer örtlichen Betäubung. Spätestens an der Stelle hätte ich mir ja schon eine genauere Information über den Behandlungsablauf gewünscht. Und ist so eine Betäubungsspritze eigentlich komplett risikolos? Ich hab, bevor ich lauter Zeugs in den Mund gestopft bekam, zumindest noch gefragt, wie lange das eigentliche Bohren dauert – “wenige Minuten” war die Antwort. Zuerst wurde an meinen Zähnen rumpoliert, eine Metallklammer und ein Keil angebracht, und weiter poliert. Gemerkt habe ich kaum was, erst als wirklich gebohrt wurde, hab ich (am Geräusch) gemerkt, dass das vorher ja noch nicht das Bohren war … Das Bohren selbst ging auch fix – aber danach wäre auch eine Information, dass jetzt “nur noch” die Füllung reinkommt, toll gewesen … Das hat nämlich (mit mehreren Schichten Kunststoff, die jeweils einzeln gehärtet wurden), auch noch mal eine Weile gedauert. Was mich auch noch interessiert hätte, wie groß diese Füllung eigentlich ist. Gehört IMO zwingend zur Aufklärung über die Behandlung, denn es macht ja schon einen Unterschied, ob das Loch einen mm groß ist oder der halbe Zahn entfernt wird …

Fazit: Ihr Handwerk dürften die meisten Ärzte ja durchaus verstehen. Aber darin, den Patienten angemessen zu informieren und “mitzunehmen”, besteht erheblicher Nachholbedarf …

Zum Konzept für die politische Meinungsbildung

Schon vor einigen Monaten (“um 15:49″ – vermutlich am 13. Juni 2011) hat unsere politische Geschäftsführerin einen Entwurf eines Konzeptes für die politische Meinungsbildung zur Diskussion gestellt. Sie selbst betont, dass alles zur Diskussion steht und einige wichtige Fragen noch offen sind. Also versuche ich mich mal an einer Stellungnahme.

Zunächst zur Einleitung: Das Ziel des Konzeptes finde ich etwas unstrukturiert dargestellt. Etwas versteckt ist ein Punkt, der mir besonders wichtig erscheint: Jeder “soll die Möglichkeit haben, eine ganzheitliche Meinung darzustellen” (Hervorhebung hinzugefügt). Dieser Punkt kommt auch bei der Unterscheidung zwischen Diskussion und Debatte wieder vor: Als Diskussion bezeichnet Marina, wenn sich die Teilnehmer “gegenseitig ihre Argumente zerlegen”, während die Debatte “anze Meinungen in Betracht” zieht. Das halte ich auch für wesentlich, damit die Meinungsbildung vorankommt. Aber natürlich ist es anstrengender, ganzheitlich andere Meinungen zu kritisieren und seine eigene Meinung darzustellen, als nur einzelne Argumente als Strohmann anzugreifen, und selbst nur einzelne Argumente zu bringen, wie es halt gerade am besten passt. Allerdings erfordert das eine ehrliche Argumentationstechnik und Darstellung der eigenen Argumentation. Wenn das nicht vorliegt, erkennt man es nicht unbedingt gleich – IMO funktioniert das daher am besten mit nicht-synchroner Kommunikation. Denn wer differenziert argumentiert, wird dabei immer langsamer sein als der, der seine Meinung apodiktischer darstellt.

Das Konzept beginnt in Schritt 1 mit dem Ist-Zustand: Diskussionen und Meinungsäußerungen erfolgen über unterschiedlichste Medien, die einzelnen Meinungen ähneln sich, sind aber jeweils leicht unterschiedlich. Hier fehlt mir die deutlich unterschiedliche Qualität bzw. Differenziertheit (und damit Länge) von Meinungsäußerungen. Vielleicht sollten die Buchstaben auch noch unterschiedliche Größe haben (wobei die kleineren Buchstaben in der Regel auch schnörkelloser sein werden …).

Die Überschrift von Schritt 2 lautet “Wiki”, die daneben befindliche Abbildung legt nahe, dass Kongresse, Mumble, AGs und Stammtische ähnliche Meinungen (Meinungsäußerungen?) bündeln. Der Zusammenhang zwischen Überschrift und Abbildung erschließt sich mir nicht auf Anhieb. Ich hoffe, er wird im Abschnitt klarer …

Grundlage dieses Schrittes ist das Debattenportal, dass Meinungen “etwa” in dafür, dagegen, neutral “oder ähnlich” einteilt, oder in inhaltliche Kategorien (“Meinung A, Meinung B und Meinung C”) einteilt. Marina stellt dazu fest: “Dieser Schritt 2 funktioniert auch, wenn der Rest überhaupt nicht funktioniert.” Hier kann ich wiederum nicht zustimmen. Ich halte diese Einteilung für höchst subjektiv. Das gilt schon bei der Einteilung in dafür, dagegen, neutral, die ja auch Marina nur als eine Möglichkeit (“etwa”, “oder ähnlich”) darstellt. Aber auch, wenn wir diese drei Möglichkeiten mal als gegeben ansehen: Eine differenzierte Position wird der Autor vielleicht als neutral ansehen, der, der die Einteilung macht, wird sie aber mit seiner eigenen Position vergleichen und als negativ oder positiv einordnen. Noch schwieriger wird es bei den inhaltlichen Kategorien: Was sind hier überhaupt sinnvolle Kategorien? Wie formuliert man die Zusammenfassungen neutral? Welche Granularität sollen die Kategorien haben? Das sind sehr subjektive und inhaltliche Fragen, keine reine Verwaltungsarbeit. Um es mit Marinas eigenen Worten zu sagen: “‎Die Überführung zweier politischer Standpunkte in einen einzigen politischen Standpunkt ist eine politische und keine sozialpädagogische Aufgabe.” (für eine autorisierte Version dieses Zitats wäre ich dankbar). Vollkommen zustimmen (siehe auch oben) kann ich dagegen der Aussage, dass jeder die Gelegenheit haben muss, “eine Meinung mit allen Prämissen und Konsequenzen darzustellen, bevor jemand widersprechen darf”.

Das hier eine offene Frage ist, erkennt Marina aber auch selbst: “Eine der offenen Fragen ist, wie die Zusammenfassungen ablaufen sollen.” Wie dargelegt, bin ich aber der Aufassung, dass es schon eine offene Frage ist, wie die Einteilung gemacht wird. Sie schlägt vor, dass man hier gründlich nachdenken muss, um Akzeptanz zu schaffen. Ich frage: Warum? Können wir hier nicht auch konkurrierende Zusammenfassungen (und Einteilungen, siehe oben) haben? Hier sehe ich auch einen Bezug zu dem Titelbild dieses Abschnitts, der im Text nicht aufgegriffen wurde: Dort tauchen (neben anderen Foren) Stammtische auf, die Positionen zusammenführen sollen. Aber es gibt ja nicht nur einen Stammtisch, also ist diese Konkurrenzsituation hier immanent.

Aber ich nehme jetzt einfach mal als gegeben an, dass wir irgendwie zu halbwegs trennscharfen Positionen kommen, denn das ist die Voraussetzung für den nächsten Schritt. Dass es hier offene Fragen gibt, er kennt ja auch Marina an.

Als Schritt 3 sieht Marina Liquid Feedback: “Einen in sich relativ konsistenten Antrag verfeinern, verbessern und mehrheitsfähig machen, das kann es super.” Dieser Abschnitt ist recht knapp gehalten und wäre sicher eine vertiefte Darstellung wert. So kaufe ich das jedenfalls nicht – ich habe LQFB leider bisher nur ziemlich unkonstruktiv erlebt … In Schritt 4 werden dann gut ausgearbeitete und konkurrierende Anträge auf einem Parteitag zur Abstimmung gestellt. So weit, so gut und folgerichtig.

Am Ende geht der Artikel dann noch auf Kritikpunkte ein. Einige davon sind für mich persönlich nicht relevant, andere greifen oben schon behandelte offene Fragen (“Wer darf sortieren? Was gilt als Debattenbeitrag?”) auf.

Mein Fazit: Das Konzept bietet eine erste Struktur für den Ablauf der politischen Meinungsbildung. Allerdings habe ich insbesondere bei Schritt 2 Zweifel, ob er — unter Erfüllung der definierten Ziele — operationalisierbar ist. Ich vermute aber, dass es dafür (unter dem Stichwort “peer production” schon einiges an Forschungsansätzen gibt … Aber vielleicht ist Ausprobieren wirklich eine gute Idee. Bis jetzt gibt es das Debattenportal allerdings offenbar noch nicht.

IKEA-Bilderrätsel: FAKTUM-Wandschränke (Korpus)

Regelmäßig ärgere ich mich über die Bilderrätsel von IKEA. Die enthalten zwar in der Tat die meisten Sachen, auf die man achten muss. Bloß worauf man hätte achten müssen, und woran das im Bild zu erkennen gewesen wäre, merkt man meist erst, wenn man etwas falsch gemacht hat.

Wie heißt es doch so schön: 1000 Worte sagen mehr als ein Dutzend Bilder. Insbesondere ist Sprache insbesondere dann direkter verständlich, wenn es darum geht, auf verschiedenen Abstraktionsniveaus wichtige Fakten zu vermitteln. Bei Bildern führt das in der Regel zu regelrechten “Bildersprachen” – bloß dass bei IKEA die Leseanleitung fehlt (anders als beispielsweise bei Bebauungsplänen, wo es die Planzeichenverordnung gibt. Da hat man wenigstens verstanden, dass solche Pläne ab einer gewissen Faktendichte alles andere als intuitiv sind).

Und ich bin mir ziemlich sicher, dass es auch bei IKEA einen Text bzw. eine Liste von Punkten gibt, worauf man achten muss. Der Ingenieur, der das weiß, ist ja vermutlich nicht derjenige, der die Bilder malt – also muss er das diesem irgendwie anders mitteilen. Zweckmäßigerweise also als Text, der damit schonmal in einer Sprache vorliegt. Und an der Stelle bricht dann der grenzenlose Geiz von IKEA durch. Die wenigen Euro (IMO vierstellig pro Anleitung), die eine kundengerechte Aufbereitung dieser Texte und eine Übersetzung kosten würde, will man sich natürlich sparen. Ebenso die wenigen Cent zusätzliche Druckkosten, wobei mir eine Anleitung im Internet vollends ausreichen würde.

Damit genug der Vorrede und des Lamentierens. Damit möchte ich es nämlich nicht belassen, sondern verschiedene IKEA-Anleitungen in normale Sprache übersetzen und dabei zugleich meine Erfahrung einfließen lassen.

Heute geht es los mit dem FAKTUM-Küchensystem, und zwar den Wandschränken, bzw. noch genauer deren Korpus (Türen, Scharniere und Griffe kommen erst noch …). Wie die meisten IKEA-Montageanleitungen gibt es auch diese Anleitung als PDF (959 kB).

Zuerst einige generelle Anmerkungen:

  • Die Anleitung gilt anscheinend für alle FAKTUM-Wandschränke. Jedenfalls war sie bei meinen Schränken in 40×92 cm, 60×70 cm und 80×92 cm jeweils identisch. Das führt dann natürlich auch dazu, dass die Abbildungen in der Regel nicht maßstabsgetreu sind, und auch die Zahl der Löcher für Einlegeböden etc. nicht unbedingt mit der Realität übereinstimmt.
  • Wie üblich, werden die Schränke mit Beschlägen, aber ohne Befestigungsmaterial geliefert. Es gilt der Rat: “Erkundigen Sie sich ggf. im Eisenwarenhandel.”, was ich auch gemacht habe. Die Anleitung weist jedenfalls darauf hin, dass der Kopf der Schrauben flach und nicht spitz zulaufend sein muss. Mir wurden 8/48-Universaldurchsteckdübel von Stabilit sowie 6,0×60-Spanplattenschrauben mit gelbem Kopf empfohlen, die auch gut funktioniert haben. Für Altbau gibt es ggf. noch bessere Dübel sowie Schrauben, die mehr Drehmoment vertragen, die man also fester ziehen kann.
  • Die Anleitung listet als Werkzeug einen Flachschlitzschraubenzieher, einen Kreuzschlitzschraubenzieher, einen Hammer, eine Schraubzwinge und eine Bohrmaschine auf. Der Flachschlitzschraubenzieher sollte recht breit sein – er dient für die runden Einsätze, mit denen die horizontalen Wände an den Seitenwänden festgezogen werden. Der Kreuzschlitzschraubenzieher sollte ganz normal groß sein, besonders viel Drehmoment braucht man da auch nicht. Als Hammer tut es auch irgendeiner – damit schlägt man die Holzstifte fest, außerdem die kleinen Nägel der Rückwand. Schraubzwinge und Bohrmaschine braucht man nur, wenn man zwei Schränke aneinander schrauben will.

Nun zu den einzelnen Schritten der Anleitung:

  1. Auf Seite 6 kommt zunächst eine Fallunterscheidung. Die ist deshalb nötig, weil man für die komplette Serie die gleiche Anleitung nimmt. Offebar gibt es Schränke, bei denen die Rückwand nicht den ganzen Schrank verschließt. Meine drei verschiedenen Modelle gehören aber offenbar nicht dazu, also geht es auf Seite 7 weiter. Zunächst richtet man die beiden Seitenwände am besten nebeneinander aus. Nach innen kommt die Seite mit der Einkerbung. Oben/unten sind die Wände übrigens symmetrisch. Innen liegt dann die Seite, die nachher hinten ist. Dort verläuft jeweils eine Reihe von Löchern für Einlegeböden. Jeweils an den oberen beiden Löchern (warum auch immer da noch ein weiteres Paar Löcher ist …) werden dann die Eckbeschläge montiert, und zwar mit den äußeren Löchern. Mit der Ecke liegen sie dann genau auf der Kante des Holzes auf.
  2. Dann werden 8 Schrauben montiert: Auf jedem Boden oben und unten sowie innen und außen – aber jeweils in das kleinere der beiden Löcher, das ist das, welches weiter innen liegt.
  3. In die anderen Löcher der linken Wand jetzt die Holzstifte einsetzen und mit dem Hammer leicht festschlagen. Dann die beiden anderen Böden (im fertigen Schrank oben und unten) auf die Holstifte und Schrauben setzen, und zwar mit den Löchern nach außen. Oben die restlichen Holzstifte in die größeren Löcher stecken und leicht festhämmern.
  4. Jetzt die rechte Seitenwand umdrehen und auf die Konstruktion aus linker Seitenwand und Böden legen. Leicht festklopfen. Die flachen “Schrauben” in die runden Löcher einsetzen, und zwar jeweils mit der Öffnung zu den dort herausstehenden Schrauben hin – unten also nach unten, oben nach oben. Mit dem Flachschlitzschraubenzieher festziehen (ca. eine halbe Umdrehung).
  5. Jetzt den Schrank nach links kippen, so dass die Beschläge (also die Rückseite des Schranks) nach oben zeigen. Die Rückwand einsetzen, und zwar mit der braunen Seite nach oben (also außen). Damit zeigt die weiße Seite nach innen.
    Die Rückwand zunächst nach oben rechts schieben und mit einem Nagel fixieren. Dabei darauf achten, dass der Nagel weit genug im inneren der Spanplatte sitzt und gerade eingeschlagen wird – sonst kommt er auf der Innen- oder Außenseite wieder raus, was extrem unschön aussieht. Mir wurde übrigens empfohlen, dass man auch kleine Schrauben (von ähnlicher Größe wie die Nägel) nehmen könne – im Gegensatz zur Befestigung mit Nägeln wäre das recht einfach reversibel.
  6. Jetzt die Rückwand nach unten rechts schieben und wieder mit einem Nagel fixieren.
  7. Dann nach unten schieben und unten links mit einem Nagel fixieren.
  8. Jetzt rundherum Nägel einschlagen. Eine Vorgabe für die Abstände gibt es nicht, 5-10 cm sollten passen. Die Zahl der Nägel in der Packung ist dafür auch kein Indikator – die ist bei kleinen und großen Schränken gleich …
  9. Ab diesem Schritt braucht man wirklich zwei Personen – es geht an die Wandmontage der Schränke. Zunächst das Anzeichnen. Eine Person hält den Schrank an die Wand, die andere stellt sich auf eine Leiter und zeichnet an. Wenn es um die absolute Höhe geht: Der Schrank rutscht bei der Montage eher noch runter, so dass die Schraube am oberen Rand des Loches des Beschlags liegt – das sollte man beim Anzeichnen bedenken (also eher oberhalb der Mitte anzeichnen bzw. bohren). Jetzt bohren (gemäß Anleitung der Dübel), Dübel einsetzen und die Schrauben bis auf ca. 1 cm festziehen. Dann den Schrank wieder an die Wand. Man kann ihn gleich “einhängen”, braucht ihn also während des Festziehens der Schrauben nicht unbedingt mit voller Kraft zu halten. Jetzt die kleinen Metallbeschläge aufsetzen, feinjustieren und festschrauben. Dabei darauf achten, dass sich die Beschläge nicht verdrehen. Danach kann man die weißen Abdeckkappen aufstecken. Schließlich könnte man benachbarte Schränke aneinander befestigen. Zwingend ist das aber nicht, und hat sich bei mir auch nicht ergeben.

Nun hat man also leere Schränke ohne Türen an der Wand hängen. Diesen Schritt beschreibe ich, sobald ich damit selbst durch bin.

Bilder mit GPS-Koordinaten versehen

Leider haben Consumer-Kameras ja noch kein GPS (meine Dezember 2009 gekaufte jedenfalls nicht). Aber wenn man ein Outdoor-GPS-Gerät sein eigen nennt, kann man das ja zum Glück recht einfach anderweitig erledigen. So ein Gerät (ich habe ein eTrex Vista HCx von Garmin) läuft mit 2 AA-Batterien ca. 20 Stunden, und man kann es einfach im Rucksack oder der Jackentasche mit sich rumtragen. Dabei zeichnet es jede Sekunde die Position in einer GPX-Datei (eine Datei pro Tag) auf Speicherkarte auf.

Prinzipiell täte es auch ein einfacher GPS-Logger (der dann deutlich kompakter ausfallen könnte), aber das Display ist ganz praktisch. Die Zeit auf der Kamera muss man ja in der Regel manuell einstellen — eine automatische Synchronisation mit GPS oder einer anderen Zeitnormalquelle haben die Dinger nicht. Das könnte man tun, man kann es aber genauso gut lassen. Denn so eine Uhr hat ja auch ein wenig Gangabweichung, beim nächsten Urlaub stimmt es dann schon wieder nicht. Eine Minute Abweichung ist jedenfalls (mir) zuviel, um mich für die GPS-Korrelation darauf zu verlassen.

An dieser Stelle kommt das Display des GPS-Empfängers ins Spiel: Man macht ab und zu (am Anfang und am Ende des Urlaubs beispielsweise …) Fotos von einer als zuverlässig bekannten Uhrzeitanzeige – dafür bietet sich die des GPS-Empfängers an (Beispiele hier und hier). Dann hat man die Kamerazeit (über EXIF-Daten) und die echte Zeit in einem Foto und kann somit die Differenz ermitteln.

Beispiel: Ich hatte zwei Fotos vom GPS-Empfänger gemacht:

  • Auf dem ersten Foto zeigte der GPS-Empfänger 12:04:40 Uhr am 30. Juli 2011 (Europe/Berlin, also MESZ). Nach Ortszeit (in diesem Fall Island, also erfreulicherweise gleichzeitig UTC – es entfällt also die schwierige Entscheidung, welche von beiden ich nehmen soll) ist das 10:04:40 Uhr. Die Zeit der Kamera war 11:06:09 (also vermutlich MEZ, ohne S) am 30. Juli 2010 (sic!). Um von der Kamerazeit auf die richtige Zeit zu kommen, muss man also ein Jahr hinzuzählen, 1 Stunde abziehen, 2 Minuten abziehen und 31 Sekunden hinzuziehen (bzw: 1:29 Minuten abziehen).
  • Auf dem zweiten Foto zeigte der GPS-Empfänger 13:13:10 Uhr am 2. August 2011 (MESZ). Nach Ortszeit/UTC ist das 11:13:10 Uhr. Die Zeit der Kamera war 12:14:38 (MEZ) am 2. August 2010 (sic!). Um von der Kamerazeit auf die richtige Zeit zu kommen, muss man also ein Jahr hinzuzählen, 1 Stunde abziehen, 2 Minuten abziehen und 28 Sekunden hinzuziehen (also 1:28 Minuten, und damit nur eine Sekunde Abweichung zum ersten Foto, die auch Rundungsfehlern geschuldet sein können).

Nachdem wir nun also wissen, wie wir die EXIF-Zeit justieren müssen, können wir diese Änderung umsetzen. Als Tool dafür benutze ich exiv2. Die relevanten Stellen der man-Page lauten:

Benutzung: exiv2 [ Optionen ] [ Aktionen ] Datei ...

Ändert die Exif-Metadaten von Bildern.

Aktionen:
ad | adjust ändert die Exif-Zeitstempel um eine gegebene Zeit. Diese
Aktion benötigt mindestens eine der Optionen -a, -Y, -O oder -D.
[...]

-a time Zeitjustierung im Format [-]HH[:MM[:SS]]. Diese Option wird
nur in Zusammenhang mit der Aktion 'Justieren' benutzt.
-Y yrs Justierung von Jahren in der Aktion "justieren".
-O mon Justierung der Monate in der Aktion 'justieren'.
-D day Jusitierung von tagen in der Aktion "Justierung".

In unserem Fall ergibt das:

exiv2 -Y 1 -a -01:01:28

In diesem Fall ist es herzlich egal, ob man nun -01:01:28 oder -01:01:29 schreibt. Bei größerem Drift sind natürlich ggf. andere Maßnahmen erforderlich. Interpolieren dürfte manuell leider etwas aufwendig werden.

Dieser Befehl muss natürlich auf alle Fotos angewendet werden. Bei mir haben diese die Endung .JPG (nicht .jpg!). Es ergibt sich folgender Befehl:

for i in *.JPG; do exiv2 -Y 1 -a -01:01:28 $i; done

Als nächstes kopiere ich die GPX-Tracks für die entsprechenden Tage ins selbe Verzeichnis wie die Bilder und rufe gpscorrelate-gui auf. Dort füge ich zunächst alle Fotos hinzu. Dort muss man nun leider jede GPX-Datei einzeln auswählen. “Interpolate”, ggf. “Between Segments” ankreuzen, “Correlate Photos” klicken – fertig.

Jetzt haben die Fotos GPS-Koordinaten in ihrem EXIF-Block. Bei Flickr und ähnlichen Diensten erscheinen sie dann in einer Karte (Achtung: Bei Flickr muss man das aus Datenschutzgründen in den Account-Einstellungen vor dem Hochladen aktivieren!).

3G in Island

Wenn ich im Ausland bin, vor allem, wenn es länger als nur ein paar Tage sind, habe ich gerne mobiles Internet via 3G/UMTS. Zum einen ist es sehr praktisch, unterwegs Karten zu haben und Infos über den Ort abrufen zu können, an dem man gerade ist. Und mit Status-Updates auf Google+ kann man auf die Schnelle die Daheimgebliebenen neidisch machen – dank Kamera und GPS im Smartphone. Auch bei eigentlich stationärem Einsatz ist das hilfreich – Internetzugang im Hotel ist oft kostenpflichtig, nur in bestimmten Bereichen (Lobby) verfügbar, oder es sind verschiedene Ports blockiert.

Also habe ich mich für Island nach einem entsprechenden Angebot umgeschaut und bin dabei auf Síminn gestoßen. Der Tarif ist recht preisgünstig, die Netzabdeckung soll gut sein (in dem Zusammenhang: Was ist eigentlich 3G Long Distance? Damit kriegt man wohl auch in der Pampa schnelle Verbindungen, jedenfalls, wenn kein Berg im Weg ist). Verkaufsstellen gibt es durchaus in jedem Ort, allerdings muss man es dorthin dann auch zu Öffnungszeiten schaffen. Rundreise durch die „Wildnis“, ein Feiertag, und recht eingeschränkte Öffnungszeiten (samstags erst ab 10 Uhr, beispielsweise) können einem da schonmal einen Strich durch die Rechnung machen.

Schließlich habe ich es zwei Tage vor Abreise doch noch geschafft, eine entsprechende SIM-Karte zu erwerben. Diese kostet 490 ISK und ist mit einem Startguthaben versehen, das für ca. 500 MB reicht. Im Prinzip ja ausreichend für den Einsatz im Urlaub – wenn nicht dummerweise der Thunderbird auf meinem Notebook auf die Idee gekommen wäre, einen IMAP-Ordner ausgerechnet jetzt zu synchronisieren. Damit war das Inklusivkontingent dann nach einem Tag aufgebraucht. Wie in der Anleitung erläutert wurde ich auch tatsächlich auf eine Seite weitergeleitet, wo ich per Kreditkarte ein 4GB- oder 8GB-Paket für 1990 bzw. 3990 ISK hätte kaufen können. Hätte – wenn die Seite denn eine meiner drei Kreditkarten akzeptiert hätte. Woran es lag, dass das nicht ging, weiß ich nicht. Jedenfalls habe ich hinterher vom Kundendienst noch folgende Auskunft bekommen:

You need to contact our customer support at 8007000. They will help you refill your credits via credit card.

- Leider erst, als ich das Land schon wieder verlassen hatte. Falls jemand ebenfalls Probleme mit der Kreditkartenzahlung hat, kann er das ja mal ausprobieren, und ggf. hier berichten, ob es geklappt hat.

Thunderbird-Addons: Optionen

Heute schauen wir uns, wieder am Beispiel von Quicker Filer 0.5.1, an, wie man in einem Thunderbird-Addon Einstellungen benutzt, die als Preferences persistiert werden.

In der install.rdf heißt es:

[sourcecode language="xml"]
<em:optionsURL>chrome://quickerfiler/content/options.xul</em:optionsURL>
[/sourcecode]

Damit wird ein Einstellungsdialog definiert. Standardmäßig wird dieser als Dialogfenster geöffnet. Über die Definition des Content Packages in der chrome.manifest (vgl. dieses Posting) ergibt sich also, dass der Dialog in content/options.xul definiert ist.

Gehen wir das also der Reihe nach durch.

[sourcecode language="xml"]
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
[/sourcecode]

Hier wird ein Stylesheet eingebunden, und zwar ein recht generisches.

[sourcecode language="xml"]
<prefwindow id="quickerfilerPrefWindow" title="Quicker Filer – Options" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
buttons="accept,cancel" height="550">
[/sourcecode]

Das Fenster ist ein prefwindow, also speziell für Einstellungsdialoge vorgesehen. Es gibt weiterführende Dokumentation, die aber bis auf ein Beispiel und einen Hinweis, wie man so ein Fenster aufruft, keine wesentlichen Infos enthält. Also gehen wir weiter unsere Datei im Detail durch.

Zwei der Attribute sind selbsterklärend: title definiert den Fenstertitel und height setzt die bevorzugte Höhe des Fensters in Pixeln. buttons definiert, welche Schaltflächen angezeigt werden, hier also OK und Abbrechen. Das dürfte üblicherweise eine gute Wahl sein.

[sourcecode language="xml"]
<script type="application/x-javascript" src="chrome://quickerfiler/content/options.js"/>
[/sourcecode]

Hier wird ein Script eingebunden. Es definiert einigige Funktionen, die dann in Event-Handlern aufgerufen werden – dazu also unten mehr.

[sourcecode language="xml"]
<prefpane id="quickerfilerOptions.general.prefpane" label="General" selected="true">
[/sourcecode]

Eine prefpane ist ein Panel, also wohl eine Seite, mit Einstellungen. Der Inhalt kann entweder aus einer gesonderten .xul-Datei geladen oder – wie hier – inline definiert werden.

label definiert eine Beschriftung. Ob es tatsächlich vorgesehen ist, selected direkt zu setzen, bezweifle ich gerade ein wenig …

[sourcecode language="xml"]
<preferences>
<preference id="extensions.quickerfiler.defaultfolder.text" name="extensions.quickerfiler.defaultfolder.text" type="string"/>
<preference id="extensions.quickerfiler.search.root" name="extensions.quickerfiler.search.root" type="string"/>
<preference id="extensions.quickerfiler.search.root.account" name="extensions.quickerfiler.search.root.account" type="string"/>
<preference id="extensions.quickerfiler.search.root.folder.text" name="extensions.quickerfiler.search.root.folder.text" type="string"/>
<preference id="extensions.quickerfiler.mkdir.enable" name="extensions.quickerfiler.mkdir.enable" type="bool"/>
<preference id="extensions.quickerfiler.debug.enable" name="extensions.quickerfiler.debug.enable" type="bool"/>
<preference id="extensions.quickerfiler.suggestlastfolder.enable" name="extensions.quickerfiler.suggestlastfolder.enable" type="bool"/>
<preference id="extensions.quickerfiler.copysentmessage.enable" name="extensions.quickerfiler.copysentmessage.enable" type="bool"/>
</preferences>
[/sourcecode]

Dieser Block beschreibt die Einstellungen, die in der prefpane geändert werden. Er besteht aus einzelnen preference-Elementen.

Die Attribute sind wieder recht selbsterklärend. name setzt den Namen der zu ändernden Einstellung (hier zweckmäßigerweise identisch zur ID des jeweiligen Elements), type legt fest, von welchem Typ der Wert ist.

[sourcecode language="xml"]
<vbox>
[/sourcecode]

Die vbox dient der Gliederung bzw. Layout-Zwecken.

[sourcecode language="xml"]
<groupbox>
<caption label="Default folder"/>
<description>Default folder for instant copy/move</description>
<textbox id="quickerfiler.defaultfolder.textbox"
preference="extensions.quickerfiler.defaultfolder.text"
type="autocomplete"
autocompletesearch="quickerfiler-autocomplete"
tabScrolling="true"
autoFill="true"
forceComplete="true"
showcommentcolumn="false" />
</groupbox>
[/sourcecode]

Die groupbox dient der Gruppierung von Elementen und wird in der Regel mit Umriss gezeichnet. Die caption wird in diesem Umnriss gezeichnet. Die description ist ein Textblock, der einfach angezeigt wird.

Die textbox kann Auto-Vervollständigung und entspricht der im letzten Artikel schon genauer erklärten. Genaueres also dort, und die Erläuterung, wie Auto-Vervollständigung im Hintergrund funktioniert, schieben wir immer noch nach hinten.

[sourcecode language="xml"]
<groupbox>
<caption label="Search Root"/>
<description>Determines the scope of the folder list</description>
<radiogroup id="quickerfiler.search.root.radiogroup"
preference="extensions.quickerfiler.search.root">
[/sourcecode]

Es folgt eine weitere groupbox mit caption und description. radiogroup definiert eine Gruppe von Radio-Buttons. Es ist die zugehörige preference angegeben. Wohlgemerkt verweist der Wert auf die ID des entsprechenden preference-Elements!

[sourcecode language="xml"]
<radio id="quickerfiler.search.root.allfolders.radio"
label="All folders"
value="msgaccounts:/"/>
[/sourcecode]

Hier wird ein einzelner Radio-Button definiert. Die Dokumentation weiß anscheinend nicht so recht, dass das value-Attribut im Zusammenhang mit Preferences eine feste Bedeutung hat. Vermutlich sollte man das mal explizit dokumentieren. label definiert die Beschriftung des Radio-Buttons.

[sourcecode language="xml"]
<hbox>
<radio id="quickerfiler.search.root.account.radio"
label="This account"
value="– account –"/>

<hbox flex="1" pack="end">
[/sourcecode]

Hier wird es layouttechnisch interessant. Der Radio-Button wird zusammen mit der menulist in eine hbox gesteckt. Die menulist wird nochmal in eine eigene hbox gesteckt, bei der zwei Attribute gesetzt sind. flex="1" sorgt dafür, dass sie sämtlichen freien Platz verbraucht. pack="end" lässt die menulist nach rechts rutschen. Was mir hier nicht klar ist:

  • Warum ist pack="end" noch nötig, wenn flex="1" angegeben ist? Wie kann in dem Fall noch Platz übrig sein?
  • Warum ist die menulist nochmal in eine hbox verpackt? Man könnte diese Attribute auch auf der menulist spezifizieren. Erzielt das ggf. auch den gewünscht Effekt? Wenn nein, warum nicht? Wenn ja, warum sollte man es so wie hier machen?

[sourcecode language="xml"]
<menulist id="quickerfiler.search.root.account.menulist"
preference="extensions.quickerfiler.search.root.account"
sortResource="http://home.netscape.com/NC-rdf#Name"
sortDirection="ascending"
datasources="rdf:msgaccountmanager rdf:mailnewsfolders"
containment="http://home.netscape.com/NC-rdf#child"
ref="msgaccounts:/" flex="1">
[/sourcecode]

menulist definiert eine Dropdown-Auswahlliste. preference legt wieder fest, welche Einstellung gesetzt wird. flex="1" (nochmal!) sorgt dafür, dass die menulist die komplette Breite ausfüllt.

Die restlichen Attribute (sortResource, sortDirection, datasources, containment, ref) beziehen sich darauf, wie man den Inhalt der Liste dynamisch aus einer RDF-Datenquelle zusammenstellen lässt.

Dazu dient auch das darauffolgende template:

[sourcecode language="xml"]
<template xmlns:nc="http://home.netscape.com/NC-rdf#">
<rule nc:ServerType="nntp"/>
<rule nc:IsDeferred="true"/>
<rule nc:IsServer="true">
<menupopup>
<menuitem uri="…"
value="…"
label="rdf:http://home.netscape.com/NC-rdf#Name"/>
</menupopup>
</rule>
</template>
[/sourcecode]

Dafür gibt es eine eigene Anleitung, und jemanden, der das alles für großen Schrott hält.

Insofern verschieben wir das lieber auf später – bis ich rausgefunden habe, ob das überhaupt etwas taugt. Jedenfalls erstellt das Template wohl ein menupopup mit vielen menuitems – aber ich verstehe schon nicht, warum/ob da nur ein menupopup, aber mehrere menuitems rauskommen …

Danach wird es zum Glück erstmal unspannend – daran merkt man, dass etwas hängen bleibt … Es werden einige noch offene Elemente geschlossen, und dann kommt eine weitere Radiobox, verbunden mit der Möglichkeit, einen Ordner auszuwählen . Hier kommt wieder die altbekannte Textbox mit Autovervollständigen zum Einsatz. So weit unproblematisch, aber da ist eine Sache, der ich noch auf den Grund gehen muss: In den Einstellungen wird definiert, was die Wurzel für die Suche nach Ordnern ist – es wäre aber unschön, wenn diese Einstellung auch bei der Festlegung der Wurzel zum Tragen kommt. Ich muss dementsprechend mal ergründen, warum sie es nicht tut – bzw., ob sie es vielleicht doch tut – das wäre dann wohl ein Bug.

Danach geht es auch relativ unspannend weiter:

[sourcecode language="xml"]
<groupbox>
<caption label="Suggest last folder"/>
<description>Search box fill be filled with the last transfer folder used</description>
<checkbox label="Suggest last folder" preference="extensions.quickerfiler.suggestlastfolder.enable"/>
</groupbox>
[/sourcecode]

Hier kommt zum ersten Mal eine checkbox vor. Die hat ein label und ist an eine bestimmte preference gebunden – alles easy. Danach kommen noch weitere checkboxes, die ich wiederum überspringe. Interessant ist in dem Zusammenhang nur die Entdeckung der Einstellung quickerfiler.debug.enable. Unter Linux habe ich nämlich Probleme – vielleicht hilft das ja beim Debuggen.

Jedenfalls ist damit:
[sourcecode language="xml"]
</prefpane>
[/sourcecode]

die erste Seite der Einstellungen fertig. Es folgt die zur Festlegung der Tastenkombinationen.

[sourcecode language="xml"]
<prefpane id="quickerfilerOptions.shortcuts.prefpane"
label="Keyboard Shortcut"
onpaneload="sQuickerFilerOptions.onPaneLoad();">
<preferences>
<preference id="extensions.quickerfiler.shortcuts.copy.key"
name="extensions.quickerfiler.shortcuts.copy.key"
type="string"/>

<!– … –>

<preference id="extensions.quickerfiler.shortcuts.selfolder.modifiers"
name="extensions.quickerfiler.shortcuts.selfolder.modifiers"
type="string"/>
</preferences>
[/sourcecode]

Zu Beginn wird wieder definiert, welche Einstellungen auf dieser Seite geändert werden können. Für diverse Aktionen (copy, move, inscopy, insmove, selfolder) wird jeweils eine Einstellung key und eine Einstellung modifiers. Aus Gründen ist das etwas gekürzt.

onpaneload definiert, dass beim Laden der Seite folgende Funktion ausgeführt wird:

[sourcecode language="javascript"]
onPaneLoad: function onPaneLoad()
{
this.updateTreeView();
},
[/sourcecode]

Die Funktion updateTreeView() füllt anscheinend einen Treeview anhand der Einstellungen mit den bis jetzt definierten Tastenkürzeln. Die genaue Funktionsweise schaue ich mir an, sobald ich die UI-Elemente selbst angeschaut habe.

In einer vbox folgt dann folgende groupbox:

[sourcecode language="xml"]
<groupbox>
<caption label="Available shortcuts"/>

<tree id="quickerfilerOptions.shortcuts.availableShortcutsTree"
onselect="sQuickerFilerOptions.onAvailableShortcutsTreeSelect();"
rows="5" hidecolumnpicker="true" seltype="single">

<treecols>
<treecol id="nameColumn" label="Name" flex="1"/>
<treecol id="shortcutColumn" label="Shortcut" flex="2"/>
</treecols>
[/sourcecode]

Bis hierhin wurde ersteinmal die Struktur des Baums definiert. Das Hauptelement ist ein tree. onselect wird ausgeführt, wenn eine Zeile im Baum ausgewählt wird. Hier werden wohl die Controls für die Auswahl der Tastenkombination für die entsprechende Aktion gesetzt. Genaueres dann unten, wenn wir uns anschauen, wie der Inhalt aufgebaut ist und initialisiert wird. rows gibt an, wieviele Zeilen gleichzeitig angezeigt werden. Das ist hier gerade die Anzahl der insgesamt existierenden Zeilen. seltype="single" bedeutet, dass es nicht möglich ist, mehrere Zeilen auf einmal auszuwählen. hidecolumnpicker="true" schließlich blendet das “Menü” zum Anzeigen und Verstecken einzelner Spalten aus. treecols enthält einzelne treecol-Elemente. Deren label-Attribut legt die Spaltenüberschrift fest.

trees sind im übrigen keine triviale Angelegenheit, weshalb es dazu auch ein Tutorial gibt. Im allgemeinen Fall können sie aus beliebigen Datenquellen mit großen Datenmengen dynamisch befüllt werden – beispielsweise die Nachrichten in einer Newsgroup. Diese Datenquellen heißen tree views. Netterweise gibt es auch einen vordefinierten treeview, bei dem die Daten aus XUL-Elementen kommen. Das nennt sich dann content tree. Was man dabei beachten muss: Dadurch, dass die Daten durch einen tree view geschleift werden, ist man nicht sehr flexibel, was man hier angeben kann. Es können wirklich nur für jede Tabellenzelle ein Text und ein Icon angegeben werden. Wie es das Tutorial ausdrückt:

Having said that the data to be displayed in a tree comes from a view and not from XUL tags, there happens to be a built-in tree view which gets its data from XUL tags.

Der Rest ist dann unspektakulär:

[sourcecode language="xml"]
<treechildren>
<treeitem>
<treerow>
<treecell label="Copy" value="copy"/>
<treecell label="disabled"/>
</treerow>
</treeitem>
<!– vier weitere <treeitem>-Elemente für die anderen Aktionen –>
</treechildren>
</tree>
</groupbox>
[/sourcecode]

Das Hauptelement ist treechildren. Dazu sagt die Doku:

This element is the body of the tree. For content trees, the content will be placed inside this element. This element is also used to define container rows in the tree.

Zum Glück haben wir einen content tree. Wie der Inhalt sonst definiert wird, oder was container rows sein sollen, steht da nämlich leider nicht.

Darin sind dann fünf treeitems, die jeweils eine treerow enthalten. Darin wiederum ist dann jeweils eine treecell pro Spalte. Dabei ist jeweils das Attribut label gesetzt, und in der linken Spalte noch value, offenbar zum Wiederfinden aus Scripts.

Und mit den oben noch zurückgestellten Scripts machen wir jetzt auch weiter. Zuerst die Funktion updateTreeView(), die (unter anderem) beim Laden der Pane ausgeführt wird:

[sourcecode language="javascript"]
updateTreeView: function updateTreeView()
{
var tree = document.getElementById(‘quickerfilerOptions.shortcuts.availableShortcutsTree’);
var rowCount = tree.view.rowCount;

for(var i = 0; i<rowCount; i++)
{
var shortcut = tree.view.getCellValue(i, tree.columns[0]);
var key = document.getElementById(‘extensions.quickerfiler.shortcuts.’+shortcut+’.key’).value;
var modifiers = document.getElementById(‘extensions.quickerfiler.shortcuts.’+shortcut+’.modifiers’).value;

if(key != undefined && key != ”)
{
var text = "";
if(modifiers)
text = modifiers.toUpperCase().split(‘ ‘).sort().join(‘ + ‘);
if(text)
text += ‘ + ‘;
text += key.toUpperCase();

tree.view.setCellText(i, tree.columns[1], text);
}
else
{
tree.view.setCellText(i, tree.columns[1], ‘disabled’);
}
}
}
[/sourcecode]

Diese Funktion holt sich zunächst das
-Element und geht alle Tabellenzeilen durch: Die Variable shortcut wird auf den value der Tabellenzelle in der ersten Spalte gesetzt. Dieses Attribut dient also, wie oben vermutet, nur dem “Wiedererkennen”. key und modifiers werden auf den Wert der entsprechenden Preferences gesetzt (ausgelesen aus den jeweiligen preference-Elementen). Falls diese Werte sinnvoll sind, wird daraus ein String zusammengebastelt, der dann in der zweiten Tabellenspalte angezeigt wird.

Interessant dürften noch die aufgerufenen Methoden (und benutzten Eigenschaften) des tree view (tree.view) sein, die im Interface nsITreeView definiert sind:

Ebenfalls bereits bemerkt hatten wir die Funktion onAvailableShortcutsTreeSelect. Die stellen wir auch weiterhin zurück, da sie Elemente bearbeitet, die wir noch nicht angeschaut haben.

In options.xul kommt nun eine weitere groupbox:

[sourcecode language="xml"]
<groupbox id="quickerfilerOptions.shortcuts.settingsGroupbox" hidden="true">
<caption label="Shortcut Settings"/>
<description>These settings apply to the selected shortcut above</description>

<hbox>
<vbox>
<groupbox>
<caption label="Key"/>

<menulist id="quickerfilerOptions.shortcuts.shortcutKey"
oncommand="sQuickerFilerOptions.onShortcutKeyMenulistCommand();">
<menupopup>
<menuitem value="" label="disabled"/>

<menuitem value="A" label="A"/>
<!– … –>
<menuitem value="Z" label="Z"/>

<menuitem value="/" label="/"/>
<!– … –>
<menuitem value="]" label="]"/>
</menupopup>
</menulist>
</groupbox>
</vbox>

<groupbox flex="1">
<caption label="Modifiers"/>

<checkbox id="quickerfilerOptions.shortcuts.shortcutModifier.accel"
label="Accel"
value="accel"
oncommand="sQuickerFilerOptions.onShortcutModifierCommand();"/>
<!– und dasselbe für alt, control, meta und shift –>
</groupbox>
</hbox>
</groupbox>
[/sourcecode]

Zu beachten ist, dass diese groupbox anfangs versteckt ist (hidden="true")! Sichtbar gemacht wird sie per Script (siehe unten), sobald im Treeview ein Befehl ausgewählt wird. Die eigentlichen Controls sind dann eine Dropdown-Liste (menulist), die alle möglichen Tasten enthält, und checkboxes für die verschiedenen Modifier. Das ist jetzt hinreichend langweilig, dass es der geneigte Leser gerne eigenständig in der Dokumentation nachlesen darf. Für Veränderungen sind Event-Listener definiert, auf die ich später noch eingehe. Damit ist die Beschreibung des Fensters dann auch schon zu Ende.

Jetzt also die Funktion, die ausgeführt wird, wenn man ein Kommando auswählt, um dafür ein Tastenkürzel zu vergeben:

[sourcecode language="javascript"]
onAvailableShortcutsTreeSelect: function onAvailableShortcutsTreeSelect()
{
var tree = document.getElementById(‘quickerfilerOptions.shortcuts.availableShortcutsTree’);
var shortcut = tree.view.getCellValue(tree.currentIndex, tree.columns[0]);

var keyEl = document.getElementById(‘extensions.quickerfiler.shortcuts.’+shortcut+’.key’);
var key = "";
var modifiers = "";
if(keyEl!=null)
{
key = keyEl.value;
if(key==null)
key = "";
else
modifiers = document.getElementById(‘extensions.quickerfiler.shortcuts.’+shortcut+’.modifiers’).value;
}

document.getElementById(‘quickerfilerOptions.shortcuts.settingsGroupbox’).hidden = false;
document.getElementById(‘quickerfilerOptions.shortcuts.shortcutKey’).value = key.toUpperCase();

for(var i in this.mModifiers)
{
document.getElementById(‘quickerfilerOptions.shortcuts.shortcutModifier.’+this.mModifiers[i]).checked = (modifiers.indexOf(this.mModifiers[i])>-1)
}

this.updateTreeView();
}
[/sourcecode]

Zunächst wird die aktuell ausgewählte Zeile der treelist bestimmt (tree.currentIndex). Diese Eigenschaft funktioniert nur bei seltype="single", aber das ist hier ja gesetzt. keyEl wird dann auf das preference-Element gesetzt. Ggf. werden aus diesem und dem für die Modifiers die entsprechenden Werte ausgelesen. Dann wird die groupbox angezeigt (hidden wird auf false gesetzt), der passende Eintrag der menulist wird selektiert, und die Chechboxes der entsprechenden Modifiers ggf. angekreuzt.

Bleiben noch die zwei Event-Listener, die auf Veränderungen an diesen Elementen reagieren:

[sourcecode language="javascript"]
onShortcutKeyMenulistCommand: function onShortcutKeyMenulistCommand()
{
// User selected another shortcut key from the pop up menu,
// set this as new shortcut key for the current selected command:
var tree = document.getElementById(‘quickerfilerOptions.shortcuts.availableShortcutsTree’)
var shortcut = tree.view.getCellValue(tree.currentIndex, tree.columns[0]);

document.getElementById(‘extensions.quickerfiler.shortcuts.’ + shortcut + ‘.key’).value =
document.getElementById(‘quickerfilerOptions.shortcuts.shortcutKey’).value;

this.updateTreeView();
}
[/sourcecode]

Eigentlich recht selbsterklärend: Wenn eine andere Taste ausgewählt wurde, wird die entsprechende preference gesetzt. updateTreeView() setzt dann für alle Zeilen des treeview die Werte neu (was im Grunde Overkill ist – aber immerhin bleiben die Zeilen an sich erhalten – sonst ginge bestimmt auch der Fokus verloren).

[sourcecode language="javascript"]
onShortcutModifierCommand: function onShortcutModifierCommand()
{
var tree = document.getElementById(‘quickerfilerOptions.shortcuts.availableShortcutsTree’);
var shortcut = tree.view.getCellValue(tree.currentIndex, tree.columns[0]);

var modifiers = [];
for(var i in this.mModifiers)
{
if(document.getElementById(‘quickerfilerOptions.shortcuts.shortcutModifier.’+this.mModifiers[i]).checked)
modifiers.push(this.mModifiers[i]);
}

document.getElementById(‘extensions.quickerfiler.shortcuts.’+shortcut+’.modifiers’).value = modifiers.join(‘ ‘);

this.updateTreeView();
}
[/sourcecode]

Auch das ist wieder selbsterklärend: Wenn sich ein Modifier geändert hat, wird die komplette Liste wieder erstellt und in der Preference gespeichert, danach werden die Werte des treelist neu gesetzt.

Damit wären wir auch am Ende dieses Teils unseres kleinen Kurses. Zum Lernen ist dieses Beispiel ja ganz nett – aber um einfach nur eine Tastenkombination zu setzen, ist das doch ziemlich viel Aufwand. Schöner wäre ein eigenes XUL-Control, bei dem man die Tastenkombination einfach eintippen kann. Daher habe ich das in Bug 673669 vorgeschlagen.

Und wieder der obligatorische Hinweis: Code-Schnipsel stammen aus Quicker Filer 0.5.1, sind Copyright (C) 2010 Eivind Rovik und stehen unter GPL (Version 3 oder jede spätere Version).

Properties in Tomcat

Wenn man danach sucht, wie man Properties in Webapps bzw. Servlets lädt, findet man viel Unsinn, bzw. nicht richtig durchdachte oder unvollständige Lösungen. Das hier ist daher ein Versuch, für mich selbst mal einen funktionierenden Ansatz zusammenzuschreiben.

Ausgangspunkt war dieser Blog-Eintrag. Zum Zugriff auf eine Properties-Datei wird dort folgender Code verwendet:

[sourcecode language="java"]
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("myApp.properties");
Properties properties = new Properties();
properties.load(inputStream);
[/sourcecode]

So weit, so gut. OK, das Laden von Konfiguration über einen Classloader erscheint auf den ersten Blick merkwürdig. Aber sei es drum …

Bloß: Wo lege ich die Konfigurationsdatei jetzt ab, so dass sie auch gefunden wird? Im WAR/AAR jedenfalls nicht – ich will diese Archive ja nicht neu packen, bloß weil sich (Deployment-spezifische) Einstellungen ändern. Ein anderes Blog brachte dann eine Lösung, jedenfalls für Tomcat: Man soll den shared class loader benutzen. Also habe ich meine Datei in $CATALINA_HOME/shared/classes angelegt. Schnell noch die Property shared.loader in conf/catalina.properties angepasst … Doch halt: Die ist schon da und ist leer, was laut Kommentar heißt, dass in $CATALINA_HOME/shared gesucht wird. Für mein Empfinden ist das etwas anderes als $CATALINA_HOME/shared/classes. Naja, egal. Ich hatte keine Lust auf weiteres Ausprobieren und habe die Property einfach neu gesetzt:

[sourcecode]
shared.loader=${catalina.home}/shared/classes
[/sourcecode]

Das tut jetzt sowohl für Webapps/Servlets als auch für Axis2-Webservices. Prima.

Thunderbird-Addons: Chrome-Manifest, XUL-Overlays

Und weiter geht es da, wo der letzte Teil aufgehört hat: Was steht eigentlich in diesem Chrome Registration Manifest so drin? Beispiel ist wieder Quicker Filer 0.5.1. Die chrome.manifest sieht dort so aus:

[sourcecode]
content quickerfiler content/

overlay chrome://messenger/content/messenger.xul chrome://quickerfiler/content/messengeroverlay.xul
overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://quickerfiler/content/messengercomposeoverlay.xul

component {1C28D908-9DD7-11E0-B67F-DCD94724019B} components/quickerfilerautocomplete.js
contract @mozilla.org/autocomplete/search;1?name=quickerfiler-autocomplete {1C28D908-9DD7-11E0-B67F-DCD94724019B}
[/sourcecode]

Der Reihe nach:

  • Die erste Zeile ist ein sog. content package.
    Das erste content ist ein Schlüsselwort. quickerfiler ist der Name des Packages. content/ ist ein URI, der auf den Inhalt des Packages zeigt – in diesem Fall ein relativer Pfad. Diese Registrierung sorgt dafür, dass Chrome-URIs der Form chrome://quickerfiler/content/... (man beachte, dass auch hier content auftaucht!) aufgelöst werden können, also die entsprechenden Dateien gefunden werden.
  • Die zweite und dritte Zeile definieren XUL-Overlays, also Erweiterungen von bestehenden Sichten der Benutzeroberfläche. Vorliegend werden das Hauptfenster (3-pane window) und das Fenster zum Verfassen neuer Mails erweitert – dazu aber später mehr.
  • Schließlich folgen noch die Definition einer Komponente und eines sog. Contracts (also einer Schnittstelle mit einer Implementierung). Mehr über Komponenten im allgemeinen und diese spezielle später.

Kommen wir also zu den XUL-Overlays. content/messengeroverlay.xul sieht wie folgt aus:

[sourcecode language="xml"]
<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://quickerfiler/content/messengeroverlay.js"/>
<keyset>
<key id="quickerfiler_key_move" oncommand="sQuickerFilerMessengerOverlay.openDialog(‘move’);" modifiers="alt" key="q" />
<key id="quickerfiler_key_copy" oncommand="sQuickerFilerMessengerOverlay.openDialog(‘copy’);" />
<key id="quickerfiler_key_insmove" oncommand="sQuickerFilerMessengerOverlay.openDialog(‘insmove’);" />
<key id="quickerfiler_key_inscopy" oncommand="sQuickerFilerMessengerOverlay.openDialog(‘inscopy’);" />
<key id="quickerfiler_key_selfolder" oncommand="sQuickerFilerMessengerOverlay.openDialog(‘selfolder’);" modifiers="alt" key="r" />
</keyset>
</window>
[/sourcecode]

Das Ganze ist, wie schon erwähnt, ein Overlay für messenger.xul, das Hauptfenster von Thunderbird. Dieses Hauptfenster ist ziemlich kompliziert und importiert noch diverse andere XUL-Dokumente. Aber zum Glück kommt es darauf nicht wirklich an – das Overlay definiert einfach Aktionen, die mit Tastenkombinationen ausgelöst werden können und legt fest, welche Javascript-Kommandos in dem Fall ausgeführt werden. Die Ergänzung von Kontextmenüs o.ä. wäre vermutlich sehr viel komplizierter …

Die Bedeutung des script-Elements ist ziemlich offensichtlich, genau wie die von keyset und key. Außerdem gibt es noch ein Tutorial zu dem ganzen Thema. Was vielleicht noch interessant ist, dass nur zwei der key-Elemente auch tatsächlich schon eine Tastenkombination festlegen. Das geschieht zur Laufzeit: content/messengeroverlay.js registriert folgenden Event-Handler:

[sourcecode language="javascript"]
window.addEventListener(‘load’, function () { sQuickerFilerMessengerOverlay.onLoad(); }, false);
[/sourcecode]

Dieser Listener wird zum Fenster hinzugefügt also ausgeführt, wenn das Fenster (in diesem Fall also das Hauptfenster von Thunderbird geladen ist. sQuickerFilerMessengerOverlay.onLoad() lädt die Tastenkombinationen aus den Preferences und setzt die entsprechenden Eigenschaften der key-Elemente.

Das andere Overlay ist content/messengercomposeoverlay.xul:

[sourcecode language="xml"]
<?xml version="1.0"?>

<overlay id="sample" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<script type="application/x-javascript" src="chrome://quickerfiler/content/common.js"/>
<script type="application/x-javascript" src="chrome://quickerfiler/content/messengercomposeoverlay.js"/>

<vbox id="addresses-box">
<toolbox id="quickerfiler.CopyToFolderToolbox">
<hbox align="center">
<label value="Copy message to:" />
<textbox id="quickerfiler.CopyToFolder" flex="1" class="toolbar" disableonsend="true"
type="autocomplete"
autocompletesearch="quickerfiler-autocomplete"
maxrows="14"
tabscrolling="true"
autoFill="true"
forcecomplete="true"
showcommentcolumn="false" />
</hbox>
</toolbox>
</vbox>

</overlay>[/sourcecode]

Dieses Overlay erweitert messengercompose.xul.

Die script-Elemente sind wieder selbsterklärend. Allerdings fällt auf, dass weiter unten keine Javascript-Befehle enthalten sind. Warum wird also überhaupt Code aufgerufen? Nun, content/messengercompose.js enthält folgende Befehle (die beim Laden des Skripts ausgeführt werden):

[sourcecode language="javascript"]
window.addEventListener(‘load’, function () { sQuickerFilerMessengerComposeOverlay.onOpen(); }, false);
window.addEventListener(‘compose-window-reopen’, function () { sQuickerFilerMessengerComposeOverlay.onOpen(); }, true);
window.addEventListener("compose-send-message", function(aEvent) { sQuickerFilerMessengerComposeOverlay.sendEventHandler(aEvent); }, true);
[/sourcecode]

Zur genauen Bedeutung der Events später mehr, wenn ich mir den Code anschaue.

Die taucht bereits im Dokument auf. Das heißt also, das dieses Element vom Overlay erweitert wird – in diesem Fall wird eine toolbox hinzugefügt (unter der Empfängerliste und der Betreffzeile. Warum ausgerechnet eine toolbox, ist mir übrigens nicht klar. Laut Dokumentation dienen diese als Container für toolbars – eine solche taucht hier aber nicht auf (ah, halt: Die Textbox unten hat class="toolbar" – vielleicht hat das ja etwas zu bedeuten). Darin ist dann eine hbox, ein einfacher Container, der der Gruppierung dient. Das label ist ebenfalls uninteressant (außer vielleicht für die Frage, wie das Ganze layouttechnisch funktioniert – dazu vielleicht ein anderes Mal mehr).

Das Spannende ist dagegen die textbox. Gehen wir einfach die Attribute einzeln durch:

  • flex: Dieses Attribut legt fest, wie freier Platz zwischen Elementen verschoben wird. In diesem Fall geht also sämtlicher freier Platz an diese Textbox.
  • class: Dieses Element wird in Stylesheets benutzt. Das deutet darauf hin, dass die Verwendung des toolbox-Elements auch nur layouttechnische Gründe hat.
  • disableonsend: Hier fehlt auf MDN Dokumentation, siehe Mozilla-Bug 670512.
  • type: Gibt den Typ der textbox an, wenn es nicht nur ein simples Textfeld sein soll. In diesem Fall, autocomplete, ist die Sache so kompliziert, dass es gesonderte Dokumentation dazu gibt. Die folgenden Attribute sind alle spezifisch für autocomplete. Im Zusammenhang ist das wohl Thema für einen eigenen Artikel …
  • autocompletesearch: Gibt an, wo die Vorschläge für die Autocompletion herkommen, in diesem Fall von einer speziellen Komponente statt von einer der vordefinierten
  • maxrows: Wie viele Vorschläge werden auf einmal angezeigt, also wie hoch ist das “Menü” höchstens?
  • tabscrolling: In diesem Fall iteriert man mit Tab durch die Vorschläge, anstatt zum nächsten Element zu gehen.
  • autoFill: Es findet automatische Vervollständigung während des Tippens statt.
  • forcecomplete: Wenn man zu einem anderen Element geht, wird die Eingabe zwangsweise zu einem Vorschlag vervollständigt. Das heißt aber offenbar nicht, dass es nicht möglich ist, auch anderen Text einzugeben als einen der Vorschläge.
  • showcommentcolumn: Es werden zu den Vorschlägen keine weiteren Kommentare angezeigt.

Außerdem gibt es noch zwei eigenständige XUL-Dialoge, options.xul und quickerfilerdialog.xul. Auf die werde ich eingehen, wenn ich alles andere durchhabe und dort noch interessante neue Dinge finde. Als nächstes sind erstmal der Javascript-Code der bisher vorgestellten Funktionalität sowie die Komponente für die Autovervollständigung dran. Es wird also unter anderem um XPCOM gehen.

Wieder der obligatorische Hinweis: Code-Schnipsel stammen aus Quicker Filer 0.5.1, sind Copyright (C) 2010 Eivind Rovik und stehen unter GPL (Version 3 oder jede spätere Version).

Thunderbird-Addons: Grundstruktur

Ich hatte ja gerade angedroht, hier mal ein Thunderbird-Addon genauer unter die Lupe zu nehmen, nämlich Quicker Filer, konkret die gerade aktuelle Version 0.5.1.

Packt man das Archiv quicker_filer-0.5.1-tb.xpi aus (mit unzip), kommen folgende Dateien zum Vorschein:

./chrome.manifest
./content
./content/common.js
./content/options.js
./content/options.xul
./content/messengercomposeoverlay.xul
./content/quickerfilerdialog.xul
./content/quickerfilerdialog.js
./content/messengeroverlay.js
./content/messengercomposeoverlay.js
./content/messengeroverlay.xul
./components
./components/quickerfilerautocomplete.js
./install.rdf

Einen Überblick, wie die Struktur so einer Extension aussehen soll, gibt diese Anleitung. Die Struktur so eines Bundles ist auch nochmal hier erläutert, wobei sich da einiges zu überschneiden scheint.

Ausgangspunkt ist jedenfalls erstmal die install.rdf, also ein Install Manifest. Im vorliegenden Fall sieht das so aus:

[sourcecode language="xml"]
<?xml version="1.0"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">

<Description about="urn:mozilla:install-manifest">
<em:id>qfiler@eivind.rovik</em:id>
<em:name>Quicker Filer</em:name>
<em:version>0.5.1</em:version>
<em:description>Quicker Filer [...]</em:description>
<em:creator>Eivind Rovik</em:creator>
<em:type>2</em:type>

<em:optionsURL>chrome://quickerfiler/content/options.xul</em:optionsURL>

<em:targetApplication>
<Description>
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>3.0</em:minVersion>
<em:maxVersion>5.*</em:maxVersion>
</Description>
</em:targetApplication>

</Description>
</RDF>
[/sourcecode]

Das “basic layout” stimmt also überein. Gehen wir die Eigenschaften mal der Reihe nach durch, erst die erforderlichen:

  • id: Hier im @-Format angegeben – das ist in der Tat deutlich anschaulicher als GUIDs …
  • version: Auch wenn man daraus durchaus eine Wissenschaft machen kann, ist es in diesem Fall recht einfach: Drei Zahlen, durch Punkte getrennt.
  • type: Hier wird es unintuitiv. “2″ steht für eine Extension – also das, worum es mir gerade auch geht.
  • targetApplication: Was hier zulässige Werte für id sind, ist auf dieser Seite aufgelistet. Thunderbird ist {3550f703-e582-4d05-9a08-453d09bdfdc6}. minVersion und maxVersion sagen aus, mit welchen Thunderbird-Versionen das Addon kompatibel ist, in diesem Fall also alle Versionen von 3.0 bis zu 5.* (das .* spielt mit dem Rapid Release Scheme wohl eh keine Rolle mehr …).
  • name: Der Name des Addons, hier also Quicker Filer.

Außerdem gibt es noch optionale Eigenschaften. Ich gehe jetzt nur auf die ein, die bei Quicker Filer gesetzt sind:

  • description: Eine einzeilige Beschreibung, die im UI (also dem Addon-Manager) angezeigt wird.
  • creator: Der Name des Entwicklers
  • optionsURL: Die chrome-URL eines Einstellungsdialogs für das Addon. Dazu in einem späteren Post mehr.

Schauen wir uns anhand der bereits genannten Seite die restlichen Dateien an:

  • chrome.manifest: Ein sog. Chrome Registration Manifest. Chrome ist alles, was zum UI der eigentlichen Anwendung gehört – bei Thunderbird also alles bis auf die angezeigten Mails, und eventuell auch angezeigte Webseiten. Im Prinzip wird dort der Aufbau des Pakets beschrieben – auf die Details werde ich in einem späteren Posting eingehen.
  • components: In diesem Verzeichnis liegen XPCOM-Komponenten – auch dazu später mehr.
  • content: Der Name dieses Verzeichnisses folgt keiner besonderen Konvention. In dem Verzeichnis liegen Teile des User-Interfaces, diese müssen aber in chrome.manifest registriert werden. Dazu also später mehr.

Damit endet der Überblick über die Struktur eines Addons und damit der erste Teil einer vermutlich längeren Serie von Postings. Zur Sicherheit noch der obligatorische Hinweis: Code-Schnipsel stammen aus Quicker Filer 0.5.1, sind Copyright (C) 2010 Eivind Rovik und stehen unter GPL (Version 3 oder jede spätere Version).

Mail-Ordner suchen

Wenn man eine große und stark verschachtelte Hierarchie von Mail-Ordnern hat, ist es nicht trivial, im Thunderbird gezielt einen davon aufzurufen oder eine Mail dorthin zu verschieben. Dieses Problem hatte ich schon vor ca. zweieinhalb Jahren und habe daraufhin damals Mozilla-Bug 479767 angelegt. Es gab ein paar andere Bugs, die das gleiche forderten, aber ansonsten passierte nichts.

… bis ich vor kurzem das Addon Quicker Filer fand. Die Beschreibung las sich gut, aber es funktionierte noch nicht mit Thunderbird 5. Eine Anfrage beim Programmierer (Eivind Rovik) löste dieses Problem aber nach wenigen Tagen. Meine Produktivität beim Wegsortieren von Mails hat das Addon tatsächlich extrem gesteigert. Leider verhindert unter Linux irgendein Problem noch, dass das simple Auswählen eines Ordner klappt. Eivind Rovik geht davon aus, dass es irgendetwas mit Ordnernamen im hiesigen Profil zu tun haben könnte (und eher nichts mit Windows vs. Linux).

Ich habe mir auch mal den Source-Code des Addons angeschaut. Es ist kompliziert genug, um diverse verschiedene Technologien zu benutzen, aber klein genug, um halbwegs überschaubar zu sein. Ich denke, ich werde es in der nächsten Zeit mal ein bisschen sezieren und die Ergebnisse hier beschreiben. Vielleicht finde ich dabei ja auch den Fehler.

Copyright Transfer

Mein Paper “The Architecture of a Secure Business-Process-Management System in Service-Oriented Environments” wurde auf der ECOWS 2011 angenommen (dort noch unter geringfügig anderem Titel). Nette Sache, gibt eine kleine Reise nach Lugano mit zwei leckeren Abendessen und hoffentlich einigen interessanten Vorträgen.

Heute habe ich die Druckfassung hochgeladen. Weniger nette Sache, denn man liefert sich damit der Content-Mafia auf Gedeih und Verderben aus. Man wird gezwungen (publish or perish …), das “Copyright” (ein Konzept, dass es im deutschen Recht so nicht gibt, dazu unten mehr) auf die IEEE zu übertragen.

Das Ganze hat es in sich. Man überträgt all rights under copyright that may exist in and to dem Artikel und eventuellen Begleitmaterialien an die IEEE. Außerdem räumt man Nutzungsrechte am Vortrag ein und gibt eine Garantie ab, dass man die Rechte am Artikel besitzt.

Man behält sogar Rechte (wow!): Man darf Auszüge aus dem Artikel für den persönlichen Gebrauch nutzen. Außerdem gilt: “4. Although authors are permitted to re-use all or portions of the Work in other works, this does not include granting third-party requests for reprinting, republishing, or other types of re-use. The IEEE Intellectual Property Rights office must handle all such third-party requests.” Was das heißt, ist mir vollkommen schleierhaft. Darf ich das Paper nehmen, etwas auswalzen, und zu einem Kapitel in meiner Diss machen, oder darf ich das nicht? Ich glaube, das ist absichtlich so nebulös formuliert.

Ich glaube ehrlich gesagt nicht, dass dieser Vertrag nach deutschem Recht so Bestand hat. Naja, immerhin finde ich gerade keine Klausel, die eine Vergütung ausschließt. Damit gilt nach § 32 UrhG die angemessene Vergütung als vereinbart.

Ich zweifle gerade sogar daran, dass das Ding nach US-Recht, also common law, Bestand hat. Die Übertragung erfolgt bedingungslos, es fehlt also an der consideration. Damit dürfte nach common law kein Vertrag vorliegen. Der Wikipedia-Artikel geht übrigens im zweiten Abschnitt explizit auf licensing contracts ein.

Mir ist übrigens noch ein netter Hack eingefallen. Beim Abrufen des Formulars wird man gefragt, ob einer der Autoren für die US-Regierung oder ein crown government arbeitet. In dem Fall wäre die Arbeit nämlich gemeinfrei, bzw. es würde crown copyright gelten. Ich gehe, ohne es ausprobiert zu haben, davon aus, dass die IEEE in dem Fall nicht so weitreichende Forderungen stellt. Man sollte sich also einen Angestellten der US-Regierung suchen, vielleicht den Pförtner des Bureau of Alcohol, Tobacco, Firearms and Explosives oder so, den man auf alle seine Papers mit raufsetzt, um sie dem Zugriff der Content-Mafia zu entziehen.

Und noch etwas ist mir eingefallen: Es kann doch nicht sein, dass ich das einzige IEEE-Mitglied (ok, Mitglied bin ich da eh nur, weil sich das wegen Ermäßigung schon bei nur einer Konferenz lohnt …) bin, das das kritisch sieht. Wenn jemand etwas über IEEE-internen Widerstand weiß, wäre ich für Hinweise dankbar.

Ist ja nur Frauenfußball

Da will beim DFB offenbar keiner Geld für ordentliche Typographie ausgeben. Gerade wunderte ich mich bei einigen kurzen Einstellungen, bei denen man die Namenszüge auf den Trikots der deutschen Fußballnationalmannschaft mal erkennen konnte, was denn das für eine seltsame Schriftart ist. Comic Sans MS, war meine erste Idee.

Eine kurze Google-Suche zeigte, dass das nicht nur mir unangenehm aufgefallen ist, vgl. dieser Artikel. Etwas fachkundiger äußert sich das Fontblog.

Was zur Hölle hat sich der DFB dabei gedacht? $Überschrift?

Geld gespart mit DHL

Am Donnerstagabend habe ich bei einer Online-Apotheke Medikamente bestellt (5 Fläschchen Livocab-Augentropfen). Die wurden sogar gestern morgen verschickt. Gerade eben bekomme ich dann die SMS von DHL. Ich denke mir: “Oh, das passt ja gut, ich wollte eh gerade in die Stadt, dann kann ich gleich bei der Packstation vorbei.” Aber nichts da: Die Sendung wurde in eine FILIALE (Großbuchstaben original von DHL) umgeleitet, ich kann sie dort am nächsten Werktag (haha, das ist übermorgen) ab 11 Uhr (haha, da arbeite ich) abholen.

Am Anfang war das mit der Packstation echt gut. Aber inzwischen ist das System nahezu unbrauchbar geworden. Immer häufiger landen Pakete in der Filiale, weil die Packstation voll gewesen sei. Das merkt “natürlich” (wg. schrottiger IT) erst der Zusteller vor Ort, der dann auch keinen Bock mehr hat, den Rest in einer anderen Packstation unterzubringen. Wenn ich gewusst hätte, dass das Paket (schon) heute kommt, hätte ich es ja nach Hause bestellt – aber auch auf Laufzeiten oder Liefertermine kann man sich ja nicht ansatzweise verlassen.

DHL ist durch Missmanagement gerade dabei, seinen guten Ruf bei Privatkunden gründlich zu verspielen.

Naja, jedenfalls kann ich jetzt zwei Tage keine Augentropfen verbrauchen, somit habe ich ja eigentlich Geld gespart ;-)

Allergologe

Nach dem die Pollenallergiesymptome dieses Jahr besonders schlimm waren, habe ich mit dazu breitschlagen lassen, es vielleicht doch einmal mit spezifischer Immuntherapie zu versuchen. Eine Broschüre der Techniker Krankenkasse behauptet zwar, dass diese Therapie bei mehr als vier allergieauslösenden Stoffen oder wenn die Allergie mehr als 5 Jahre besteht, nicht sinnvoll sei. Da sie dafür aber keinerlei Begründung nennt, ist das ja nicht unbedingt ernstzunehmen.

Der Wirkmechanismus der spezifischen Immuntherapie ist offenbar (erst) seit einigen Jahren halbwegs verstanden, da hatte ich eh schon mehr als 5 Jahre Pollenallergie. Insofern sind das eh ziemliche Witzbolde. Jedenfalls ist die Therapie nach den einschlägigen Leitlinien (PDF) offenbar als wirksam nachgewiesen. Also kann man es ja mal probieren.

Aber wo geht man damit eigentlich hin? Beim Allergologen war ich in Karlsruhe noch nicht, mit Empfehlungen ist es auch so eine Sache, und im Internet findet man gleich gar keine brauchbaren Informationen. Da ich keine große Lust hatte, mir da Gedanken zu machen, habe ich einfach den TK-TerminService genutzt. Ich bekam einen Termin zweieinhalb Wochen später, nämlich heute nachmittag.

Das Gebäude sah nicht sonderlich modern aus, nicht sonderlich gepflegter Altbau halt. Bei der Anmeldung war alles ok, und als ich ins Wartezimmer kam, saß dort nur eine Person. Nach und nach wurde das Wartezimmer aber immer voller, und ganz selten wurde jemand aufgerufen. Ich kam trotz Termin erst nach 45 Minuten dran. Meines Erachtens eine Unverschämtheit, und vor allem ein Zeichen dafür, dass dort jemand seine Praxisorganisation nicht im Griff hat.

Das Ganze war dann in 5 Minuten vorbei. Ein 10 Jahre alter Allergietest tauge eh nichts mehr, meine Nasenscheidewand sei ziemlich schief, ob ich mich da denn nicht operieren lassen wolle, und ich bräuchte dann einen neuen Termin für einen Allergietest. Die Ärztin wollte mir einen Fragebogen (zu Allergenkontakten oder so ähnlich) mitgeben lassen, aber die waren gerade aus und nicht (rechtzeitig) nachbestellt. Haben die da keinen Kopierer oder Drucker? Noch ein Zeichen für eine extrem mangelhafte Praxisorganisation.

Jetzt habe ich dort nächsten Montag wieder einen Termin, und irgendwie schon keinen Bock mehr. Vermutlich bekomme ich dann auch diesen ominösen Fragebogen und soll mir spontan Antworten aus den Fingern saugen. Falls ich dort wieder mehr als eine Viertelstunde warten müssen sollte, war es das, dann suche ich mir halt einen anderen Arzt.

Jedenfalls ist das ein guter Anlass für Fundamentalkritik am deutschen Gesundheitssystem, namentlich am Konzept der niedergelassenen Ärzte. Eine brauchbare Qualitätssicherung ist dort überhaupt nicht möglich, anständig ausgebildetes Verwaltungspersonal dürfte auch eher Glückssache sein. Mit diesem Konzept dürfte Deutschland unter den Ländern mit staatlich organisisiertem Gesundheitssystem (und nichts anderes ist unsere GKV) ziemlich allein auf weiter Flur stehen. Wie wäre es mit Polikliniken? Und wie wäre es darüber hinaus mit brauchbaren Qualitätssicherungssystemen? Stattdessen gibt es hier die “Therapiefreiheit”, also eine Lizenz zur Stümperei.

Von der GEK fast ausgesperrt

Nein, ich war kein CityBKK-Kunde, den die Gmünder Ersatzkasse erst nicht aufnehmen wollte. Es ist viel ernster. Gerade eben war ich laufen. Meinen Wohnungsschlüssel hatte ich (zusammen mit meinem Fahrradschlüssel) an einem Schlüsselanhängerhalsband, das wohl mal ein Werbegeschenk der Gmünder Ersatzkasse war. Dieses Band war in der Innentasche meiner Laufhose. Kurz bevor ich zu Hause ankam, zog ich das Band mit dem Schlüssel aus der Tasche. Es macht pling, und ich hatte nur noch das Band und einen kaputten Anhänger in der Hand. Der Fahrradschlüssel lag auf einem Abflussgitter, der Haustürschlüssel war erst nicht zu finden. Anheben ließ sich das Gitter auch nicht, da es (anscheinend mit Sechskantschrauben) verschraubt war. Ich überlegte schon, wie ich jetzt die Nacht verbringe, als ich den Schlüssel dann links von dem Gitter doch noch wiederfand.

Wenn schon die Werbegeschenke derart minderwertig sind, möchte ich dort lieber nicht versichert sein … Ein Foto des kaputten Schlüsselanhängers folgt.:

IMG_1513

Zensus? Schlamperei!

Vor einigen Monaten bekam ich für die Vorerhebung zur Gebäude- und Wohnungszählung im Rahmen des Zensus 2011 einen Fragebogen zum ehemaligen Haus meiner Oma, das zu dem Zeitpunkt schon längst verkauft war … Zwar auch seltsam, aber die haben die Daten aus den Grundsteuerämtern etc. über längere Zeit zusammengetragen usw. – von mir aus. Also die Käufer und deren Anschrift (bzw. die damalige Anschrift und den Hinweis, dass die inzwischen vermutlich in eben dem Haus, dass sie sich gekauft haben, wohnen) angegeben und zurückgeschickt.

Damit hätte die Sache ja eigentlich erledigt sein sollen. Ist sie aber nicht. Heute bekam ich den Fragebogen zur Gebäude- und Wohnungszählung. Wofür habe ich dann damals bitte den Bogen ausgefüllt? Nun, denke ich mir, dann haben sie den Bogen wohl nicht bearbeitet, so wie in Bremen. Aber wieso kam der Bogen dann (direkt, ohne Nachsendung) an meine neue Anschrift (ich bin vor kurzem umgezogen)? Die können die eigentlich nur aus der Vorerhebung haben …

Da ist jetzt einiges an Papierkrieg (beispielsweise ein Auskunftsverlangen) angesagt. Bin ich eigentlich überhaupt verpflichtet, da jetzt irgendetwas zurückzusenden? § 18 Abs. 2 S. 6 Zensusgesetz 2011 lautet:

Gehört eine nach § 10 Absatz 2 des Zensusvorbereitungsgesetzes 2011 ermittelte auskunftspflichtige Person auf Grund eines zum Berichtszeitpunkt bei den Stellen nach § 10 Absatz 2 des Zensusvorbereitungsgesetzes 2011 noch nicht nachvollzogenen Eigentümerwechsels nicht mehr zum Kreis der Auskunftspflichtigen nach Satz 1 und 2, hat sie dem zuständigen statistischen Amt die Namen und Anschriften der Erwerber und Erwerberinnen mitzuteilen.

OK, das ist die Rechtsgrundlage – aber einmal reicht ja wohl? Oder woraus soll sich ergeben, dass ich beliebig oft, auf eigene Kosten, zur Auskunft verpflichtet bin?

Begriff gesucht

Ich fange mal mit einem Beispiel an: Ein Compiler übersetzt ja ein Programm von einer Hochsprache in Maschinencode (jetzt mal ganz platt ausgedrückt). Operational gesehen ist das das Gleiche. Aber dabei geht (insbesondere, wenn man Optimierungen anwendet), Struktur verloren. Das führt dann beispielsweise dazu, dass Debugger nicht mehr richtig funktionieren (oder jedenfalls sehr viel schwerer zu schreiben sind). Wenn man das vermeidet und dafür sorgt, dass die Information aus dem Hochsprachenprogramm auch auf Maschinencodeebene verfügbar ist – wie könnte man das nennen? “Semantikerhaltende Transformation” trifft es nicht – die Semantik (im Sinne von Ausführungssemantik) bleibt ja erhalten. Vielleicht “strukturerhaltende Transformation”?

Oder vielleicht gibt es sogar Literatur, die sich mit dieser eher philosophischen Frage befasst?

Transparenz der Krankenkassenleistungen II

Vor einigen Monaten hatte ich über eine Klarstellung des Gesundheitsministeriums berichtet: Bei der Beantragung der Auskunft nach § 305 Abs. 1 SGB V ist es nicht nötig, die behandelnden Ärzte zu nennen.

Ich hatte dann nochmal nachgefragt, wie es ist, wenn man nicht nur “bei” der Heimat-KV Leistungen in Anspruch genommen hat. Antwort des BMG: Dann sollte man zumindest die KVen benennen.

Da es in Grenzregionen der Kassenärztlichen Vereinigungen oder z. B. bei Reisen der Versicherten häufiger dazu kommen kann, dass Leistungen bei Ärztinnen oder Ärzten von zwei oder mehreren Kassenärztlichen Vereinigungen von Versicherten in Anspruch genommen werden, ist davon auszugehen, dass die von Ihnen geschilderte Konstellation keinen Einzelfall darstellt.

Auch in diesem Fall ist es nach Auffassung des Bundesministeriums für Gesundheit nicht erforderlich, dass der Versicherte mit dem Auskunftsersuchen die Namen und Adressen der in Anspruch genommenen Ärztinnen und Ärzte nennen muss. Jedoch ist es aufgrund des geltenden Abrechnungsverfahrens, das die Abrechnung einer Ärztin oder eines Arztes mit der für sie oder ihn zuständigen Kassenärztlichen Vereinigung vorsieht, eine Information der Krankenkasse über den Ort bzw. die Kassenärztliche Vereinigung, wo die Leistungen in Anspruch genommen wurden, notwendig. Mit dieser Angabe kann die Krankenkasse die entsprechenden Kassenärztlichen Vereinigungen gezielt anschreiben und die entsprechenden Abrechnungsunterlagen anfordern.

(Puh, das Gegendere macht den Text ganz schon umständlich. Und ob der Sachbearbeiter wohl ein Makro für “KV” in den verschiedenen Kasus und Numeri hat?)

Praktisch umsetzbar, von der Wort-für-Wort-Vereinbarkeit mit dem Gesetz bin ich noch nicht vollständig überzeugt …

Arbeitszuteilungsverfahren

ConsiderGegeben sei folgendes Problem:

Es existiere eine Organisation, in der Kaffee in Codezeilen (und Papers) umgewandelt wird. Der Kaffee wird von einer Kaffeemaschine produziert, die einen gewissen Wartungsaufwand hat (regelmäßiges Entkalken und Reinigen). Der Kaffeeverbrauch ist unterschiedlich (mag mit einem unterschiedlichen Ausstoß an Codezeilen (und Papers) zusammenhängen, aber ein linearer Zusammenhang lässt sich empirisch bisher nicht bestätigen).

Gesucht ist nun ein Verfahren, mit dem der Arbeitsaufwand (also vorzunehmende Wartungsarbeiten) möglichst gerecht auf die Kaffeetrinker verteilt werden kann. Informationen über den Kaffeeverbrauch liegen immer nur rückwirkend für die abgelaufene Periode vor. Es ist zu erwarten, dass innerhalb einer Abrechnungsperiode die Arbeit nicht gerecht verteilt werden kann, alleine schon, weil gar nicht alle drankommen. Es soll also periodenübergreifende Gerechtigkeit hergestellt werden.

Irgendwelche Ideen? Als erster Ansatzpunkt würde ich mit den Tassenzahlen der letzten Periode anfangen und anhand dessen eine Reihenfolge für die aktuelle Periode festlegen. Bloß wie macht man das? Kann man dafür Sitzzuteilungsverfahren missbrauchen? Also anhand der Bruchteile die Sitze für ein Parlament mit 1,2,3, vielen Sitzen ausrechnen, und der jeweils zusätzliche Sitz ist dann der n-te in der Reihe? Sollte doch eigentlich passen – das Verfahren darf bloß keine Anomalie aufweisen, dass sich bei einer Vergrößerung um einen Sitz plötzlich Verwerfungen in der Zuteilung ergeben, die mehr als den einen zusätzlichen Sitz betreffen. Welches Verfahren würden die geneigten Leser da empfehlen?

Als nächstes Problem kommt die Übertragung nicht ausgeschöpfter Bruchteile auf die nächste Periode – und da habe ich noch keinen blassen Schimmer. Wobei, im Zweifel vergrößert man das “Parlament” immer weiter, nimmt die Gesamttassenzahl und berücksichtigt die bereits erledigte Arbeit? Müsste doch passen, oder?

Kein Verkehrsverbot bei Straßenbahnschienen

Heute habe ich das Urteil im Rechtsstreit gegen die Stadt Rheinstetten wegen eines Verkehrsverbots für Radfahrer an einem Bahnübergang bekommen (Urteil des VGH Baden-Württemberg, 5 S 2285/09, PDF, ca. 2,3 MB). Ich habe, auch dank meines Anwalts Dr. Kettler, in vollem Umfang gewonnen.

Das Urteil war in zentralen Punkten vorgezeichnet, enthält aber durchaus interessante Passagen.

  • Der Senat verschweigt nicht, dass sein erster Beschluss über die Ablehnung der Berufungszulassung vom Bundesverfassungsgericht kassiert wurde, sondern erwähnt das explizit (Seite 6).
  • Er stellt klar, dass positiv festgestellt werden muss, dass Angaben des Klägers über die erstmalige Betroffenheit unzutreffend sein sollen. Mutmaßungen reichen dafür nicht aus (Seite 10). Dies entspricht wohltuend der Rechtsweggarantie des Art. 19 Abs. 4 GG. Auf Verdacht kann man niemandem den Zugang zu den Gerichten verwehren.
  • Das Urteil erläutert die Anfechtungsfrist für Verkehrszeichen unter Bezug auf die jüngste Rechtsprechung des BVerwG. “Die­ser Auffassung schließt sich der Senat im Interesse einer einheitlichen Recht­sprechung nunmehr an.” (Seite 11)
  • Bei Zuständigkeitswechsel sind Widerspruch und Klage, insbesondere gegen Verkehrszeichen als Dauerverwaltungsakte, gegen die nunmehr zuständige Behörde (bzw. deren Rechtsträger) zu richten (Seite 12/13).
  • Den Streit über die Nichtigkeit der 46. StVO-Novelle wird erläutert, letztendlich kommt es darauf aber nicht an (Seite 14).
  • Es wird ausgeführt, dass sogar für Warnzeichen strenge Vorschriften gelten. Diese Maßstäbe müssen dann erst recht für Verkehrsbeschränkungen und -verbote gelten (Seite 19).

An diversen Stellen gibt man mir Nachhilfe. Auf fast jedes meiner laienhaften Argumente wird irgendwie eingegangen:

  • Der Regelungsgehalt eines Zeichen 254 sei eindeutig erkennbar (insbesondere sperrt es wohl nicht stets die gesamte Straße), Seite 14.
  • Bei Dauerverwaltungsakten kommt es auch in Bezug auf die Ermessensausübung auf die mündliche Verhandlung in der letzten Tatsacheninstanz an (Seite 19/20).

Übrigens enthält das Urteil mindestens vier offensichtliche Schreibfehler.

  • Seite 6: “hat der Senat nunmehr mit – dem Kläger am 26.10.2009 zugestelltem – Beschluss vom 16.10.2010 – 5 S 2142/09 – die Berufung zugelassen.”
  • Rubrum: “Rappwörthstraße” statt “Rappenwörthstraße” (die schreibt sich übrigens wirklich mit “h”, obwohl sie nach Rappenwört benannt ist …)
  • “Im Übrigen hat sie den Rechtsstreit ebenfalls teilweise in der Hauptsache für erledigt.” (Seite 9) – hier fehlt ein “erklärt”.
  • “Am 16.05.2008 hat der Kläger Klage zum Verwaltungsgericht Karlsruhe Klage erhoben.”