/*- * Copyright (c) 2017-2021 Carsten Sonne 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. * */ #include "config.h" #include "global.h" #include "message.h" #include "setting.h" #include "timer.h" #include "conv.h" #include "text.h" #include "mem.h" #include "win.h" #include "val.h" #include "tz.h" #include "logmod.h" #define MODULENAME "Window" struct AppSettingWindowGadgets { struct Gadget *ServerGadget; struct Gadget *PortGadget; struct Gadget *TimeoutGadget; struct Gadget *IntervalGadget; struct Gadget *ThresholdGadget; struct Gadget *PriorityGadget; struct Gadget *TimezoneGadget; struct Gadget *LastSyncGadget; }; static const char *serverLabel = "Server address"; static const char *portLabel = "Server port"; static const char *timeoutLabel = "Timeout (ms)"; static const char *intervalLabel = "Interval (ms)"; static const char *thresholdLabel = "Threshold (us)"; static const char *priorityLabel = "CX priority"; static const char *TimezoneLabel = "Time zone"; static const char *lastSyncLabel = "Last sync"; static const char *saveLabel = "Save"; static const char *useLabel = "Use"; static const char *cancelLabel = "Cancel"; static const char **textLabels[] = { &serverLabel, &portLabel, &timeoutLabel, &intervalLabel, &thresholdLabel, &priorityLabel, &TimezoneLabel, &lastSyncLabel, NULL}; int GetLabelWidth(struct RastPort *rp) { int len, max = 0; int c, i = 0; const char **label = textLabels[0]; while (*label != NULL) { c = StrLen(*label); len = TextLength(rp, (CONST_STRPTR)*label, c); if (len > max) { max = len; } label = textLabels[++i]; } return max; } bool CreateGadgets(void) { struct Gadget *gadget; struct NewGadget *ng; long x, y, h; long labelWidth; long textWidth, boxWidth; long col1, col2; long labelId; long tmp1, tmp2; SettingWindow.Gadgets = AllocStructSafe(struct AppSettingWindowGadgets); ng = AllocStructSafe(struct NewGadget); if (!ng) return false; gadget = CreateContext(&SettingWindow.GadgetList); if (!gadget) return false; ng->ng_VisualInfo = SettingWindow.VisualInfo; ng->ng_TextAttr = SettingWindow.Screen->Font; ng->ng_Flags = 0; h = SettingWindow.Screen->RastPort.TxHeight; x = SettingWindow.Screen->WBorLeft + 8; y = SettingWindow.Screen->WBorTop + h + 9; labelWidth = GetLabelWidth(&SettingWindow.Screen->RastPort); col1 = x; textWidth = labelWidth + SettingWindow.Screen->RastPort.TxWidth / 2; col2 = col1 + textWidth; boxWidth = labelWidth; ng->ng_TopEdge = y; ng->ng_Height = h + 6; labelId = 5000; // Server ng->ng_LeftEdge = col1; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)serverLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = GID_SERVER; gadget = CreateGadget( STRING_KIND, gadget, ng, GTST_String, (IPTR)Settings->DestinationAddress, TAG_END); if (!gadget) return false; SettingWindow.Gadgets->ServerGadget = gadget; if (Settings->Expert) { // Port ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)portLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = GID_PORT; gadget = CreateGadget( STRING_KIND, gadget, ng, GTST_String, (IPTR)Settings->DestinationPort, TAG_END); if (!gadget) return false; SettingWindow.Gadgets->PortGadget = gadget; // Interval ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTNM_MaxNumberLen, 8, GTTX_Text, (IPTR)intervalLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = GID_INTERVAL; gadget = CreateGadget( INTEGER_KIND, gadget, ng, GTNM_MaxNumberLen, 8, GTIN_Number, Settings->Interval, TAG_END); if (!gadget) return false; gadget->Flags |= GFLG_TABCYCLE; SettingWindow.Gadgets->IntervalGadget = gadget; // Timeout ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)timeoutLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = GID_TIMEOUT; gadget = CreateGadget( INTEGER_KIND, gadget, ng, GTNM_MaxNumberLen, 8, GTIN_Number, Settings->Timeout, TAG_END); if (!gadget) return false; gadget->Flags |= GFLG_TABCYCLE; SettingWindow.Gadgets->TimeoutGadget = gadget; // Threshold ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)thresholdLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = GID_THRESHOLD; gadget = CreateGadget( STRING_KIND, gadget, ng, GTST_String, (IPTR)SettingWindow.ThresholdText, TAG_END); if (!gadget) return false; gadget->Flags |= GFLG_TABCYCLE; SettingWindow.Gadgets->ThresholdGadget = gadget; // Priority ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)priorityLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = (boxWidth + 20) / 2; ng->ng_GadgetID = GID_PRIORITY; gadget = CreateGadget( STRING_KIND, gadget, ng, GTST_String, (IPTR)SettingWindow.PriorityText, TAG_END); if (!gadget) return false; gadget->Flags |= GFLG_TABCYCLE; SettingWindow.Gadgets->PriorityGadget = gadget; } // Time zone ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)TimezoneLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)SettingWindow.TimezoneText, TAG_END); if (!gadget) return false; SettingWindow.Gadgets->TimezoneGadget = gadget; // Last sync ng->ng_LeftEdge = col1; ng->ng_TopEdge += ng->ng_Height + 4; ng->ng_Width = textWidth; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, GTTX_Text, (IPTR)lastSyncLabel, TAG_END); if (!gadget) return false; ng->ng_LeftEdge = col2; ng->ng_Width = boxWidth + 20; ng->ng_GadgetID = labelId++; gadget = CreateGadget( TEXT_KIND, gadget, ng, TAG_END); if (!gadget) return false; SettingWindow.Gadgets->LastSyncGadget = gadget; tmp1 = ng->ng_LeftEdge + ng->ng_Width - 18; // Why is this 18? tmp2 = tmp1 / 3; ng->ng_TopEdge += ng->ng_Height + 6; ng->ng_Width = tmp2; ng->ng_LeftEdge = col1; ng->ng_GadgetText = (STRPTR)saveLabel; ng->ng_GadgetID = GID_SAVE; ng->ng_Flags = 0; gadget = CreateGadget(BUTTON_KIND, gadget, ng, TAG_END); if (!gadget) return false; ng->ng_LeftEdge += ng->ng_Width + 4; ng->ng_GadgetText = (STRPTR)useLabel; ng->ng_GadgetID = GID_USE; gadget = CreateGadget(BUTTON_KIND, gadget, ng, TAG_END); if (!gadget) return false; ng->ng_LeftEdge += ng->ng_Width + 4; ng->ng_GadgetText = (STRPTR)cancelLabel; ng->ng_GadgetID = GID_CANCEL; gadget = CreateGadget(BUTTON_KIND, gadget, ng, TAG_END); if (!gadget) return false; SettingWindow.Height = ng->ng_TopEdge + ng->ng_Height; SettingWindow.Width = textWidth + boxWidth; FreeMemSafe(ng); return true; } void UseSettings(void) { LogNotice("Apply new settings"); ReadUiServer(); ReadUiPort(); ReadUiInterval(); ReadUiTimeout(); ReadUiThreshold(); ReadUiCxPriority(); } void WriteUiServer(void) { if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->ServerGadget == NULL) return; GT_SetGadgetAttrs( SettingWindow.Gadgets->ServerGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)Settings->DestinationAddress, TAG_END); } void ReadUiServer(void) { char *valueString; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->ServerGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->ServerGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)&valueString, TAG_END); SetServer(valueString, APPLY_UI_FRONT | APPLY_RUNTIME); } void WriteUiPort(void) { if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->PortGadget == NULL) return; GT_SetGadgetAttrs( SettingWindow.Gadgets->PortGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)Settings->DestinationPort, TAG_END); } void ReadUiPort(void) { char *valueString; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->PortGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->PortGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)&valueString, TAG_END); SetPort(valueString, APPLY_UI_FRONT | APPLY_RUNTIME); } void WriteUiInterval(void) { if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->IntervalGadget == NULL) return; GT_SetGadgetAttrs( SettingWindow.Gadgets->IntervalGadget, SettingWindow.Window, NULL, GTIN_Number, (ULONG)Settings->Interval, TAG_END); } void ReadUiInterval(void) { unsigned long value; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->IntervalGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->IntervalGadget, SettingWindow.Window, NULL, GTIN_Number, (IPTR)&value, TAG_END); SetInterval(value, APPLY_UI_FRONT | APPLY_RUNTIME); } void WriteUiTimeout(void) { if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->TimeoutGadget == NULL) return; GT_SetGadgetAttrs( SettingWindow.Gadgets->TimeoutGadget, SettingWindow.Window, NULL, GTIN_Number, (ULONG)Settings->Timeout, TAG_END); } void ReadUiTimeout(void) { unsigned long value; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->TimeoutGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->TimeoutGadget, SettingWindow.Window, NULL, GTIN_Number, (IPTR)&value, TAG_END); SetTimeout(value, APPLY_UI_FRONT | APPLY_RUNTIME); } void WriteUiThreshold(void) { char value[MAXLONGLONGCHARSIZE]; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->ThresholdGadget == NULL) return; LongLongToStr(Settings->Threshold, value); GT_SetGadgetAttrs( SettingWindow.Gadgets->ThresholdGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)value, TAG_END); } void ReadUiThreshold(void) { char *valueString; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->ThresholdGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->ThresholdGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)&valueString, TAG_END); SetThreshold(valueString, APPLY_UI_FRONT | APPLY_RUNTIME); } void WriteUiCxPriority(void) { char value[MAXLONGCHARSIZE]; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->PriorityGadget == NULL) return; LongToStr(Settings->Priority, value); GT_SetGadgetAttrs( SettingWindow.Gadgets->PriorityGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)value, TAG_END); } void ReadUiCxPriority(void) { char *valueString; if (SettingWindow.Gadgets == NULL || SettingWindow.Gadgets->PriorityGadget == NULL) return; GT_GetGadgetAttrs( SettingWindow.Gadgets->PriorityGadget, SettingWindow.Window, NULL, GTST_String, (IPTR)&valueString, TAG_END); SetPriority(valueString, APPLY_UI_FRONT | APPLY_RUNTIME); } void ShowLastSync(struct timeval *tv) { static char label[10]; struct timeval nowLocal, lastLocal; struct ClockData clockdata; struct DateTime dateTime = { .dat_Stamp = {.ds_Days = 0}, .dat_Format = FORMAT_DOS, .dat_Flags = 0, .dat_StrDay = NULL, .dat_StrDate = NULL, .dat_StrTime = (STRPTR)label}; long seconds; if (tv->tv_secs == 0) { static const char *never = "Not synced yet"; GT_SetGadgetAttrs( SettingWindow.Gadgets->LastSyncGadget, SettingWindow.Window, NULL, GTTX_Text, (IPTR)never, TAG_END); return; } GetLocalTimeOfDay(&nowLocal); UnixUtc2AmigaLocal(tv, &lastLocal); seconds = nowLocal.tv_secs - lastLocal.tv_secs; if (seconds > 60 * 60 * 24) { static const char *tooOld = "> 24 hours"; GT_SetGadgetAttrs( SettingWindow.Gadgets->LastSyncGadget, SettingWindow.Window, NULL, GTTX_Text, (IPTR)tooOld, TAG_END); return; } Amiga2Date(lastLocal.tv_secs, &clockdata); dateTime.dat_Stamp.ds_Minute = clockdata.hour * 60 + clockdata.min; dateTime.dat_Stamp.ds_Tick = clockdata.sec * 50; DateToStr(&dateTime); GT_SetGadgetAttrs( SettingWindow.Gadgets->LastSyncGadget, SettingWindow.Window, NULL, GTTX_Text, (IPTR)label, TAG_END); } void ShowNewTimezone(void) { char *temp = SettingWindow.TimezoneText; char *new = AllocStringSafe(TIMEZONE_TEXT_LEN); GetTimezoneText(new, TZD_ZONE_IN_PARENS); GT_SetGadgetAttrs( SettingWindow.Gadgets->TimezoneGadget, SettingWindow.Window, NULL, GTTX_Text, (IPTR) new, TAG_END); SettingWindow.TimezoneText = new; FreeMemSafe(temp); }