From 060806ab511ded5b06d02222963d8d5171fcf0fe Mon Sep 17 00:00:00 2001 From: llsth Date: Sun, 21 Jun 2015 00:34:10 +0200 Subject: [PATCH] Time zone preferences --- tzselect.c | 342 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 tzselect.c diff --git a/tzselect.c b/tzselect.c new file mode 100644 index 0000000..551117d --- /dev/null +++ b/tzselect.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2015 Carsten Larsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * @file tzselect.c + * @brief + * Inspired from example at: + * http://thomas-rapp.homepage.t-online.de/examples/lv.c + * + * Retrieved 2015-06-20 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zone.h" + +#define GID_LIST 1001 +#define GID_STRING 1002 +#define GID_SAVE 1010 +#define GID_USE 1011 +#define GID_CANCEL 1012 + +#ifndef __amigaos4__ +#define NewList(list) ((list)->lh_Head = (struct Node *)&(list)->lh_Tail,(list)->lh_TailPred = (struct Node *)&(list)->lh_Head,(list)->lh_Tail = NULL) +#define GetHead(list) ((list) && (list)->lh_Head && (list)->lh_Head->ln_Succ ? (list)->lh_Head : NULL) +#define GetTail(list) ((list) && (list)->lh_TailPred && (list)->lh_TailPred->ln_Pred ? (list)->lh_TailPred : NULL) +#define GetSucc(node) ((node) && (node)->ln_Succ->ln_Succ ? (node)->ln_Succ : NULL) +#define GetPred(node) ((node) && (node)->ln_Pred->ln_Pred ? (node)->ln_Pred : NULL) +#endif + +void free_list (struct List *list) + +{ + struct Node *node; + + while (node = RemHead (list)) + FreeVec (node); +} + +struct Node *get_node (struct List *list,ULONG num) + +{ + struct Node *node; + ULONG i = 0; + + for (node = GetHead(list); node; node = GetSucc(node)) + { + if (i == num) + return (node); + i ++; + } + + return (NULL); +} + +ULONG node_number (struct List *list,struct Node *node_to_find) + +{ + struct Node *node; + ULONG i = 0; + + for (node = GetHead(list); node; node = GetSucc(node)) + { + if (node == node_to_find) + return (i); + i ++; + } + + return (-1); +} +/*----------------------------------------------------------------------------*/ +/* Eine Node mit neuem Text ersetzen */ +/*----------------------------------------------------------------------------*/ + +struct Node *replace_node_text (struct List *list,struct Node *node,char *text) + +{ + struct Node *pred; + struct Node *new; + + if (new = AllocVec (sizeof(struct Node) + strlen(text) + 1,MEMF_CLEAR)) + { + new->ln_Name = (STRPTR)(new + 1); + strcpy (new->ln_Name,text); + + pred = node->ln_Pred; + + Remove (node); + FreeVec (node); + + Insert (list,new,pred); + } + + return (new); +} + +int cmploc (const void * a, const void * b) +{ + struct Location *loca, *locb; + loca = (struct Location*)a; + locb = (struct Location*)b; + return strcmp(loca->tz, locb->tz); +} + +/**********************************/ + +int main (void) +{ + struct Screen *screen; + struct Window *window; + struct NewGadget ng; + + struct Gadget *glist, *gad; + + int width, height; + int fontw, fonth; + struct List lvlist; + + ULONG winsig; + ULONG sigs; + BOOL cont; + struct Gadget *lvgad; + struct Gadget *strgad; + struct Node *node = NULL; + struct Node *nextnode; + struct IntuiMessage *imsg; + ULONG size; + char *text; + ULONG num; + + unsigned int i; + const unsigned int count = sizeof(locations) / sizeof(struct Location); + + NewList (&lvlist); + + if (!(screen = LockPubScreen(NULL))) + { + exit(10); + } + + glist = NULL; + gad = CreateContext(&glist); + + // ********************************************************** // + ng.ng_VisualInfo = GetVisualInfo(screen, TAG_END); + ng.ng_TextAttr = screen->Font; + ng.ng_Flags = 0; + + fontw = screen->RastPort.TxWidth; + fonth = screen->RastPort.TxHeight; + + width = screen->WBorTop + fonth + 5; /* top of listview */ + height = 20 * fonth + 4; /* height of listview */ + + ng.ng_LeftEdge = screen->WBorLeft + 4; + ng.ng_TopEdge = width + height; + ng.ng_Height = fonth + 6; + ng.ng_Width = (3*16 * fontw + 3*8 + 2*4) / 2 - 2; + ng.ng_GadgetText = NULL; + ng.ng_GadgetID = GID_STRING; + gad = CreateGadget (STRING_KIND,gad,&ng,GA_Disabled,TRUE,TAG_END); + strgad = gad; + + ng.ng_TopEdge = width; + ng.ng_Height += height; /* including string height */ + ng.ng_GadgetID = GID_LIST; + gad = CreateGadget (LISTVIEW_KIND,gad,&ng,GTLV_Labels,&lvlist,GTLV_ShowSelected,gad,TAG_END); + lvgad = gad; + + ng.ng_TopEdge += ng.ng_Height + 4; + ng.ng_Width = 16 * fontw + 8; + ng.ng_Height = fonth + 6; + /* + ng.ng_GadgetText = "Add"; + ng.ng_GadgetID = GID_ADD; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Remove"; + ng.ng_GadgetID = GID_REMOVE; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Sort"; + ng.ng_GadgetID = GID_SORT; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + */ + + ng.ng_TopEdge += ng.ng_Height + 4; + ng.ng_LeftEdge = screen->WBorLeft + 4; + ng.ng_GadgetText = "Save"; + ng.ng_GadgetID = GID_SAVE; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Use"; + ng.ng_GadgetID = GID_USE; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Cancel"; + ng.ng_GadgetID = GID_CANCEL; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + // ********************************************************** // + + if (!gad) + { + Printf ("cannot create objects\n"); + FreeGadgets (glist); + UnlockPubScreen (NULL,screen); + exit(10); + } + + width = ng.ng_LeftEdge + ng.ng_Width + 4 + screen->WBorRight; + height = ng.ng_TopEdge + ng.ng_Height + 4 + screen->WBorBottom; + + qsort(locations, count, sizeof(struct Location), cmploc); + for (i = 0; i < count; i++) { + if (node = AllocVec (sizeof(struct Node) + strlen(locations[i].tz) + 1,MEMF_CLEAR)) + { + node->ln_Name = (STRPTR)(node + 1); + strcpy (node->ln_Name,locations[i].tz); + AddTail (&lvlist, node); + } + } + + if (window = OpenWindowTags (NULL, + WA_Title, "Time zone preferences", + WA_Width, width, + WA_Height, height, + WA_Left, (screen->Width - width) / 2, + WA_Top, (screen->Height - height) / 2, + WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE, + WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_REFRESHWINDOW | BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP, + WA_PubScreen, screen, + WA_Gadgets, glist, + TAG_END)) + { + GT_RefreshWindow(window, NULL); + GT_SetGadgetAttrs(lvgad, window, NULL, GTLV_Labels, &lvlist, TAG_END); + + winsig = 1L << window->UserPort->mp_SigBit; + + // ********************************************************** // + + cont = TRUE; + do { + sigs = Wait(winsig | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + cont = FALSE; + + if (sigs & winsig) + { + while (imsg = GT_GetIMsg (window->UserPort)) + { + switch (imsg->Class) { + case IDCMP_GADGETUP: + gad = (struct Gadget *) imsg->IAddress; + switch (gad->GadgetID) + { + case GID_CANCEL: + cont = FALSE; + break; + case GID_LIST: + GT_GetGadgetAttrs (lvgad,window,NULL,GTLV_Selected,&num,TAG_END); + if (node = get_node (&lvlist,num)) + { + GT_SetGadgetAttrs (strgad,window,NULL,GTST_String,node->ln_Name,GA_Disabled,FALSE,TAG_END); + ActivateGadget (strgad,window,NULL); + } + break; + case GID_STRING: + if (node) + { + GT_GetGadgetAttrs (strgad,window,NULL,GTST_String,&text,TAG_END); + GT_SetGadgetAttrs (lvgad,window,NULL,GTLV_Labels,-1,TAG_END); + node = replace_node_text (&lvlist,node,text); + GT_SetGadgetAttrs (lvgad,window,NULL,GTLV_Labels,&lvlist,TAG_END); + } + break; + } + break; + case IDCMP_VANILLAKEY: + if (imsg->Code == 0x1b) /* Esc */ + cont = FALSE; + break; + case IDCMP_REFRESHWINDOW: + GT_BeginRefresh(window); + GT_EndRefresh(window, TRUE); + break; + case IDCMP_CLOSEWINDOW: + cont = FALSE; + break; + } + GT_ReplyIMsg (imsg); + } + } + } while (cont); + + CloseWindow(window); + } + + FreeGadgets (glist); + UnlockPubScreen (NULL, screen); + + free_list(&lvlist); + + return (0); +}