/* * 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); }