Keep your time right
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

627 lines
14 KiB

/*-
* Copyright (c) 2017-2021 Carsten Sonne Larsen <cs@innolan.net>
* 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);
}