This is gui.c in view mode; [Download] [Up]
/* $Id: gui.c,v 2.8 1993/06/28 09:31:07 klute Exp klute $ */ /* * Copyright 1993 Rainer Klute <klute@irb.informatik.uni-dortmund.de> * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. The author makes no representations about the suitability * of this software for any purpose. It is provided "as is" without express * or implied warranty. * */ #include <malloc.h> #include <string.h> #include <Xm/Xm.h> #include <Xm/Text.h> #include "gui.h" #include "ui.h" #include "gui_batch.h" #include "gui_build.h" #include "gui_utils.h" #include "convert.h" #include "message.h" #include "parse.h" #include "strada.h" #include "utils.h" #if defined (HANDLE_BROKEN_DATAFILES) #define IbmToIso IbmAndBrokenToIso #endif static char *messageBuffer = (char *) 0; XtCallbackProc StrassenverzeichnisCallback (Widget widget, XtPointer clientData, XtPointer callData) { ConversionData *cd = (ConversionData *) clientData; PlzConversion *pc = cd->pc; GuiComponents *gc = cd->gc; SetBusyCursor (gc->plz_neu); LabelSetString (gc->plz_neu, ""); if (pc->orte->entries > 0) pc->strassen = Strassenverzeichnis (pc->orte->list[0].alort); else if (pc->archivOrte->entries > 0) pc->strassen = Strassenverzeichnis (pc->archivOrte->list[0].alort); StradaSetToList (gc->list, pc->strassen, pc->ort); XtAddCallback (gc->list, XmNsingleSelectionCallback, (XtCallbackProc) ListStreetSelected, cd); UnsetBusyCursor (gc->plz_neu); } static void GuiMsgFlush (UiComponents *uc) { GuiComponents *gc = (GuiComponents *) uc; InformationDialog (TopLevelShell (gc->messages), "Hinweis:", messageBuffer); free (messageBuffer); messageBuffer = (char *) 0; } static void GuiMsgWrite (UiComponents *uc, char *msg) { char *help; if (messageBuffer == (char *) 0) { messageBuffer = (char *) malloc (1); *messageBuffer = '\0'; } help = messageBuffer; messageBuffer = (char *) malloc (strlen (messageBuffer) + strlen (msg) + 1); strcpy (messageBuffer, help); strcat (messageBuffer, msg); free (help); } static void GuiNoteWrite (UiComponents *uc, char *msg) { GuiComponents *gc = (GuiComponents *) uc; XmTextInsert (gc->messages, XmTextGetLastPosition (gc->messages), msg); XmTextSetInsertionPosition (gc->messages, XmTextGetLastPosition (gc->messages)); XmUpdateDisplay (gc->messages); } static void GuiNoteClear (UiComponents *uc) { GuiComponents *gc = (GuiComponents *) uc; XtVaSetValues (gc->messages, XmNvalue, "", NULL); } void InitDisplay (ConversionData *cd, char **strasse, char **hausnummer, char**postfach, char **plz_alt, char **ort, char **postanstalt, char **ortsteil) { GuiComponents *gc = cd->gc; LabelSetString (gc->plz_neu, ""); XtVaSetValues (gc->list, XmNitems, (XmString *) 0, XmNitemCount, 0L, NULL); } XtCallbackProc ConvertCallback (Widget widget, XtPointer clientData, XtPointer callData) { char string[300]; char *help; ConversionData *conversionData = (ConversionData *) clientData; PlzConversion *pc = conversionData->pc; char *strasse, *hausnummer, *postfach, *plz_alt, *ort, *postanstalt, *ortsteil; static XtCallbackRec emptyCallbackList[] = {{(XtCallbackProc) 0, (XtPointer) 0}}; SetBusyCursor (widget); LabelSetString (conversionData->gc->plz_neu, ""); XtVaSetValues (conversionData->gc->list, XmNitems, (XmString *) 0, XmNitemCount, 0L, NULL); help = XmTextGetString (conversionData->gc->strasse); ParseStrasse (help, &strasse, &hausnummer, &postfach); XtFree (help); help = XmTextGetString (conversionData->gc->ort); ParseOrt (help, &plz_alt, &ort, &postanstalt, &ortsteil); XtFree (help); ConvertPlz (pc, strasse, hausnummer, postfach, plz_alt, ort, postanstalt, ortsteil); free (strasse); free (hausnummer); free (postfach); free (plz_alt); free (ort); free (postanstalt); free (ortsteil); Message (ConversionStatusString (pc->status)); MessageFlush (); XtVaSetValues (conversionData->gc->list, XmNitems, (XmString *) 0, XmNitemCount, 0L, XmNsingleSelectionCallback, emptyCallbackList, NULL); XtVaSetValues (conversionData->gc->menuStrassenverzeichnis, XmNsensitive, False, NULL); if (IsOrtGefunden (pc)) { if (IsOrtEindeutig (pc)) { if ((pc->orte->entries > 0 && pc->orte->list[0].nplzo_z[0] == '2') || (pc->archivOrte && pc->archivOrte->entries == 1 && pc->archivOrte->list[0].nplz_z[0] == '2')) XtVaSetValues (conversionData->gc->menuStrassenverzeichnis, XmNsensitive, True, NULL); XmProcessTraversal (conversionData->gc->strasse, XmTRAVERSE_CURRENT); } else { /* Mehrere PLZ, möglicherweise auch mehrere Orte */ OrteToList (conversionData->gc->list, pc->orte, pc->archivOrte); XtAddCallback (conversionData->gc->list, XmNsingleSelectionCallback, (XtCallbackProc) ListPlaceSelected, conversionData); XmProcessTraversal (conversionData->gc->list, XmTRAVERSE_CURRENT); } if (pc->status == PlzPlzNeuGefunden) LabelSetString (conversionData->gc->plz_neu, pc->plz_neu); strcpy (string, OrtString (pc->plz_alt, pc->ort, pc->postanstalt, pc->ortsteil)); XmTextSetString (conversionData->gc->ort, string); } else XmProcessTraversal (conversionData->gc->ort, XmTRAVERSE_CURRENT); if (IsStrasseGefunden (pc)) { strcpy (string, StrasseString (pc->strasse, pc->hausnummer, pc->postfach)); XmTextSetString (conversionData->gc->strasse, string); if (!IsStrasseEindeutig (pc)) { StradaSetToList (conversionData->gc->list, pc->strassen, pc->ort); XtAddCallback (conversionData->gc->list, XmNsingleSelectionCallback, (XtCallbackProc) ListStreetSelected, conversionData); } } if (IsPostfachGefunden (pc)) { if (IsPostfachEindeutig (pc)) { strcpy (string, "Postfach "); strcat (string, pc->postfach); XmTextSetString (conversionData->gc->strasse, string); } else { PofadaSetToList (conversionData->gc->list, pc->postfaecher, pc->orte->list->ortname_a); XtAddCallback (conversionData->gc->list, XmNsingleSelectionCallback, (XtCallbackProc) ListPoboxSelected, conversionData); } } UnsetBusyCursor (widget); } XtCallbackProc ListActivated (Widget widget, XtPointer clientData, XtPointer callData) { XtCallCallbacks (widget, XmNsingleSelectionCallback, callData); ConvertCallback (widget, clientData, callData); } /* * "ListPlaceSelected" holt den Orts-String aus dem ersten Segment des * CompountString und überträgt ihn in das Ortseingabefeld. Falls das zweite * Segment als erste Zeichen " -> " enthält, ist dies der aktuelle Ortsname, * und der Inhalt des ersten Segments historisch. Er wird als Ortsteil * eingesetzt. */ XtCallbackProc ListPlaceSelected (Widget widget, XtPointer clientData, XtPointer callData) { XmListCallbackStruct *cd = (XmListCallbackStruct *) callData; ConversionData *conversionData = (ConversionData *) clientData; XmStringContext context; Boolean success; XmStringCharSet tag; XmStringDirection direction; Boolean separator; char *item; char *plz, *ort, *zustellamt, *ortsteil; if (cd->reason != XmCR_SINGLE_SELECT && cd->reason != XmCR_DEFAULT_ACTION) return; success = XmStringInitContext (&context, cd->item); success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil); success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); if (success && strncmp (item, " -> ", 4) == 0) { free (ortsteil); ortsteil = ort; ort = (char *) malloc (strlen (item + 4) + 1); strcpy (ort, item + 4); } item = OrtString (plz, ort, zustellamt, ortsteil); free (plz); free (ort); free (zustellamt); free (ortsteil); XmTextSetString (conversionData->gc->ort, item); conversionData->pc->status = PlzOrtEindeutig; } XtCallbackProc ListPoboxSelected (Widget widget, XtPointer clientData, XtPointer callData) { XmListCallbackStruct *cd = (XmListCallbackStruct *) callData; ConversionData *conversionData = (ConversionData *) clientData; char *item; XmStringContext context; XmStringCharSet tag; XmStringDirection direction; Boolean separator; char *plz; char *ort; char *zustellamt; char *ortsteil; if (cd->reason != XmCR_SINGLE_SELECT && cd->reason != XmCR_DEFAULT_ACTION) return; XmStringInitContext (&context, cd->item); XmStringGetNextSegment (context, &item, &tag, &direction, &separator); ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil); item = OrtString (plz, ort, zustellamt, ortsteil); XmTextSetString (conversionData->gc->ort, item); conversionData->pc->status = PlzSuchePostfach; } /* * "ListStreetSelected" holt den Straßennamen und gegebenenfalls den * Orts-String aus dem CompoundString. Dieser ist wie folgt aufgebaut: * <PLZ>< ><Straßenname>[<, ><Hausnummernbereich>][<SEP><Orts-String>] */ XtCallbackProc ListStreetSelected (Widget widget, XtPointer clientData, XtPointer callData) { XmListCallbackStruct *cbs = (XmListCallbackStruct *) callData; ConversionData *cd = (ConversionData *) clientData; char *item; XmStringContext context; Boolean success; XmStringCharSet tag; XmStringDirection direction; Boolean separator; XmStringComponentType unknown_tag; unsigned short unknown_length; unsigned char *unknown_value; char *postfach; char *plz; char *ort; char *zustellamt; char *ortsteil; if (cbs->reason != XmCR_SINGLE_SELECT && cbs->reason != XmCR_DEFAULT_ACTION) return; success = XmStringInitContext (&context, cbs->item); /* Postleitzahl: */ success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); UpdateString (&cd->pc->plz_neu, item); LabelSetString (cd->gc->plz_neu, item); cd->pc->status = PlzPlzNeuGefunden; success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); /* Straßenname: */ success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); UpdateString (&cd->pc->strasse, item); item = StrasseString (item, cd->pc->hausnummer, postfach); XmTextSetString (cd->gc->strasse, item); /* Hausnummernbereich: */ if (!separator) { success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); } /* Orts-String: */ if (separator) { XmStringGetNextComponent (context, &item, &tag, &direction, &unknown_tag, &unknown_length, &unknown_value); success = XmStringGetNextSegment (context, &item, &tag, &direction, &separator); ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil); item = OrtString (plz, ort, zustellamt, ortsteil); UpdateString (&cd->pc->plz_alt, plz); UpdateString (&cd->pc->ort, ort); UpdateString (&cd->pc->postanstalt, zustellamt); UpdateString (&cd->pc->ortsteil, ortsteil); free (plz); free (ort); free (zustellamt); free (ortsteil); XmTextSetString (cd->gc->ort, item); } else { UpdateString (&cd->pc->postanstalt, ""); UpdateString (&cd->pc->ortsteil, ""); item = OrtString (cd->pc->plz_alt, cd->pc->ort, "", ""); XmTextSetString (cd->gc->ort, item); } XmStringFreeContext (context); } void PofadaSetToList (Widget list, PofadaSet *pofadaSet, char *ortsname) { Pofada *l; Pofada *newPobox; int i, j; XmString *stringList = (XmString *) calloc ((int) pofadaSet->entries, sizeof (XmString *)); char msg[300]; char *isoMsg; int entriesLeft = pofadaSet->entries; char postanstalt[5]; newPobox = pofadaSet->list; postanstalt[0] = '\0'; for (l = pofadaSet->list, i = j = 0; i < pofadaSet->entries; i++, l++) { msg[0] = '\0'; if (strncmp (l->npanst, postanstalt, sizeof (l->npanst)) != 0) { strncpy (postanstalt, l->npanst, sizeof (l->npanst)); strncat (msg, l->plz_w_o, sizeof (l->plz_w_o)); strncat (msg, l->plzalt, sizeof (l->plzalt)); strcat (msg, " "); strncat (msg, ortsname, sizeof (((Umsda *) 0)->ortname_a)); StripBlanks (msg); strcat (msg, " "); strncat (msg, l->npanst, sizeof (l->npanst)); } else { entriesLeft--; continue; } #if defined (HANDLE_BROKEN_DATAFILES) isoMsg = IbmAndBrokenToIso (msg); #else isoMsg = IbmToIso (msg); #endif stringList[j++] = XmStringCreateLtoR (isoMsg, XmFONTLIST_DEFAULT_TAG); free (isoMsg); } XtVaSetValues (list, XmNitems, stringList, XmNitemCount, (long) entriesLeft, NULL); for (i = 0; i < entriesLeft; i++) XmStringFree (stringList[i]); free (stringList); } static void AppendHn (char *s, char *tag, int length) { char *c = tag; while (*c == ' ' && c - tag < length) c++; if (c - tag < length) { strncat (s, c, length - (c - tag)); StripBlanks (s); } } void StradaSetToList (Widget list, StradaSet *stradaSet, char *ortsname) { Strada *l; Strada *newStreet; int i, j; XmString s1; XmString *stringList = (XmString *) calloc ((int) stradaSet->entries, sizeof (XmString *)); char msg[300]; char *isoMsg; char ortsteil[sizeof (((Strada *) 0)->ortsteil)]; char sname[sizeof (((Strada *) 0)->sname)]; char strlfdnr[sizeof (((Strada *) 0)->strlfdnr)]; int entriesLeft = stradaSet->entries; newStreet = stradaSet->list; ortsteil[0] = sname[0] = strlfdnr[0] = '\0'; for (l = stradaSet->list, i = j = 0; i < stradaSet->entries; i++, l++) { /* neue Postleitzahl: */ msg[0] = '\0'; strncat (msg, l->plz_z, sizeof (l->plz_z)); s1 = XmStringCreate (msg, XmFONTLIST_DEFAULT_TAG); s1 = StringCat (s1, XmStringCreate (" ", XmFONTLIST_DEFAULT_TAG)); /* Straßenname: */ msg[0] = '\0'; strncat (msg, l->sname, sizeof (l->sname)); StripBlanks (msg); isoMsg = IbmToIso (msg); s1 = StringCat (s1, XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG)); free (isoMsg); /* Hausnummernbereich (falls vorhanden): */ if (strntoi (l->nplz_z, sizeof (l->nplz_z)) > 1) { s1 = StringCat (s1, XmStringCreate (", ", XmFONTLIST_DEFAULT_TAG)); msg[0] = '\0'; AppendHn (msg, l->hnr1von, sizeof (l->hnr1von)); AppendHn (msg, l->hnr2von, sizeof (l->hnr2von)); strcat (msg, "-"); AppendHn (msg, l->hnr1bis, sizeof (l->hnr1bis)); AppendHn (msg, l->hnr2bis, sizeof (l->hnr2bis)); isoMsg = IbmToIso (msg); s1 = StringCat (s1, XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG)); free (isoMsg); } else { if (strncmp (l->sname, sname, sizeof (l->sname)) != 0 || strncmp (l->strlfdnr, strlfdnr, sizeof (l->strlfdnr)) != 0) { strncpy (sname, l->sname, sizeof (l->sname)); strncpy (strlfdnr, l->strlfdnr, sizeof (l->strlfdnr)); } else { entriesLeft--; XmStringFree (s1); continue; } } /* Orts-String (bei mehreren gleichnamigen Straßen): */ if (strntoi (l->anzgleist, sizeof (l->anzgleist)) > 1) { if (strncmp (l->ortsteil, ortsteil, sizeof (l->ortsteil)) != 0) { s1 = StringCat (s1, XmStringSeparatorCreate ()); strncpy (ortsteil, l->ortsteil, sizeof (l->ortsteil)); strcpy (msg, " "); strncat (msg, l->plz_w_o, sizeof (l->plz_w_o)); StripBlanks (msg); strncat (msg, l->plzalt, sizeof (l->plzalt)); strcat (msg, " "); strncat (msg, ortsname, sizeof (((Umsda *) 0)->ortname_a)); StripBlanks (msg); strcat (msg, " "); strncat (msg, l->npanst, sizeof (l->npanst)); StripBlanks (msg); strcat (msg, " ("); strncat (msg, l->ortsteil, sizeof (l->ortsteil)); StripBlanks (msg); strcat (msg, ")"); StripBlanks (msg); isoMsg = IbmToIso (msg); s1 = StringCat (s1, XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG)); free (isoMsg); } else { entriesLeft--; XmStringFree (s1); continue; } } stringList[j++] = s1; } XtVaSetValues (list, XmNitems, stringList, XmNitemCount, (long) entriesLeft, NULL); for (i = 0; i < entriesLeft; i++) XmStringFree (stringList[i]); free (stringList); } void OrteToList (Widget list, UmsdaSet *orte, OrtardaSet *archivOrte) { Umsda *lu; Ortarda *lo; int i; XmString *stringList = (XmString *) calloc ((int) orte->entries + (int) archivOrte->entries, sizeof (XmString *)); XmString s1; char msg[300]; char *isoMsg; char *c; for (lu = orte->list, i = 0; i < orte->entries; i++) { /* PLZ alt, Ortsname, Postanstalt: */ msg[0] = '\0'; strncat (msg, lu->plz_w_o, sizeof (lu->plz_w_o)); strncat (msg, lu->plzalt, sizeof (lu->plzalt)); strcat (msg, " "); strncat (msg, lu->ortname_a, sizeof (lu->ortname_a)); StripBlanks (msg); strcat (msg, " "); strncat (msg, lu->npanst_a, sizeof (lu->npanst_a)); StripBlanks (msg); isoMsg = IbmToIso (msg); s1 = XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG); free (isoMsg); /* Ortszusatz: */ *msg = '\0'; c = lu->ortzusa; if (*c != ',' && *c != '-') strcat (msg, " "); while (*c == ' ' && c - lu->ortzusa < sizeof (lu->ortzusa)) c++; if (c - lu->ortzusa < sizeof (lu->ortzusa)) strncat (msg, c, sizeof (lu->ortzusa) - (c - lu->ortzusa)); StripBlanks (msg); isoMsg = IbmToIso (msg); stringList[i] = StringCat (s1, XmStringCreate (isoMsg, "italic")); free (isoMsg); lu++; } for (lo = archivOrte->list; i < orte->entries + archivOrte->entries; i++) { /* PLZ alt, Ortsname, Postanstalt: */ msg[0] = '\0'; strncat (msg, lo->plz_w_o, sizeof (lo->plz_w_o)); strncat (msg, lo->plzalt, sizeof (lo->plzalt)); strcat (msg, " "); strncat (msg, lo->ortname_a, sizeof (lo->ortname_a)); StripBlanks (msg); strcat (msg, " "); strncat (msg, lo->npanst_a, sizeof (lo->npanst_a)); StripBlanks (msg); isoMsg = IbmToIso (msg); s1 = XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG); free (isoMsg); /* aktueller Ortsname: */ strcpy (msg, " -> "); strncat (msg, lo->ortname_n, sizeof (lo->ortname_n)); StripBlanks (msg); isoMsg = IbmToIso (msg); stringList[i] = StringCat (s1, XmStringCreate (isoMsg, "italic")); free (isoMsg); lo++; } XtVaSetValues (list, XmNitems, stringList, XmNitemCount, (long) (orte->entries + archivOrte->entries), NULL); for (i = 0; i < orte->entries + archivOrte->entries; i++) XmStringFree (stringList[i]); free (stringList); } XtCallbackProc QuitCallback (Widget widget, XtPointer clientData, XtPointer callData) { XtDestroyApplicationContext (XtWidgetToApplicationContext (widget)); exit (0); } static Boolean RecordRead (char *record) { Note ("."); return True; } static Boolean PofadaRecordRead (char *record) { return RecordRead (record); } static Boolean StradaRecordRead (char *record) { return RecordRead (record); } static Boolean UmsdaRecordRead (char *record) { return RecordRead (record); } static Boolean OrtardaRecordRead (char *record) { return RecordRead (record); } void MotifInterface (Display *display) { static ConversionData cd; static PlzConversion pc; static GuiComponents gc; Widget applicationShell; cd.pc = &pc; cd.gc = &gc; cd.batch = (Batch *) 0; gc.strasse = gc.ort = gc.plz_neu = (Widget) 0; cd.pc->plz_alt = (char *) 0; cd.pc->ort = (char *) 0; cd.pc->postanstalt = (char *) 0; cd.pc->ortsteil = (char *) 0; cd.pc->strasse = (char *) 0; cd.pc->hausnummer = (char *) 0; cd.pc->postfach = (char *) 0; cd.pc->plz_neu = (char *) 0; cd.pc->verkehrsgebiet = 'W'; cd.pc->orte = (UmsdaSet *) 0; cd.pc->strassen = (StradaSet *) 0; cd.pc->postfaecher = (PofadaSet *) 0; /* kleiner Hack für Motif 1.2.1: */ XDeleteProperty (display, RootWindowOfScreen (DefaultScreenOfDisplay (display)), XInternAtom (display, "_MOTIF_DRAG_WINDOW", False)); applicationShell = CreateMainWindow (display, &cd); userInterfaceMethods.uiComponents = (UiComponents *) &gc; userInterfaceMethods.NoteClear = GuiNoteClear; userInterfaceMethods.NoteWrite = GuiNoteWrite; userInterfaceMethods.MsgWrite = GuiMsgWrite; userInterfaceMethods.MsgFlush = GuiMsgFlush; userInterfaceMethods.PofadaRecordRead = PofadaRecordRead; userInterfaceMethods.StradaRecordRead = StradaRecordRead; userInterfaceMethods.UmsdaRecordRead = UmsdaRecordRead; userInterfaceMethods.OrtardaRecordRead = OrtardaRecordRead; XmProcessTraversal (cd.gc->ort, XmTRAVERSE_CURRENT); XtAppMainLoop (XtWidgetToApplicationContext (applicationShell)); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.