MeOS, version 4.0 BETA 1

This commit is contained in:
Erik Melin 2024-03-19 08:51:20 +01:00
parent 16272ffa20
commit 11942302fa
205 changed files with 11350 additions and 3589 deletions

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -41,28 +41,30 @@ extern Image image;
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
using namespace std;
double getLocalScale(const wstring &fontName, wstring &faceName); double getLocalScale(const wstring &fontName, wstring &faceName);
wstring getMeosCompectVersion(); wstring getMeosCompectVersion();
map <string, shared_ptr<HTMLWriter>> HTMLWriter::tCache; map <string, shared_ptr<HTMLWriter>> HTMLWriter::tCache;
extern wchar_t exePath[MAX_PATH]; extern wchar_t exePath[MAX_PATH];
static void generateStyles(const gdioutput &gdi, ostream &fout, double scale, bool withTbl, const list<TextInfo> &TL, static void generateStyles(const gdioutput &gdi, std::ostream &fout, double scale, bool withTbl, const list<TextInfo> &TL,
map< pair<gdiFonts, string>, pair<string, string> > &styles) { map< pair<gdiFonts, string>, pair<string, string> > &styles) {
fout << "<style type=\"text/css\">\n"; fout << "<style type=\"text/css\">\n";
fout << "body {background-color: rgb(250,250,255)}\n"; fout << "body {background-color: rgb(250,250,255)}\n";
fout << "h1 {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 24 * scale << "px;font-weight:normal;white-space:nowrap}\n"; fout << "h1 {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 24 * scale << "px;font-weight:normal;white-space:nowrap}\n";
fout << "h2 {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 20 * scale << "px;font-weight:normal;white-space:nowrap}\n"; fout << "h2 {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 20 * scale << "px;font-weight:normal;white-space:nowrap}\n";
fout << "h3 {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 16 * scale << "px;font-weight:normal;white-space:nowrap}\n"; fout << "h3 {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 16 * scale << "px;font-weight:normal;white-space:nowrap}\n";
fout << "p {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal}\n"; fout << "p {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal}\n";
fout << "div {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal;white-space:nowrap}\n"; fout << "div {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal;white-space:nowrap}\n";
if (withTbl) { if (withTbl) {
fout << "td {font-family:arial,sans-serif;font-size:" << fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal;white-space:nowrap}\n"; fout << "td {font-family:arial,sans-serif;font-size:" << std::fixed << std::setprecision(2) << 12 * scale << "px;font-weight:normal;white-space:nowrap}\n";
fout << "td.e0 {background-color: rgb(238,238,255)}\n"; fout << "td.e0 {background-color: rgb(238,238,255)}\n";
fout << "td.e1 {background-color: rgb(245,245,255)}\n"; fout << "td.e1 {background-color: rgb(245,245,255)}\n";
fout << "td.header {line-height:" << fixed << std::setprecision(2) << 1.8 * scale << ";height:" << fixed << std::setprecision(2) << 40 * scale << "px}\n"; fout << "td.header {line-height:" << std::fixed << std::setprecision(2) << 1.8 * scale << ";height:" << std::fixed << std::setprecision(2) << 40 * scale << "px}\n";
fout << "td.freeheader {line-height:" << fixed << std::setprecision(2) << 1.2 * scale << "}\n"; fout << "td.freeheader {line-height:" << std::fixed << std::setprecision(2) << 1.2 * scale << "}\n";
} }
list<TextInfo>::const_iterator it=TL.begin(); list<TextInfo>::const_iterator it=TL.begin();
int styleList = 1; int styleList = 1;

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -49,11 +49,11 @@ class HTMLWriter {
ImageWriter(const wstring& dst, bool writeImages) : destination(dst), writeImages(writeImages) {} ImageWriter(const wstring& dst, bool writeImages) : destination(dst), writeImages(writeImages) {}
void write(ostream &fout, const string &xp, const string &yp, const wstring &img, int width, int height); void write(std::ostream &fout, const string &xp, const string &yp, const wstring &img, int width, int height);
}; };
template<typename T, typename TI> template<typename T, typename TI>
static void formatTL(ostream& fout, static void formatTL(std::ostream& fout,
ImageWriter& imageWriter, ImageWriter& imageWriter,
const map< pair<gdiFonts, string>, pair<string, string> >& styles, const map< pair<gdiFonts, string>, pair<string, string> >& styles,
const T& tl, const T& tl,
@ -87,7 +87,7 @@ public:
void read(const wstring &fileName); void read(const wstring &fileName);
void generate(gdioutput &gdi, void generate(gdioutput &gdi,
ostream &fout, std::ostream &fout,
const wstring &title, const wstring &title,
const wstring &contentDescription, const wstring &contentDescription,
bool respectPageBreak, bool respectPageBreak,
@ -99,12 +99,12 @@ public:
void getPage(const oEvent &oe, string &out) const; void getPage(const oEvent &oe, string &out) const;
static void writeHTML(gdioutput &gdi, ostream &dout, const wstring &title, static void writeHTML(gdioutput &gdi, std::ostream &dout, const wstring &title,
bool includeImages, bool includeImages,
const wstring& imageDirectoryDestination, const wstring& imageDirectoryDestination,
int refreshTimeOut, double scale); int refreshTimeOut, double scale);
static void writeTableHTML(gdioutput &gdi, ostream &fout, static void writeTableHTML(gdioutput &gdi, std::ostream &fout,
const wstring &title, const wstring &title,
bool includeImages, bool includeImages,
const wstring &imageDirectoryDestination, const wstring &imageDirectoryDestination,
@ -121,13 +121,13 @@ public:
const wstring &title, int refreshTimeOut, double scale); const wstring &title, int refreshTimeOut, double scale);
static void write(gdioutput& gdi, const wstring& file, const wstring& title, int refresh, oListParam& param, const oEvent& oe); static void write(gdioutput& gdi, const wstring& file, const wstring& title, int refresh, oListParam& param, const oEvent& oe);
static void write(gdioutput& gdi, ostream& fout, const wstring& title, int refresh, oListParam& param, const oEvent& oe); static void write(gdioutput& gdi, std::ostream& fout, const wstring& title, int refresh, oListParam& param, const oEvent& oe);
static void write(gdioutput& gdi, const wstring& file, const wstring& title, const wstring& contentsDescription, static void write(gdioutput& gdi, const wstring& file, const wstring& title, const wstring& contentsDescription,
bool respectPageBreak, const string& typeTag, int refresh, bool respectPageBreak, const string& typeTag, int refresh,
int rows, int cols, int time_ms, int margin, double scale); int rows, int cols, int time_ms, int margin, double scale);
static void write(gdioutput& gdi, ostream& fout, const wstring& title, static void write(gdioutput& gdi, std::ostream& fout, const wstring& title,
bool includeImages, bool includeImages,
const wstring& imageDirectoryDestination, const wstring& imageDirectoryDestination,
const wstring& contentsDescription, const wstring& contentsDescription,

31
code/MeOS.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeOS", "MeOS.vcxproj", "{60BC59CB-8987-4A39-B866-403066F59B0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{60BC59CB-8987-4A39-B866-403066F59B0F}.Debug|x64.ActiveCfg = Debug|x64
{60BC59CB-8987-4A39-B866-403066F59B0F}.Debug|x64.Build.0 = Debug|x64
{60BC59CB-8987-4A39-B866-403066F59B0F}.Debug|x86.ActiveCfg = Debug|Win32
{60BC59CB-8987-4A39-B866-403066F59B0F}.Debug|x86.Build.0 = Debug|Win32
{60BC59CB-8987-4A39-B866-403066F59B0F}.Release|x64.ActiveCfg = Release|x64
{60BC59CB-8987-4A39-B866-403066F59B0F}.Release|x64.Build.0 = Release|x64
{60BC59CB-8987-4A39-B866-403066F59B0F}.Release|x86.ActiveCfg = Release|Win32
{60BC59CB-8987-4A39-B866-403066F59B0F}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0AA159AF-578B-49E9-8D52-50F9272169DB}
EndGlobalSection
EndGlobal

379
code/MeOS.vcxproj Normal file
View File

@ -0,0 +1,379 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{60BC59CB-8987-4A39-B866-403066F59B0F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>./libharu;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4267;4244;4018</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>./lib_db</AdditionalLibraryDirectories>
<AdditionalDependencies>Msimg32.lib;comctl32.lib;odbc32.lib;odbccp32.lib;winmm.lib;ws2_32.lib;wininet.lib;zlibstat_vc15.lib;libmysql.lib;libhpdf.lib;RestBed.lib;libpng.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>meos_dpi_manifest.xml %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4267;4244;4018</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>./libharu;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>Msimg32.lib;comctl32.lib;odbc32.lib;odbccp32.lib;winmm.lib;ws2_32.lib;wininet.lib;zlibstat.lib;libharu.lib;RestBed.lib;libpng.lib;libmysql.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>./lib64_db</AdditionalLibraryDirectories>
</Link>
<Manifest>
<AdditionalManifestFiles>meos_dpi_manifest.xml %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4267;4244;4018</DisableSpecificWarnings>
<AdditionalIncludeDirectories>./libharu;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>./lib</AdditionalLibraryDirectories>
<AdditionalDependencies>Msimg32.lib;comctl32.lib;odbc32.lib;odbccp32.lib;winmm.lib;ws2_32.lib;wininet.lib;zlibstat_vc15.lib;libmysql.lib;libhpdf.lib;RestBed.lib;libpng.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>meos_dpi_manifest.xml %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<DisableSpecificWarnings>4267;4244;4018</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>./libharu;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Msimg32.lib;comctl32.lib;odbc32.lib;odbccp32.lib;winmm.lib;ws2_32.lib;wininet.lib;zlibstat.lib;libharu.lib;RestBed.lib;libpng.lib;libmysql.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>./lib64</AdditionalLibraryDirectories>
</Link>
<Manifest>
<AdditionalManifestFiles>meos_dpi_manifest.xml %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="animationdata.cpp" />
<ClCompile Include="autocomplete.cpp" />
<ClCompile Include="autotask.cpp" />
<ClCompile Include="binencoder.cpp" />
<ClCompile Include="classconfiginfo.cpp" />
<ClCompile Include="csvparser.cpp" />
<ClCompile Include="download.cpp" />
<ClCompile Include="gdioutput.cpp" />
<ClCompile Include="generalresult.cpp" />
<ClCompile Include="HTMLWriter.cpp" />
<ClCompile Include="image.cpp" />
<ClCompile Include="importformats.cpp" />
<ClCompile Include="infoserver.cpp" />
<ClCompile Include="iof30interface.cpp" />
<ClCompile Include="listeditor.cpp" />
<ClCompile Include="liveresult.cpp" />
<ClCompile Include="localizer.cpp" />
<ClCompile Include="machinecontainer.cpp" />
<ClCompile Include="meos.cpp" />
<ClCompile Include="MeOSFeatures.cpp" />
<ClCompile Include="MeosSQL.cpp" />
<ClCompile Include="meosversion.cpp" />
<ClCompile Include="meos_util.cpp" />
<ClCompile Include="metalist.cpp" />
<ClCompile Include="methodeditor.cpp" />
<ClCompile Include="mysqldaemon.cpp" />
<ClCompile Include="mysqlwrapper.cpp" />
<ClCompile Include="newcompetition.cpp" />
<ClCompile Include="oBase.cpp" />
<ClCompile Include="oCard.cpp" />
<ClCompile Include="oClass.cpp" />
<ClCompile Include="oClub.cpp" />
<ClCompile Include="oControl.cpp" />
<ClCompile Include="oCourse.cpp" />
<ClCompile Include="oDataContainer.cpp" />
<ClCompile Include="oEvent.cpp" />
<ClCompile Include="oEventDraw.cpp" />
<ClCompile Include="oEventResult.cpp" />
<ClCompile Include="oEventSpeaker.cpp" />
<ClCompile Include="oEventSQL.cpp" />
<ClCompile Include="oevent_transfer.cpp" />
<ClCompile Include="oFreeImport.cpp" />
<ClCompile Include="oFreePunch.cpp" />
<ClCompile Include="oImportExport.cpp" />
<ClCompile Include="oListInfo.cpp" />
<ClCompile Include="onlineinput.cpp" />
<ClCompile Include="onlineresults.cpp" />
<ClCompile Include="oPunch.cpp" />
<ClCompile Include="oReport.cpp" />
<ClCompile Include="oRunner.cpp" />
<ClCompile Include="oTeam.cpp" />
<ClCompile Include="oTeamEvent.cpp" />
<ClCompile Include="parser.cpp" />
<ClCompile Include="pdfwriter.cpp" />
<ClCompile Include="prefseditor.cpp" />
<ClCompile Include="printer.cpp" />
<ClCompile Include="progress.cpp" />
<ClCompile Include="qf_editor.cpp" />
<ClCompile Include="qualification_final.cpp" />
<ClCompile Include="random.cpp" />
<ClCompile Include="recorder.cpp" />
<ClCompile Include="restserver.cpp" />
<ClCompile Include="RestService.cpp" />
<ClCompile Include="RunnerDB.cpp" />
<ClCompile Include="socket.cpp" />
<ClCompile Include="speakermonitor.cpp" />
<ClCompile Include="SportIdent.cpp" />
<ClCompile Include="StdAfx.cpp" />
<ClCompile Include="TabAuto.cpp" />
<ClCompile Include="TabBase.cpp" />
<ClCompile Include="TabClass.cpp" />
<ClCompile Include="TabClub.cpp" />
<ClCompile Include="TabCompetition.cpp" />
<ClCompile Include="TabControl.cpp" />
<ClCompile Include="TabCourse.cpp" />
<ClCompile Include="Table.cpp" />
<ClCompile Include="TabList.cpp" />
<ClCompile Include="TabMulti.cpp" />
<ClCompile Include="TabRunner.cpp" />
<ClCompile Include="TabSI.cpp" />
<ClCompile Include="TabSpeaker.cpp" />
<ClCompile Include="TabTeam.cpp" />
<ClCompile Include="testmeos.cpp" />
<ClCompile Include="tests.cpp" />
<ClCompile Include="TimeStamp.cpp" />
<ClCompile Include="toolbar.cpp" />
<ClCompile Include="xmlparser.cpp" />
<ClCompile Include="zip.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="animationdata.h" />
<ClInclude Include="autocomplete.h" />
<ClInclude Include="autocompletehandler.h" />
<ClInclude Include="autotask.h" />
<ClInclude Include="binencoder.h" />
<ClInclude Include="classconfiginfo.h" />
<ClInclude Include="csvparser.h" />
<ClInclude Include="download.h" />
<ClInclude Include="gdiconstants.h" />
<ClInclude Include="gdifonts.h" />
<ClInclude Include="gdiimpl.h" />
<ClInclude Include="gdioutput.h" />
<ClInclude Include="gdistructures.h" />
<ClInclude Include="generalresult.h" />
<ClInclude Include="guihandler.h" />
<ClInclude Include="HTMLWriter.h" />
<ClInclude Include="image.h" />
<ClInclude Include="importformats.h" />
<ClInclude Include="infoserver.h" />
<ClInclude Include="inthashmap.h" />
<ClInclude Include="intkeymap.hpp" />
<ClInclude Include="intkeymapimpl.hpp" />
<ClInclude Include="iof30interface.h" />
<ClInclude Include="listeditor.h" />
<ClInclude Include="liveresult.h" />
<ClInclude Include="localizer.h" />
<ClInclude Include="machinecontainer.h" />
<ClInclude Include="meos.h" />
<ClInclude Include="meosexception.h" />
<ClInclude Include="MeOSFeatures.h" />
<ClInclude Include="MeosSQL.h" />
<ClInclude Include="meos_util.h" />
<ClInclude Include="metalist.h" />
<ClInclude Include="methodeditor.h" />
<ClInclude Include="mysqlwrapper.h" />
<ClInclude Include="oBase.h" />
<ClInclude Include="oCard.h" />
<ClInclude Include="oClass.h" />
<ClInclude Include="oClub.h" />
<ClInclude Include="oControl.h" />
<ClInclude Include="oCourse.h" />
<ClInclude Include="oDataContainer.h" />
<ClInclude Include="oEvent.h" />
<ClInclude Include="oEventDraw.h" />
<ClInclude Include="oFreeImport.h" />
<ClInclude Include="oFreePunch.h" />
<ClInclude Include="oListInfo.h" />
<ClInclude Include="onlineinput.h" />
<ClInclude Include="onlineresults.h" />
<ClInclude Include="oPunch.h" />
<ClInclude Include="oRunner.h" />
<ClInclude Include="ospeaker.h" />
<ClInclude Include="oTeam.h" />
<ClInclude Include="parser.h" />
<ClInclude Include="pdfwriter.h" />
<ClInclude Include="prefseditor.h" />
<ClInclude Include="Printer.h" />
<ClInclude Include="progress.h" />
<ClInclude Include="qf_editor.h" />
<ClInclude Include="qualification_final.h" />
<ClInclude Include="random.h" />
<ClInclude Include="recorder.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="restserver.h" />
<ClInclude Include="RestService.h" />
<ClInclude Include="RunnerDB.h" />
<ClInclude Include="socket.h" />
<ClInclude Include="speakermonitor.h" />
<ClInclude Include="SportIdent.h" />
<ClInclude Include="StdAfx.h" />
<ClInclude Include="subcommand.h" />
<ClInclude Include="TabAuto.h" />
<ClInclude Include="TabBase.h" />
<ClInclude Include="TabClass.h" />
<ClInclude Include="TabClub.h" />
<ClInclude Include="TabCompetition.h" />
<ClInclude Include="TabControl.h" />
<ClInclude Include="TabCourse.h" />
<ClInclude Include="Table.h" />
<ClInclude Include="TabList.h" />
<ClInclude Include="TabMulti.h" />
<ClInclude Include="TabRunner.h" />
<ClInclude Include="TabSI.h" />
<ClInclude Include="TabSpeaker.h" />
<ClInclude Include="TabTeam.h" />
<ClInclude Include="testmeos.h" />
<ClInclude Include="timeconstants.hpp" />
<ClInclude Include="TimeStamp.h" />
<ClInclude Include="toolbar.h" />
<ClInclude Include="xmlparser.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="meos.rc" />
<ResourceCompile Include="meoslang.rc" />
</ItemGroup>
<ItemGroup>
<None Include="html1.htm" />
</ItemGroup>
<ItemGroup>
<Image Include="announcer24.png" />
<Image Include="bitmap1.bmp" />
<Image Include="bmp00001.bmp" />
<Image Include="class24.png" />
<Image Include="clubs24.png" />
<Image Include="competition24.png" />
<Image Include="course24.png" />
<Image Include="ctrl24.png" />
<Image Include="edit.png" />
<Image Include="info24.png" />
<Image Include="lists24.png" />
<Image Include="meos.ICO" />
<Image Include="meos.png" />
<Image Include="readout24.png" />
<Image Include="runner24.png" />
<Image Include="services24.png" />
<Image Include="team24.png" />
<Image Include="title.png" />
<Image Include="warn24.png" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -470,6 +470,12 @@ void MeosSQL::upgradeDB(const string &db, oDataContainer const * dc) {
sql = sql.substr(0, sql.length() - 2); sql = sql.substr(0, sql.length() - 2);
query.execute(sql); query.execute(sql);
} }
if (!eCol.count("Origin")) {
string sql = "ALTER TABLE " + db + " ";
sql += "ADD COLUMN " + C_INT("Origin");
sql = sql.substr(0, sql.length() - 2);
query.execute(sql);
}
} }
if (dc) { if (dc) {
// Ugrade table // Ugrade table
@ -700,7 +706,8 @@ bool MeosSQL::openDB(oEvent *oe)
<< C_INT("CardNo") << C_INT("CardNo")
<< C_INT("Time") << C_INT("Time")
<< C_INT("Type") << C_INT("Type")
<< C_INT("Unit") << C_END(); << C_INT("Unit")
<< C_INT("Origin") << C_END();
query.execute(); query.execute();
upgradeDB("oPunch", nullptr); upgradeDB("oPunch", nullptr);
@ -1622,6 +1629,8 @@ void MeosSQL::storePunch(const RowWrapper &row, oFreePunch &p, bool rehash)
p.type = row["Type"]; p.type = row["Type"];
} }
p.punchUnit = row["Unit"]; p.punchUnit = row["Unit"];
p.origin = row["Origin"];
p.sqlUpdated = row["Modified"]; p.sqlUpdated = row["Modified"];
p.counter = row["Counter"]; p.counter = row["Counter"];
p.Removed = row["Removed"]; p.Removed = row["Removed"];
@ -2953,6 +2962,7 @@ OpFailStatus MeosSQL::syncUpdate(oFreePunch *c, bool forceWriteAll)
queryset << " CardNo=" << c->CardNo << ", " queryset << " CardNo=" << c->CardNo << ", "
<< " Type=" << c->type << "," << " Type=" << c->type << ","
<< " Time=" << c->punchTime << "," << " Time=" << c->punchTime << ","
<< " Origin=" << c->origin << ","
<< " Unit=" << c->punchUnit; << " Unit=" << c->punchUnit;
return syncUpdate(queryset, "oPunch", c); return syncUpdate(queryset, "oPunch", c);

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -4,7 +4,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -28,7 +28,7 @@
#include <ShellAPI.h> #include <ShellAPI.h>
int AutomaticCB(gdioutput *gdi, int type, void *data); int AutomaticCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
RestService::RestService() : AutoMachine("Informationsserver", Machines::mInfoService), port(-1) { RestService::RestService() : AutoMachine("Informationsserver", Machines::mInfoService), port(-1) {
} }
@ -88,12 +88,12 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, State state) {
gdi.pushX(); gdi.pushX();
gdi.addCheckbox("AllowEntry", "Tillåt anmälan", 0, false).setHandler(this); gdi.addCheckbox("AllowEntry", "Tillåt anmälan", 0, false).setHandler(this);
gdi.addSelection("PermissionPerson", 180, 200, 0, L"Vem får anmäla sig:"); gdi.addSelection("PermissionPerson", 180, 200, 0, L"Vem får anmäla sig:");
gdi.addItem("PermissionPerson", RestServer::getPermissionsPersons()); gdi.setItems("PermissionPerson", RestServer::getPermissionsPersons());
gdi.autoGrow("PermissionPerson"); gdi.autoGrow("PermissionPerson");
gdi.selectFirstItem("PermissionPerson"); gdi.selectFirstItem("PermissionPerson");
gdi.fillDown(); gdi.fillDown();
gdi.addSelection("PermissionClass", 180, 200, 0, L"Till vilka klasser:"); gdi.addSelection("PermissionClass", 180, 200, 0, L"Till vilka klasser:");
gdi.addItem("PermissionClass", RestServer::getPermissionsClass()); gdi.setItems("PermissionClass", RestServer::getPermissionsClass());
gdi.autoGrow("PermissionClass"); gdi.autoGrow("PermissionClass");
gdi.selectFirstItem("PermissionClass"); gdi.selectFirstItem("PermissionClass");
bool disablePermisson = true; bool disablePermisson = true;

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -464,7 +464,7 @@ void RunnerDB::compactifyClubs()
ba=nba; ba=nba;
} }
} }
swap(ref, *best); std::swap(ref, *best);
//Update map //Update map
for (size_t j=0;j<compacted.size();j++) { for (size_t j=0;j<compacted.size();j++) {
@ -789,7 +789,7 @@ string RunnerDB::getDataDate() const
void RunnerDB::setDataDate(const string &date) void RunnerDB::setDataDate(const string &date)
{ {
int d = convertDateYMS(date.substr(0, 10), false); int d = convertDateYMD(date.substr(0, 10), false);
int t = date.length()>11 ? convertAbsoluteTimeHMS(date.substr(11), -1) : 0; int t = date.length()>11 ? convertAbsoluteTimeHMS(date.substr(11), -1) : 0;
if (d<=0) if (d<=0)
@ -1960,7 +1960,7 @@ const wstring& RunnerDBEntry::getBirthDate() const {
void RunnerDBEntry::setBirthDate(const wstring& in) { void RunnerDBEntry::setBirthDate(const wstring& in) {
SYSTEMTIME st; SYSTEMTIME st;
if (convertDateYMS(in, st, true) > 0) { if (convertDateYMD(in, st, true) > 0) {
setBirthYear(st.wYear); setBirthYear(st.wYear);
setBirthMonth(st.wMonth); setBirthMonth(st.wMonth);
setBirthDay(st.wDay); setBirthDay(st.wDay);

View File

@ -11,7 +11,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -385,7 +385,7 @@ private:
protected: protected:
/** Get internal data buffers for DI */ /** Get internal data buffers for DI */
oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const; oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const;
int getDISize() const {return 0;} int getDISize() const final {return 0;}
void changedObject() {} void changedObject() {}
public: public:
void merge(const oBase &input, const oBase * base) final {} void merge(const oBase &input, const oBase * base) final {}

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -1858,7 +1858,7 @@ bool SportIdent::getCard6Data(BYTE *data, SICard &card)
} }
string2Wide(lastNameByte, lastName); string2Wide(lastNameByte, lastName);
wcsncpy(card.lastName, lastName.c_str(), 20); wcsncpy_s(card.lastName, lastName.c_str(), 20);
card.lastName[20] = 0; card.lastName[20] = 0;
memcpy(firstNameByte, data+32+20, 20); memcpy(firstNameByte, data+32+20, 20);
@ -1869,7 +1869,7 @@ bool SportIdent::getCard6Data(BYTE *data, SICard &card)
} }
string2Wide(firstNameByte, firstName); string2Wide(firstNameByte, firstName);
wcsncpy(card.firstName, firstName.c_str(), 20); wcsncpy_s(card.firstName, firstName.c_str(), 20);
card.firstName[20] = 0; card.firstName[20] = 0;
data+=128-16; data+=128-16;

View File

@ -9,7 +9,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -96,6 +96,9 @@ struct SICard
int relativeFinishTime; int relativeFinishTime;
bool statusOK; bool statusOK;
bool statusDNF; bool statusDNF;
//
bool isDebugCard = false;
vector<string> codeLogData(gdioutput &converter, int row) const; vector<string> codeLogData(gdioutput &converter, int row) const;
static vector<string> logHeader(); static vector<string> logHeader();

View File

@ -1,9 +1,13 @@
#pragma once #pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define NOMINMAX #define NOMINMAX
#include <winsdkver.h>
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0601 // Target Windows 7.
#include <sdkddkver.h>
#include <windows.h> #include <windows.h>
#include <commctrl.h> #include <commctrl.h>
#include "timeconstants.hpp" #include "timeconstants.hpp"
@ -20,8 +24,34 @@
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <list> #include <list>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <deque>
#include <algorithm>
using std::shared_ptr;
using std::string;
using std::wstring;
using std::vector;
using std::list;
using std::map;
using std::set;
using std::pair;
using std::make_pair;
using std::make_shared;
using std::unordered_set;
using std::unordered_map;
using std::min;
using std::max;
using std::numeric_limits;
using std::multimap;
using std::unique_ptr;
using std::deque;
using std::tuple;
using namespace std;
bool getUserFile(wchar_t *fileNamePath, const wchar_t *fileName); bool getUserFile(wchar_t *fileNamePath, const wchar_t *fileName);
bool getDesktopFile(wchar_t *fileNamePath, const wchar_t *fileName, const wchar_t *subFolder = 0); bool getDesktopFile(wchar_t *fileNamePath, const wchar_t *fileName, const wchar_t *subFolder = 0);
bool getMeOSFile(wchar_t *FileNamePath, const wchar_t *FileName); bool getMeOSFile(wchar_t *FileNamePath, const wchar_t *FileName);

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -163,8 +163,7 @@ void tabForceSync(gdioutput &gdi, pEvent oe) {
tabAuto->syncCallback(gdi); tabAuto->syncCallback(gdi);
} }
int AutomaticCB(gdioutput *gdi, int type, void *data) int AutomaticCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
if (!tabAuto) if (!tabAuto)
throw std::exception("tabAuto undefined."); throw std::exception("tabAuto undefined.");
@ -178,6 +177,10 @@ int AutomaticCB(gdioutput *gdi, int type, void *data)
ListBoxInfo lbi=*static_cast<ListBoxInfo *>(data); ListBoxInfo lbi=*static_cast<ListBoxInfo *>(data);
return tabAuto->processListBox(*gdi, lbi); return tabAuto->processListBox(*gdi, lbi);
} }
case GuiEventType::GUI_POSTCLEAR:
case GuiEventType::GUI_CLEAR:
return tabAuto->clearPage(*gdi, type == GUI_POSTCLEAR);
} }
return 0; return 0;
} }
@ -289,11 +292,47 @@ void TabAuto::setTimer(AutoMachine *am)
} }
} }
bool TabAuto::clearPage(gdioutput &gdi, bool postClear) {
if (!postClear) {
if (wasSaved) {
AutoMachine* sm = getMachine(currentMachineEditId);
if (sm && wasCreated)
stopMachine(sm);
}
else {
auto ans = gdi.askCancel(wasCreated ? L"Vill du starta automaten?" : L"Vill du spara ändringar?");
if (ans == gdioutput::AskAnswer::AnswerCancel)
return false;
else {
AutoMachine* sm = getMachine(currentMachineEditId);
if (sm) {
if (ans == gdioutput::AskAnswer::AnswerYes) {
sm->save(*oe, gdi, true);
setTimer(sm);
updateSyncInfo();
}
else {
if (wasCreated)
stopMachine(sm);
}
}
return true;
}
}
}
else {
currentMachineEditId = -1;
wasSaved = false;
wasCreated = false;
}
return true;
}
int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu) int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
{ {
if (bu.id=="GenerateCMP") { if (bu.id=="GenerateCMP") {
#ifndef MEOSDB
int nClass=gdi.getTextNo("nClass"); int nClass=gdi.getTextNo("nClass");
int nRunner=gdi.getTextNo("nRunner"); int nRunner=gdi.getTextNo("nRunner");
@ -303,7 +342,6 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
gdi.getTabs().get(TCmpTab)->loadPage(gdi); gdi.getTabs().get(TCmpTab)->loadPage(gdi);
return 0; return 0;
} }
#endif
} }
else if (bu.id == "BrowseFolder") { else if (bu.id == "BrowseFolder") {
const wchar_t *edit = bu.getExtra(); const wchar_t *edit = bu.getExtra();
@ -399,6 +437,7 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
if (gdi.hasWidget("Interval")) if (gdi.hasWidget("Interval"))
iv = gdi.getText("Interval"); iv = gdi.getText("Interval");
sm->saveMachine(*oe, iv); sm->saveMachine(*oe, iv);
wasSaved = true;
oe->updateChanged(); oe->updateChanged();
oe->synchronize(false); oe->synchronize(false);
} }
@ -500,42 +539,46 @@ bool TabAuto::stopMachine(AutoMachine *am)
return false; return false;
} }
void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, AutoMachine::State state, Machines ms) { void TabAuto::settings(gdioutput& gdi, AutoMachine* sm, AutoMachine::State state, Machines ms) {
editMode=true; editMode = true;
if (sm) { if (sm) {
if (state == AutoMachine::State::Create) if (state == AutoMachine::State::Create)
state = AutoMachine::State::Edit; state = AutoMachine::State::Edit;
ms = sm->getType(); ms = sm->getType();
} }
else { else {
state = AutoMachine::State::Create; state = AutoMachine::State::Create;
sm = AutoMachine::construct(ms); sm = AutoMachine::construct(ms);
machines.push_back(sm); machines.push_back(sm);
} }
gdi.restore("", false); gdi.restore("", false);
gdi.dropLine(); gdi.dropLine();
int cx = gdi.getCX(); int cx = gdi.getCX();
int cy = gdi.getCY(); int cy = gdi.getCY();
int d = gdi.scaleLength(6); int d = gdi.scaleLength(6);
gdi.setCX(cx + d); gdi.setCX(cx + d);
sm->setEditMode(true); sm->setEditMode(true);
sm->settings(gdi, *oe, state); sm->settings(gdi, *oe, state);
int w = gdi.getWidth(); int w = gdi.getWidth();
int h = gdi.getHeight(); int h = gdi.getHeight();
RECT rc; RECT rc;
rc.top = cy - d; rc.top = cy - d;
rc.bottom = h + d; rc.bottom = h + d;
rc.left = cx - d; rc.left = cx - d;
rc.right = w + d; rc.right = w + d;
gdi.addRectangle(rc, colorLightBlue, true, true); gdi.addRectangle(rc, colorLightBlue, true, true);
gdi.refresh(); gdi.setOnClearCb(AutomaticCB);
gdi.setPostClearCb(AutomaticCB);
currentMachineEditId = sm->getId();
wasCreated = (state == AutoMachine::State::Create) || (state == AutoMachine::State::Load);
wasSaved = false;
gdi.refresh();
} }
void TabAuto::killMachines() void TabAuto::killMachines() {
{
while(!machines.empty()) { while(!machines.empty()) {
machines.back()->stop(); machines.back()->stop();
delete machines.back(); delete machines.back();
@ -544,8 +587,7 @@ void TabAuto::killMachines()
AutoMachine::resetGlobalId(); AutoMachine::resetGlobalId();
} }
bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast) bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast) {
{
oe->checkDB(); oe->checkDB();
oe->synchronize(); oe->synchronize();
tabAuto=this; tabAuto=this;
@ -773,7 +815,7 @@ void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
gdi.pushX(); gdi.pushX();
gdi.fillDown(); gdi.fillDown();
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
gdi.addItem("Classes", oe.fillClasses(d, oEvent::extraNone, oEvent::filterNone)); gdi.setItems("Classes", oe.fillClasses(d, oEvent::extraNone, oEvent::filterNone));
gdi.setSelection("Classes", classesToPrint); gdi.setSelection("Classes", classesToPrint);
gdi.addSelection("ListType", 200, 100, 0, L"Lista"); gdi.addSelection("ListType", 200, 100, 0, L"Lista");
@ -797,7 +839,7 @@ void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
set<int> clsUnused; set<int> clsUnused;
vector< pair<wstring, size_t> > out; vector< pair<wstring, size_t> > out;
oe.fillLegNumbers(clsUnused, listInfo.isTeamList(), true, out); oe.fillLegNumbers(clsUnused, listInfo.isTeamList(), true, out);
gdi.addItem("LegNumber", out); gdi.setItems("LegNumber", out);
gdi.selectItemByData("LegNumber", listInfo.getLegNumberCoded()); gdi.selectItemByData("LegNumber", listInfo.getLegNumberCoded());
gdi.addCheckbox("PageBreak", "Sidbrytning mellan klasser", 0, pageBreak); gdi.addCheckbox("PageBreak", "Sidbrytning mellan klasser", 0, pageBreak);
@ -981,7 +1023,7 @@ void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
gdi.fillDown(); gdi.fillDown();
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
oe.fillControls(d, oEvent::ControlType::CourseControl); oe.fillControls(d, oEvent::ControlType::CourseControl);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
gdi.setSelection("Controls", controls); gdi.setSelection("Controls", controls);
gdi.popX(); gdi.popX();
gdi.addButton("SelectAll", "Välj alla", AutomaticCB, "").setExtra(L"Controls"); gdi.addButton("SelectAll", "Välj alla", AutomaticCB, "").setExtra(L"Controls");
@ -1205,7 +1247,7 @@ void SplitsMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
if (doProcess) { if (doProcess) {
//Try exporting. //Try exporting.
oe.exportIOFSplits(oEvent::IOF20, file.c_str(), true, false, oe.exportIOFSplits(oEvent::IOF20, file.c_str(), true, false,
set<int>(), -1, false, true, true, false, false); set<int>(), make_pair("",""), -1, false, true, true, false, false);
interval = iv; interval = iv;
synchronize = true; synchronize = true;
} }
@ -1244,7 +1286,8 @@ void SplitsMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
{ {
if ((interval>0 && ast==SyncTimer) || (interval==0 && ast==SyncDataUp)) { if ((interval>0 && ast==SyncTimer) || (interval==0 && ast==SyncDataUp)) {
if (!file.empty()) if (!file.empty())
oe->exportIOFSplits(oEvent::IOF20, file.c_str(), true, false, classes, oe->exportIOFSplits(oEvent::IOF20, file.c_str(),
true, false, classes, make_pair("", ""),
leg, false, true, true, false, false); leg, false, true, true, false, false);
} }
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -311,12 +311,12 @@ class TabAuto :
public TabBase public TabBase
{ {
private: private:
//DWORD printResultIntervalSec; bool editMode = false;
//DWORD printResultTimeOut; int currentMachineEditId = -1;
bool editMode; bool wasCreated = false;
bool wasSaved = false;
bool synchronize; bool synchronize = false;
bool synchronizePunches; bool synchronizePunches = false;
void updateSyncInfo(); void updateSyncInfo();
list<AutoMachine *> machines; list<AutoMachine *> machines;
@ -336,6 +336,7 @@ public:
AutoMachine *getMachine(int id); AutoMachine *getMachine(int id);
bool stopMachine(AutoMachine *am); bool stopMachine(AutoMachine *am);
void killMachines(); void killMachines();
bool clearPage(gdioutput &gdi, bool postClear);
AutoMachine &addMachine(const AutoMachine &am) { AutoMachine &addMachine(const AutoMachine &am) {
machines.push_back(am.clone()); machines.push_back(am.clone());

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -190,19 +190,6 @@ void FixedTabs::clearCompetitionData() {
tabs[k]->clearCompetitionData(); tabs[k]->clearCompetitionData();
} }
TabObject::TabObject(TabBase *t)
{
tab = t;
tab->tabId = id;
}
TabObject::~TabObject()
{
//delete tab;
}
bool TabObject::loadPage(gdioutput &gdi) bool TabObject::loadPage(gdioutput &gdi)
{ {
if (tab) if (tab)

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -74,42 +74,23 @@ public:
class TabObject class TabObject
{ {
protected: protected:
mutable TabBase *tab; TabBase * const tab = nullptr;
public: public:
string name; const string name;
int id; const int imageId = -1;
int id = -1;
TabObject(TabBase *t, string n):name(n),tab(t) {} TabObject(TabBase *t, string n, int imageId) : name(n), tab(t), imageId(imageId) {}
void setId(int i){id=i; if (tab) tab->tabId=id;} void setId(int i){id=i; if (tab) tab->tabId=id;}
void setPage(TabBase *tb){delete tab; tab=tb;}
const type_info &getType() const {return typeid(*tab);} const type_info &getType() const {return typeid(*tab);}
const TabBase &getTab() const {return *tab;} const TabBase &getTab() const {return *tab;}
TabObject(const TabObject &t)
{
if (&t!=this) {
name=t.name;
id=t.id;
tab=t.tab;
//t.tab=0;
}
}
TabObject &operator=(TabObject &t) TabObject(const TabObject& t) = delete;
{ TabObject& operator=(TabObject& t) = delete;
if (&t!=this) { ~TabObject() = default;
delete tab;
name=t.name;
id=t.id;
tab=t.tab;
//t.tab=0;
}
}
TabObject(TabBase *t);
~TabObject();
bool loadPage(gdioutput &gdi); bool loadPage(gdioutput &gdi);
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,6 +24,8 @@
#include "tabbase.h" #include "tabbase.h"
#include "oEventDraw.h" #include "oEventDraw.h"
class QFEditor;
class TabClass : class TabClass :
public TabBase public TabBase
{ {
@ -45,7 +47,6 @@ class TabClass :
double pTimeScaling; double pTimeScaling;
int pInterval; int pInterval;
class HandleCloseWindow : public GuiHandler { class HandleCloseWindow : public GuiHandler {
TabClass *tabClass; TabClass *tabClass;
HandleCloseWindow(const HandleCloseWindow&); HandleCloseWindow(const HandleCloseWindow&);
@ -57,7 +58,6 @@ class TabClass :
}; };
HandleCloseWindow handleCloseWindow; HandleCloseWindow handleCloseWindow;
bool EditChanged; bool EditChanged;
int ClassId; int ClassId;
int currentStage; int currentStage;
@ -71,7 +71,9 @@ class TabClass :
void legSetup(gdioutput &gdi); void legSetup(gdioutput &gdi);
vector<ClassInfo> cInfo; vector<ClassInfo> cInfo;
void saveDrawSettings() const; void saveDrawSettings() const;
void dynamicStart(gdioutput& gdi);
map<int, ClassInfo> cInfoCache; map<int, ClassInfo> cInfoCache;
DrawInfo drawInfo; DrawInfo drawInfo;
@ -120,9 +122,6 @@ class TabClass :
void showClassSelection(gdioutput &gdi, int &bx, int &by, GUICALLBACK classesCB) const; void showClassSelection(gdioutput &gdi, int &bx, int &by, GUICALLBACK classesCB) const;
// Set simultaneous start in a class
void simultaneous(int classId, const wstring &time, int nVacant);
void updateFairForking(gdioutput &gdi, pClass pc) const; void updateFairForking(gdioutput &gdi, pClass pc) const;
void selectCourses(gdioutput &gdi, int legNo); void selectCourses(gdioutput &gdi, int legNo);
bool showMulti(bool singleOnly) const; bool showMulti(bool singleOnly) const;
@ -168,11 +167,15 @@ class TabClass :
void fillResultModules(gdioutput &gdi, pClass pc); void fillResultModules(gdioutput &gdi, pClass pc);
shared_ptr<GuiHandler> startGroupHandler; shared_ptr<GuiHandler> startGroupHandler;
shared_ptr<QFEditor> qfEditor;
public: public:
void loadStartGroupSettings(gdioutput &gdi, bool reload); void loadStartGroupSettings(gdioutput &gdi, bool reload);
void drawStartGroups(gdioutput &gdi); void drawStartGroups(gdioutput &gdi);
// Set simultaneous start in a class
static void simultaneous(oEvent &oe, int classId, const wstring& time, int nVacant);
void clearCompetitionData(); void clearCompetitionData();
void closeWindow(gdioutput &gdi); void closeWindow(gdioutput &gdi);
@ -182,14 +185,14 @@ public:
bool loadPage(gdioutput &gdi); bool loadPage(gdioutput &gdi);
void selectClass(gdioutput &gdi, int cid); void selectClass(gdioutput &gdi, int cid);
int classCB(gdioutput &gdi, int type, void *data); int classCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
int multiCB(gdioutput &gdi, int type, void *data); int multiCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
const char * getTypeStr() const {return "TClassTab";} const char * getTypeStr() const {return "TClassTab";}
TabType getType() const {return TClassTab;} TabType getType() const {return TClassTab;}
friend int DrawClassesCB(gdioutput *gdi, int type, void *data); friend int DrawClassesCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
TabClass(oEvent *oe); TabClass(oEvent *oe);
~TabClass(void); ~TabClass();
}; };

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -108,14 +108,12 @@ void ageFilter(gdioutput &gdi, bool on, bool use) {
gdi.setInputStatus("FilterAge", use); gdi.setInputStatus("FilterAge", use);
} }
int ClubsCB(gdioutput *gdi, int type, void *data) int ClubsCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
TabClub &tc = dynamic_cast<TabClub &>(*gdi->getTabs().get(TClubTab)); TabClub &tc = dynamic_cast<TabClub &>(*gdi->getTabs().get(TClubTab));
return tc.clubCB(*gdi, type, data); return tc.clubCB(*gdi, type, data);
} }
int TabClub::clubCB(gdioutput &gdi, int type, void *data) int TabClub::clubCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
{
if (type==GUI_BUTTON) { if (type==GUI_BUTTON) {
ButtonInfo bi=*(ButtonInfo *)data; ButtonInfo bi=*(ButtonInfo *)data;
@ -414,7 +412,7 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
oe->fillClassTypes(types); oe->fillClassTypes(types);
oe->fillClasses(classes, oEvent::extraNone, oEvent::filterNone); oe->fillClasses(classes, oEvent::extraNone, oEvent::filterNone);
types.insert(types.end(), classes.begin(), classes.end()); types.insert(types.end(), classes.begin(), classes.end());
gdi.addItem("ClassType", types); gdi.setItems("ClassType", types);
gdi.addItem("ClassType", lang.tl("Alla typer"), -5); gdi.addItem("ClassType", lang.tl("Alla typer"), -5);
gdi.selectItemByData("ClassType", -5); gdi.selectItemByData("ClassType", -5);

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@
class TabClub : class TabClub :
public TabBase public TabBase
{ {
int clubCB(gdioutput &gdi, int type, void *data); int clubCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
wstring firstDate; wstring firstDate;
wstring lastDate; wstring lastDate;
@ -59,5 +59,5 @@ public:
TabClub(oEvent *oe); TabClub(oEvent *oe);
~TabClub(void); ~TabClub(void);
friend int ClubsCB(gdioutput *gdi, int type, void *data); friend int ClubsCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
}; };

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -67,7 +67,7 @@ void exportSetup();
void resetSaveTimer(); void resetSaveTimer();
extern bool enableTests; extern bool enableTests;
int ListsCB(gdioutput *gdi, int type, void *data); int ListsCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
TabCompetition::TabCompetition(oEvent *poe):TabBase(poe) TabCompetition::TabCompetition(oEvent *poe):TabBase(poe)
{ {
@ -198,7 +198,7 @@ bool TabCompetition::exportFileAs(HWND hWnd, gdioutput &gdi)
return true; return true;
} }
int CompetitionCB(gdioutput *gdi, int type, void *data) int CompetitionCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab)); TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab));
@ -206,8 +206,7 @@ int CompetitionCB(gdioutput *gdi, int type, void *data)
} }
int restoreCB(gdioutput *gdi, int type, void *data) int restoreCB(gdioutput *gdi, GuiEventType type, BaseInfo *data) {
{
TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab)); TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab));
return tc.restoreCB(*gdi, type, data); return tc.restoreCB(*gdi, type, data);
@ -359,7 +358,7 @@ bool TabCompetition::checkEventor(gdioutput &gdi, ButtonInfo &bi) {
return false; return false;
} }
int eventorServer(gdioutput *gdi, int type, void *data) { int eventorServer(gdioutput *gdi, GuiEventType type, BaseInfo *data) {
TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab)); TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab));
if (type == GUI_COMBO) { if (type == GUI_COMBO) {
const ListBoxInfo &lbi = *((ListBoxInfo *)data); const ListBoxInfo &lbi = *((ListBoxInfo *)data);
@ -390,8 +389,7 @@ bool TabCompetition::useEventorUTC() const {
enum StartMethod {SMCommon = 1, SMDrawn, SMFree, SMCustom}; enum StartMethod {SMCommon = 1, SMDrawn, SMFree, SMCustom};
int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data) int TabCompetition::competitionCB(gdioutput &gdi, GuiEventType type, BaseInfo *data) {
{
if (type == GUI_LINK) { if (type == GUI_LINK) {
TextInfo ti = *(TextInfo *)data; TextInfo ti = *(TextInfo *)data;
if (ti.id == "link") { if (ti.id == "link") {
@ -569,10 +567,10 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
gdi.addButton("Cancel", "Återgå", CompetitionCB); gdi.addButton("Cancel", "Återgå", CompetitionCB);
gdi.dropLine(); gdi.dropLine();
if (prefsEditor.empty()) if (!prefsEditor)
prefsEditor.push_back(PrefsEditor(oe)); prefsEditor = make_shared<PrefsEditor>(oe);
prefsEditor->showPrefs(gdi);
prefsEditor.back().showPrefs(gdi);
gdi.refresh(); gdi.refresh();
} }
else if (bi.id=="Test") { else if (bi.id=="Test") {
@ -1143,7 +1141,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
wstring startlist = getTempFile(); wstring startlist = getTempFile();
bool eventorUTC = oe->getPropertyInt("UseEventorUTC", 0) != 0; bool eventorUTC = oe->getPropertyInt("UseEventorUTC", 0) != 0;
oe->exportIOFStartlist(oEvent::IOF30, startlist.c_str(), eventorUTC, oe->exportIOFStartlist(oEvent::IOF30, startlist.c_str(), eventorUTC,
set<int>(), false, false, true, true); set<int>(), make_pair("",""), false, false, true, true);
vector<wstring> fileList; vector<wstring> fileList;
fileList.push_back(startlist); fileList.push_back(startlist);
@ -1236,7 +1234,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
set<int> classes; set<int> classes;
bool eventorUTC = oe->getPropertyInt("UseEventorUTC", 0) != 0; bool eventorUTC = oe->getPropertyInt("UseEventorUTC", 0) != 0;
oe->exportIOFSplits(oEvent::IOF30, resultlist.c_str(), false, oe->exportIOFSplits(oEvent::IOF30, resultlist.c_str(), false,
eventorUTC, classes, -1, false, true, eventorUTC, classes, make_pair("", ""), -1, false, true,
false, true, true); false, true, true);
vector<wstring> fileList; vector<wstring> fileList;
fileList.push_back(resultlist); fileList.push_back(resultlist);
@ -1531,7 +1529,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
gdi.dropLine(); gdi.dropLine();
gdi.addString("", 1, "Behandlar tävlingsdata").setColor(colorGreen); gdi.addString("", 1, "Behandlar tävlingsdata").setColor(colorGreen);
set<int> noFilter; set<int> noFilter;
string noType; pair<string, string> noType;
if (createNew && id>0) { if (createNew && id>0) {
gdi.addString("", 1, "Skapar ny tävling"); gdi.addString("", 1, "Skapar ny tävling");
@ -1559,9 +1557,12 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
removeTempFile(tClass); removeTempFile(tClass);
set<int> stageFilter; set<int> stageFilter;
string preferredIdType; pair<string, string> preferredIdType;
checkStageFilter(gdi, tEntry, stageFilter, preferredIdType); checkStageFilter(gdi, tEntry, stageFilter, preferredIdType);
oe->importXML_EntryData(gdi, tEntry.c_str(), false, removeRemoved, stageFilter, 0, 0, preferredIdType); oe->importXML_EntryData(gdi, tEntry.c_str(), false, removeRemoved, stageFilter, 0, 0, preferredIdType);
if (!preferredIdType.second.empty())
oe->setRunnerIdTypes(preferredIdType);
removeTempFile(tEntry); removeTempFile(tEntry);
if (!course.empty()) { if (!course.empty()) {
@ -1791,6 +1792,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
oe->setProperty("ExpWithRaceNo", includeStage); oe->setProperty("ExpWithRaceNo", includeStage);
} }
auto preferredIdTypes = getPreferredIdTypes(gdi);
gdi.getSelection("ClassNewEntries", allTransfer); gdi.getSelection("ClassNewEntries", allTransfer);
ImportFormats::ExportFormats filterIndex = ImportFormats::setExportFormat(*oe, gdi.getSelectedItem("Type").first); ImportFormats::ExportFormats filterIndex = ImportFormats::setExportFormat(*oe, gdi.getSelectedItem("Type").first);
int cSVLanguageHeaderIndex = gdi.getSelectedItem("LanguageType").first; int cSVLanguageHeaderIndex = gdi.getSelectedItem("LanguageType").first;
@ -1800,7 +1803,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
if (filterIndex == ImportFormats::IOF30 || filterIndex == ImportFormats::IOF203) { if (filterIndex == ImportFormats::IOF30 || filterIndex == ImportFormats::IOF203) {
bool useUTC = oe->getDCI().getInt("UTC") != 0; bool useUTC = oe->getDCI().getInt("UTC") != 0;
oe->exportIOFStartlist(filterIndex == ImportFormats::IOF30 ? oEvent::IOF30 : oEvent::IOF20, oe->exportIOFStartlist(filterIndex == ImportFormats::IOF30 ? oEvent::IOF30 : oEvent::IOF20,
save.c_str(), useUTC, allTransfer, individual, includeStage, false, false); save.c_str(), useUTC, allTransfer, preferredIdTypes, individual, includeStage, false, false);
} }
else if (filterIndex == ImportFormats::OE) { else if (filterIndex == ImportFormats::OE) {
oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, false); oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, false);
@ -1849,6 +1852,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
oe->setProperty("ExpWithRaceNo", includeStage); oe->setProperty("ExpWithRaceNo", includeStage);
} }
auto preferredIdTypes = getPreferredIdTypes(gdi);
gdi.setWaitCursor(true); gdi.setWaitCursor(true);
if (filterIndex == ImportFormats::IOF30 || filterIndex == ImportFormats::IOF203) { if (filterIndex == ImportFormats::IOF30 || filterIndex == ImportFormats::IOF203) {
oEvent::IOFVersion ver = filterIndex == ImportFormats::IOF30 ? oEvent::IOF30 : oEvent::IOF20; oEvent::IOFVersion ver = filterIndex == ImportFormats::IOF30 ? oEvent::IOF30 : oEvent::IOF20;
@ -1858,7 +1863,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
if (!gdi.hasWidget("LegType")) { if (!gdi.hasWidget("LegType")) {
oe->exportIOFSplits(ver, save.c_str(), true, useUTC, oe->exportIOFSplits(ver, save.c_str(), true, useUTC,
allTransfer, -1, false, unroll, includeStage, false, false); allTransfer, preferredIdTypes, -1, false, unroll, includeStage, false, false);
} }
else { else {
ListBoxInfo leglbi; ListBoxInfo leglbi;
@ -1880,16 +1885,16 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
for (int leg = 0; leg<legMax; leg++) { for (int leg = 0; leg<legMax; leg++) {
file = fileBase + L"_" + itow(leg+1) + fileEnd; file = fileBase + L"_" + itow(leg+1) + fileEnd;
oe->exportIOFSplits(ver, file.c_str(), true, useUTC, oe->exportIOFSplits(ver, file.c_str(), true, useUTC,
allTransfer, leg, false, unroll, includeStage, false, false); allTransfer, preferredIdTypes, leg, false, unroll, includeStage, false, false);
} }
} }
else if (leglbi.data == 3) { else if (leglbi.data == 3) {
oe->exportIOFSplits(ver, file.c_str(), true, useUTC, allTransfer, oe->exportIOFSplits(ver, file.c_str(), true, useUTC, allTransfer, preferredIdTypes,
-1, true, unroll, includeStage, false, false); -1, true, unroll, includeStage, false, false);
} }
else { else {
int leg = leglbi.data == 1 ? -1 : leglbi.data - 10; int leg = leglbi.data == 1 ? -1 : leglbi.data - 10;
oe->exportIOFSplits(ver, file.c_str(), true, useUTC, allTransfer, oe->exportIOFSplits(ver, file.c_str(), true, useUTC, allTransfer, preferredIdTypes,
leg, false, unroll, includeStage, false, false); leg, false, unroll, includeStage, false, false);
} }
} }
@ -2202,6 +2207,14 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
else if (type==GUI_LISTBOX) { else if (type==GUI_LISTBOX) {
ListBoxInfo lbi=*(ListBoxInfo *)data; ListBoxInfo lbi=*(ListBoxInfo *)data;
if (lbi.id == "DataFields") {
oEvent::ExtraFieldContext context = oEvent::ExtraFieldContext(gdi.getDataInt("DataFieldsContext"));
saveExtraFields(gdi, context);
oe->synchronize(true);
oEvent::ExtraFieldContext contextNew = oEvent::ExtraFieldContext(lbi.data);
showExtraFields(gdi, contextNew);
}
if (lbi.id=="LocalCmp") { if (lbi.id=="LocalCmp") {
gdi.selectItemByData("ServerCmp", -1); gdi.selectItemByData("ServerCmp", -1);
gdi.disableInput("Repair", true); gdi.disableInput("Repair", true);
@ -2302,7 +2315,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
gdi.setData("RunnerIx", ix); gdi.setData("RunnerIx", ix);
gdi.dropLine(); gdi.dropLine();
gdi.addSelection("Classes", 200, 300, 0, L"Klasser:"); gdi.addSelection("Classes", 200, 300, 0, L"Klasser:");
oe->fillClasses(gdi, "Classes", oEvent::extraNone, oEvent::filterOnlySingle); oe->fillClasses(gdi, "Classes", {}, oEvent::extraNone, oEvent::filterOnlySingle);
if (lastSelectedClass == -1 || !gdi.selectItemByData("Classes", lastSelectedClass)) if (lastSelectedClass == -1 || !gdi.selectItemByData("Classes", lastSelectedClass))
gdi.selectFirstItem("Classes"); gdi.selectFirstItem("Classes");
@ -2357,8 +2370,8 @@ void TabCompetition::openCompetition(gdioutput &gdi, int id) {
} }
} }
int TabCompetition::restoreCB(gdioutput &gdi, int type, void *data) { int TabCompetition::restoreCB(gdioutput &gdi, GuiEventType type, BaseInfo *data) {
TextInfo &ti = *(TextInfo *)data; TextInfo &ti = dynamic_cast<TextInfo&>(*data);
int id = ti.getExtraInt(); int id = ti.getExtraInt();
const BackupInfo &bi = oe->getBackup(id); const BackupInfo &bi = oe->getBackup(id);
@ -2417,7 +2430,7 @@ void TabCompetition::copyrightLine(gdioutput &gdi) const
gdi.dropLine(0.4); gdi.dropLine(0.4);
gdi.fillDown(); gdi.fillDown();
gdi.addString("", 0, makeDash(L"#Copyright © 2007-2023 Melin Software HB")); gdi.addString("", 0, makeDash(L"#Copyright © 2007-2024 Melin Software HB"));
gdi.dropLine(1); gdi.dropLine(1);
gdi.popX(); gdi.popX();
@ -2447,12 +2460,9 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
gdi.dropLine(1.5); gdi.dropLine(1.5);
gdi.setCX(gdi.getCX() + gdi.scaleLength(20)); gdi.setCX(gdi.getCX() + gdi.scaleLength(20));
gdi.addStringUT(1, makeDash(L"Copyright © 2007-2023 Melin Software HB")); gdi.addStringUT(1, makeDash(L"Copyright © 2007-2024 Melin Software HB"));
gdi.dropLine(); gdi.dropLine();
gdi.addStringUT(10, "The database connection used is MySQL++\nCopyright " gdi.addStringUT(10, "The database used is MySQL, Copyright (c) 2008-2024 Oracle, Inc."
"(c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by MySQL AB,"
"\nand (c) 2004-2007 by Educational Technology Resources, Inc.\n"
"The database used is MySQL, Copyright (c) 2008-2017 Oracle, Inc."
"\n\nGerman Translation by Erik Nilsson-Simkovics" "\n\nGerman Translation by Erik Nilsson-Simkovics"
"\n\nDanish Translation by Michael Leth Jess and Chris Bagge" "\n\nDanish Translation by Michael Leth Jess and Chris Bagge"
"\n\nRussian Translation by Paul A. Kazakov and Albert Salihov" "\n\nRussian Translation by Paul A. Kazakov and Albert Salihov"
@ -2462,7 +2472,9 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
"\n\nCzech Translation by Marek Kustka" "\n\nCzech Translation by Marek Kustka"
"\n\nSpanish Translation by Manuel Pedre" "\n\nSpanish Translation by Manuel Pedre"
"\n\nUkranian Translation by Oleg Rozhko" "\n\nUkranian Translation by Oleg Rozhko"
"\n\nPortuguese Translation by Bruno Santos"
"\n\nHelp with English documentation: Torbjörn Wikström"); "\n\nHelp with English documentation: Torbjörn Wikström");
gdi.dropLine(); gdi.dropLine();
gdi.addString("", 0, "Det här programmet levereras utan någon som helst garanti. Programmet är "); gdi.addString("", 0, "Det här programmet levereras utan någon som helst garanti. Programmet är ");
@ -2519,6 +2531,7 @@ bool TabCompetition::loadPage(gdioutput &gdi)
gdi.fillDown(); gdi.fillDown();
if (oe->empty()) { if (oe->empty()) {
gdi.selectTab(tabId);
gdi.addString("", 2, "Välkommen till MeOS"); gdi.addString("", 2, "Välkommen till MeOS");
gdi.addString("", 1, makeDash(L"#- ")+ lang.tl("ett Mycket Enkelt OrienteringsSystem")).setColor(colorDarkBlue); gdi.addString("", 1, makeDash(L"#- ")+ lang.tl("ett Mycket Enkelt OrienteringsSystem")).setColor(colorDarkBlue);
gdi.dropLine(); gdi.dropLine();
@ -2578,7 +2591,7 @@ bool TabCompetition::loadPage(gdioutput &gdi)
vector< pair<wstring, size_t> > tests; vector< pair<wstring, size_t> > tests;
TestMeOS tm(oe, "ALL"); TestMeOS tm(oe, "ALL");
tm.getTests(tests); tm.getTests(tests);
gdi.addItem("Tests", tests); gdi.setItems("Tests", tests);
gdi.selectFirstItem("Tests"); gdi.selectFirstItem("Tests");
gdi.addButton("RunSpecificTest", "#Run", CompetitionCB); gdi.addButton("RunSpecificTest", "#Run", CompetitionCB);
@ -3011,7 +3024,7 @@ void TabCompetition::getEventorCompetitions(gdioutput &gdi,
eBreak.getObjectString("Date", breakDate); eBreak.getObjectString("Date", breakDate);
SYSTEMTIME st; SYSTEMTIME st;
convertDateYMS(breakDate, st, false); convertDateYMD(breakDate, st, false);
__int64 time = SystemTimeToInt64TenthSecond(st) - 10; __int64 time = SystemTimeToInt64TenthSecond(st) - 10;
breakDate = convertSystemDate(Int64TenthSecondToSystemTime(time)); breakDate = convertSystemDate(Int64TenthSecondToSystemTime(time));
@ -3319,6 +3332,7 @@ void TabCompetition::loadRunnerDB(gdioutput &gdi, int tableToShow, bool updateTa
void TabCompetition::welcomeToMeOS(gdioutput &gdi) { void TabCompetition::welcomeToMeOS(gdioutput &gdi) {
gdi.clearPage(false, false); gdi.clearPage(false, false);
gdi.selectTab(tabId);
gdi.scaleSize(1.4*gdi.getScale()); gdi.scaleSize(1.4*gdi.getScale());
gdi.dropLine(5); gdi.dropLine(5);
gdi.setCX(gdi.getCX() + 5*gdi.getLineHeight()); gdi.setCX(gdi.getCX() + 5*gdi.getLineHeight());
@ -3372,7 +3386,7 @@ void TabCompetition::selectTransferClasses(gdioutput &gdi, bool expand) {
if (expand) { if (expand) {
gdi.fillDown(); gdi.fillDown();
gdi.addListBox("ClassNewEntries", 200, 400, 0, L"Klasser där nyanmälningar ska överföras:", L"", true); gdi.addListBox("ClassNewEntries", 200, 400, 0, L"Klasser där nyanmälningar ska överföras:", L"", true);
oe->fillClasses(gdi, "ClassNewEntries", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "ClassNewEntries", {}, oEvent::extraNone, oEvent::filterNone);
gdi.setSelection("ClassNewEntries", allTransfer); gdi.setSelection("ClassNewEntries", allTransfer);
gdi.pushX(); gdi.pushX();
@ -3396,14 +3410,14 @@ void TabCompetition::selectTransferClasses(gdioutput &gdi, bool expand) {
gdi.refresh(); gdi.refresh();
} }
static int ClearFeaturesCB(gdioutput *gdi, int type, void *data) static int ClearFeaturesCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab)); TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab));
tc.saveMeosFeatures(*gdi, true); tc.saveMeosFeatures(*gdi, true);
return 1; return 1;
} }
static int CheckFeaturesCB(gdioutput *gdi, int type, void *data) static int CheckFeaturesCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab)); TabCompetition &tc = dynamic_cast<TabCompetition &>(*gdi->getTabs().get(TCmpTab));
tc.saveMeosFeatures(*gdi, false); tc.saveMeosFeatures(*gdi, false);
@ -3653,13 +3667,16 @@ FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, in
} }
else { else {
set<int> stageFilter; set<int> stageFilter;
string preferredIdType; pair<string, string> preferredIdType;
FlowOperation res = checkStageFilter(gdi, filename[i], stageFilter, preferredIdType); FlowOperation res = checkStageFilter(gdi, filename[i], stageFilter, preferredIdType);
if (res != FlowContinue) if (res != FlowContinue)
return res; return res;
if (!preferredIdType.second.empty())
oe->setRunnerIdTypes(preferredIdType);
const int courseIdOffset = 0; const int courseIdOffset = 0;
oe->importXML_EntryData(gdi, filename[i], false, removeRemoved, stageFilter, oe->importXML_EntryData(gdi, filename[i], false, removeRemoved, stageFilter,
classOffset, courseIdOffset, preferredIdType); classOffset, courseIdOffset, preferredIdType);
@ -3687,10 +3704,10 @@ FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, in
return FlowContinue; return FlowContinue;
} }
int stageInfoCB(gdioutput *gdi, int type, void *data) int stageInfoCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
if (type == GUI_BUTTON) { if (type == GUI_BUTTON) {
ButtonInfo &bi = *(ButtonInfo *)data; ButtonInfo &bi = dynamic_cast<ButtonInfo &>(*data);
bi.setExtra(1); bi.setExtra(1);
} }
return 0; return 0;
@ -3702,12 +3719,12 @@ FlowOperation importFilterGUI(oEvent *oe,
const set<int>& stages, const set<int>& stages,
const vector<string> &idProviders, const vector<string> &idProviders,
set<int> & filter, set<int> & filter,
string &preferredIdProvider); pair<string, string>&preferredIdProvider);
FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi, FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi,
const wstring & fname, const wstring & fname,
set<int>& filter, set<int>& filter,
string &preferredIdProvider) { pair<string, string> &preferredIdProvider) {
xmlparser xml; xmlparser xml;
xml.read(fname); xml.read(fname);
xmlobject xo = xml.getObject("EntryList"); xmlobject xo = xml.getObject("EntryList");
@ -3728,7 +3745,7 @@ FlowOperation importFilterGUI(oEvent *oe,
const set<int>& stages, const set<int>& stages,
const vector<string> &idProviders, const vector<string> &idProviders,
set<int> & filter, set<int> & filter,
string &preferredIdProvider) { pair<string, string> &preferredIdProvider) {
auto &scanFilter = stages; auto &scanFilter = stages;
bool stageFilter = scanFilter.size() > 1; bool stageFilter = scanFilter.size() > 1;
bool idtype = idProviders.size() > 1; bool idtype = idProviders.size() > 1;
@ -3748,6 +3765,7 @@ FlowOperation importFilterGUI(oEvent *oe,
gdi.fillRight(); gdi.fillRight();
gdi.addSelection("Stage", 150, 200, stageInfoCB, L"Välj etapp att importera:"); gdi.addSelection("Stage", 150, 200, stageInfoCB, L"Välj etapp att importera:");
gdi.addItem("Stage", lang.tl("Alla"), 0); gdi.addItem("Stage", lang.tl("Alla"), 0);
gdi.fillDown();
for (int sn : scanFilter) { for (int sn : scanFilter) {
if (sn > 0) if (sn > 0)
gdi.addItem("Stage", lang.tl("Etapp X#" + itos(sn)), sn); gdi.addItem("Stage", lang.tl("Etapp X#" + itos(sn)), sn);
@ -3757,14 +3775,12 @@ FlowOperation importFilterGUI(oEvent *oe,
gdi.selectItemByData("Stage", cn); gdi.selectItemByData("Stage", cn);
else else
gdi.selectItemByData("Stage", 0); gdi.selectItemByData("Stage", 0);
gdi.popX();
gdi.dropLine(3.5);
} }
if (idtype) { if (idtype) {
if (stageFilter) {
gdi.popX();
gdi.dropLine(2);
}
gdi.dropLine(0.5);
gdi.addString("", 0, "Det finns multiplia Id-nummer för personer"); gdi.addString("", 0, "Det finns multiplia Id-nummer för personer");
gdi.dropLine(0.5); gdi.dropLine(0.5);
gdi.fillRight(); gdi.fillRight();
@ -3773,9 +3789,12 @@ FlowOperation importFilterGUI(oEvent *oe,
for (const string &sn : idProviders) { for (const string &sn : idProviders) {
gdi.addItem("IdType", gdi.widen(sn), i++); gdi.addItem("IdType", gdi.widen(sn), i++);
} }
gdi.popX();
gdi.dropLine(3.6);
} }
if (needUseInput) { if (needUseInput) {
gdi.fillRight();
gdi.dropLine(); gdi.dropLine();
gdi.addButton("OK_Stage", "OK", stageInfoCB); gdi.addButton("OK_Stage", "OK", stageInfoCB);
gdi.fillDown(); gdi.fillDown();
@ -3817,7 +3836,14 @@ FlowOperation importFilterGUI(oEvent *oe,
if (idProviders.size() > 1) { if (idProviders.size() > 1) {
ListBoxInfo lbi; ListBoxInfo lbi;
if (gdi.getSelectedItem("IdType", lbi)) { if (gdi.getSelectedItem("IdType", lbi)) {
preferredIdProvider = gdi.narrow(lbi.text); preferredIdProvider.first = gdi.narrow(lbi.text);
}
// Auto select secondary type. TODO: Manually select if not unique...
for (const string& sn : idProviders) {
if (preferredIdProvider.first != sn) {
preferredIdProvider.second = sn;
}
} }
} }
@ -3837,7 +3863,7 @@ void TabCompetition::selectStartlistOptions(gdioutput &gdi) {
gdi.addString("", boldLarge, "Exportera startlista"); gdi.addString("", boldLarge, "Exportera startlista");
gdi.pushY(); gdi.pushY();
gdi.addListBox("ClassNewEntries", 250, 400, 0, L"Klassval:", L"", true); gdi.addListBox("ClassNewEntries", 250, 400, 0, L"Klassval:", L"", true);
oe->fillClasses(gdi, "ClassNewEntries", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "ClassNewEntries", {}, oEvent::extraNone, oEvent::filterNone);
gdi.setSelection("ClassNewEntries", allTransfer); gdi.setSelection("ClassNewEntries", allTransfer);
gdi.pushX(); gdi.pushX();
@ -3854,7 +3880,7 @@ void TabCompetition::selectStartlistOptions(gdioutput &gdi) {
vector< pair<wstring, size_t> > types; vector< pair<wstring, size_t> > types;
ImportFormats::getExportFormats(types, false); ImportFormats::getExportFormats(types, false);
gdi.addItem("Type", types); gdi.setItems("Type", types);
ImportFormats::ExportFormats format = ImportFormats::getDefaultExportFormat(*oe); ImportFormats::ExportFormats format = ImportFormats::getDefaultExportFormat(*oe);
gdi.selectItemByData("Type", format); gdi.selectItemByData("Type", format);
@ -3862,7 +3888,7 @@ void TabCompetition::selectStartlistOptions(gdioutput &gdi) {
ImportFormats::getOECSVLanguage(typeLanguages); ImportFormats::getOECSVLanguage(typeLanguages);
gdi.addSelection("LanguageType", 250, 200, CompetitionCB, L"Export language:"); gdi.addSelection("LanguageType", 250, 200, CompetitionCB, L"Export language:");
gdi.addItem("LanguageType", typeLanguages); gdi.setItems("LanguageType", typeLanguages);
gdi.selectItemByData("LanguageType", ImportFormats::getDefaultCSVLanguage(*oe)); gdi.selectItemByData("LanguageType", ImportFormats::getDefaultCSVLanguage(*oe));
@ -3878,6 +3904,9 @@ void TabCompetition::selectStartlistOptions(gdioutput &gdi) {
gdi.addCheckbox("IncludeRaceNumber", "Inkludera information om flera lopp per löpare", nullptr, gdi.addCheckbox("IncludeRaceNumber", "Inkludera information om flera lopp per löpare", nullptr,
oe->getPropertyInt("ExpWithRaceNo", true) != 0); oe->getPropertyInt("ExpWithRaceNo", true) != 0);
pair<bool, bool> priSecondId = hasPersonExtId();
showSelectId(priSecondId, gdi);
wstring fn = oe->getPropertyString("ExpStaFilename", L""); wstring fn = oe->getPropertyString("ExpStaFilename", L"");
gdi.addInput("Filename", fn, gdi.addInput("Filename", fn,
48, CompetitionCB, L"Filnamn:").setExtra(L"DoSaveStartlist"); 48, CompetitionCB, L"Filnamn:").setExtra(L"DoSaveStartlist");
@ -3892,13 +3921,34 @@ void TabCompetition::selectStartlistOptions(gdioutput &gdi) {
gdi.refresh(); gdi.refresh();
} }
pair<bool, bool> TabCompetition::hasPersonExtId() const {
vector<pRunner> runners;
oe->getRunners(-1, -1, runners, false);
pair<bool, bool> res(false, false);
for (pRunner r : runners) {
if (!res.first && r->getExtIdentifier() != 0) {
res.first = true;
if (res.second)
break;
}
if (!res.second && r->getExtIdentifier2() != 0) {
res.second = true;
if (res.first)
break;
}
}
return res;
}
void TabCompetition::selectExportSplitOptions(gdioutput &gdi) { void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
gdi.clearPage(false); gdi.clearPage(false);
gdi.addString("", boldLarge, "Export av resultat/sträcktider"); gdi.addString("", boldLarge, "Export av resultat/sträcktider");
gdi.dropLine(); gdi.dropLine();
gdi.pushY(); gdi.pushY();
gdi.addListBox("ClassNewEntries", 250, 400, 0, L"Klassval:", L"", true); gdi.addListBox("ClassNewEntries", 250, 400, 0, L"Klassval:", L"", true);
oe->fillClasses(gdi, "ClassNewEntries", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "ClassNewEntries", {}, oEvent::extraNone, oEvent::filterNone);
gdi.setSelection("ClassNewEntries", allTransfer); gdi.setSelection("ClassNewEntries", allTransfer);
gdi.pushX(); gdi.pushX();
@ -3915,7 +3965,7 @@ void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
vector<pair<wstring, size_t>> types; vector<pair<wstring, size_t>> types;
ImportFormats::getExportFormats(types, true); ImportFormats::getExportFormats(types, true);
gdi.addItem("Type", types); gdi.setItems("Type", types);
ImportFormats::ExportFormats format = ImportFormats::getDefaultExportFormat(*oe); ImportFormats::ExportFormats format = ImportFormats::getDefaultExportFormat(*oe);
gdi.selectItemByData("Type", format); gdi.selectItemByData("Type", format);
@ -3923,7 +3973,7 @@ void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
ImportFormats::getOECSVLanguage(typeLanguages); ImportFormats::getOECSVLanguage(typeLanguages);
gdi.addSelection("LanguageType", 250, 200, CompetitionCB, L"Export language:"); gdi.addSelection("LanguageType", 250, 200, CompetitionCB, L"Export language:");
gdi.addItem("LanguageType", typeLanguages); gdi.setItems("LanguageType", typeLanguages);
gdi.selectItemByData("LanguageType", ImportFormats::getDefaultCSVLanguage(*oe)); gdi.selectItemByData("LanguageType", ImportFormats::getDefaultCSVLanguage(*oe));
@ -3933,7 +3983,8 @@ void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
if (cnf.hasTeamClass() || cnf.hasQualificationFinal()) { if (cnf.hasTeamClass() || cnf.hasQualificationFinal()) {
gdi.addSelection("LegType", 300, 100, 0, L"Exportval, IOF-XML"); gdi.dropLine(0.2);
gdi.addSelection("LegType", 300, 100, 0, L"Exportval, IOF-XML:");
gdi.addItem("LegType", lang.tl("Totalresultat"), 1); gdi.addItem("LegType", lang.tl("Totalresultat"), 1);
gdi.addItem("LegType", lang.tl("Alla lopp som individuella"), 3); gdi.addItem("LegType", lang.tl("Alla lopp som individuella"), 3);
if (cnf.hasTeamClass()) { if (cnf.hasTeamClass()) {
@ -3961,6 +4012,9 @@ void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
gdi.addCheckbox("IncludeRaceNumber", "Inkludera information om flera lopp per löpare", 0, gdi.addCheckbox("IncludeRaceNumber", "Inkludera information om flera lopp per löpare", 0,
oe->getPropertyInt("ExpWithRaceNo", true) != 0); oe->getPropertyInt("ExpWithRaceNo", true) != 0);
pair<bool, bool> priSecondId = hasPersonExtId();
showSelectId(priSecondId, gdi);
wstring fn = oe->getPropertyString("ExpResFilename", L""); wstring fn = oe->getPropertyString("ExpResFilename", L"");
gdi.addInput("Filename", fn, 48, CompetitionCB, L"Filnamn:").setExtra(L"DoSaveSplits"); gdi.addInput("Filename", fn, 48, CompetitionCB, L"Filnamn:").setExtra(L"DoSaveSplits");
setExportOptionsStatus(gdi, format); setExportOptionsStatus(gdi, format);
@ -3975,6 +4029,60 @@ void TabCompetition::selectExportSplitOptions(gdioutput &gdi) {
gdi.refresh(); gdi.refresh();
} }
void TabCompetition::showSelectId(std::pair<bool, bool>& priSecondId, gdioutput& gdi) {
class IdType : public GuiHandler {
void handle(gdioutput& gdi, BaseInfo& info, GuiEventType type) final {
string baseType = info.id.substr(0, info.id.length() - 2);
gdi.setInputStatus(baseType + "Type", gdi.isChecked(info.id));
}
};
if (priSecondId.first && priSecondId.second) {
auto idTypes = oe->getRunnerIdTypes();
gdi.dropLine(0.5);
gdi.addString("", 0, "Välj typ av ID att exportera:");
gdi.dropLine(0.3);
gdi.fillRight();
const int baseX = gdi.getCX();
gdi.addCheckbox("PrimaryId", "Primärt").setHandler(make_shared<IdType>());
const int idx = baseX + (3 * (gdi.getCX() - baseX)) / 2;
gdi.setCX(idx);
gdi.addInput("PrimaryType", idTypes.first);
gdi.popX();
gdi.dropLine(2);
gdi.fillRight();
gdi.addCheckbox("SecondaryId", "Sekundärt").setHandler(make_shared<IdType>());
gdi.setCX(max(idx, gdi.getCX()));
gdi.addInput("SecondaryType", idTypes.second);
gdi.popX();
gdi.dropLine(2);
gdi.fillDown();
}
}
pair<string, string> TabCompetition::getPreferredIdTypes(gdioutput& gdi) {
pair<string, string> preferredIdTypes;
if (gdi.hasWidget("PrimaryId")) {
if (gdi.isChecked("PrimaryId")) {
wstring pt = gdi.getText("PrimaryType");
preferredIdTypes.first = gdioutput::narrow(pt);
if (preferredIdTypes.first.empty())
preferredIdTypes.first = "PRIMARY";
}
if (gdi.isChecked("SecondaryId")) {
wstring st = gdi.getText("SecondaryType");
preferredIdTypes.second = gdioutput::narrow(st);
if (preferredIdTypes.second.empty())
preferredIdTypes.second = "SECONDARY";
}
}
return preferredIdTypes;
}
void TabCompetition::setExportOptionsStatus(gdioutput &gdi, int format) const { void TabCompetition::setExportOptionsStatus(gdioutput &gdi, int format) const {
if (gdi.hasWidget("LegType")) { if (gdi.hasWidget("LegType")) {
gdi.setInputStatus("LegType", format == ImportFormats::IOF30 || format == ImportFormats::IOF203); // Enable on IOF-XML gdi.setInputStatus("LegType", format == ImportFormats::IOF30 || format == ImportFormats::IOF203); // Enable on IOF-XML
@ -3993,6 +4101,17 @@ void TabCompetition::setExportOptionsStatus(gdioutput &gdi, int format) const {
gdi.setInputStatus("IncludeRaceNumber", format == ImportFormats::IOF30); // Enable on IOF-XML gdi.setInputStatus("IncludeRaceNumber", format == ImportFormats::IOF30); // Enable on IOF-XML
} }
if (gdi.hasWidget("PrimaryId")) {
for (auto s : {"Primary", "Secondary" }) {
bool enable = format == ImportFormats::IOF30;
string ss = s;
string ids = ss + "Id";
// Enable on IOF-XML
gdi.setInputStatus(ids, enable);
gdi.setInputStatus(ss + "Type", enable && gdi.isChecked(ids));
}
}
gdi.setInputStatus("LanguageType", format == ImportFormats::OE); gdi.setInputStatus("LanguageType", format == ImportFormats::OE);
if (gdi.hasWidget("Filename")) { if (gdi.hasWidget("Filename")) {
@ -4064,10 +4183,25 @@ void TabCompetition::loadSettings(gdioutput &gdi) {
oe->getDI().buildDataFields(gdi, fields, 10); oe->getDI().buildDataFields(gdi, fields, 10);
gdi.popX();
gdi.dropLine(3);
gdi.fillDown();
gdi.addString("", gdi.getCY(), gdi.getCX(), 10| breakLines,
L"help_second_fee",
gdi.scaleLength(250));
gdi.fillRight();;
fields.clear();
fields.push_back("SecondEntryDate");
fields.push_back("SecondEntryFactor");
oe->getDI().buildDataFields(gdi, fields, 10);
gdi.fillDown(); gdi.fillDown();
gdi.popX(); gdi.popX();
gdi.dropLine(3); gdi.dropLine(3);
gdi.addString("", 1, "Åldersgränser, reducerad anmälningsavgift"); gdi.addString("", 1, "Åldersgränser, reducerad anmälningsavgift");
gdi.addString("", 0, "Ungdomar och äldre kan få reducerad avgift"); gdi.addString("", 0, "Ungdomar och äldre kan få reducerad avgift");
gdi.dropLine(0.5); gdi.dropLine(0.5);
@ -4188,19 +4322,32 @@ void TabCompetition::loadSettings(gdioutput &gdi) {
string ms = itos(modes[k].second); string ms = itos(modes[k].second);
gdi.addInput("M" + itos(k), modes[k].first, 24).setExtra(modes[k].second); gdi.addInput("M" + itos(k), modes[k].first, 24).setExtra(modes[k].second);
if (k > 0) if (k > 0)
gdi.addButton(gdi.getCX(), gdi.getCY(), gdi.scaleLength(20), gdi.addButton(gdi.getCX(), gdi.getCY(), gdi.scaleLength(20),
"RemovePayMode", makeDash(L"-"), CompetitionCB, "RemovePayMode", makeDash(L"-"), CompetitionCB,
L"Ta bort", false, false).setExtra(modes[k].second); L"Ta bort", false, false).setExtra(modes[k].second);
if (k == 0) if (k == 0)
gdi.addButton(gdi.getCX(), gdi.getCY(), gdi.scaleLength(20), gdi.addButton(gdi.getCX(), gdi.getCY(), gdi.scaleLength(20),
"AddPayMode", "+", CompetitionCB, "AddPayMode", "+", CompetitionCB,
"Lägg till", false, false); "Lägg till", false, false);
gdi.dropLine(2.5); gdi.dropLine(2.5);
gdi.popX(); gdi.popX();
} }
bottom = max(bottom, gdi.getCY());
gdi.fillDown();
gdi.addString("", 1, "Extra datafält");
gdi.dropLine(0.2);
gdi.addSelection("DataFields", 200, 200, CompetitionCB, L"Sida:");
gdi.addItem("DataFields", lang.tl("Deltagare"), 0);
gdi.addItem("DataFields", lang.tl("Lag"), 1);
gdi.addItem("DataFields", lang.tl("Klass"), 2);
gdi.addItem("DataFields", lang.tl("Direktanmälan"), 3);
gdi.selectFirstItem("DataFields");
gdi.setData("FieldX", gdi.getCX());
gdi.setData("FieldY", gdi.getCY());
bottom = max(bottom, gdi.getCY());
gdi.popX(); gdi.popX();
gdi.setCY(bottom); gdi.setCY(bottom);
gdi.fillRight(); gdi.fillRight();
@ -4208,18 +4355,145 @@ void TabCompetition::loadSettings(gdioutput &gdi) {
gdi.addButton("Cancel", "Avbryt", CompetitionCB).setCancel(); gdi.addButton("Cancel", "Avbryt", CompetitionCB).setCancel();
gdi.dropLine(2); gdi.dropLine(2);
gdi.setOnClearCb(CompetitionCB); gdi.setOnClearCb(CompetitionCB);
gdi.refresh();
showExtraFields(gdi, oEvent::ExtraFieldContext::Runner);
}
void TabCompetition::showExtraFields(gdioutput& gdi, oEvent::ExtraFieldContext type) {
gdi.restore("ExtraFields", false);
gdi.setRestorePoint("ExtraFields");
gdi.setData("DataFieldsContext", int(type));
auto ef = oe->getExtraFields(type);
auto efNames = oe->getExtraFieldNames();
auto getName = [&ef, &efNames](oEvent::ExtraFields field) -> wstring {
auto res = ef.find(field);
if (res != ef.end() && !res->second.empty())
return res->second;
res = efNames.find(field);
if (res != efNames.end() && !res->second.empty())
return res->second;
return L"";
};
gdi.setCX(gdi.getDataInt("FieldX"));
gdi.setCY(gdi.getDataInt("FieldY"));
gdi.dropLine(0.5);
gdi.pushX();
gdi.fillRight();
auto dataA = ef.find(oEvent::ExtraFields::DataA);
gdi.dropLine(-0.2);
gdi.addCheckbox("DataA", L"Extra data X:#(A)", nullptr, dataA != ef.end());
gdi.addInput("DataAName", getName(oEvent::ExtraFields::DataA), 16);
gdi.dropLine(2.5);
gdi.popX();
auto dataB = ef.find(oEvent::ExtraFields::DataB);
gdi.addCheckbox("DataB", L"Extra data X:#(B)", nullptr, dataB != ef.end());
gdi.dropLine(-0.2);
gdi.addInput("DataBName", getName(oEvent::ExtraFields::DataB), 16);
gdi.dropLine(2.5);
gdi.popX();
auto textA = ef.find(oEvent::ExtraFields::TextA);
gdi.addCheckbox("TextA", L"Text:", nullptr, textA != ef.end());
gdi.dropLine(-0.2);
gdi.addInput("TextAName", getName(oEvent::ExtraFields::TextA), 16);
gdi.dropLine(2.5);
gdi.popX();
if (type == oEvent::ExtraFieldContext::DirectEntry) {
gdi.addCheckbox("StartTime", L"Starttid", nullptr, ef.count(oEvent::ExtraFields::StartTime));
gdi.addCheckbox("Bib", L"Nummerlapp", nullptr, ef.count(oEvent::ExtraFields::Bib));
}
if (type != oEvent::ExtraFieldContext::Class)
gdi.addCheckbox("Nationality", L"Nationalitet", nullptr, ef.count(oEvent::ExtraFields::Nationality));
if (type == oEvent::ExtraFieldContext::DirectEntry) {
gdi.dropLine(2.5);
gdi.popX();
}
if (type == oEvent::ExtraFieldContext::Runner || type == oEvent::ExtraFieldContext::DirectEntry) {
gdi.addCheckbox("Sex", L"Kön", nullptr, ef.count(oEvent::ExtraFields::Sex));
gdi.addCheckbox("BirthDate", L"Födelsedatum", nullptr, ef.count(oEvent::ExtraFields::BirthDate));
gdi.addCheckbox("Rank", L"Ranking", nullptr, ef.count(oEvent::ExtraFields::Rank));
gdi.addCheckbox("Phone", L"Telefon", nullptr, ef.count(oEvent::ExtraFields::Phone));
}
gdi.refresh();
}
void TabCompetition::saveExtraFields(gdioutput& gdi, oEvent::ExtraFieldContext type) {
map<oEvent::ExtraFields, wstring> fields;
if (gdi.isChecked("DataA")) {
wstring name = gdi.getText("DataAName");
if (trim(name).empty())
name = L"Data A";
fields[oEvent::ExtraFields::DataA] = name;
}
if (gdi.isChecked("DataB")) {
wstring name = gdi.getText("DataBName");
if (trim(name).empty())
name = L"Data B";
fields[oEvent::ExtraFields::DataB] = name;
}
if (gdi.isChecked("TextA")) {
wstring name = gdi.getText("TextAName");
if (trim(name).empty())
name = L"Text";
fields[oEvent::ExtraFields::TextA] = name;
}
if (gdi.isChecked("Nationality"))
fields[oEvent::ExtraFields::Nationality] = L"";
if (gdi.isChecked("Sex"))
fields[oEvent::ExtraFields::Sex] = L"";
if (gdi.isChecked("BirthDate"))
fields[oEvent::ExtraFields::BirthDate] = L"";
if (gdi.isChecked("Rank"))
fields[oEvent::ExtraFields::Rank] = L"";
if (gdi.isChecked("Phone"))
fields[oEvent::ExtraFields::Phone] = L"";
if (gdi.isChecked("Sex"))
fields[oEvent::ExtraFields::Sex] = L"";
if (gdi.isChecked("StartTime"))
fields[oEvent::ExtraFields::StartTime] = L"";
if (gdi.isChecked("Bib"))
fields[oEvent::ExtraFields::Bib] = L"";
if (gdi.isChecked("Sex"))
fields[oEvent::ExtraFields::Sex] = L"";
oe->updateExtraFields(type, fields);
} }
void TabCompetition::saveSettings(gdioutput &gdi) { void TabCompetition::saveSettings(gdioutput &gdi) {
vector<string> fields = { "CardFee" ,"EliteFee" ,"EntryFee","YouthFee" }; vector<string> fields = { "CardFee", "EliteFee", "EntryFee", "YouthFee" };
vector<int> fees(4); vector<int> fees(4);
for (int k = 0; k<4; k++) for (int k = 0; k<4; k++)
fees[k] = oe->getDCI().getInt(fields[k]); fees[k] = oe->getDCI().getInt(fields[k]);
wstring factor = oe->getDCI().getString("LateEntryFactor"); wstring factor = oe->getDCI().getString("LateEntryFactor");
wstring factor2 = oe->getDCI().getString("SecondEntryFactor");
bool useFactor2 = oe->getDCI().getInt("SecondEntryDate") > 0;
set<string> modified; set<string> modified;
oe->getDI().saveDataFields(gdi, modified); oe->getDI().saveDataFields(gdi, modified);
@ -4241,6 +4515,13 @@ void TabCompetition::saveSettings(gdioutput &gdi) {
if (factor != oe->getDCI().getString("LateEntryFactor")) if (factor != oe->getDCI().getString("LateEntryFactor"))
changedFee = true; changedFee = true;
if (factor2 != oe->getDCI().getString("SecondEntryFactor"))
changedFee = true;
bool useFactor2Now = oe->getDCI().getInt("SecondEntryDate") > 0;
if (useFactor2 != useFactor2Now)
changedFee = true;
if (oe->getDI().setInt("UTC", gdi.isChecked("UTC") ? 1 : 0)) if (oe->getDI().setInt("UTC", gdi.isChecked("UTC") ? 1 : 0))
setEventorUTC(gdi.isChecked("UTC")); setEventorUTC(gdi.isChecked("UTC"));
@ -4284,33 +4565,11 @@ void TabCompetition::saveSettings(gdioutput &gdi) {
throw std::exception(); throw std::exception();
} }
} }
//oe->setProperty("PayModes", oe->getDCI().getString("PayModes"));
/*oe->setProperty("Organizer", oe->getDCI().getString("Organizer"));
oe->setProperty("Street", oe->getDCI().getString("Street"));
oe->setProperty("Address", oe->getDCI().getString("Address"));
oe->setProperty("EMail", oe->getDCI().getString("EMail"));
oe->setProperty("Homepage", oe->getDCI().getString("Homepage"));
oe->setProperty("CardFee", oe->getDCI().getInt("CardFee"));
oe->setProperty("EliteFee", oe->getDCI().getInt("EliteFee"));
oe->setProperty("EntryFee", oe->getDCI().getInt("EntryFee"));
oe->setProperty("YouthFee", oe->getDCI().getInt("YouthFee"));
oe->setProperty("YouthAge", oe->getDCI().getInt("YouthAge"));
oe->setProperty("SeniorAge", oe->getDCI().getInt("SeniorAge"));
oe->setProperty("Account", oe->getDCI().getString("Account"));
oe->setProperty("LateEntryFactor", oe->getDCI().getString("LateEntryFactor"));
oe->setProperty("CurrencySymbol", oe->getDCI().getString("CurrencySymbol"));
oe->setProperty("CurrencyFactor", oe->getDCI().getInt("CurrencyFactor"));
oe->setProperty("CurrencyPreSymbol", oe->getDCI().getInt("CurrencyPreSymbol"));
oe->setProperty("CurrencySeparator", oe->getDCI().getString("CurrencySeparator"));
*/
//oe->setProperty("PayModes", oe->getDCI().getString("PayModes"));
} }
oEvent::ExtraFieldContext context = oEvent::ExtraFieldContext(gdi.getSelectedItem("DataFields").first);
saveExtraFields(gdi, context);
oe->synchronize(true); oe->synchronize(true);
set<int> dummy; set<int> dummy;
if (changedFee && oe->getNumClasses() > 0) { if (changedFee && oe->getNumClasses() > 0) {

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -45,7 +45,7 @@ class TabCompetition :
// Events from Eventor // Events from Eventor
vector<CompetitionInfo> events; vector<CompetitionInfo> events;
list<PrefsEditor> prefsEditor; shared_ptr<PrefsEditor> prefsEditor;
oFreeImport fi; oFreeImport fi;
wstring entryText; wstring entryText;
@ -83,8 +83,7 @@ class TabCompetition :
vector<CompetitionInfo> &events) const; vector<CompetitionInfo> &events) const;
void saveSettings(gdioutput &gdi); void saveSettings(gdioutput &gdi);
void loadSettings(gdioutput &gdi);
void getEventorCmpData(gdioutput &gdi, int id, void getEventorCmpData(gdioutput &gdi, int id,
const wstring &eventFile, const wstring &eventFile,
const wstring &clubFile, const wstring &clubFile,
@ -98,6 +97,8 @@ class TabCompetition :
string eventorOrigin; // The command used when checking eventor string eventorOrigin; // The command used when checking eventor
bool checkEventor(gdioutput &gdi, ButtonInfo &bi); bool checkEventor(gdioutput &gdi, ButtonInfo &bi);
pair<bool, bool> hasPersonExtId() const;
bool useEventor() const; bool useEventor() const;
bool useEventorUTC() const; bool useEventorUTC() const;
@ -125,13 +126,18 @@ class TabCompetition :
void entryForm(gdioutput &gdi, bool isGuide); void entryForm(gdioutput &gdi, bool isGuide);
FlowOperation saveEntries(gdioutput &gdi, bool removeRemoved, int classOffset, bool isGuide); FlowOperation saveEntries(gdioutput &gdi, bool removeRemoved, int classOffset, bool isGuide);
FlowOperation checkStageFilter(gdioutput &gdi, const wstring &fname, set<int> &filter, string &preferredIdProvider); FlowOperation checkStageFilter(gdioutput &gdi, const wstring &fname, set<int> &filter, pair<string, string> &preferredIdProvider);
void setExportOptionsStatus(gdioutput &gdi, int format) const; void setExportOptionsStatus(gdioutput &gdi, int format) const;
void selectStartlistOptions(gdioutput &gdi); void selectStartlistOptions(gdioutput &gdi);
void selectExportSplitOptions(gdioutput &gdi); void selectExportSplitOptions(gdioutput &gdi);
void showSelectId(std::pair<bool, bool>& priSecondId, gdioutput& gdi);
pair<string, string> TabCompetition::getPreferredIdTypes(gdioutput& gdi);
void saveExtraFields(gdioutput& gdi, oEvent::ExtraFieldContext type);
void entryChoice(gdioutput &gdi); void entryChoice(gdioutput &gdi);
void createCompetition(gdioutput &gdi); void createCompetition(gdioutput &gdi);
@ -149,6 +155,9 @@ protected:
void clearCompetitionData(); void clearCompetitionData();
public: public:
void loadSettings(gdioutput& gdi);
void showExtraFields(gdioutput& gdi, oEvent::ExtraFieldContext type);
const char * getTypeStr() const {return "TCmpTab";} const char * getTypeStr() const {return "TCmpTab";}
TabType getType() const {return TCmpTab;} TabType getType() const {return TCmpTab;}
@ -158,9 +167,9 @@ public:
void setEventorServer(const wstring &server); void setEventorServer(const wstring &server);
void setEventorUTC(bool useUTC); void setEventorUTC(bool useUTC);
int competitionCB(gdioutput &gdi, int type, void *data); int competitionCB(gdioutput &gdi, GuiEventType type, BaseInfo *data);
int restoreCB(gdioutput &gdi, int type, void *data); int restoreCB(gdioutput &gdi, GuiEventType type, BaseInfo *data);
int newGuideCB(gdioutput &gdi, int type, void *data); int newGuideCB(gdioutput &gdi, GuiEventType type, BaseInfo *data);
bool loadPage(gdioutput &gdi); bool loadPage(gdioutput &gdi);
TabCompetition(oEvent *oe); TabCompetition(oEvent *oe);

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -151,8 +151,7 @@ void TabControl::selectControl(gdioutput &gdi, pControl pc)
} }
} }
int ControlsCB(gdioutput *gdi, int type, void *data) int ControlsCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
TabControl &tc = dynamic_cast<TabControl &>(*gdi->getTabs().get(TControlTab)); TabControl &tc = dynamic_cast<TabControl &>(*gdi->getTabs().get(TControlTab));
return tc.controlCB(*gdi, type, data); return tc.controlCB(*gdi, type, data);
} }
@ -278,7 +277,7 @@ void TabControl::save(gdioutput &gdi) {
vector<pair<wstring, size_t>> d; vector<pair<wstring, size_t>> d;
oe->fillControls(d, oEvent::ControlType::All); oe->fillControls(d, oEvent::ControlType::All);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
oe->reEvaluateAll(set<int>(), true); oe->reEvaluateAll(set<int>(), true);
@ -402,8 +401,7 @@ void TabControl::visitorTable(Table &table) const {
} }
} }
int TabControl::controlCB(gdioutput &gdi, int type, void *data) int TabControl::controlCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
{
if (type==GUI_BUTTON) { if (type==GUI_BUTTON) {
ButtonInfo bi=*(ButtonInfo *)data; ButtonInfo bi=*(ButtonInfo *)data;
@ -431,7 +429,7 @@ int TabControl::controlCB(gdioutput &gdi, int type, void *data)
pc->synchronize(); pc->synchronize();
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
oe->fillControls(d, oEvent::ControlType::All); oe->fillControls(d, oEvent::ControlType::All);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
selectControl(gdi, pc); selectControl(gdi, pc);
} }
else if (bi.id=="Remove") { else if (bi.id=="Remove") {
@ -449,7 +447,7 @@ int TabControl::controlCB(gdioutput &gdi, int type, void *data)
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
oe->fillControls(d, oEvent::ControlType::All); oe->fillControls(d, oEvent::ControlType::All);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
selectControl(gdi, 0); selectControl(gdi, 0);
} }
else if (bi.id=="SwitchMode") { else if (bi.id=="SwitchMode") {
@ -565,7 +563,7 @@ bool TabControl::loadPage(gdioutput &gdi)
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
oe->fillControls(d, oEvent::ControlType::All); oe->fillControls(d, oEvent::ControlType::All);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
gdi.newColumn(); gdi.newColumn();
gdi.fillDown(); gdi.fillDown();

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@
class TabControl : class TabControl :
public TabBase public TabBase
{ {
int controlCB(gdioutput &gdi, int type, void *data); int controlCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
bool tableMode; bool tableMode;
int controlId; int controlId;
@ -48,5 +48,5 @@ public:
TabControl(oEvent *oe); TabControl(oEvent *oe);
~TabControl(void); ~TabControl(void);
friend int ControlsCB(gdioutput *gdi, int type, void *data); friend int ControlsCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
}; };

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -179,9 +179,13 @@ void TabCourse::selectCourse(gdioutput &gdi, pCourse pc)
if (cc) { if (cc) {
gdi.selectItemByData("CommonControl", cc); gdi.selectItemByData("CommonControl", cc);
} }
fillOtherCourses(gdi, *pc, cc != 0);
auto sh = pc->getShorterVersion(); auto sh = pc->getShorterVersion();
if (sh.first)
fillOtherCourses(gdi, *pc, cc != 0);
else
gdi.selectItemByData("ShortCourse", -1);
gdi.check("Shorten", sh.first); gdi.check("Shorten", sh.first);
gdi.setInputStatus("ShortCourse", sh.first); gdi.setInputStatus("ShortCourse", sh.first);
gdi.selectItemByData("ShortCourse", sh.second ? sh.second->getId() : 0); gdi.selectItemByData("ShortCourse", sh.second ? sh.second->getId() : 0);
@ -216,7 +220,7 @@ void TabCourse::selectCourse(gdioutput &gdi, pCourse pc)
gdi.setInputStatus("DrawCourse", pc != 0, true); gdi.setInputStatus("DrawCourse", pc != 0, true);
} }
int CourseCB(gdioutput *gdi, int type, void *data) { int CourseCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
TabCourse &tc = dynamic_cast<TabCourse &>(*gdi->getTabs().get(TCourseTab)); TabCourse &tc = dynamic_cast<TabCourse &>(*gdi->getTabs().get(TCourseTab));
return tc.courseCB(*gdi, type, data); return tc.courseCB(*gdi, type, data);
} }
@ -307,7 +311,7 @@ void TabCourse::save(gdioutput &gdi, int canSwitchViewMode) {
pc->synchronize();//Update SQL pc->synchronize();//Update SQL
oe->fillCourses(gdi, "Courses"); oe->fillCourses(gdi, "Courses", {}, false);
oe->reEvaluateCourse(pc->getId(), true); oe->reEvaluateCourse(pc->getId(), true);
if (canSwitchViewMode != 2 && changedCourse && pc->getLegLengths().size() > 2) { if (canSwitchViewMode != 2 && changedCourse && pc->getLegLengths().size() > 2) {
@ -331,8 +335,7 @@ void TabCourse::save(gdioutput &gdi, int canSwitchViewMode) {
selectCourse(gdi, pc); selectCourse(gdi, pc);
} }
int TabCourse::courseCB(gdioutput &gdi, int type, void *data) int TabCourse::courseCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
{
if (type==GUI_BUTTON) { if (type==GUI_BUTTON) {
ButtonInfo bi=*(ButtonInfo *)data; ButtonInfo bi=*(ButtonInfo *)data;
@ -448,9 +451,13 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
bool w = gdi.isChecked(bi.id); bool w = gdi.isChecked(bi.id);
gdi.setInputStatus("ShortCourse", w); gdi.setInputStatus("ShortCourse", w);
if (w) { if (w) {
pCourse pc = oe->getCourse(courseId);
if (pc) {
fillOtherCourses(gdi, *pc, gdi.isChecked("WithLoops"));
}
ListBoxInfo clb; ListBoxInfo clb;
if (!gdi.getSelectedItem("ShortCoursse", clb) || clb.data <= 0) if (!gdi.getSelectedItem("ShortCourse", clb) || clb.data <= 0)
gdi.selectFirstItem("CommonControl"); gdi.selectFirstItem("ShortCourse");
} }
} }
else if (bi.id == "ExportCourses") { else if (bi.id == "ExportCourses") {
@ -621,7 +628,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
} }
pCourse pc = oe->addCourse(oe->getAutoCourseName()); pCourse pc = oe->addCourse(oe->getAutoCourseName());
pc->synchronize(); pc->synchronize();
oe->fillCourses(gdi, "Courses"); oe->fillCourses(gdi, "Courses", {}, false);
selectCourse(gdi, pc); selectCourse(gdi, pc);
gdi.setInputFocus("Name", true); gdi.setInputFocus("Name", true);
addedCourse = true; addedCourse = true;
@ -636,7 +643,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
else else
oe->removeCourse(cid); oe->removeCourse(cid);
oe->fillCourses(gdi, "Courses"); oe->fillCourses(gdi, "Courses", {}, false);
selectCourse(gdi, 0); selectCourse(gdi, 0);
} }
@ -757,7 +764,7 @@ bool TabCourse::loadPage(gdioutput &gdi) {
gdi.addListBox("Courses", 250, 360, CourseCB, L"Banor (antal kontroller)").isEdit(false).ignore(true); gdi.addListBox("Courses", 250, 360, CourseCB, L"Banor (antal kontroller)").isEdit(false).ignore(true);
gdi.setTabStops("Courses", 240); gdi.setTabStops("Courses", 240);
oe->fillCourses(gdi, "Courses"); oe->fillCourses(gdi, "Courses", {}, false);
gdi.dropLine(0.7); gdi.dropLine(0.7);
gdi.pushX(); gdi.pushX();
@ -911,7 +918,7 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
gdi.fillDown(); gdi.fillDown();
} }
else if (filename.find(L".txt") != wstring::npos || filename.find(L".TXT") != wstring::npos) { else if (filename.find(L".txt") != wstring::npos || filename.find(L".TXT") != wstring::npos) {
ifstream fin(filename); std::ifstream fin(filename);
if (!fin.good()) if (!fin.good())
throw meosException(L"Cannot read " + filename); throw meosException(L"Cannot read " + filename);
@ -970,7 +977,7 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
} }
else { else {
set<int> noFilter; set<int> noFilter;
string noType; pair<string, string> noType;
int classIdOffset = 0; int classIdOffset = 0;
int courseIdOffset = 0; int courseIdOffset = 0;
oe->importXML_EntryData(gdi, filename.c_str(), addToClasses, false, oe->importXML_EntryData(gdi, filename.c_str(), addToClasses, false,
@ -1174,7 +1181,7 @@ void TabCourse::fillCourseControls(gdioutput &gdi, const wstring &ctrl) {
} }
gdi.clearList("CommonControl"); gdi.clearList("CommonControl");
gdi.addItem("CommonControl", item); gdi.setItems("CommonControl", item);
} }
void TabCourse::fillOtherCourses(gdioutput &gdi, oCourse &crs, bool withLoops) { void TabCourse::fillOtherCourses(gdioutput &gdi, oCourse &crs, bool withLoops) {
@ -1198,8 +1205,7 @@ void TabCourse::fillOtherCourses(gdioutput &gdi, oCourse &crs, bool withLoops) {
out.push_back(ac[k]); out.push_back(ac[k]);
} }
gdi.clearList("ShortCourse"); gdi.setItems("ShortCourse", out);
gdi.addItem("ShortCourse", out);
} }
void TabCourse::saveLegLengths(gdioutput &gdi) { void TabCourse::saveLegLengths(gdioutput &gdi) {

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -31,7 +31,7 @@ class TabCourse :
int courseId; int courseId;
/** canSwitchViewMode: 0 = no, 1 = yes, 2 = switching to legs */ /** canSwitchViewMode: 0 = no, 1 = yes, 2 = switching to legs */
void save(gdioutput &gdi, int canSwitchViewMode); void save(gdioutput &gdi, int canSwitchViewMode);
int courseCB(gdioutput &gdi, int type, void *data); int courseCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
bool addedCourse; bool addedCourse;
wstring time_limit; wstring time_limit;
@ -74,5 +74,5 @@ public:
static void setupCourseImport(gdioutput& gdi, GUICALLBACK cb); static void setupCourseImport(gdioutput& gdi, GUICALLBACK cb);
friend int CourseCB(gdioutput *gdi, int type, void *data); friend int CourseCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
}; };

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -80,10 +80,9 @@ TabList::~TabList(void)
liveResults.clear(); liveResults.clear();
} }
int ListsCB(gdioutput *gdi, int type, void *data); int ListsCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
int ListsEventCB(gdioutput *gdi, int type, void *data) int ListsEventCB(gdioutput *gdi, GuiEventType type, BaseInfo *data) {
{
if (type!=GUI_EVENT) if (type!=GUI_EVENT)
return -1; return -1;
@ -105,10 +104,10 @@ void TabList::rebuildList(gdioutput &gdi)
} }
} }
int openRunnerTeamCB(gdioutput *gdi, int type, void *data) int openRunnerTeamCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
if (type==GUI_LINK && data) { if (type==GUI_LINK && data) {
TextInfo *ti = static_cast<TextInfo *>(data); TextInfo *ti = dynamic_cast<TextInfo *>(data);
int id = ti->getExtraInt(); int id = ti->getExtraInt();
if (id != 0 && ti->id == "T" && gdi->canClear()) { if (id != 0 && ti->id == "T" && gdi->canClear()) {
@ -123,31 +122,28 @@ int openRunnerTeamCB(gdioutput *gdi, int type, void *data)
return 0; return 0;
} }
int NoStartRunnerCB(gdioutput *gdi, int type, void *data) int NoStartRunnerCB(gdioutput* gdi, GuiEventType type, BaseInfo* data) {
{ if (type == GUI_LINK) {
if (type==GUI_LINK) TextInfo* ti = dynamic_cast<TextInfo*>(data);
{ int id = atoi(ti->id.c_str());
TextInfo *ti=(TextInfo *)data;
int id=atoi(ti->id.c_str());
TabList &tc = dynamic_cast<TabList &>(*gdi->getTabs().get(TListTab)); TabList& tc = dynamic_cast<TabList&>(*gdi->getTabs().get(TListTab));
pRunner p = tc.getEvent()->getRunner(id, 0); pRunner p = tc.getEvent()->getRunner(id, 0);
if (p) { if (p) {
p->setStatus(StatusDNS, true, oBase::ChangeType::Update); p->setStatus(StatusDNS, true, oBase::ChangeType::Update);
p->synchronize(); p->synchronize();
ti->callBack=0; ti->callBack = 0;
ti->highlight=false; ti->highlight = false;
ti->active=false; ti->active = false;
ti->color=RGB(255,0,0); ti->color = RGB(255, 0, 0);
gdi->setText(ti->id, L"Ej start", true); gdi->setText(ti->id, L"Ej start", true);
} }
} }
return 0; return 0;
} }
int ListsCB(gdioutput *gdi, int type, void *data) int ListsCB(gdioutput *gdi, GuiEventType type, BaseInfo *data) {
{
TabList &tc = dynamic_cast<TabList &>(*gdi->getTabs().get(TListTab)); TabList &tc = dynamic_cast<TabList &>(*gdi->getTabs().get(TListTab));
return tc.listCB(*gdi, type, data); return tc.listCB(*gdi, type, data);
@ -218,7 +214,7 @@ void TabList::generateList(gdioutput &gdi, bool forceUpdate)
} }
gdi.setRestorePoint("GeneralList"); gdi.setRestorePoint("GeneralList");
currentList.setCallback(ownWindow ? 0 : openRunnerTeamCB); currentList.setCallback(ownWindow ? nullptr : openRunnerTeamCB);
const auto &par = currentList.getParam(); const auto &par = currentList.getParam();
int bgColor = par.bgColor; int bgColor = par.bgColor;
@ -276,7 +272,7 @@ void TabList::generateList(gdioutput &gdi, bool forceUpdate)
gdi.addButton(gdi.getWidth() + 20, baseY, gdi.scaleLength(baseButtonWidth), gdi.addButton(gdi.getWidth() + 20, baseY, gdi.scaleLength(baseButtonWidth),
"ListDesign", "Utseende...", ListsCB, "Justera visningsinställningar", true, false); "ListDesign", "Utseende...", ListsCB, "Justera visningsinställningar", true, false);
if (!currentList.getParam().saved && !oe->isReadOnly()) { if (!currentList.getParam().saved && !oe->isKiosk()) {
baseY += 3 + gdi.getButtonHeight(); baseY += 3 + gdi.getButtonHeight();
gdi.addButton(gdi.getWidth()+20, baseY, gdi.scaleLength(baseButtonWidth), gdi.addButton(gdi.getWidth()+20, baseY, gdi.scaleLength(baseButtonWidth),
"Remember", "Kom ihåg listan...", ListsCB, "Spara den här listan som en favoritlista", true, false); "Remember", "Kom ihåg listan...", ListsCB, "Spara den här listan som en favoritlista", true, false);
@ -300,19 +296,18 @@ void TabList::generateList(gdioutput &gdi, bool forceUpdate)
} }
} }
int TabList::listCB(gdioutput &gdi, int type, void *data) int TabList::listCB(gdioutput &gdi, GuiEventType type, BaseInfo *data) {
{
int index; int index;
if (type==GUI_BUTTON || type==GUI_EVENT) { if (type==GUI_BUTTON || type==GUI_EVENT) {
BaseInfo *tbi = 0; BaseInfo *tbi = 0;
ButtonInfo button; ButtonInfo button;
EventInfo evnt; EventInfo evnt;
if (type == GUI_BUTTON) { if (type == GUI_BUTTON) {
button = *(ButtonInfo *)data; button = dynamic_cast<ButtonInfo &>(*data);
tbi = &button; tbi = &button;
} }
else if (type == GUI_EVENT) { else if (type == GUI_EVENT) {
evnt = *(EventInfo *)data; evnt = dynamic_cast<EventInfo&>(*data);
tbi = &evnt; tbi = &evnt;
} }
else else
@ -490,7 +485,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
gdi.addListBox("Merge", 350, 250, 0, L"Slå ihop med:"); gdi.addListBox("Merge", 350, 250, 0, L"Slå ihop med:");
vector < pair<wstring, size_t> > cand; vector < pair<wstring, size_t> > cand;
oe->getListContainer().getMergeCandidates(lbi.data, cand); oe->getListContainer().getMergeCandidates(lbi.data, cand);
gdi.addItem("Merge", cand); gdi.setItems("Merge", cand);
gdi.addCheckbox("ShowTitle", "Visa rubrik mellan listorna", 0, false); gdi.addCheckbox("ShowTitle", "Visa rubrik mellan listorna", 0, false);
gdi.fillRight(); gdi.fillRight();
gdi.addButton("DoMerge", "Slå ihop", ListsCB).setDefault(); gdi.addButton("DoMerge", "Slå ihop", ListsCB).setDefault();
@ -636,7 +631,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ListBoxInfo lbi; ListBoxInfo lbi;
bool advancedResults = false; bool advancedResults = false;
if (gdi.getSelectedItem("ListType", lbi)) { if (gdi.getSelectedItem("ListType", lbi)) {
currentListType=EStdListType(lbi.data); currentListType = EStdListType(lbi.data);
} }
else if (gdi.getSelectedItem("ResultType", lbi)) { else if (gdi.getSelectedItem("ResultType", lbi)) {
currentListType = getTypeFromResultIndex(lbi.data); currentListType = getTypeFromResultIndex(lbi.data);
@ -1230,6 +1225,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else if (lbi.id == "ListSelection") { else if (lbi.id == "ListSelection") {
gdi.getSelection(lbi.id, lastClassSelection); gdi.getSelection(lbi.id, lastClassSelection);
if (gdi.hasWidget("ResultType")) { if (gdi.hasWidget("ResultType")) {
lastResultClassSelection = lastClassSelection;
ListBoxInfo entry; ListBoxInfo entry;
gdi.getSelectedItem("ResultType", entry); gdi.getSelectedItem("ResultType", entry);
gdi.setInputStatus("Generate", !lastClassSelection.empty() && int(entry.data) >= 0); gdi.setInputStatus("Generate", !lastClassSelection.empty() && int(entry.data) >= 0);
@ -1348,7 +1344,7 @@ void TabList::enableFromTo(oEvent &oe, gdioutput &gdi, bool from, bool to) {
vector< pair<wstring, size_t> > ds; vector< pair<wstring, size_t> > ds;
ds.push_back(make_pair(lang.tl("Start"), 0)); ds.push_back(make_pair(lang.tl("Start"), 0));
ds.insert(ds.end(), d.begin(), d.end()); ds.insert(ds.end(), d.begin(), d.end());
gdi.addItem("ResultSpecialFrom", ds); gdi.setItems("ResultSpecialFrom", ds);
if (!gdi.selectItemByData("ResultSpecialFrom", oe.getPropertyInt("ControlFrom", 0))) { if (!gdi.selectItemByData("ResultSpecialFrom", oe.getPropertyInt("ControlFrom", 0))) {
gdi.selectItemByData("ResultSpecialFrom", 0); // Fallback gdi.selectItemByData("ResultSpecialFrom", 0); // Fallback
} }
@ -1360,7 +1356,7 @@ void TabList::enableFromTo(oEvent &oe, gdioutput &gdi, bool from, bool to) {
if (to) { if (to) {
gdi.enableInput("ResultSpecialTo"); gdi.enableInput("ResultSpecialTo");
gdi.addItem("ResultSpecialTo", d); gdi.setItems("ResultSpecialTo", d);
gdi.addItem("ResultSpecialTo", lang.tl("Mål"), 0); gdi.addItem("ResultSpecialTo", lang.tl("Mål"), 0);
if (!gdi.selectItemByData("ResultSpecialTo", oe.getPropertyInt("ControlTo", 0))) { if (!gdi.selectItemByData("ResultSpecialTo", oe.getPropertyInt("ControlTo", 0))) {
gdi.selectItemByData("ResultSpecialTo", 0); // Fallback gdi.selectItemByData("ResultSpecialTo", 0); // Fallback
@ -1379,7 +1375,7 @@ void TabList::selectGeneralList(gdioutput &gdi, EStdListType type)
oe->setProperty("ListType", type); oe->setProperty("ListType", type);
if (li.supportClasses) { if (li.supportClasses) {
gdi.enableInput("ListSelection"); gdi.enableInput("ListSelection");
oe->fillClasses(gdi, "ListSelection", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "ListSelection", {}, oEvent::extraNone, oEvent::filterNone);
if (lastClassSelection.empty()) if (lastClassSelection.empty())
lastClassSelection.insert(-1); lastClassSelection.insert(-1);
gdi.setSelection("ListSelection", lastClassSelection); gdi.setSelection("ListSelection", lastClassSelection);
@ -1404,7 +1400,7 @@ void TabList::selectGeneralList(gdioutput &gdi, EStdListType type)
set<int> clsUnused; set<int> clsUnused;
vector< pair<wstring, size_t> > out; vector< pair<wstring, size_t> > out;
oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out); oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out);
gdi.addItem("LegNumber", out); gdi.setItems("LegNumber", out);
gdi.setInputStatus("LegNumber", !out.empty()); gdi.setInputStatus("LegNumber", !out.empty());
} }
else { else {
@ -1654,7 +1650,7 @@ void TabList::loadRememberList(gdioutput &gdi, string targetTag) {
gdi.addListBox("Merge", 350, 250); gdi.addListBox("Merge", 350, 250);
vector < pair<wstring, size_t> > cand; vector < pair<wstring, size_t> > cand;
oe->getListContainer().getMergeCandidates(-1, cand); oe->getListContainer().getMergeCandidates(-1, cand);
gdi.addItem("Merge", cand); gdi.setItems("Merge", cand);
gdi.dropLine(-0.2); gdi.dropLine(-0.2);
gdi.addCheckbox("ShowTitle", "Visa rubrik mellan listorna", 0, false); gdi.addCheckbox("ShowTitle", "Visa rubrik mellan listorna", 0, false);
gdi.dropLine(0.5); gdi.dropLine(0.5);
@ -2025,7 +2021,7 @@ void TabList::htmlSettings(gdioutput &gdi, string targetTag) {
if (!htmlTemplateTag2Id.count(tmpSettingsParam.htmlTypeTag)) if (!htmlTemplateTag2Id.count(tmpSettingsParam.htmlTypeTag))
tmpSettingsParam.htmlTypeTag = "free"; tmpSettingsParam.htmlTypeTag = "free";
gdi.addItem("Format", items); gdi.setItems("Format", items);
int tid = htmlTemplateTag2Id[tmpSettingsParam.htmlTypeTag]; int tid = htmlTemplateTag2Id[tmpSettingsParam.htmlTypeTag];
gdi.selectItemByData("Format", tid); gdi.selectItemByData("Format", tid);
@ -2174,7 +2170,7 @@ void TabList::loadClassSettings(gdioutput &gdi, string targetTag) {
oEvent::ClassFilter ct = currentList.isTeamList() ? oEvent::filterOnlyMulti : oEvent::filterNone; oEvent::ClassFilter ct = currentList.isTeamList() ? oEvent::filterOnlyMulti : oEvent::filterNone;
oe->fillClasses(gdi, "ListSelection", oEvent::extraNone, ct); oe->fillClasses(gdi, "ListSelection", {}, oEvent::extraNone, ct);
gdi.setSelection("ListSelection", currentList.getParam().selection); gdi.setSelection("ListSelection", currentList.getParam().selection);
gdi.dropLine(2.5); gdi.dropLine(2.5);
@ -2184,14 +2180,15 @@ void TabList::loadClassSettings(gdioutput &gdi, string targetTag) {
ages.emplace_back(lang.tl("Alla"), size_t(oListParam::AgeFilter::All)); ages.emplace_back(lang.tl("Alla"), size_t(oListParam::AgeFilter::All));
ages.emplace_back(lang.tl("Ungdom"), size_t(oListParam::AgeFilter::OnlyYouth)); ages.emplace_back(lang.tl("Ungdom"), size_t(oListParam::AgeFilter::OnlyYouth));
ages.emplace_back(lang.tl("Vuxna"), size_t(oListParam::AgeFilter::ExludeYouth)); ages.emplace_back(lang.tl("Vuxna"), size_t(oListParam::AgeFilter::ExludeYouth));
gdi.addItem("AgeFilter", ages); gdi.setItems("AgeFilter", ages);
gdi.selectItemByData("AgeFilter", int(currentList.getParam().ageFilter)); gdi.selectItemByData("AgeFilter", int(currentList.getParam().ageFilter));
gdi.addCheckbox("PageBreak", "Sidbrytning mellan klasser", 0, currentList.getParam().pageBreak).setHandler(&settingsClassSelection); gdi.addCheckbox("PageBreak", "Sidbrytning mellan klasser", 0, currentList.getParam().pageBreak).setHandler(&settingsClassSelection);
gdi.addCheckbox("ShowHeader", "Visa rubrik", 0, currentList.getParam().showHeader).setHandler(&settingsClassSelection); gdi.addCheckbox("ShowHeader", "Visa rubrik", 0, currentList.getParam().showHeader).setHandler(&settingsClassSelection);
gdi.dropLine(-0.3); gdi.dropLine(-0.3);
gdi.addInput("Heading", currentList.getParam().getCustomTitle(wstring(L"")), 28, 0, L"Egen listrubrik:"); wstring hdr;
gdi.addInput("Heading", currentList.getParam().getCustomTitle(hdr), 28, 0, L"Egen listrubrik:");
gdi.setInputStatus("Heading", currentList.getParam().showHeader); gdi.setInputStatus("Heading", currentList.getParam().showHeader);
gdi.dropLine(0.5); gdi.dropLine(0.5);
gdi.fillRight(); gdi.fillRight();
@ -2305,7 +2302,7 @@ void TabList::settingsResultList(gdioutput &gdi)
} }
sort(lists.begin() + startIx, lists.end()); sort(lists.begin() + startIx, lists.end());
gdi.addItem("ResultType", lists); gdi.setItems("ResultType", lists);
gdi.autoGrow("ResultType"); gdi.autoGrow("ResultType");
int lastSelectedResultListOK = -1; int lastSelectedResultListOK = -1;
@ -2615,7 +2612,7 @@ bool TabList::loadPage(gdioutput &gdi)
gdi.pushX(); gdi.pushX();
gdi.addSelection("SavedInstance", 250, 200, ListsCB); gdi.addSelection("SavedInstance", 250, 200, ListsCB);
gdi.addItem("SavedInstance", savedParams); gdi.setItems("SavedInstance", savedParams);
gdi.autoGrow("SavedInstance"); gdi.autoGrow("SavedInstance");
gdi.selectFirstItem("SavedInstance"); gdi.selectFirstItem("SavedInstance");
gdi.addButton("ShowSaved", "Visa", ListsCB); gdi.addButton("ShowSaved", "Visa", ListsCB);
@ -2796,7 +2793,7 @@ void TabList::splitPrintSettings(oEvent &oe, gdioutput &gdi, bool setupPrinter,
lists.insert(lists.begin(), make_pair(lang.tl("Standard"), -10)); lists.insert(lists.begin(), make_pair(lang.tl("Standard"), -10));
lists.insert(lists.begin(), make_pair(lang.tl("Automatisk"), -11)); lists.insert(lists.begin(), make_pair(lang.tl("Automatisk"), -11));
gdi.addItem("SplitPrintList", lists); gdi.setItems("SplitPrintList", lists);
gdi.autoGrow("SplitPrintList"); gdi.autoGrow("SplitPrintList");
gdi.dropLine(0.8); gdi.dropLine(0.8);
@ -2870,7 +2867,7 @@ void TabList::splitPrintSettings(oEvent &oe, gdioutput &gdi, bool setupPrinter,
for (size_t j = 1; j < 8; j++) for (size_t j = 1; j < 8; j++)
nsp.push_back(make_pair(itow(j), j)); nsp.push_back(make_pair(itow(j), j));
gdi.addSelection("NumPerPage", 90, 200, ListsCB, L"Max antal brickor per sida"); gdi.addSelection("NumPerPage", 90, 200, ListsCB, L"Max antal brickor per sida");
gdi.addItem("NumPerPage", nsp); gdi.setItems("NumPerPage", nsp);
gdi.selectItemByData("NumPerPage", printLen); gdi.selectItemByData("NumPerPage", printLen);
int maxWait = oe.getPropertyInt("SplitPrintMaxWait", 60); int maxWait = oe.getPropertyInt("SplitPrintMaxWait", 60);
@ -2924,7 +2921,7 @@ void TabList::customTextLines(oEvent &oe, const char *dataField, bool withSymbol
gdi.addInput(row, L"", 24); gdi.addInput(row, L"", 24);
string key = "font"+itos(k); string key = "font"+itos(k);
gdi.addSelection(key, 100, 100); gdi.addSelection(key, 100, 100);
gdi.addItem(key, fonts); gdi.setItems(key, fonts);
if (lines.size() > size_t(k)) { if (lines.size() > size_t(k)) {
gdi.selectItemByData(key.c_str(), lines[k].second); gdi.selectItemByData(key.c_str(), lines[k].second);
gdi.setText(row, lines[k].first); gdi.setText(row, lines[k].first);
@ -2947,7 +2944,7 @@ void TabList::customTextLines(oEvent &oe, const char *dataField, bool withSymbol
gdi.setTabStops("Symbols", 300); gdi.setTabStops("Symbols", 300);
vector < pair<wstring, size_t>> symb; vector < pair<wstring, size_t>> symb;
MetaList::fillSymbols(symb); MetaList::fillSymbols(symb);
gdi.addItem("Symbols", symb); gdi.setItems("Symbols", symb);
gdi.popX(); gdi.popX();
gdi.popY(); gdi.popY();
} }
@ -3010,38 +3007,29 @@ void TabList::setResultOptionsFromType(gdioutput &gdi, int data) {
gdi.setInputStatus("ShowInterResults", builtIn); gdi.setInputStatus("ShowInterResults", builtIn);
gdi.setInputStatus("ShowSplits", builtIn); gdi.setInputStatus("ShowSplits", builtIn);
set<int> clsUnused; set<int> clsUnused;
vector< pair<wstring, size_t> > out; vector< pair<wstring, size_t> > out;
oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out); oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out);
gdi.addItem("LegNumber", out); gdi.setItems("LegNumber", out);
gdi.setInputStatus("LegNumber", !out.empty()); gdi.setInputStatus("LegNumber", !out.empty());
if (!out.empty() && lastLeg >= 0) if (!out.empty() && lastLeg >= 0)
gdi.selectItemByData("LegNumber", lastLeg); gdi.selectItemByData("LegNumber", lastLeg);
//oe->fillLegNumbers(gdi, "LegNumber", li.isTeamList(), true);
gdi.setInputStatus("InputNumber", false); gdi.setInputStatus("InputNumber", false);
} }
else { else {
gdi.setInputStatus("UseLargeSize", li.supportLarge); gdi.setInputStatus("UseLargeSize", li.supportLarge);
gdi.setInputStatus("InputNumber", li.supportParameter); gdi.setInputStatus("InputNumber", li.supportParameter);
//gdi.setInputStatus("SplitAnalysis", li.supportSplitAnalysis);
//gdi.setInputStatus("ShowInterResults", li.supportInterResults);
//gdi.setInputStatus("PageBreak", li.supportPageBreak);
//gdi.setInputStatus("ClassLimit", li.supportClassLimit);
if (li.supportLegs) { if (li.supportLegs) {
gdi.enableInput("LegNumber"); gdi.enableInput("LegNumber");
//oe->fillLegNumbers(gdi, "LegNumber", li.isTeamList(), true);
set<int> clsUnused; set<int> clsUnused;
vector< pair<wstring, size_t> > out; vector< pair<wstring, size_t> > out;
oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out); oe->fillLegNumbers(clsUnused, li.isTeamList(), true, out);
gdi.addItem("LegNumber", out); gdi.setItems("LegNumber", out);
if (!out.empty() && lastLeg >= 0) if (!out.empty() && lastLeg >= 0)
gdi.selectItemByData("LegNumber", lastLeg); gdi.selectItemByData("LegNumber", lastLeg);
gdi.setInputStatus("LegNumber", !out.empty()); gdi.setInputStatus("LegNumber", !out.empty());
@ -3091,16 +3079,23 @@ void TabList::setResultOptionsFromType(gdioutput &gdi, int data) {
if (lastFilledResultClassType != ct) { if (lastFilledResultClassType != ct) {
lastFilledResultClassType = ct; lastFilledResultClassType = ct;
lastResultClassSelection.insert(curSel.begin(), curSel.end()); lastResultClassSelection.insert(curSel.begin(), curSel.end());
oe->fillClasses(gdi, "ListSelection", oEvent::extraNone, ct); oe->fillClasses(gdi, "ListSelection", {}, oEvent::extraNone, ct);
gdi.setSelection("ListSelection", lastResultClassSelection); gdi.setSelection("ListSelection", lastResultClassSelection);
} }
gdi.setInputStatus("Generate", data >= 0 && !lastResultClassSelection.empty()); gdi.setInputStatus("Generate", data >= 0 && hasSelectedClass(gdi));
}
bool TabList::hasSelectedClass(gdioutput& gdi) {
set<int> sel;
gdi.getSelection("ListSelection", sel);
return !sel.empty();
} }
void TabList::clearCompetitionData() { void TabList::clearCompetitionData() {
SelectedList = ""; SelectedList = "";
lastResultClassSelection.clear(); lastResultClassSelection.clear();
lastClassSelection.clear();
ownWindow = false; ownWindow = false;
hideButtons = false; hideButtons = false;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -49,6 +49,8 @@ protected:
static void createListButtons(gdioutput &gdi); static void createListButtons(gdioutput &gdi);
static bool hasSelectedClass(gdioutput& gdi);
void generateList(gdioutput &gdi, bool forceUpdate = false); void generateList(gdioutput &gdi, bool forceUpdate = false);
void selectGeneralList(gdioutput &gdi, EStdListType type); void selectGeneralList(gdioutput &gdi, EStdListType type);
@ -124,7 +126,7 @@ public:
static void enableFromTo(oEvent &oe, gdioutput &gdi, bool from, bool to); static void enableFromTo(oEvent &oe, gdioutput &gdi, bool from, bool to);
void liveResult(gdioutput &gdi, oListInfo &currentList); void liveResult(gdioutput &gdi, oListInfo &currentList);
int listCB(gdioutput &gdi, int type, void *data); int listCB(gdioutput &gdi, GuiEventType type, BaseInfo *data);
void loadGeneralList(gdioutput &gdi); void loadGeneralList(gdioutput &gdi);
void rebuildList(gdioutput &gdi); void rebuildList(gdioutput &gdi);
void settingsResultList(gdioutput &gdi); void settingsResultList(gdioutput &gdi);

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
#include "tabbase.h" #include "tabbase.h"
#include "Printer.h" #include "Printer.h"
#include "autocompletehandler.h" #include "autocompletehandler.h"
#include <deque>
class Table; class Table;
struct AutoCompleteRecord; struct AutoCompleteRecord;
@ -43,15 +44,27 @@ private:
void selectRunner(gdioutput &gdi, pRunner r); void selectRunner(gdioutput &gdi, pRunner r);
void updateCardStatus(const pCard& pc, gdioutput& gdi);
void updatePunchStatus(const pPunch& punch, InputInfo* bb, gdioutput& gdi);
int numReportRow = 1;
int numReportColumn = 1;
bool hideReportControls = false;
bool showReportHeader = true;
void addToReport(int cardNo, bool punchForShowReport);
void addToReport(int id);
string computeKeyForReport();
wstring lastSearchExpr; wstring lastSearchExpr;
unordered_set<int> lastFilter; unordered_set<int> lastFilter;
DWORD timeToFill; DWORD timeToFill;
int inputId; int inputId;
int searchCB(gdioutput &gdi, int type, void *data);
int runnerCB(gdioutput &gdi, int type, void *data); int searchCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
int punchesCB(gdioutput &gdi, int type, void *data); int runnerCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
int vacancyCB(gdioutput &gdi, int type, void *data); int punchesCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
int vacancyCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
int currentMode; int currentMode;
pRunner save(gdioutput &gdi, int runnerId, bool dontReloadRunners); pRunner save(gdioutput &gdi, int runnerId, bool dontReloadRunners);
@ -64,7 +77,7 @@ private:
int runnerId; int runnerId;
bool ownWindow; bool ownWindow;
bool listenToPunches; bool listenToPunches;
vector< pair<int, bool> > runnersToReport; deque<pair<int, bool>> runnersToReport;
vector<pRunner> unknown_dns; vector<pRunner> unknown_dns;
vector<pRunner> known_dns; vector<pRunner> known_dns;
@ -76,7 +89,19 @@ private:
PrinterObject splitPrinter; PrinterObject splitPrinter;
void showRunnerReport(gdioutput &gdi); void showRunnerReport(gdioutput &gdi);
static void runnerReport(oEvent &oe, gdioutput &gdi, int id, bool compactReport);
static void runnerReport(oEvent &oe, gdioutput &gdi,
int id, bool compactReport,
int maxWidth,
RECT& rc);
static void teamReport(oEvent& oe, gdioutput& gdi,
const oTeam *team,
bool onlySelectedRunner,
const deque<pair<int, bool>> &runners,
int maxWidth,
RECT &rc);
void showVacancyList(gdioutput &gdi, const string &method="", int classId=0); void showVacancyList(gdioutput &gdi, const string &method="", int classId=0);
void showCardsList(gdioutput &gdi); void showCardsList(gdioutput &gdi);
@ -94,26 +119,41 @@ private:
static void autoGrowCourse(gdioutput &gdi); static void autoGrowCourse(gdioutput &gdi);
void loadEconomy(gdioutput &gdi, oRunner &r); void loadEconomy(gdioutput &gdi, oRunner &r);
class EconomyHandler : public GuiHandler { class EconomyHandler : public GuiHandler {
int runnerId; int runnerId;
oEvent *oe; oEvent *oe;
oRunner &getRunner() const; oRunner &getRunner() const;
void updateColor(gdioutput& gdi); void updateColor(gdioutput& gdi);
void init(oRunner& r);
public: public:
void init(oRunner &r); EconomyHandler(oRunner& r) { init(r); }
void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type); void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type);
void save(gdioutput &gdi); void save(gdioutput &gdi);
}; };
shared_ptr<EconomyHandler> ecoHandler; class CommentHandler : public GuiHandler {
EconomyHandler *getEconomyHandler(oRunner &r); int runnerId;
bool isTeam = false;
oEvent* oe;
oAbstractRunner& getRunner() const;
public:
CommentHandler(oAbstractRunner& r) : oe(r.getEvent()) {
runnerId = r.getId(); isTeam = r.isTeam();
}
void handle(gdioutput& gdi, BaseInfo& info, GuiEventType type);
void save(gdioutput& gdi);
};
void getAutoCompleteUnpairedCards(gdioutput &gdi, const wstring& w, vector<AutoCompleteRecord>& records); void getAutoCompleteUnpairedCards(gdioutput &gdi, const wstring& w, vector<AutoCompleteRecord>& records);
protected: protected:
void clearCompetitionData(); void clearCompetitionData();
public: public:
static void renderComments(gdioutput& gdi, oAbstractRunner& r);
static void loadComments(gdioutput& gdi, oAbstractRunner& r);
static pClub extractClub(oEvent *oe, gdioutput &gdi); static pClub extractClub(oEvent *oe, gdioutput &gdi);
void handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) override; void handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) override;
@ -126,13 +166,21 @@ public:
bool loadPage(gdioutput &gdi); bool loadPage(gdioutput &gdi);
bool loadPage(gdioutput &gdi, int runnerId); bool loadPage(gdioutput &gdi, int runnerId);
static void generateRunnerReport(oEvent &oe, gdioutput &gdi, vector<pair<int, bool>> &runnersToReport); static int addExtraFields(const oEvent &oe, gdioutput& gdi, oEvent::ExtraFieldContext context);
static void saveExtraFields(gdioutput& gdi, oBase &r);
static void loadExtraFields(gdioutput& gdi, const oBase* r);
static void generateRunnerReport(oEvent &oe,
gdioutput &gdi,
int numX, int numY,
bool onlySelectedRunner,
const deque<pair<int, bool>> &runnersToReport);
TabRunner(oEvent *oe); TabRunner(oEvent *oe);
~TabRunner(void); ~TabRunner(void);
friend int runnerSearchCB(gdioutput *gdi, int type, void *data); friend int runnerSearchCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
friend int RunnerCB(gdioutput *gdi, int type, void *data); friend int RunnerCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
friend int PunchesCB(gdioutput *gdi, int type, void *data); friend int PunchesCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
friend int VacancyCB(gdioutput *gdi, int type, void *data); friend int VacancyCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ public:
ModeEntry, ModeEntry,
ModeCardData, ModeCardData,
ModeRegisterCards, ModeRegisterCards,
ModeRequestStartTime,
}; };
map<SIMode, string> modeName; map<SIMode, string> modeName;
@ -94,6 +95,10 @@ private:
shared_ptr<GuiHandler> resetHiredCardHandler; shared_ptr<GuiHandler> resetHiredCardHandler;
GuiHandler *getResetHiredCardHandler(); GuiHandler *getResetHiredCardHandler();
shared_ptr<GuiHandler> requestStartTimeHandler;
SortOrder sortAssignCards = SortOrder::Custom;
int runnerMatchedId; int runnerMatchedId;
bool printErrorShown; bool printErrorShown;
void printProtected(gdioutput &gdi, gdioutput &gdiprint); void printProtected(gdioutput &gdi, gdioutput &gdiprint);
@ -110,6 +115,7 @@ private:
void assignCard(gdioutput &gdi, const SICard &sic); void assignCard(gdioutput &gdi, const SICard &sic);
void entryCard(gdioutput &gdi, const SICard &sic); void entryCard(gdioutput &gdi, const SICard &sic);
void requestStartTime(gdioutput& gdi, const SICard& sic);
void updateEntryInfo(gdioutput &gdi); void updateEntryInfo(gdioutput &gdi);
void generateEntryLine(gdioutput &gdi, pRunner r); void generateEntryLine(gdioutput &gdi, pRunner r);
@ -120,6 +126,7 @@ private:
int numSavedCardsOnCmpOpen = 0; int numSavedCardsOnCmpOpen = 0;
void showCheckCardStatus(gdioutput &gdi, const string &cmd); void showCheckCardStatus(gdioutput &gdi, const string &cmd);
void showRegisterHiredCards(gdioutput &gdi); void showRegisterHiredCards(gdioutput &gdi);
void showRequestStartTime(gdioutput &gdi);
wstring getCardInfo(bool param, vector<int> &count) const; wstring getCardInfo(bool param, vector<int> &count) const;
// Formatting for card tick off // Formatting for card tick off
@ -185,17 +192,32 @@ private:
static int analyzePunch(SIPunch &p, int &start, int &accTime, int &days); static int analyzePunch(SIPunch &p, int &start, int &accTime, int &days);
void createCompetitionFromCards(gdioutput &gdi); void createCompetitionFromCards(gdioutput &gdi);
int NC; int NC = 8;
int testType = 0;
bool showTestingPanel = false;
wstring testStartTime;
bool useTestStart = true;
wstring testFinishTime;
bool useTestFinish = true;
wstring testCheckTime;
bool useTestCheck = false;
int testRadioNumber = 50;
wstring testPunchTime;
vector<int> testControls;
int testCardNumber = 0;
void readTestData(gdioutput& gdi);
class EditCardData : public GuiHandler { class EditCardData : public GuiHandler {
TabSI *tabSI; TabSI *tabSI;
EditCardData(const EditCardData&);
EditCardData &operator=(const EditCardData&);
public: public:
EditCardData() : tabSI(0) {} EditCardData() : tabSI(0) {}
EditCardData(const EditCardData&) = delete;
EditCardData& operator=(const EditCardData&) = delete;
void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type); void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type);
friend class TabSI; friend class TabSI;
}; };
@ -235,7 +257,8 @@ private:
Manual, Manual,
SeveralTurns, SeveralTurns,
AutoTie, AutoTie,
AutoTieRent AutoTieRent,
ExtraDataFields
}; };
void checkBoxToolBar(gdioutput& gdi, const set<CheckBox> &items) const; void checkBoxToolBar(gdioutput& gdi, const set<CheckBox> &items) const;
@ -252,6 +275,7 @@ private:
vector<int> MP; vector<int> MP;
GDICOLOR color; GDICOLOR color;
bool rentCard = false; bool rentCard = false;
int runnerId = 0;
RECT computeRC(gdioutput &gdi) const; RECT computeRC(gdioutput &gdi) const;
void render(gdioutput &gdi, const RECT &rc) const; void render(gdioutput &gdi, const RECT &rc) const;
@ -286,6 +310,15 @@ public:
wstring storedFee; wstring storedFee;
wstring storedPhone; wstring storedPhone;
wstring storedStartTime; wstring storedStartTime;
wstring dataA;
wstring dataB;
wstring textA;
wstring nationality;
int sex = 2;
wstring birthDate;
wstring rank;
bool allStages; bool allStages;
bool rentState; bool rentState;
bool hasPaid; bool hasPaid;
@ -305,11 +338,11 @@ public:
static SportIdent &getSI(const gdioutput &gdi); static SportIdent &getSI(const gdioutput &gdi);
void printerSetup(gdioutput &gdi); void printerSetup(gdioutput &gdi);
void generateStartInfo(gdioutput &gdi, const oRunner &r); void generateStartInfo(gdioutput &gdi, const oRunner &r, bool includeEconomy);
bool hasPrintStartInfo() const {return printStartInfo;} bool hasPrintStartInfo() const {return printStartInfo;}
void setPrintStartInfo(bool info) {printStartInfo = info;} void setPrintStartInfo(bool info) {printStartInfo = info;}
int siCB(gdioutput &gdi, int type, void *data); int siCB(gdioutput &gdi, GuiEventType type, BaseInfo *data);
void writeDefaultHiredCards(); void writeDefaultHiredCards();
@ -327,6 +360,7 @@ public:
void insertSICard(gdioutput &gdi, SICard &sic); void insertSICard(gdioutput &gdi, SICard &sic);
void clearQueue() { CardQueue.clear(); } void clearQueue() { CardQueue.clear(); }
void refillComPorts(gdioutput &gdi); void refillComPorts(gdioutput &gdi);
bool anyActivePort() const;
bool loadPage(gdioutput &gdi) final; bool loadPage(gdioutput &gdi) final;
void showReadoutMode(gdioutput & gdi); void showReadoutMode(gdioutput & gdi);

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -67,8 +67,7 @@ TabSpeaker::~TabSpeaker()
} }
int tabSpeakerCB(gdioutput *gdi, int type, void *data) int tabSpeakerCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
TabSpeaker &ts = dynamic_cast<TabSpeaker &>(*gdi->getTabs().get(TSpeakerTab)); TabSpeaker &ts = dynamic_cast<TabSpeaker &>(*gdi->getTabs().get(TSpeakerTab));
switch(type){ switch(type){
@ -165,7 +164,7 @@ int TabSpeaker::processButton(gdioutput &gdi, const ButtonInfo &bu)
gdi.addButton("AllClass", "Alla", tabSpeakerCB); gdi.addButton("AllClass", "Alla", tabSpeakerCB);
gdi.addButton("NoClass", "Inga", tabSpeakerCB); gdi.addButton("NoClass", "Inga", tabSpeakerCB);
oe->fillClasses(gdi, "Classes", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "Classes", {}, oEvent::extraNone, oEvent::filterNone);
gdi.setSelection("Classes", classesToWatch); gdi.setSelection("Classes", classesToWatch);
gdi.fillRight(); gdi.fillRight();
@ -177,7 +176,7 @@ int TabSpeaker::processButton(gdioutput &gdi, const ButtonInfo &bu)
vector< pair<wstring, size_t> > d; vector< pair<wstring, size_t> > d;
oe->fillControls(d, oEvent::ControlType::CourseControl); oe->fillControls(d, oEvent::ControlType::CourseControl);
gdi.addItem("Controls", d); gdi.setItems("Controls", d);
gdi.setSelection("Controls", controlsToWatch); gdi.setSelection("Controls", controlsToWatch);
@ -241,11 +240,11 @@ int TabSpeaker::processButton(gdioutput &gdi, const ButtonInfo &bu)
gdi.dropLine(3); gdi.dropLine(3);
gdi.popX(); gdi.popX();
gdi.registerEvent("DataUpdate", tabSpeakerCB); gdi.registerEvent("DataUpdate", tabSpeakerCB);
vector<pair<int, bool>> runnersToReport; deque<pair<int, bool>> runnersToReport;
if (runnerId > 0) { if (runnerId > 0) {
runnersToReport.emplace_back(runnerId, false); runnersToReport.emplace_back(runnerId, false);
} }
TabRunner::generateRunnerReport(*oe, gdi, runnersToReport); TabRunner::generateRunnerReport(*oe, gdi, 1, 1, false, runnersToReport);
gdi.refresh(); gdi.refresh();
} }
else if (bu.id == "Priority") { else if (bu.id == "Priority") {
@ -257,7 +256,7 @@ int TabSpeaker::processButton(gdioutput &gdi, const ButtonInfo &bu)
gdi.pushX(); gdi.pushX();
gdi.addString("", 0, "Klass:"); gdi.addString("", 0, "Klass:");
gdi.addSelection("Class", 200, 200, tabSpeakerCB, L"", L"Välj klass"); gdi.addSelection("Class", 200, 200, tabSpeakerCB, L"", L"Välj klass");
oe->fillClasses(gdi, "Class", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(gdi, "Class", {}, oEvent::extraNone, oEvent::filterNone);
gdi.addButton("ClosePri", "Stäng", tabSpeakerCB); gdi.addButton("ClosePri", "Stäng", tabSpeakerCB);
gdi.dropLine(2); gdi.dropLine(2);
gdi.popX(); gdi.popX();
@ -278,7 +277,7 @@ int TabSpeaker::processButton(gdioutput &gdi, const ButtonInfo &bu)
gdi_new->pushX(); gdi_new->pushX();
TabList::makeClassSelection(*gdi_new); TabList::makeClassSelection(*gdi_new);
oe->fillClasses(*gdi_new, "ListSelection", oEvent::extraNone, oEvent::filterNone); oe->fillClasses(*gdi_new, "ListSelection", {}, oEvent::extraNone, oEvent::filterNone);
gdi_new->popY(); gdi_new->popY();
gdi_new->setCX(gdi_new->getCX() + gdi_new->scaleLength(280)); gdi_new->setCX(gdi_new->getCX() + gdi_new->scaleLength(280));
@ -1223,7 +1222,7 @@ void TabSpeaker::storeManualTime(gdioutput &gdi)
throw std::exception(bf); throw std::exception(bf);
} }
oe->addFreePunch(itime, punch, 0, sino, true); oe->addFreePunch(itime, punch, 0, sino, true, false);
gdi.restore("manual", false); gdi.restore("manual", false);
gdi.addString("", 0, L"Löpare: X, kontroll: Y, kl Z#" + Name + L"#" + oPunch::getType(punch) + L"#" + oe->getAbsTime(itime)); gdi.addString("", 0, L"Löpare: X, kontroll: Y, kl Z#" + Name + L"#" + oPunch::getType(punch) + L"#" + oe->getAbsTime(itime));

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -46,26 +46,19 @@
#include "TabSI.h" #include "TabSI.h"
TabTeam::TabTeam(oEvent *poe):TabBase(poe) TabTeam::TabTeam(oEvent *poe):TabBase(poe) {
{
clearCompetitionData(); clearCompetitionData();
} }
TabTeam::~TabTeam(void) TabTeam::~TabTeam(void) = default;
{
}
int TeamCB(gdioutput *gdi, int type, void *data) int TeamCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
TabTeam &tt = dynamic_cast<TabTeam &>(*gdi->getTabs().get(TTeamTab)); TabTeam &tt = dynamic_cast<TabTeam &>(*gdi->getTabs().get(TTeamTab));
return tt.teamCB(*gdi, type, data); return tt.teamCB(*gdi, type, data);
} }
int teamSearchCB(gdioutput *gdi, int type, void *data) int teamSearchCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
TabTeam &tc = dynamic_cast<TabTeam &>(*gdi->getTabs().get(TTeamTab)); TabTeam &tc = dynamic_cast<TabTeam &>(*gdi->getTabs().get(TTeamTab));
return tc.searchCB(*gdi, type, data); return tc.searchCB(*gdi, type, data);
} }
@ -134,7 +127,7 @@ int TabTeam::searchCB(gdioutput &gdi, int type, void *data) {
if (filter.empty()) { if (filter.empty()) {
vector< pair<wstring, size_t> > runners; vector< pair<wstring, size_t> > runners;
runners.push_back(make_pair(lang.tl(L"Ingen matchar 'X'#" + expr), -1)); runners.push_back(make_pair(lang.tl(L"Ingen matchar 'X'#" + expr), -1));
gdi.addItem("Teams", runners); gdi.setItems("Teams", runners);
} }
else else
gdi.filterOnData("Teams", filter); gdi.filterOnData("Teams", filter);
@ -164,7 +157,7 @@ int TabTeam::searchCB(gdioutput &gdi, int type, void *data) {
runners.swap(runners2); runners.swap(runners2);
} }
gdi.addItem("Teams", runners); gdi.setItems("Teams", runners);
} }
if (type == GUI_TIMER) if (type == GUI_TIMER)
@ -187,8 +180,9 @@ void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
gdi.enableInput("Save"); gdi.enableInput("Save");
gdi.enableInput("Undo"); gdi.enableInput("Undo");
gdi.enableInput("Remove"); gdi.enableInput("Remove");
gdi.enableInput("EditAnnotation");
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterOnlyMulti); oe->fillClasses(gdi, "RClass", {}, oEvent::extraNone, oEvent::filterOnlyMulti);
gdi.selectItemByData("RClass", t->getClassId(false)); gdi.selectItemByData("RClass", t->getClassId(false));
gdi.selectItemByData("Teams", t->getId()); gdi.selectItemByData("Teams", t->getId());
@ -209,6 +203,8 @@ void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
gdi.check("NoRestart", t->preventRestart()); gdi.check("NoRestart", t->preventRestart());
} }
TabRunner::loadExtraFields(gdi, t);
loadTeamMembers(gdi, 0, 0, t); loadTeamMembers(gdi, 0, 0, t);
} }
else { else {
@ -218,6 +214,7 @@ void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
gdi.disableInput("Save"); gdi.disableInput("Save");
gdi.disableInput("Undo"); gdi.disableInput("Undo");
gdi.disableInput("Remove"); gdi.disableInput("Remove");
gdi.disableInput("EditAnnotation");
ListBoxInfo lbi; ListBoxInfo lbi;
gdi.getSelectedItem("RClass", lbi); gdi.getSelectedItem("RClass", lbi);
@ -342,6 +339,8 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
if (gdi.hasWidget("NoRestart")) if (gdi.hasWidget("NoRestart"))
t->preventRestart(gdi.isChecked("NoRestart")); t->preventRestart(gdi.isChecked("NoRestart"));
TabRunner::saveExtraFields(gdi, *t);
t->apply(oBase::ChangeType::Quiet, nullptr); t->apply(oBase::ChangeType::Quiet, nullptr);
if (gdi.hasWidget("Club")) { if (gdi.hasWidget("Club")) {
@ -404,6 +403,7 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
} }
t->setClassId(classId, true); t->setClassId(classId, true);
t->adjustMultiRunners();
if (gdi.hasWidget("TimeAdjust")) { if (gdi.hasWidget("TimeAdjust")) {
int time = convertAbsoluteTimeMS(gdi.getText("TimeAdjust")); int time = convertAbsoluteTimeMS(gdi.getText("TimeAdjust"));
@ -552,14 +552,14 @@ wstring getForking(pClass pc, int key, int maxLen) {
return crsList; return crsList;
} }
int TabTeam::teamCB(gdioutput &gdi, int type, void *data) { int TabTeam::teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
if (type==GUI_BUTTON) { if (type==GUI_BUTTON) {
ButtonInfo bi=*(ButtonInfo *)data; ButtonInfo bi=*(ButtonInfo *)data;
if (bi.id=="Save") { if (bi.id=="Save") {
return save(gdi, false); return save(gdi, false);
} }
if (bi.id == "Cancel") { else if (bi.id == "Cancel") {
loadPage(gdi); loadPage(gdi);
return 0; return 0;
} }
@ -582,6 +582,15 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data) {
selectTeam(gdi, t); selectTeam(gdi, t);
return 0; return 0;
} }
else if (bi.id == "EditAnnotation") {
if (!teamId)
return 0;
pTeam t = oe->getTeam(teamId);
if (t && getExtraWindow("comments", true) == nullptr) {
gdioutput* settings = createExtraWindow("comments", L"Kommentarer", gdi.scaleLength(550), gdi.scaleLength(350), true);
TabRunner::loadComments(*settings, *t);
}
}
else if (bi.id=="Search") { else if (bi.id=="Search") {
ListBoxInfo lbi; ListBoxInfo lbi;
gdi.getSelectedItem("Teams", lbi); gdi.getSelectedItem("Teams", lbi);
@ -744,7 +753,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data) {
keys.push_back(make_pair(itow(f+1) + L": " + getForking(pc, f+1, 30), f)); keys.push_back(make_pair(itow(f+1) + L": " + getForking(pc, f+1, 30), f));
} }
int currentKey = max(t->getStartNo()-1, 0) % nf; int currentKey = max(t->getStartNo()-1, 0) % nf;
gdi.addItem("ForkKey", keys); gdi.setItems("ForkKey", keys);
gdi.autoGrow("ForkKey"); gdi.autoGrow("ForkKey");
gdi.selectItemByData("ForkKey", currentKey); gdi.selectItemByData("ForkKey", currentKey);
@ -911,7 +920,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data) {
gdi.fillDown(); gdi.fillDown();
gdi.addButton("Cancel", "Avbryt", TeamCB); gdi.addButton("Cancel", "Avbryt", TeamCB);
gdi.addItem("SelectR", otherR); gdi.setItems("SelectR", otherR);
} }
else { else {
gdi.addButton("Cancel", "Avbryt", TeamCB); gdi.addButton("Cancel", "Avbryt", TeamCB);
@ -1265,7 +1274,7 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
int yp = gdi.getCY(); int yp = gdi.getCY();
int numberPos = xp; int numberPos = xp;
xp += gdi.scaleLength(25); xp += gdi.scaleLength(25);
const int dxIn[6] = {0, 184, 220, 300, 326, 374}; const int dxIn[6] = {0, 184, 220, 300, 326, 364};
int dx[6]; int dx[6];
dx[0] = 0; dx[0] = 0;
@ -1292,7 +1301,7 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
gdi.addStringUT(yp + textOffY, numberPos, 0, pc->getLegNumber(i) + L"."); gdi.addStringUT(yp + textOffY, numberPos, 0, pc->getLegNumber(i) + L".");
if (pc->getLegRunner(i) == i) { if (pc->getLegRunner(i) == i) {
gdi.addInput(xp + dx[0], yp, bf, L"", 18, TeamCB);//Name gdi.addInput(xp + dx[0], yp, bf, L"", 18, TeamCB);//Name
gdi.addButton(xp + dx[1], yp - 2, gdi.scaleLength(28), "DR" + itos(i), "<>", TeamCB, "Knyt löpare till sträckan.", false, false); // Change gdi.addButton(xp + dx[1], yp - 2, gdi.scaleLength(28), "DR" + itos(i), L"\u21C6", TeamCB, L"Knyt löpare till sträckan.", false, false); // Change
sprintf_s(bf_si, "SI%d", i); sprintf_s(bf_si, "SI%d", i);
hasSI = true; hasSI = true;
gdi.addInput(xp + dx[2], yp, bf_si, L"", 7, TeamCB).setExtra(i); //Si gdi.addInput(xp + dx[2], yp, bf_si, L"", 7, TeamCB).setExtra(i); //Si
@ -1302,7 +1311,7 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
gdi.addInput(xp + dx[0], yp, bf, L"", 18, 0);//Name gdi.addInput(xp + dx[0], yp, bf, L"", 18, 0);//Name
gdi.disableInput(bf); gdi.disableInput(bf);
} }
gdi.addButton(xp + dx[4], yp - 2, gdi.scaleLength(38), "MR" + itos(i), "...", TeamCB, "Redigera deltagaren.", false, false); // Change gdi.addButton(xp + dx[4], yp - 2, gdi.scaleLength(28), "MR" + itos(i), L"\u21BA", TeamCB, L"Redigera deltagaren.", false, false); // Change
gdi.addString(("STATUS" + itos(i)).c_str(), yp + textOffY, xp + dx[5], 0, "#MMMMMMMMMMMMMMMM"); gdi.addString(("STATUS" + itos(i)).c_str(), yp + textOffY, xp + dx[5], 0, "#MMMMMMMMMMMMMMMM");
gdi.setText("STATUS" + itos(i), L"", false); gdi.setText("STATUS" + itos(i), L"", false);
@ -1335,39 +1344,30 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
} }
} }
} }
if (t)
forkingKey(gdi, t);
gdi.refresh();
}
void TabTeam::forkingKey(gdioutput& gdi, pTeam t) {
pClass pc = t->getClassRef(false);
int cx = gdi.getCX();
int cy = gdi.getCY();
TabRunner::renderComments(gdi, *t);
gdi.setCX(cx);
gdi.setCY(cy);
gdi.pushX();
gdi.setRestorePoint("SelectR"); gdi.setRestorePoint("SelectR");
gdi.addString("", 1, "help:7618"); gdi.addString("", 0, "help:7618");
gdi.dropLine(); gdi.dropLine();
int numF = pc->getNumForks(); int numF = pc->getNumForks();
if (numF>1 && t) { if (numF > 1 && t) {
gdi.addString ("", 1, "Gafflingsnyckel X#" + itos(1+(max(t->getStartNo()-1, 0) % numF))).setColor(colorGreen); gdi.addString("", 1, "Gafflingsnyckel X#" + itos(1 + (max(t->getStartNo() - 1, 0) % numF))).setColor(colorGreen);
wstring crsList = getForking(pc, t->getStartNo(), 50); wstring crsList = getForking(pc, t->getStartNo(), 50);
/*bool hasCrs = false;
for (size_t k = 0; k < pc->getNumStages(); k++) {
pCourse crs = pc->getCourse(k, t->getStartNo());
wstring cS;
if (crs != 0) {
cS = crs->getName();
hasCrs = true;
}
else
cS = makeDash(L"-");
if (!crsList.empty())
crsList += L", ";
crsList += cS;
if (hasCrs && crsList.length() > 50) {
gdi.addStringUT(0, crsList);
crsList.clear();
}
}
if (hasCrs && !crsList.empty()) {
gdi.addStringUT(0, crsList);
}*/
if (!crsList.empty()) { if (!crsList.empty()) {
gdi.addStringUT(0, crsList); gdi.addStringUT(0, crsList);
gdi.dropLine(0.5); gdi.dropLine(0.5);
@ -1375,7 +1375,6 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB); gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB);
} }
} }
gdi.refresh();
} }
void TabTeam::enableRunner(gdioutput& gdi, int index, bool enable) { void TabTeam::enableRunner(gdioutput& gdi, int index, bool enable) {
@ -1456,8 +1455,7 @@ bool TabTeam::loadPage(gdioutput &gdi)
} }
gdi.addSelection("RClass", 170, 300, TeamCB, L"Klass:"); gdi.addSelection("RClass", 170, 300, TeamCB, L"Klass:");
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterOnlyMulti); oe->fillClasses(gdi, "RClass", {make_pair(lang.tl("Ny klass"), 0)}, oEvent::extraNone, oEvent::filterOnlyMulti);
gdi.addItem("RClass", lang.tl("Ny klass"), 0);
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::Economy)) if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::Economy))
gdi.addInput("Fee", L"", 5, 0, L"Avgift:"); gdi.addInput("Fee", L"", 5, 0, L"Avgift:");
@ -1517,11 +1515,11 @@ bool TabTeam::loadPage(gdioutput &gdi)
} }
gdi.addString("TeamInfo", 0, " ").setColor(colorRed); gdi.addString("TeamInfo", 0, " ").setColor(colorRed);
gdi.dropLine(1.5);
const bool multiDay = oe->hasPrevStage(); const bool multiDay = oe->hasPrevStage();
if (multiDay) { if (multiDay) {
gdi.dropLine(1.5);
int xx = gdi.getCX(); int xx = gdi.getCX();
int yy = gdi.getCY(); int yy = gdi.getCY();
gdi.dropLine(0.5); gdi.dropLine(0.5);
@ -1552,10 +1550,14 @@ bool TabTeam::loadPage(gdioutput &gdi)
rc.bottom = gdi.getCY(); rc.bottom = gdi.getCY();
gdi.addRectangle(rc, colorLightGreen, true, false); gdi.addRectangle(rc, colorLightGreen, true, false);
gdi.dropLine(1.5);
gdi.popX(); gdi.popX();
} }
TabRunner::addExtraFields(*oe, gdi, oEvent::ExtraFieldContext::Team);
gdi.dropLine(0.5);
gdi.popX();
gdi.fillRight(); gdi.fillRight();
gdi.addButton("Save", "Spara", TeamCB, "help:save"); gdi.addButton("Save", "Spara", TeamCB, "help:save");
gdi.disableInput("Save"); gdi.disableInput("Save");
@ -1568,6 +1570,10 @@ bool TabTeam::loadPage(gdioutput &gdi)
gdi.disableInput("Remove"); gdi.disableInput("Remove");
gdi.addButton("Add", "Nytt lag", TeamCB); gdi.addButton("Add", "Nytt lag", TeamCB);
gdi.popX();
gdi.dropLine(2.2);
gdi.addButton("EditAnnotation", L"Kommentar >>", TeamCB, L"Lägg till eller redigera kommentarer om laget.");
gdi.setOnClearCb(TeamCB); gdi.setOnClearCb(TeamCB);
addToolbar(gdi); addToolbar(gdi);
@ -1880,7 +1886,13 @@ void TabTeam::showRunners(gdioutput &gdi, const char *title,
usedR.insert(it->second); usedR.insert(it->second);
if (!any) { if (!any) {
gdi.addString("", boldText, title); gdi.dropLine(0.2);
int YC = gdi.getCY() + gdi.getLineHeight() / 2;
int CX = gdi.getCX();
int hy = gdi.scaleLength(2);
RECT rc = { CX, YC-hy, CX + gdi.getLineHeight(), YC + hy };
gdi.addRectangle(rc, GDICOLOR::colorMediumDarkRed, false);
gdi.addString("", boldText|Capitalize, title);
gdi.dropLine(1.2); gdi.dropLine(1.2);
gdi.popX(); gdi.popX();
any = true; any = true;
@ -1891,7 +1903,7 @@ void TabTeam::showRunners(gdioutput &gdi, const char *title,
gdi.popX(); gdi.popX();
} }
gdi.addString("SelectR", 0, L"#" + it->first, TeamCB).setExtra(it->second); gdi.addString("SelectR", 0, L"#" + it->first, TeamCB).setColor(colorRed).setExtra(it->second);
} }
if (any) { if (any) {
@ -1906,6 +1918,7 @@ void TabTeam::processChangeRunner(gdioutput &gdi, pTeam t, int leg, pRunner r) {
gdioutput::AskAnswer ans = gdioutput::AskAnswer::AnswerNo; gdioutput::AskAnswer ans = gdioutput::AskAnswer::AnswerNo;
if (r == oldR) { if (r == oldR) {
gdi.restore("SelectR"); gdi.restore("SelectR");
forkingKey(gdi, t);
return; return;
} }
else if (oldR) { else if (oldR) {
@ -1975,6 +1988,7 @@ void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
} }
otherTeam->checkValdParSetup(); otherTeam->checkValdParSetup();
otherTeam->apply(oBase::ChangeType::Update, nullptr); otherTeam->apply(oBase::ChangeType::Update, nullptr);
otherTeam->adjustMultiRunners();
otherTeam->synchronize(true); otherTeam->synchronize(true);
} }
else if (oldR) { else if (oldR) {
@ -1995,6 +2009,7 @@ void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
r->evaluateCard(true, mp, 0, oBase::ChangeType::Update); r->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
t->checkValdParSetup(); t->checkValdParSetup();
t->apply(oBase::ChangeType::Update, nullptr); t->apply(oBase::ChangeType::Update, nullptr);
t->adjustMultiRunners();
t->synchronize(true); t->synchronize(true);
if (removeAnnonumousTeamMember) if (removeAnnonumousTeamMember)
@ -2042,7 +2057,7 @@ bool TabTeam::warnDuplicateCard(gdioutput &gdi, string id, int cno, pRunner r) {
} }
void TabTeam::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) { void TabTeam::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) {
auto bi = gdi.setText(info.getTarget(), info.getCurrent().c_str()); auto bi = gdi.setText(info.getTarget().c_str(), info.getCurrent(), false, -1, false);
if (bi) { if (bi) {
int ix = info.getCurrentInt(); int ix = info.getCurrentInt();
bi->setExtra(ix); bi->setExtra(ix);
@ -2053,10 +2068,10 @@ void TabTeam::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) {
if (runner && gdi.hasWidget("Club") && gdi.getText("Club").empty()) { if (runner && gdi.hasWidget("Club") && gdi.getText("Club").empty()) {
pClub club = db.getClub(runner->dbe().clubNo); pClub club = db.getClub(runner->dbe().clubNo);
if (club) if (club)
gdi.setText("Club", club->getName()); gdi.setText("Club", club->getName(), false, -1, false);
} }
if (runner && runner->dbe().cardNo > 0 && gdi.hasWidget("DirCard") && gdi.getText("DirCard").empty()) { if (runner && runner->dbe().cardNo > 0 && gdi.hasWidget("DirCard") && gdi.getText("DirCard").empty()) {
gdi.setText("DirCard", runner->dbe().cardNo); gdi.setText("DirCard", itow(runner->dbe().cardNo), false, -1, false);
} }
} }
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -77,6 +77,8 @@ private:
/** Enable or disable edit for a team runner*/ /** Enable or disable edit for a team runner*/
void enableRunner(gdioutput &gdi, int index, bool enable); void enableRunner(gdioutput &gdi, int index, bool enable);
/// Show forking key in the window
void forkingKey(gdioutput& gdi, pTeam t);
protected: protected:
void clearCompetitionData(); void clearCompetitionData();
@ -87,12 +89,12 @@ public:
const char * getTypeStr() const {return "TTeamTab";} const char * getTypeStr() const {return "TTeamTab";}
TabType getType() const {return TTeamTab;} TabType getType() const {return TTeamTab;}
int teamCB(gdioutput &gdi, int type, void *data); int teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data);
bool loadPage(gdioutput &gdi, int id); bool loadPage(gdioutput &gdi, int id);
bool loadPage(gdioutput &gdi); bool loadPage(gdioutput &gdi);
TabTeam(oEvent *oe); TabTeam(oEvent *oe);
~TabTeam(void); ~TabTeam(void);
friend int teamSearchCB(gdioutput *gdi, int type, void *data); friend int teamSearchCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
}; };

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -274,7 +274,7 @@ void Table::filter(int col, const wstring &filt, bool forceFilter)
wchar_t filt_lc[1024]; wchar_t filt_lc[1024];
wcscpy_s(filt_lc, filt.c_str()); wcscpy_s(filt_lc, filt.c_str());
CharLowerBuff(filt_lc, filt.length()); prepareMatchString(filt_lc, filt.length());
sortIndex.resize(2); sortIndex.resize(2);
for (size_t k=2;k<baseIndex.size();k++) { for (size_t k=2;k<baseIndex.size();k++) {
@ -707,7 +707,7 @@ bool Table::mouseLeftUp(gdioutput &gdi, int x, int y)
return false; return false;
} }
int tblSelectionCB(gdioutput *gdi, int type, void *data) { int tblSelectionCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
if (type == GUI_LISTBOX) { if (type == GUI_LISTBOX) {
ListBoxInfo lbi = *static_cast<ListBoxInfo *>(data); ListBoxInfo lbi = *static_cast<ListBoxInfo *>(data);
Table &t = gdi->getTable(); Table &t = gdi->getTable();
@ -1104,7 +1104,7 @@ bool Table::editCell(gdioutput &gdi, int row, int col) {
max<int>(int((rc.right-rc.left+1)/gdi.scale), width), (rc.bottom-rc.top)*10, max<int>(int((rc.right-rc.left+1)/gdi.scale), width), (rc.bottom-rc.top)*10,
tblSelectionCB).setExtra(id); tblSelectionCB).setExtra(id);
} }
gdi.addItem(tId, out); gdi.setItems(tId, out);
gdi.selectItemByData(tId, selected); gdi.selectItemByData(tId, selected);
return true; return true;
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@
#include <set> #include <set>
#include "oBase.h" #include "oBase.h"
#include "inthashmap.h" #include "inthashmap.h"
#include "guihandler.h"
#define TableXMargin 40 #define TableXMargin 40
#define TableYMargin 30 #define TableYMargin 30
@ -62,7 +63,7 @@ class TableCell
friend class TableRow; friend class TableRow;
friend class Table; friend class Table;
friend int tblSelectionCB(gdioutput *gdi, int type, void *data); friend int tblSelectionCB(gdioutput *gdi, GuiEventType type, BaseInfo* data);
public: public:
void update(CellType t, const wstring &str) { void update(CellType t, const wstring &str) {

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -10,7 +10,7 @@
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -39,14 +39,14 @@ class AnimationData : public GuiHandler {
DWORD nextTime; DWORD nextTime;
DWORD timeOut; DWORD timeOut;
bool doAnimation; bool doAnimation;
atomic_bool errorState; std::atomic_bool errorState;
gdioutput *gdiRef; gdioutput *gdiRef;
void renderSubPage(HDC hDC, gdioutput &gdi, RenderedPage &page, int x, int y, int animationDelay); void renderSubPage(HDC hDC, gdioutput &gdi, RenderedPage &page, int x, int y, int animationDelay);
void doRender(HDC hDC, gdioutput &gdi, size_t sp, int delay); void doRender(HDC hDC, gdioutput &gdi, size_t sp, int delay);
shared_ptr<thread> animationThread; shared_ptr<std::thread> animationThread;
shared_ptr<AnimationData> delayedTakeOver; shared_ptr<AnimationData> delayedTakeOver;
void takeOverInternal(const shared_ptr<AnimationData> &other); void takeOverInternal(const shared_ptr<AnimationData> &other);

BIN
code/announcer24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,6 +26,8 @@
#include <cassert> #include <cassert>
#include "binencoder.h" #include "binencoder.h"
using namespace std;
Encoder92::Encoder92() { Encoder92::Encoder92() {
int d = 32; int d = 32;
fill(reverse_table, reverse_table + 128, 0); fill(reverse_table, reverse_table + 128, 0);

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

BIN
code/class24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

BIN
code/clubs24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

BIN
code/competition24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

BIN
code/course24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -35,13 +35,7 @@
#include "meosexception.h" #include "meosexception.h"
#ifdef _DEBUG using namespace std;
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include <vector>
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Construction/Destruction // Construction/Destruction
@ -216,7 +210,7 @@ bool csvparser::importOS_CSV(oEvent &oe, const wstring &file) {
DI.setString("Nationality", sp[OSnat]); DI.setString("Nationality", sp[OSnat]);
if (sp[rindex + OSRrentcard].length() > 0) if (sp[rindex + OSRrentcard].length() > 0)
DI.setInt("CardFee", oe.getDCI().getInt("CardFee")); r->setRentalCard(true);
//r->setCardNo(atoi(sp[rindex+OSRcard]), false); //r->setCardNo(atoi(sp[rindex+OSRcard]), false);
r->setStartTime(oe.convertAbsoluteTime(sp[rindex + OSRstart]), true, oBase::ChangeType::Update); r->setStartTime(oe.convertAbsoluteTime(sp[rindex + OSRstart]), true, oBase::ChangeType::Update);
@ -383,7 +377,7 @@ bool csvparser::importOE_CSV(oEvent &event, const wstring &file) {
oDataInterface DI=pr->getDI(); oDataInterface DI=pr->getDI();
pr->setSex(interpretSex(sp[OEsex])); pr->setSex(interpretSex(sp[OEsex]));
DI.setInt("BirthYear", extendYear(wtoi(sp[OEbirth]))); pr->setBirthDate(sp[OEbirth]);
DI.setString("Nationality", sp[OEnat]); DI.setString("Nationality", sp[OEnat]);
if (sp.size()>OEbib && needBib) if (sp.size()>OEbib && needBib)
@ -391,7 +385,9 @@ bool csvparser::importOE_CSV(oEvent &event, const wstring &file) {
if (sp.size()>=38) {//ECO if (sp.size()>=38) {//ECO
DI.setInt("Fee", wtoi(sp[OEfee])); DI.setInt("Fee", wtoi(sp[OEfee]));
DI.setInt("CardFee", wtoi(sp[OErent])); if (wtoi(sp[OErent]))
pr->setRentalCard(true);
DI.setInt("Paid", wtoi(sp[OEpaid])); DI.setInt("Paid", wtoi(sp[OEpaid]));
} }

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -61,8 +61,8 @@ struct TeamLineup {
class csvparser class csvparser
{ {
protected: protected:
ofstream fout; std::ofstream fout;
ifstream fin; std::ifstream fin;
int LineNumber; int LineNumber;
string ErrorMessage; string ErrorMessage;

BIN
code/ctrl24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -205,10 +205,10 @@ void Download::downloadFile(const wstring &url, const wstring &file, const vecto
} }
} }
fileno=_wopen(file.c_str(), O_BINARY|O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE); //fileno=_wopen(file.c_str(), O_BINARY|O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE);
errno_t err = _wsopen_s(&fileno, file.c_str(), _O_BINARY | _O_CREAT | _O_WRONLY | _O_TRUNC, _SH_DENYWR ,_S_IREAD | _S_IWRITE);
if (fileno==-1) { if (err != 0) {
fileno=0; fileno = 0;
endDownload(); endDownload();
wchar_t bf[256]; wchar_t bf[256];
swprintf_s(bf, L"Error opening '%s' for writing", file.c_str()); swprintf_s(bf, L"Error opening '%s' for writing", file.c_str());
@ -463,7 +463,13 @@ bool Download::httpSendReqEx(HINTERNET hConnect, bool https, const wstring &dest
} }
} }
int rfileno = _wopen(outFile.c_str(), O_BINARY|O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE); // int rfileno = _wopen(outFile.c_str(), O_BINARY|O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE);
int rfileno;
errno_t err = _wsopen_s(&rfileno, outFile.c_str(), _O_BINARY | _O_CREAT | _O_WRONLY | _O_TRUNC, _SH_DENYWR, _S_IREAD | _S_IWRITE);
if (err != 0) {
InternetCloseHandle(hRequest);
throw meosException(L"Failed to open + " + outFile);
}
do { do {
dwBytesRead=0; dwBytesRead=0;

View File

@ -7,7 +7,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

BIN
code/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

View File

@ -130,7 +130,7 @@ Automater = Services
Automatic rogaining point reduction = Automatic rogaining point reduction Automatic rogaining point reduction = Automatic rogaining point reduction
Automatisera = Automatize Automatisera = Automatize
Automatisk = Automatic Automatisk = Automatic
Automatisk hyrbrickshantering genom registrerade hyrbrickor = Automatic handling of hired cards using pre-registered card numbers Automatisk hyrbrickshantering genom registrerade hyrbrickor = Automatic handling of rental cards using pre-registered card numbers
Automatisk lottning = Draw Automatically Automatisk lottning = Draw Automatically
Automatisk omladdning = Automatic update Automatisk omladdning = Automatic update
Automatisk skroll = Automatic Scroll Automatisk skroll = Automatic Scroll
@ -161,7 +161,7 @@ Avmarkera 'X' för att hantera alla bricktildelningar samtidigt = Uncheck 'X' to
Avmarkera allt = Deselect all Avmarkera allt = Deselect all
Avrundad tävlingsavgift = Competition fee, rounded Avrundad tävlingsavgift = Competition fee, rounded
Avsluta = Exit Avsluta = Exit
Avstämning hyrbrickor = Count returned hired cards Avstämning hyrbrickor = Count returned rental cards
Avstånd = Distance Avstånd = Distance
Bad file format = Bad file format Bad file format = Bad file format
Bakgrund = Background Bakgrund = Background
@ -256,7 +256,7 @@ Checkenhet = Check unit
Choose result module = Choose result module Choose result module = Choose result module
ClassAvailableMaps = Available maps for class ClassAvailableMaps = Available maps for class
ClassCourseResult = Class, course, result ClassCourseResult = Class, course, result
ClassDefaultResult = Class, Default result ClassDefaultResult = Class, default result
ClassFinishTime = Class, finish time ClassFinishTime = Class, finish time
ClassKnockoutTotalResult = Class, knock-out total result ClassKnockoutTotalResult = Class, knock-out total result
ClassLength = Course length for class ClassLength = Course length for class
@ -681,8 +681,8 @@ Hoppar över stafettklass: X = Skipping relay class: X
Huvudlista = Main list Huvudlista = Main list
Hyravgift = Card hire Hyravgift = Card hire
Hyrbricka = Hired card Hyrbricka = Hired card
Hyrbricksrapport = Report with Hired Cards Hyrbricksrapport = Report with Rental Cards
Hyrbricksrapport - %s = Hired Cards - %s Hyrbricksrapport - %s = Rental Cards - %s
Hyrd = Hired Hyrd = Hired
Hämta (efter)anmälningar från Eventor = Fetch (late) entries from Eventor Hämta (efter)anmälningar från Eventor = Fetch (late) entries from Eventor
Hämta data från Eventor = Fetch Data from Eventor Hämta data från Eventor = Fetch Data from Eventor
@ -795,7 +795,7 @@ Inget filter = No filter
Inget nummer = No number Inget nummer = No number
Inkludera bana = Include course Inkludera bana = Include course
Inkludera bomanalys = Include analysis of lost time Inkludera bomanalys = Include analysis of lost time
Inkludera individuellt resultat = Include indiviual result Inkludera individuellt resultat = Include individual result
Inkludera information om flera lopp per löpare = Include information about multiple races for a single runner. Inkludera information om flera lopp per löpare = Include information about multiple races for a single runner.
Inkludera resultat från tidigare etapper = Include results from all stages Inkludera resultat från tidigare etapper = Include results from all stages
Inkludera sträcktider = Include splits Inkludera sträcktider = Include splits
@ -856,7 +856,7 @@ Klassen X är individuell = The class X is individual
Klassen X är listad flera gånger = The class X is listed several times Klassen X är listad flera gånger = The class X is listed several times
Klassen använder banpool = The class has a course pool Klassen använder banpool = The class has a course pool
Klassen används och kan inte tas bort = The class is in use and cannot be removed Klassen används och kan inte tas bort = The class is in use and cannot be removed
Klassen lottas inte, startstämpling = Use only start punch Klassen lottas inte, startstämpling = Start list not drawn, use start punch
Klassen måste ha ett namn = The class must have a name Klassen måste ha ett namn = The class must have a name
Klassen saknas = Missing class Klassen saknas = Missing class
Klassen är full = The class is full Klassen är full = The class is full
@ -1941,12 +1941,12 @@ Tillagda: X = Added: X
Tilldela = Assign Tilldela = Assign
Tilldela avgifter = Assign Fees Tilldela avgifter = Assign Fees
Tilldela endast avgift till deltagare utan avgift = Assign fee only to competitors without fee Tilldela endast avgift till deltagare utan avgift = Assign fee only to competitors without fee
Tilldela hyrbrickor = Assign cards Tilldela hyrbrickor = Assign rental cards
Tilldela nummerlappar = Assign bibs Tilldela nummerlappar = Assign bibs
Tilldela nya fakturanummer till alla klubbar? = Assign new invoice numbers to all clubs? Tilldela nya fakturanummer till alla klubbar? = Assign new invoice numbers to all clubs?
Tilldela starttider = Assign start times Tilldela starttider = Assign start times
Tilldelad = Assigned Tilldelad = Assigned
Tilldelning av hyrbrickor = Assign Cards Tilldelning av hyrbrickor = Assign Rental Cards
Tillgängliga automater = Available services Tillgängliga automater = Available services
Tillgängliga filer installerades. Starta om MeOS. = Settings was installed. Please restart MeOS. Tillgängliga filer installerades. Starta om MeOS. = Settings was installed. Please restart MeOS.
Tillgängliga listor = Available lists Tillgängliga listor = Available lists
@ -2122,7 +2122,7 @@ Vi stöder MeOS = We Support MeOS
Viktiga händelser = Important events Viktiga händelser = Important events
Vill du använda den nya brickan till alla etapper? = Do you want to use the new card for all stages? Vill du använda den nya brickan till alla etapper? = Do you want to use the new card for all stages?
Vill du att X går in i laget? = Do you want to put X in the team? Vill du att X går in i laget? = Do you want to put X in the team?
Vill du att X och Y byter sträcka? = Do you want X and Y to switch leg? Vill du att X och Y byter sträcka? = Do you want X and Y to swap legs?
Vill du att X tar sträckan istället för Y? = Do you want X to run the leg instead of Y? Vill du att X tar sträckan istället för Y? = Do you want X to run the leg instead of Y?
Vill du dumpa aktuellt tävling och skapa en testtävling? = Do you want to dump the current competition and create a test competition? Vill du dumpa aktuellt tävling och skapa en testtävling? = Do you want to dump the current competition and create a test competition?
Vill du flytta löpare från X till Y och ta bort Z? = Do you want to move runners from X to Y and remove Z? Vill du flytta löpare från X till Y och ta bort Z? = Do you want to move runners from X to Y and remove Z?
@ -2230,7 +2230,7 @@ X (Saknar e-post) = X (Has no e-mail)
X (Y deltagare, grupp Z, W) = X (Y competitors, group Z, W) X (Y deltagare, grupp Z, W) = X (Y competitors, group Z, W)
X (press Ctrl+Space to confirm) = X (press <Ctrl>+<Space> to confirm) X (press Ctrl+Space to confirm) = X (press <Ctrl>+<Space> to confirm)
X anmälda = X entries X anmälda = X entries
X går vidare, klass enligt ranking = X qualified, class by ranking X går vidare, klass enligt ranking = X qualifies, class by ranking
X har en tid (Y) som inte är kompatibel med förändringen = X has a time (Y) that is incompatible with this change X har en tid (Y) som inte är kompatibel med förändringen = X has a time (Y) that is incompatible with this change
X har redan bricknummer Y. Vill du ändra det? = X already has card number Y. Do you want to change it? X har redan bricknummer Y. Vill du ändra det? = X already has card number Y. Do you want to change it?
X har redan ett resultat. Vi du fortsätta? = X already has a result. Do you wish to continue? X har redan ett resultat. Vi du fortsätta? = X already has a result. Do you wish to continue?
@ -2294,7 +2294,6 @@ edit_in_forest = Manage\nRemaining Runners
ej aktiv = not active ej aktiv = not active
elfte = eleventh elfte = eleventh
elva = eleventh elva = eleventh
encoding = ANSI
error:invalidmethod = The selected method gave no distribution. Source data is insufficient. error:invalidmethod = The selected method gave no distribution. Source data is insufficient.
ett Mycket Enkelt OrienteringsSystem = a Much Easier Orienteering System ett Mycket Enkelt OrienteringsSystem = a Much Easier Orienteering System
eventor:help = If you use MeOS for orienteering in Sweden, we recommend that you use MeOS's Eventor connection. eventor:help = If you use MeOS for orienteering in Sweden, we recommend that you use MeOS's Eventor connection.
@ -2375,8 +2374,8 @@ help:restore_backup = Choose a backup to restore by clicking the time when the b
help:runnerdatabase = By importing a runner and club database, MeOS will automatically recognize unknown runners (by card number), and you will get addresses and phone numbers to clubs. help:runnerdatabase = By importing a runner and club database, MeOS will automatically recognize unknown runners (by card number), and you will get addresses and phone numbers to clubs.
help:save = MeOS automatically saves all settings when needed. help:save = MeOS automatically saves all settings when needed.
help:seeding_info = Seeded start time allocation means that an earlier result or ranking controls the process in part. In the field seeding groups you may either enter a single group size, meaning that the entire class is partitioned into groups of this size. The group size "1" means that the seeding order is strictly used. You can also specify several group sizes. "15, 1000" would mean a seeded group with the 15 highest ranked runners and the remaining (at most 1000) runners are placed in a non-seeded group. help:seeding_info = Seeded start time allocation means that an earlier result or ranking controls the process in part. In the field seeding groups you may either enter a single group size, meaning that the entire class is partitioned into groups of this size. The group size "1" means that the seeding order is strictly used. You can also specify several group sizes. "15, 1000" would mean a seeded group with the 15 highest ranked runners and the remaining (at most 1000) runners are placed in a non-seeded group.
help:selectsound = Select sounds to play. By default MeOS built-in sounds are played. help:selectsound = Select sounds to play. By default, MeOS built-in sounds are played.
help:simulate = This service lets you simulate readout of SI cards. Times and punches are generated for all runners. Also radio contol punches can be simulated.\n\nWARNING: Use for testing only. If you use this on a real event, it will be corrupted. help:simulate = This service lets you simulate readout of SI cards. Times and punches are generated for all runners. Also radio control punches can be simulated.\n\nWARNING: Use for testing only. If you use this on a real event, it will be corrupted.
help:speaker_setup = Choose which classes and courses you want to watch. help:speaker_setup = Choose which classes and courses you want to watch.
help:speakerprio = Check those runners/teams you wish to watch from start, and as long as the runner/team is doing well. Put two checks to watch even if the result is not so good. No check means monitoring only if the runner/team is doing well (not from start). help:speakerprio = Check those runners/teams you wish to watch from start, and as long as the runner/team is doing well. Put two checks to watch even if the result is not so good. No check means monitoring only if the runner/team is doing well (not from start).
help:splitexport = Decide if you want to export total results, or individual results for each race. If you choose to export all races, numbered files will be created. help:splitexport = Decide if you want to export total results, or individual results for each race. If you choose to export all races, numbered files will be created.
@ -2476,7 +2475,7 @@ prefsOrganizer = Organizer
prefsPayModes = Modes of payment prefsPayModes = Modes of payment
prefsPlaySound = Play sounds prefsPlaySound = Play sounds
prefsPort = MySQL network port prefsPort = MySQL network port
prefsRentCard = Rent card prefsRentCard = Rent cards by default
prefsSeniorAge = Upper (pensioner) age limit prefsSeniorAge = Upper (pensioner) age limit
prefsServer = Default network server prefsServer = Default network server
prefsServicePort = Default service port prefsServicePort = Default service port
@ -2672,5 +2671,131 @@ Välj bild = Select image
Välj bland befintliga bilder = Select existing image Välj bland befintliga bilder = Select existing image
Bevara höjd/bredd-relationen = Preserve aspect ratio Bevara höjd/bredd-relationen = Preserve aspect ratio
RunnerLegTeamLeaderName = First competitor in team to finish leg RunnerLegTeamLeaderName = First competitor in team to finish leg
info:offsetclassid = If you import entries and classes from different sources to the same competition, it might happen that there are clashes in the Id numbers of the classes. To separate the classes, you may enter an offset for the Class Id when working with files from a particular source; this will be added to the Id numbers.\n\nYou must specify the same offset each time you import from that source.\n\n A suitble number could be1000 (which will work as long as every Id is less that 1000). info:offsetclassid = If you import entries and classes from different sources to the same competition, it might happen that there are clashes in the Id numbers of the classes. To separate the classes, you may enter an offset for the Class Id when working with files from a particular source; this will be added to the Id numbers.\n\nYou must specify the same offset each time you import from that source.\n\n A suitable number could be 1000 (which will work as long as every Id is less that 1000).
Förskjutning av klassers Id = Offset Class ID Förskjutning av klassers Id = Offset Class ID
Tilldela nummerlapp till vakanter = Assign bibs to vacancies
Avläsning = Readout
Inmatning Testning = Input Testing
Testning = Testing
CourseNumControls = Number of controls
PunchControlPlaceTeamAcc = Total team place at control
PunchTeamTime = Team total time and split at control
PunchTeamTotalNamedTime = Total team named split time
PunchTeamTotalTime = Total team running time to control
PunchTeamTotalTimeAfter = Team's time after at control
Aktivera kioskläge = Activate kiosk mode
Avstånd mellan förslag (minuter) = Distance between suggestions (minutes)
Boka starttid = Request start time
Ingen ledig starttid kunde hittas = No free start time was found
Minsta tid till start (minuter) = Least time to start (minutes)
Sista starttid = Last start time
Startintervall (minuter) = Start interval (minutes)
Tillåt klass med samma bana på samma starttid = Allow class with same course on same start time
Tillåt klass med samma bana på stattid före/efter = Allow class with same course before and after
Tillåt klass med samma första kontroll vid samma starttid = Allow class with same first control at the same time
Tiden har passerat sista tillåtna starttid = Time has passed last allowed start time
Starttiden är låst = The start time is locked
Starttiden är redan tilldelad = The start time is already assigned
Klassen tillåter ej val av starttid = The class does not allow request of start time
Klassen lottas inte, boka starttid = Start list not drawn, request start time on the page SportIdent
Simulerar starttidstilldelning för X deltagare = Simulating start time assignments for X competitors
Simulering = Simulation
Välj från flera förslag = Choose start time
Välj starttid för X = Choose start time for X
X: Startid för Y kl Z = X: Start time for Y at Z
Önskad starttid = Desired start time
ask:startkiosk = If you start a start time reservation kiosk, MeOS enters a state where no other operations are supported or settings can be changed. You need a connected and activated SI unit.\n\nYou should consider password protecting the database if you are exposing a kiosk.\n\nDo you want to start the kiosk mode?
ask:simulatestart = Carry out a simulation with the settings you have made (classes, starting depth, distance, rules) and with the registered participants who are in the classes. The competition is not affected. The result shows whether it is reasonable that everyone has time to start within the set start depth and how long extra waiting time to start may be required in different classes.\n\nAfterwards, you can also save a copy of the competition with simulated start times to study e.g. minute start list.\n\nDo you want to run the simulation?
help:requeststart = Requesting start time is something in between free and drawn start time. By requesting a start time, MeOS ensures that there is a certain distance between participants in the same class or on the same course. If you have a requested start time, it is not necessary to use a start punch.\n\nSet parameters for start depth and how many/who are allowed to start at the same time. How far it is from the place where the booking is made to the start determines what is an appropriate minimum time to start value.\n\nYou can let the participants automatically get the first possible available start time after the minimum time to start, or let them choose from a number possible start times. It is possible and appropriate to print out a start certificate to take with you to the start.\n\nIf you are using a live results service, the start time will probably be displayed there when booked.
Anslut en SI-enhet och aktivera den = Connect and activate a SI unit
Manuellt startönskemål = Manual start request
Stämpla för välja starttid = Punch to choose a start time
Tillåt deltagare med samma klubb och klass på närliggande starttid = Allow competitors from the same club and class on next start time
prevsExpResFilename = Export results
prefsExpStaFilename = Export start list
prefsRequestClubNeighbour = Request start: Allow same club neighbour
prefsRequestLastStart = Request start: Last start
prefsRequestMaxParallel = Request start: Max parallel starts
prefsRequestMinTime = Request start: Time to start
prefsRequestProvideSuggestion = Request start: Make suggestions
prefsRequestSameCourse = Request start: Same course
prefsRequestSameCourseNeighbour = Request start: Same course for neighbour
prefsRequestSameFirstControl = Request start: Samma first control
prefsRequestStartInterval = Request start: Interval
prefsRequestSuggestInterval = Request start: Time between suggestions
Omstart: X = Restart: X
Reptid: X = Rope time: X
Datortid = Computer time
Start på signal = Start on signal
Sätt tiden = Set time
Välj vilken tid du vill sätta = Select which time to set
Starta nu = Start now
Alla okvalificerade = Any unqualified
Antal nivåer = Number of levels
Använd ranking istället för placering i kval för att placera kvalificerade löpare i klasser = Use ranking instead of placement to distribute qualified runners into classes
Bästa tid = Best time
Final = Final
Klass / placering = Class / place
Klass X (namnsuffix) = Class X (name suffix)
Klass efter ranking = Select class by ranking
Kval = Qualification
Kvalificeringsregler för X = Qualification Rules for X
Kvalklass = Qualification class
Ladda = Load
N bästa = N best
Nivå X = Level X
Placeringar = Placements
Regler = Rules
Tidsgräns X = Time limit X
Tidskval = Time qualification
Use in X = Use in X
X bästa okvalificerade = X best unqualified
X kvalificerade = X qualified
Övriga okvalificerade = Remaining unqualified
Lägg till regler = Add rules
Placering X kvalificerar till Y = Place X qualifies for Y
X bästa = X best
Alla övriga = All remaining
Vill du starta automaten? = Do you want to start the service?
För kommunikationstest kan man använda en separat testtävling = To test communication, you can use a separate test competition
Observera att stämplingar före tävlingens nolltid inte kan hämtas = Note MeOS cannot fetch punches preceding the competition zero time
Individual Rogaining Split Print = Individual Rogaining Split Print
Lap Count = Lap count
Lap count with extra punch = Lap count with extra punch
Live results, radio = Live results, radio
Patrol results = Patrol results
Patrol, start list = Patrol, start list
Resultatlista, Rogaining, lag = Results, Rogaining, team
Startlista, lag = Start list, team
Team Rogaining Split Print = Team Rogaining Split Print
RunnerRentalCard = Rental card
Primärt = Primary
Sekundärt = Secondary
Välj typ av ID att exportera = Select ID types to export
Ursprunglig tid: X = Original time: X
Manuellt ändrad stämpling = Manually changed data
help_second_fee = Use a second raised fee for direct entry at the competition day (for example). The higher fee is applied starting from and including the specified day. The specified percentage is relative the original fee.
Avgiftshöjning två (procent) = Second fee increase (percent)
ClassDataA = Class data A
ClassDataB = Class data B
ClassTextA = Class text
Extra data X = Extra data X
Extra datafält = Extra data fields
Kommentarer = Comments
Oförändrad brickdata = Original card data
Okänd ursprungsstatus = Unknown data origin status
RunnerDataA = Competitor data A
RunnerDataB = Competitor data B
RunnerTextA = Competitor text
Sida = Page
Stoppdatum två = Second stop date
TeamDataA = Team data A
TeamDataB = Team data B
TeamTextA = Team text
Födelsedatum = Birth date
Kommentar = Comment
Lägg till eller redigera kommentarer om deltagaren = Add or edit a comment about the competitor
Lägg till eller redigera kommentarer om deltagaren = Add or edit a comment about the team
Manuellt ändrad brickdata = Manually modified card data
Efteranmälan = Late entry
Reducerad = Reduced

View File

@ -214,7 +214,9 @@ Bevakar händelser i X = Moniteur d'évènement X
Bevakningsprioritering = Sélectionner le coureur à surveiller Bevakningsprioritering = Sélectionner le coureur à surveiller
Bevara höjd/bredd-relationen = Conserver les proportions Bevara höjd/bredd-relationen = Conserver les proportions
Bibs = Dossards Bibs = Dossards
Bild = Image
Bild under text = Mettre l'image sous le texte Bild under text = Mettre l'image sous le texte
Bilder = Images
Block = Bloc Block = Bloc
Blockbredd = Largeur de bloc Blockbredd = Largeur de bloc
Bläddra = Parcourir Bläddra = Parcourir
@ -265,7 +267,7 @@ ClassKnockoutTotalResult = Class, knock-out total result
ClassLength = Longueur du circuit pour la catégorie ClassLength = Longueur du circuit pour la catégorie
ClassLiveResult = Live results (temps radios), par catégorie ClassLiveResult = Live results (temps radios), par catégorie
ClassName = Catégorie ClassName = Catégorie
ClassNumEntries = Nombre d'inscrits ClassNumEntries = Nombre d'inscrits dans la catégorie
ClassPoints = Catégorie, points ClassPoints = Catégorie, points
ClassResult = Catégorie, résultat ClassResult = Catégorie, résultat
ClassResultFraction = Pourcentage de la catégorie ayant terminé ClassResultFraction = Pourcentage de la catégorie ayant terminé
@ -422,6 +424,7 @@ Elektronisk godkänd = Accepté électroniquement
Elit = Élite Elit = Élite
Elitavgift = Frais élites Elitavgift = Frais élites
Elitklasser = Catégorie élite Elitklasser = Catégorie élite
Empty Results Split Print = Temps intermédiaires sans résultats
En bana med slingor tillåter deltagaren att ta slingorna i valfri ordning = Un circuit avec des boucles autorise le coureur à effectuer les boucles dans n'importe quel ordre. En bana med slingor tillåter deltagaren att ta slingorna i valfri ordning = Un circuit avec des boucles autorise le coureur à effectuer les boucles dans n'importe quel ordre.
En gafflad sträcka = Circuit avec variations En gafflad sträcka = Circuit avec variations
En klass kan inte slås ihop med sig själv = Vous ne pouvez pas fusionner une catégorie avec elle-même En klass kan inte slås ihop med sig själv = Vous ne pouvez pas fusionner une catégorie avec elle-même
@ -621,6 +624,7 @@ Förhindra att laget deltar i någon omstart = Permet à l'équipe de ne pas pre
Förhindra omstart = Refuser le départ des attardés Förhindra omstart = Refuser le départ des attardés
Förhöjd avgift = Frais supplémentaires Förhöjd avgift = Frais supplémentaires
Förskjutning = Déplacement Förskjutning = Déplacement
Förskjutning av klassers Id = Décalage de l'identifiant de catégorie
Först = En premier Först = En premier
Först-i-mål, gemensam = Du premier au dernier, commun Först-i-mål, gemensam = Du premier au dernier, commun
Först-i-mål, klassvis = Du premier au dernier, par catégorie Först-i-mål, klassvis = Du premier au dernier, par catégorie
@ -685,6 +689,7 @@ Hittar inte hjälpfilen, X = Documentation introuvable, X
Hittar inte klass X = Impossible de trouver la catégorie X Hittar inte klass X = Impossible de trouver la catégorie X
Hjälp = Aide Hjälp = Aide
Hoppar över stafettklass: X = Sauter la catégorie de relais: X Hoppar över stafettklass: X = Sauter la catégorie de relais: X
Horisontell = Horizontal
Horizontell = Horizontalement Horizontell = Horizontalement
Huvudlista = Liste principale Huvudlista = Liste principale
Hyravgift = Tarif de location Hyravgift = Tarif de location
@ -763,6 +768,8 @@ Inconsistent qualification rule, X = Règle de qualification incohérente, X
Index = Index Index = Index
Index in X[index] = Index en X[index] Index in X[index] = Index en X[index]
Individual Example = Exemple de course individuelle Individual Example = Exemple de course individuelle
Individual Results Split Print = Avec résultats individuels
Individual Rogaining Split Print = Avec résultats de la course au score
Individual result by finish time = Résultat individuel sur l'heure d'arrivée Individual result by finish time = Résultat individuel sur l'heure d'arrivée
Individual results in a club = Résultats individuel au sein du club Individual results in a club = Résultats individuel au sein du club
Individuell = par catégorie Individuell = par catégorie
@ -1009,6 +1016,7 @@ Liveresultat, radiotider = Résultats en direct avec radios
Ljud = Son Ljud = Son
Ljudfiler, baskatalog = Répertoire de base des fichiers sonores Ljudfiler, baskatalog = Répertoire de base des fichiers sonores
Ljudval = Sélection des sons Ljudval = Sélection des sons
Lokal kopia från X = Copie locale de X
Lokalt = Localement Lokalt = Localement
Long = Longue Long = Longue
Longitud = Longitude Longitud = Longitude
@ -1402,6 +1410,8 @@ Relation till föregående = Lien avec le précédent
Relativ skalfaktor för typsnittets storlek i procent = Facteur d'échelle pour la police (pourcentage) Relativ skalfaktor för typsnittets storlek i procent = Facteur d'échelle pour la police (pourcentage)
Relay Example = Exemple de relais Relay Example = Exemple de relais
Relay Example (Lokal kopia från: localhost) = Exemple de relais (Copie locale depuis : localhost) Relay Example (Lokal kopia från: localhost) = Exemple de relais (Copie locale depuis : localhost)
Relay Results Split Print = Avec résultats du relais
Relay/Team Results Split Print = Avec résultats du relais/de l'équipe
Relays = Relais Relays = Relais
Rep = Arrêt attardés Rep = Arrêt attardés
Reparera vald tävling = Réparer la compétition sélectionnée Reparera vald tävling = Réparer la compétition sélectionnée
@ -1526,6 +1536,7 @@ RunnerId = Licence/ID
RunnerLeg = Concurrent (variation spécifique) RunnerLeg = Concurrent (variation spécifique)
RunnerLegNumber = Numéro de relais groupé du coureur RunnerLegNumber = Numéro de relais groupé du coureur
RunnerLegNumberAlpha = Numéro de relais exact du coureur RunnerLegNumberAlpha = Numéro de relais exact du coureur
RunnerLegTeamLeaderName = Premier membre de l'équipe à terminer son circuit
RunnerName = Nom du coureur RunnerName = Nom du coureur
RunnerNationality = Nationalité du coureur RunnerNationality = Nationalité du coureur
RunnerPaid = Payé RunnerPaid = Payé
@ -1888,6 +1899,7 @@ Tabelläge = Mode table
Tar bort X = Retrait de X Tar bort X = Retrait de X
Team = Équipe Team = Équipe
Team Rogaining = Course au score en équipe Team Rogaining = Course au score en équipe
Team Rogaining Split Print = Avec résultats de la course au score en équipe
TeamBib = Dossard de l'équipe TeamBib = Dossard de l'équipe
TeamClub = Club de l'équipe TeamClub = Club de l'équipe
TeamCourseName = Nom du circuit pour l'équipe/la branche TeamCourseName = Nom du circuit pour l'équipe/la branche
@ -2217,6 +2229,7 @@ Välj alla klasser = Sélectionner toutes les catégories
Välj allt = Sélectionner tout Välj allt = Sélectionner tout
Välj automatiskt = Sélection automatique Välj automatiskt = Sélection automatique
Välj bild = Choisir une image Välj bild = Choisir une image
Välj bland befintliga bilder = Sélectionner une image existante
Välj deltagare för förhandsgranskning = Sélectionner un coureur pour prévisualisation Välj deltagare för förhandsgranskning = Sélectionner un coureur pour prévisualisation
Välj den etapp som föregår denna tävling = Sélectionner l'étape précédente Välj den etapp som föregår denna tävling = Sélectionner l'étape précédente
Välj den etapp som kommer efter denna tävling = Sélectionner l'étape suivante Välj den etapp som kommer efter denna tävling = Sélectionner l'étape suivante
@ -2428,11 +2441,12 @@ info:mapcontrol = MeOS ne sait pas déterminer la fonction d'un boîtier s'il n'
info:multieventnetwork = Pour prendre en charge plus d'une étape vous devez travailler localement. Faite une copie de sauvegarde de la compétition, ouvrez-la en local et transférez les résultats à l'étape suivante. Enfin, remontez l'étape suivante sur le serveur. info:multieventnetwork = Pour prendre en charge plus d'une étape vous devez travailler localement. Faite une copie de sauvegarde de la compétition, ouvrez-la en local et transférez les résultats à l'étape suivante. Enfin, remontez l'étape suivante sur le serveur.
info:multiple_start = Un coureur peut faire plusieurs fois le même circuit. Une nouvelle inscription est créée à chaque lecture de la puce info:multiple_start = Un coureur peut faire plusieurs fois le même circuit. Une nouvelle inscription est créée à chaque lecture de la puce
info:nosplitprint = Chargement de la liste personnalisée impossible\n\nCelle par défaut la remplace info:nosplitprint = Chargement de la liste personnalisée impossible\n\nCelle par défaut la remplace
info:offsetclassid = Si vous importez des inscrits et des catégories depuis des sources différentes dans la même compétition, il peut y avoir des conflits entre les numéros d'identifiant des catégories. Pour différencier les catégories, vous pouvez entrer un décalage de la valeur de l'identifiant des catégorires pour chacune des sources. Celui-ci sera ajouté à l'identifiant existant.\n\nVous pouvez par exemple entrer 1000 (si aucune catégorie n'a déjà un identifiant supérieur à 1000).
info:pageswithcolumns = Montrer la liste page par page, avec un nombre spécifié de colonnes. Les infos sont mises à jour à chaque bouclage. info:pageswithcolumns = Montrer la liste page par page, avec un nombre spécifié de colonnes. Les infos sont mises à jour à chaque bouclage.
info:readout_action = X: Puce no. Y lue.\nDes actions manuelles sont requises. info:readout_action = X: Puce no. Y lue.\nDes actions manuelles sont requises.
info:readout_queue = X: Puce no. Y lue.\nLa puce a été mise en file d'attente. info:readout_queue = X: Puce no. Y lue.\nLa puce a été mise en file d'attente.
info:readoutbase = Activez le boîtier SI en sélectionnant son port COM ou en recherchant les boîtiers SI installés. Appuyez sur Information pour obtenir le statut du port sélectionné.\n\nLecture Interactive vous permet de gérer directement les problèmes tels qu'un numéro de puce erroné. N'utilisez pas cette possibilité quand les coureurs ayant des problèmes sont pris en charge séparément.\n\nLa base de données des coureurs est utilisée si vous voulez ajouter automatiquement de nouveaux coureurs. Les poinçons sont utilisés pour trouver (détecter) la bonne catégorie. info:readoutbase = Activez le boîtier SI en sélectionnant son port COM ou en recherchant les boîtiers SI installés. Appuyez sur Information pour obtenir le statut du port sélectionné.\n\nLecture Interactive vous permet de gérer directement les problèmes tels qu'un numéro de puce erroné. N'utilisez pas cette possibilité quand les coureurs ayant des problèmes sont pris en charge séparément.\n\nLa base de données des coureurs est utilisée si vous voulez ajouter automatiquement de nouveaux coureurs. Les poinçons sont utilisés pour trouver (détecter) la bonne catégorie.
info:readoutmore = Verrouillez la fonction pour éviter toute modification accidentelle.\n\nSélection des sons vous permet de lancer différents sons lors de la lecture des puces pour être plus facilement informé des problèmes.\n\n"Fenêtre de prévisualisation coureur" affiche une nouvelle fenêtre destinée au coureur qui lit sa puce, regroupant les informations principales de sa course.\n\nPlusieurs courses pour un coureur est utile si un coureur est autorisé a faire plusieurs fois son circuit. Une nouvelle inscriprion est créée à chaque lecture de la puce. info:readoutmore = Verrouillez la fonction pour éviter toute modification accidentelle.\n\nSélection des sons vous permet de lancer différents sons lors de la lecture des puces pour être plus facilement informé des problèmes.\n\n"Fenêtre de prévisualisation coureur" affiche une nouvelle fenêtre destinée au coureur qui lit sa puce, regroupant les informations principales de sa course.\n\nPlusieurs courses pour un coureur est utile si un coureur est autorisé a faire plusieurs fois son circuit. Une nouvelle inscription est créée à chaque lecture de la puce.
info:readoutwindow = Cette fenêtre affiche les informations principales de chaque lecture de puce info:readoutwindow = Cette fenêtre affiche les informations principales de chaque lecture de puce
info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'éditer les bases de données club et coureurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML). info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'éditer les bases de données club et coureurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML).
info:teamcourseassignment = Le fichier des circuits IOF XML 3.0 contient les variations des équipes. Pour importer ces données, vous devez préparer la compétition en fonction des données du fichier :\n\n1.Assurez-vous que les catégories de relais ont le bon nombre de branches.\n2. Affectez les dossards à chaque catégorie. Passez par la Configuration Rapide dans l'onglet Catégories et renseignez le premier dossard de chaque catégorie (avec la répartition automatique des dossards). Vous pouvez aussi importer les équipes et leur attribuer des dossards comme d'habitude.\n\n\n3. Importez les circuits. Vous pouvez importer plusieurs fois ce fichier si nécessaire pour mettre à jour les variations. info:teamcourseassignment = Le fichier des circuits IOF XML 3.0 contient les variations des équipes. Pour importer ces données, vous devez préparer la compétition en fonction des données du fichier :\n\n1.Assurez-vous que les catégories de relais ont le bon nombre de branches.\n2. Affectez les dossards à chaque catégorie. Passez par la Configuration Rapide dans l'onglet Catégories et renseignez le premier dossard de chaque catégorie (avec la répartition automatique des dossards). Vous pouvez aussi importer les équipes et leur attribuer des dossards comme d'habitude.\n\n\n3. Importez les circuits. Vous pouvez importer plusieurs fois ce fichier si nécessaire pour mettre à jour les variations.

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -62,6 +62,7 @@ constexpr int skipBoundingBox = 1 << 18;
constexpr int hiddenText = 1 << 19; constexpr int hiddenText = 1 << 19;
constexpr int textLimitEllipsis = 1 << 20; constexpr int textLimitEllipsis = 1 << 20;
constexpr int imageNoUpdatePos = 1 << 21; constexpr int imageNoUpdatePos = 1 << 21;
constexpr int time24HourClock = 1 << 22;
enum GDICOLOR { enum GDICOLOR {
colorBlack = RGB(0, 0, 0), colorBlack = RGB(0, 0, 0),

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -59,8 +59,8 @@ public:
class GDIImplFontEnum { class GDIImplFontEnum {
private: private:
int width; int width = 0;
int height; int height = 0;
double relScale; double relScale;
wstring face; wstring face;
public: public:

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -320,6 +320,18 @@ void gdioutput::initCommon(double _scale, const wstring &font)
fontHeightCache.clear(); fontHeightCache.clear();
fonts[currentFont].init(scale, currentFont, L""); fonts[currentFont].init(scale, currentFont, L"");
updateTabFont();
}
void gdioutput::updateTabFont() {
if (this == gdi_main && hWndTab) {
HFONT gui = fonts[currentFont].getGUIFont();
SendMessage(hWndTab, WM_SETFONT, WPARAM(gui), TRUE);
RECT rc;
GetClientRect(hWndAppMain, &rc);
SendMessage(hWndAppMain, WM_SIZE, 0, MAKELONG(rc.right, rc.bottom));
}
} }
double getLocalScale(const wstring &fontName, wstring &faceName) { double getLocalScale(const wstring &fontName, wstring &faceName) {
@ -888,6 +900,7 @@ TextInfo& gdioutput::addImage(const string& id, int yp, int xp, int format,
imageReferences.push_back(&TI); imageReferences.push_back(&TI);
TI.id = id;
TI.format = format | textImage; TI.format = format | textImage;
TI.xp = xp; TI.xp = xp;
TI.yp = yp; TI.yp = yp;
@ -1043,9 +1056,14 @@ TextInfo& gdioutput::addString(const char* id, int yp, int xp, int format, const
TI.format = format; TI.format = format;
TI.xp = xp; TI.xp = xp;
TI.yp = yp; TI.yp = yp;
TI.text = lang.tl(text); if ((format & 0xFF) != textImage) {
if ((format & Capitalize) == Capitalize && lang.capitalizeWords()) TI.text = lang.tl(text);
capitalizeWords(TI.text); if ((format & Capitalize) == Capitalize && lang.capitalizeWords())
capitalizeWords(TI.text);
}
else {
TI.text = text;
}
TI.id = id; TI.id = id;
TI.xlimit = xlimit; TI.xlimit = xlimit;
TI.callBack = cb; TI.callBack = cb;
@ -1201,7 +1219,7 @@ void ButtonInfo::moveButton(gdioutput &gdi, int nxp, int nyp) {
gdi.updatePos(xp, yp, w, h); gdi.updatePos(xp, yp, w, h);
} }
void ButtonInfo::getDimension(gdioutput &gdi, int &w, int &h) { void ButtonInfo::getDimension(const gdioutput &gdi, int &w, int &h) const {
RECT rc; RECT rc;
GetWindowRect(hWnd, &rc); GetWindowRect(hWnd, &rc);
w = rc.right - rc.left + gdi.scaleLength(GDI_BUTTON_SPACING); w = rc.right - rc.left + gdi.scaleLength(GDI_BUTTON_SPACING);
@ -1214,12 +1232,21 @@ ButtonInfo &gdioutput::addButton(int x, int y, int w, const string &id,
return addButton(x, y, w, id, widen(text), cb, widen(tooltip), AbsPos, hasState); return addButton(x, y, w, id, widen(text), cb, widen(tooltip), AbsPos, hasState);
} }
ButtonInfo &gdioutput::addButton(int x, int y, int w, const string &id, ButtonInfo& gdioutput::addButton(int x, int y, int w, const string& id,
const wstring &text, GUICALLBACK cb, const wstring &tooltip, const wstring& text, GUICALLBACK cb, const wstring& toolTip,
bool AbsPos, bool hasState) bool absPos, bool hasState) {
{ return addButton(x, y, w, getButtonHeight(), id, text,
int style = hasState ? BS_CHECKBOX|BS_PUSHLIKE : BS_PUSHBUTTON; gdiFonts::normalText, cb, toolTip, absPos, hasState);
}
ButtonInfo& gdioutput::addButton(int x, int y, int width, int height,
const string& id, const wstring& text,
gdiFonts font, GUICALLBACK cb,
const wstring& tooltip,
bool absPos, bool hasState) {
int style = hasState ? BS_CHECKBOX | BS_PUSHLIKE : BS_PUSHBUTTON;
if (text[0] == '@') if (text[0] == '@')
style |= BS_BITMAP; style |= BS_BITMAP;
@ -1234,36 +1261,38 @@ ButtonInfo &gdioutput::addButton(int x, int y, int w, const string &id,
} }
if (lang.capitalizeWords()) if (lang.capitalizeWords())
capitalizeWords(ttext); capitalizeWords(ttext);
int height = getButtonHeight(); if (absPos) {
if (AbsPos){ if (ttext.find_first_of('\n') != string::npos) {
if (ttext.find_first_of('\n') != string::npos) { //WCS
style |= BS_MULTILINE; style |= BS_MULTILINE;
height *= 2; height *= 2;
} }
bi.hWnd=CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP|WS_VISIBLE|WS_CHILD | WS_CLIPSIBLINGS |style|BS_NOTIFY, bi.hWnd = CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | style | BS_NOTIFY,
x-OffsetX, y, w, height, hWndTarget, NULL, x - OffsetX, y, width, height, hWndTarget, NULL,
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL); (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
} }
else { else {
bi.hWnd=CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP|WS_VISIBLE|WS_CHILD | WS_CLIPSIBLINGS |style|BS_NOTIFY, bi.hWnd = CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | style | BS_NOTIFY,
x-OffsetX, y-OffsetY-1, w, height, hWndTarget, NULL, x - OffsetX, y - OffsetY - 1, width, height, hWndTarget, NULL,
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL); (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
} }
SendMessage(bi.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0);
if (!AbsPos) if (font == gdiFonts::normalText)
updatePos(x, y, w+scaleLength(GDI_BUTTON_SPACING), height+5); SendMessage(bi.hWnd, WM_SETFONT, (WPARAM)getGUIFont(), 0);
else
SendMessage(bi.hWnd, WM_SETFONT, (WPARAM)getCurrentFont().getFont(font), 0);
bi.xp=x; if (!absPos)
bi.yp=y; updatePos(x, y, width + scaleLength(GDI_BUTTON_SPACING), height + 5);
bi.width = w;
bi.text=ttext;
bi.id=id;
bi.callBack=cb;
bi.AbsPos=AbsPos;
if (tooltip.length()>0) bi.xp = x;
bi.yp = y - 1;
bi.width = width;
bi.text = ttext;
bi.id = id;
bi.callBack = cb;
bi.AbsPos = absPos;
if (tooltip.length() > 0)
addToolTip(id, tooltip, bi.hWnd); addToolTip(id, tooltip, bi.hWnd);
BI.push_back(bi); BI.push_back(bi);
@ -1273,7 +1302,7 @@ ButtonInfo &gdioutput::addButton(int x, int y, int w, const string &id,
return BI.back(); return BI.back();
} }
static int checkBoxCallback(gdioutput *gdi, int type, void *data) { static int checkBoxCallback(gdioutput *gdi, GuiEventType type, BaseInfo *data) {
if (type == GUI_LINK) { if (type == GUI_LINK) {
TextInfo *ti = (TextInfo *)data; TextInfo *ti = (TextInfo *)data;
string cid = ti->id.substr(1); string cid = ti->id.substr(1);
@ -1321,23 +1350,23 @@ ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const string
return addCheckbox(x,y,id, widen(text), cb, Checked, widen(tooltip), AbsPos); return addCheckbox(x,y,id, widen(text), cb, Checked, widen(tooltip), AbsPos);
} }
ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const wstring &text, ButtonInfo& gdioutput::addCheckbox(int x, int y, const string& id, const wstring& text,
GUICALLBACK cb, bool Checked, const wstring &tooltip, bool AbsPos) GUICALLBACK cb, bool Checked, const wstring& tooltip, bool AbsPos)
{ {
ButtonInfo bi; ButtonInfo bi;
SIZE size; SIZE size;
wstring ttext = lang.tl(text); wstring ttext = lang.tl(text);
HDC hDC=GetDC(hWndTarget); HDC hDC = GetDC(hWndTarget);
SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT)); SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
GetTextExtentPoint32(hDC, L"M", 1, &size); GetTextExtentPoint32(hDC, L"M", 1, &size);
int ox=OffsetX; int ox = OffsetX;
int oy=OffsetY; int oy = OffsetY;
if (AbsPos) { if (AbsPos) {
ox=0; ox = 0;
oy=0; oy = 0;
} }
int h = size.cy; int h = size.cy;
@ -1345,15 +1374,16 @@ ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const wstring
GetTextExtentPoint32(hDC, ttext.c_str(), ttext.length(), &size); GetTextExtentPoint32(hDC, ttext.c_str(), ttext.length(), &size);
ReleaseDC(hWndTarget, hDC); ReleaseDC(hWndTarget, hDC);
bi.hWnd=CreateWindowEx(0,L"BUTTON", L"", WS_TABSTOP|WS_VISIBLE| int cbY = y + (size.cy - h) / 2;
WS_CHILD | WS_CLIPSIBLINGS |BS_AUTOCHECKBOX|BS_NOTIFY, bi.hWnd = CreateWindowEx(0, L"BUTTON", L"", WS_TABSTOP | WS_VISIBLE |
x-ox, y-oy + (size.cy-h)/2, h, h, hWndTarget, NULL, WS_CHILD | WS_CLIPSIBLINGS | BS_AUTOCHECKBOX | BS_NOTIFY,
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL); x - ox, cbY - oy, h, h, hWndTarget, NULL,
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
TextInfo &desc = addStringUT(y , x + (3*h)/2, 0, ttext, 0, checkBoxCallback); TextInfo& desc = addStringUT(y, x + (3 * h) / 2, 0, ttext, 0, checkBoxCallback);
desc.id = "T" + id; desc.id = "T" + id;
SendMessage(bi.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0); SendMessage(bi.hWnd, WM_SETFONT, (WPARAM)getGUIFont(), 0);
if (Checked) if (Checked)
SendMessage(bi.hWnd, BM_SETCHECK, BST_CHECKED, 0); SendMessage(bi.hWnd, BM_SETCHECK, BST_CHECKED, 0);
@ -1366,18 +1396,18 @@ ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const wstring
else else
updatePos(x, y, size.cx + int(30 * scale), desc.textRect.bottom - desc.textRect.top + scaleLength(4)); updatePos(x, y, size.cx + int(30 * scale), desc.textRect.bottom - desc.textRect.top + scaleLength(4));
} }
if (tooltip.length()>0) { if (tooltip.length() > 0) {
addToolTip(id, tooltip, bi.hWnd); addToolTip(id, tooltip, bi.hWnd);
addToolTip(desc.id, tooltip, 0, &desc.textRect); addToolTip(desc.id, tooltip, 0, &desc.textRect);
} }
bi.isCheckbox = true; bi.isCheckbox = true;
bi.xp=x; bi.xp = x;
bi.yp=y; bi.yp = cbY;
bi.width = desc.textRect.right - (x-ox); bi.width = desc.textRect.right - (x - ox);
bi.text=ttext; bi.text = ttext;
bi.id=id; bi.id = id;
bi.callBack=cb; bi.callBack = cb;
bi.AbsPos=AbsPos; bi.AbsPos = AbsPos;
bi.originalState = Checked; bi.originalState = Checked;
bi.isEdit(true); bi.isEdit(true);
BI.push_back(bi); BI.push_back(bi);
@ -1514,14 +1544,15 @@ InputInfo &gdioutput::addInputBox(const string &id, int width, int height, const
return addInputBox(id, CurrentX, CurrentY, width, height, text, cb, explanation); return addInputBox(id, CurrentX, CurrentY, width, height, text, cb, explanation);
} }
InputInfo &gdioutput::addInputBox(const string &id, int x, int y, int width, int height, InputInfo &gdioutput::addInputBox(const string &id, int x, int y, int widthIn, int heightIn,
const wstring &text, GUICALLBACK cb, const wstring &Explanation) const wstring &text, GUICALLBACK cb, const wstring &explanation)
{ {
if (Explanation.length()>0) { if (explanation.length()>0) {
addString("", y, x, 0, Explanation); addString("", y, x, 0, explanation);
y+=lineHeight; y+=lineHeight;
} }
int width = scaleLength(widthIn);
int height = scaleLength(heightIn);
InputInfo ii; InputInfo ii;
int ox=OffsetX; int ox=OffsetX;
@ -1532,7 +1563,7 @@ InputInfo &gdioutput::addInputBox(const string &id, int x, int y, int width, int
x-ox, y-oy, width, height, hWndTarget, NULL, x-ox, y-oy, width, height, hWndTarget, NULL,
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL); (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
updatePos(x, y, width, height); updatePos(x, y, width, height + scaleLength(5));
SendMessage(ii.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0); SendMessage(ii.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0);
@ -1545,13 +1576,10 @@ InputInfo &gdioutput::addInputBox(const string &id, int x, int y, int width, int
ii.focusText = text; ii.focusText = text;
ii.id=id; ii.id=id;
ii.callBack=cb; ii.callBack=cb;
II.push_back(ii); II.push_back(ii);
iiByHwnd[ii.hWnd] = &II.back(); iiByHwnd[ii.hWnd] = &II.back();
//if (Help.length() > 0)
// addToolTip(Help, ii.hWnd);
FocusList.push_back(ii.hWnd); FocusList.push_back(ii.hWnd);
return II.back(); return II.back();
} }
@ -1775,8 +1803,7 @@ ListBoxInfo &gdioutput::addCombo(int x, int y, const string &id, int width, int
return LBI.back(); return LBI.back();
} }
bool gdioutput::addItem(const string &id, const wstring &text, size_t data) bool gdioutput::addItem(const string &id, const wstring &text, size_t data) {
{
list<ListBoxInfo>::reverse_iterator it; list<ListBoxInfo>::reverse_iterator it;
for (it=LBI.rbegin(); it != LBI.rend(); ++it) { for (it=LBI.rbegin(); it != LBI.rend(); ++it) {
if (it->id==id) { if (it->id==id) {
@ -1784,11 +1811,13 @@ bool gdioutput::addItem(const string &id, const wstring &text, size_t data)
LRESULT index=SendMessage(it->hWnd, CB_ADDSTRING, 0, LPARAM(text.c_str())); LRESULT index=SendMessage(it->hWnd, CB_ADDSTRING, 0, LPARAM(text.c_str()));
SendMessage(it->hWnd, CB_SETITEMDATA, index, data); SendMessage(it->hWnd, CB_SETITEMDATA, index, data);
it->data2Index[data] = int(index); it->data2Index[data] = int(index);
it->computed_hash = 0;
} }
else { else {
LRESULT index=SendMessage(it->hWnd, LB_INSERTSTRING, -1, LPARAM(text.c_str())); LRESULT index=SendMessage(it->hWnd, LB_INSERTSTRING, -1, LPARAM(text.c_str()));
SendMessage(it->hWnd, LB_SETITEMDATA, index, data); SendMessage(it->hWnd, LB_SETITEMDATA, index, data);
it->data2Index[data] = int(index); it->data2Index[data] = int(index);
it->computed_hash = 0;
} }
return true; return true;
} }
@ -1796,39 +1825,67 @@ bool gdioutput::addItem(const string &id, const wstring &text, size_t data)
return false; return false;
} }
bool gdioutput::addItem(const string& id, const vector< pair<wstring, size_t> >& items) bool gdioutput::modifyItemDescription(const string& id, size_t itemData, const wstring &description) {
{ for (auto it = LBI.rbegin(); it != LBI.rend(); ++it) {
list<ListBoxInfo>::reverse_iterator it;
for (it = LBI.rbegin(); it != LBI.rend(); ++it) {
if (it->id == id) { if (it->id == id) {
int ix = it->data2Index[itemData];
// It is intentioal that the hash is not modified. This method allows "customization" of
// some description without reloading a complete listbox
if (it->IsCombo) { if (it->IsCombo) {
SendMessage(it->hWnd, CB_RESETCONTENT, 0, 0); SendMessage(it->hWnd, CB_DELETESTRING, ix, 0);
SendMessage(it->hWnd, CB_INITSTORAGE, items.size(), 48); SendMessage(it->hWnd, CB_INSERTSTRING, ix, LPARAM(description.c_str()));
SendMessage(it->hWnd, WM_SETREDRAW, FALSE, 0); SendMessage(it->hWnd, CB_SETITEMDATA, ix, itemData);
it->data2Index.clear();
for (size_t k = 0; k < items.size(); k++) {
LRESULT index = SendMessage(it->hWnd, CB_ADDSTRING, 0, LPARAM(items[k].first.c_str()));
SendMessage(it->hWnd, CB_SETITEMDATA, index, items[k].second);
it->data2Index[items[k].second] = int(index);
}
SendMessage(it->hWnd, WM_SETREDRAW, TRUE, 0);
RedrawWindow(it->hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
} }
else { else {
SendMessage(it->hWnd, LB_RESETCONTENT, 0, 0); SendMessage(it->hWnd, LB_DELETESTRING, ix, 0);
SendMessage(it->hWnd, LB_INITSTORAGE, items.size(), 48); SendMessage(it->hWnd, LB_INSERTSTRING, ix, LPARAM(description.c_str()));
SendMessage(it->hWnd, WM_SETREDRAW, FALSE, 0); SendMessage(it->hWnd, LB_SETITEMDATA, ix, itemData);
}
return true;
}
}
it->data2Index.clear(); return false;
for (size_t k = 0; k < items.size(); k++) { }
LRESULT index = SendMessage(it->hWnd, LB_INSERTSTRING, -1, LPARAM(items[k].first.c_str()));
SendMessage(it->hWnd, LB_SETITEMDATA, index, items[k].second); bool gdioutput::setItems(const string& id, const vector<pair<wstring, size_t>>& items) {
it->data2Index[items[k].second] = int(index); auto hash = ListBoxInfo::computeItemHash(items);
for (auto it = LBI.rbegin(); it != LBI.rend(); ++it) {
if (it->id == id) {
if (it->IsCombo) {
if (it->computed_hash == 0 || it->computed_hash != hash) {
SendMessage(it->hWnd, CB_RESETCONTENT, 0, 0);
SendMessage(it->hWnd, CB_INITSTORAGE, items.size(), 48);
SendMessage(it->hWnd, WM_SETREDRAW, FALSE, 0);
it->data2Index.clear();
for (size_t k = 0; k < items.size(); k++) {
LRESULT index = SendMessage(it->hWnd, CB_ADDSTRING, 0, LPARAM(items[k].first.c_str()));
SendMessage(it->hWnd, CB_SETITEMDATA, index, items[k].second);
it->data2Index[items[k].second] = int(index);
}
SendMessage(it->hWnd, WM_SETREDRAW, TRUE, 0);
RedrawWindow(it->hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
it->computed_hash = hash;
} }
}
else {
if (it->computed_hash == 0 || it->computed_hash != hash) {
SendMessage(it->hWnd, LB_RESETCONTENT, 0, 0);
SendMessage(it->hWnd, LB_INITSTORAGE, items.size(), 48);
SendMessage(it->hWnd, WM_SETREDRAW, FALSE, 0);
SendMessage(it->hWnd, WM_SETREDRAW, TRUE, 0); it->data2Index.clear();
RedrawWindow(it->hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); for (size_t k = 0; k < items.size(); k++) {
LRESULT index = SendMessage(it->hWnd, LB_INSERTSTRING, -1, LPARAM(items[k].first.c_str()));
SendMessage(it->hWnd, LB_SETITEMDATA, index, items[k].second);
it->data2Index[items[k].second] = int(index);
}
SendMessage(it->hWnd, WM_SETREDRAW, TRUE, 0);
RedrawWindow(it->hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
it->computed_hash = hash;
}
} }
return true; return true;
} }
@ -1843,6 +1900,7 @@ void gdioutput::filterOnData(const string &id, const unordered_set<int> &filter)
if (it->IsCombo) { if (it->IsCombo) {
} }
else { else {
it->computed_hash = 0;
const HWND &hWnd = it->hWnd; const HWND &hWnd = it->hWnd;
LRESULT count = SendMessage(hWnd, LB_GETCOUNT, 0, 0); LRESULT count = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (intptr_t ix = count - 1; ix>=0; ix--) { for (intptr_t ix = count - 1; ix>=0; ix--) {
@ -1857,17 +1915,18 @@ void gdioutput::filterOnData(const string &id, const unordered_set<int> &filter)
assert(false); assert(false);
} }
bool gdioutput::clearList(const string &id) bool gdioutput::clearList(const string& id) {
{ for (auto it = LBI.begin(); it != LBI.end(); ++it) {
list<ListBoxInfo>::iterator it; if (it->id == id) {
for(it=LBI.begin(); it != LBI.end(); ++it){
if (it->id==id) {
it->original = L""; it->original = L"";
it->originalIdx = -1; it->originalIdx = -1;
it->computed_hash = 0;
it->data2Index.clear();
if (it->IsCombo) if (it->IsCombo)
SendMessage(it->hWnd, CB_RESETCONTENT , 0, 0); SendMessage(it->hWnd, CB_RESETCONTENT, 0, 0);
else else
SendMessage(it->hWnd, LB_RESETCONTENT , 0, 0); SendMessage(it->hWnd, LB_RESETCONTENT, 0, 0);
return true; return true;
} }
} }
@ -1908,6 +1967,17 @@ void ListBoxInfo::copyUserData(ListBoxInfo &dest) const {
dest.IsCombo = IsCombo; dest.IsCombo = IsCombo;
} }
uint64_t ListBoxInfo::computeItemHash(const vector<pair<wstring, size_t>>& items) {
uint64_t res = 1;
for (auto& it : items) {
res = res * 997 + it.second;
for (auto ch : it.first)
res = res * 2003 + ch;
}
return res;
}
bool gdioutput::getSelectedItem(ListBoxInfo &lbi) { bool gdioutput::getSelectedItem(ListBoxInfo &lbi) {
if (lbi.IsCombo) { if (lbi.IsCombo) {
LRESULT index=SendMessage(lbi.hWnd, CB_GETCURSEL, 0, 0); LRESULT index=SendMessage(lbi.hWnd, CB_GETCURSEL, 0, 0);
@ -2240,7 +2310,7 @@ void gdioutput::processButtonMessage(ButtonInfo &bi, WPARAM wParam)
if (bi.isCheckbox) if (bi.isCheckbox)
bi.checked = SendMessage(bi.hWnd, BM_GETCHECK, 0, 0)==BST_CHECKED; bi.checked = SendMessage(bi.hWnd, BM_GETCHECK, 0, 0)==BST_CHECKED;
bi.synchData(); bi.synchData();
if (bi.callBack || bi.handler) { if (bi.callBack || bi.hasEventHandler()) {
setWaitCursor(true); setWaitCursor(true);
if (!bi.handleEvent(*this, GUI_BUTTON) && bi.callBack) if (!bi.handleEvent(*this, GUI_BUTTON) && bi.callBack)
bi.callBack(this, GUI_BUTTON, &bi); //it may be destroyed here... bi.callBack(this, GUI_BUTTON, &bi); //it may be destroyed here...
@ -3027,10 +3097,8 @@ void gdioutput::doEnter() {
HWND hWnd=GetFocus(); HWND hWnd=GetFocus();
for (list<ButtonInfo>::iterator it=BI.begin(); it!=BI.end(); ++it) for (list<ButtonInfo>::iterator it=BI.begin(); it!=BI.end(); ++it)
if (it->isDefaultButton() && (it->callBack || it->handler)) { if (it->isDefaultButton()) {
if (it->handler) if (!it->handleEvent(*this, GUI_BUTTON) && it->callBack)
it->handleEvent(*this, GUI_BUTTON);
else
it->callBack(this, GUI_BUTTON, &*it); it->callBack(this, GUI_BUTTON, &*it);
return; return;
} }
@ -3038,13 +3106,11 @@ void gdioutput::doEnter() {
list<InputInfo>::iterator it; list<InputInfo>::iterator it;
for(it=II.begin(); it != II.end(); ++it) for(it=II.begin(); it != II.end(); ++it)
if (it->hWnd==hWnd && (it->callBack || it->handler)){ if (it->hWnd==hWnd && (it->hasEventHandler() || it->callBack)){
TCHAR bf[1024]; TCHAR bf[1024];
GetWindowText(hWnd, bf, 1024); GetWindowText(hWnd, bf, 1024);
it->text=bf; it->text = bf;
if (it->handler) if (!it->handleEvent(*this, GUI_INPUT))
it->handleEvent(*this, GUI_INPUT);
else
it->callBack(this, GUI_INPUT, &*it); it->callBack(this, GUI_INPUT, &*it);
return; return;
} }
@ -3139,10 +3205,8 @@ void gdioutput::doEscape()
tit->table->escape(*this); tit->table->escape(*this);
for (list<ButtonInfo>::iterator it=BI.begin(); it!=BI.end(); ++it) { for (list<ButtonInfo>::iterator it=BI.begin(); it!=BI.end(); ++it) {
if (it->isCancelButton() && (it->callBack || it->handler) ) { if (it->isCancelButton() && (it->callBack || it->hasEventHandler()) ) {
if (it->handler) if (!it->handleEvent(*this, GUI_BUTTON))
it->handleEvent(*this, GUI_BUTTON);
else
it->callBack(this, GUI_BUTTON, &*it); it->callBack(this, GUI_BUTTON, &*it);
return; return;
} }
@ -3263,7 +3327,7 @@ void gdioutput::clearPage(bool autoRefresh, bool keepToolbar) {
try { try {
if (postClear) if (postClear)
postClear(this, GUI_POSTCLEAR, 0); postClear->makeEvent(*this, GUI_POSTCLEAR);
} }
catch (const meosCancel&) { catch (const meosCancel&) {
} }
@ -3458,7 +3522,7 @@ BaseInfo *gdioutput::setTextZeroBlank(const char *id, int number, bool Update)
} }
BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool Update, int requireExtraMatch) BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool update, int requireExtraMatch, bool updateOriginal)
{ {
for (auto it = II.begin(); it != II.end(); ++it) { for (auto it = II.begin(); it != II.end(); ++it) {
if (it->id == id && it->matchExtra(requireExtraMatch)) { if (it->id == id && it->matchExtra(requireExtraMatch)) {
@ -3468,7 +3532,8 @@ BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool Update, i
it->writeLock = oldWR; it->writeLock = oldWR;
it->text = text; it->text = text;
it->synchData(); it->synchData();
it->original = text; if (updateOriginal)
it->original = text;
it->focusText = text; it->focusText = text;
return &*it; return &*it;
} }
@ -3478,7 +3543,8 @@ BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool Update, i
if (it->id == id && it->IsCombo && it->matchExtra(requireExtraMatch)) { if (it->id == id && it->IsCombo && it->matchExtra(requireExtraMatch)) {
SetWindowText(it->hWnd, text.c_str()); SetWindowText(it->hWnd, text.c_str());
it->text = text; it->text = text;
it->original = text; if (updateOriginal)
it->original = text;
return &*it; return &*it;
} }
} }
@ -3503,7 +3569,7 @@ BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool Update, i
bool changed = updatePos(0, 0, it->textRect.right, it->textRect.bottom); bool changed = updatePos(0, 0, it->textRect.right, it->textRect.bottom);
if (Update && hWndTarget) { if (update && hWndTarget) {
if (changed) if (changed)
InvalidateRect(hWndTarget, 0, true); InvalidateRect(hWndTarget, 0, true);
else else
@ -3512,20 +3578,20 @@ BaseInfo *gdioutput::setText(const char *id, const wstring &text, bool Update, i
return &*it; return &*it;
} }
} }
return 0; return nullptr;
} }
bool gdioutput::insertText(const string &id, const wstring &text) bool gdioutput::insertText(const string &id, const wstring &text)
{ {
for (list<InputInfo>::iterator it=II.begin(); for (list<InputInfo>::iterator it = II.begin();
it != II.end(); ++it) { it != II.end(); ++it) {
if (it->id==id) { if (it->id == id) {
SetWindowText(it->hWnd, text.c_str()); SetWindowText(it->hWnd, text.c_str());
it->text = text; it->text = text;
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_INPUT); it->handleEvent(*this, GUI_INPUT);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_INPUT, &*it); it->callBack(this, GUI_INPUT, &*it);
return true; return true;
@ -3651,7 +3717,6 @@ bool gdioutput::updatePosTight(int x, int y, int width, int height, int marginx,
bool gdioutput::updatePos(int x, int y, int width, int height) { bool gdioutput::updatePos(int x, int y, int width, int height) {
return updatePosTight(x, y, width, height, 0, 0); return updatePosTight(x, y, width, height, 0, 0);
} }
void gdioutput::adjustDimension(int width, int height) void gdioutput::adjustDimension(int width, int height)
@ -4385,9 +4450,6 @@ void gdioutput::RenderString(TextInfo &ti, HDC hDC) {
h = ti.textRect.bottom - ti.textRect.top; h = ti.textRect.bottom - ti.textRect.top;
image.drawImage(imgId, Image::ImageMethod::Default, hDC, rc.left, rc.top, w, h); image.drawImage(imgId, Image::ImageMethod::Default, hDC, rc.left, rc.top, w, h);
//width = image.getWidth(imgId);
//height = image.getHeight(imgId);
} }
} }
if (!fixedRect) { if (!fixedRect) {
@ -4450,7 +4512,7 @@ void gdioutput::RenderString(TextInfo &ti, HDC hDC) {
memset(&rc, 0, sizeof(rc)); memset(&rc, 0, sizeof(rc));
int width = scaleLength( (breakLines&ti.format) ? ti.xlimit : 450 ); int width = scaleLength( (breakLines&ti.format) ? ti.xlimit : 450 );
rc.right = width; rc.right = width;
int dx = (breakLines&ti.format) ? 0 : scaleLength(20); int dx = format != 10 ? 0 : scaleLength(20);
ti.realWidth = width + dx; ti.realWidth = width + dx;
DrawText(hDC, ti.text.c_str(), ti.text.length(), &rc, DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK); DrawText(hDC, ti.text.c_str(), ti.text.length(), &rc, DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
ti.textRect=rc; ti.textRect=rc;
@ -4459,7 +4521,7 @@ void gdioutput::RenderString(TextInfo &ti, HDC hDC) {
ti.textRect.top+=ti.yp; ti.textRect.top+=ti.yp;
ti.textRect.bottom+=ti.yp+dx; ti.textRect.bottom+=ti.yp+dx;
if (ti.format == 10) { if (format == 10) {
DWORD c = colorLightYellow;// GetSysColor(COLOR_INFOBK); DWORD c = colorLightYellow;// GetSysColor(COLOR_INFOBK);
double red=GetRValue(c); double red=GetRValue(c);
double green=GetGValue(c); double green=GetGValue(c);
@ -4715,7 +4777,7 @@ void gdioutput::calcStringSize(TextInfo &ti, HDC hDC_in) const {
else { else {
memset(&rc, 0, sizeof(rc)); memset(&rc, 0, sizeof(rc));
rc.right = scaleLength( (breakLines&ti.format) ? ti.xlimit : 450 ); rc.right = scaleLength( (breakLines&ti.format) ? ti.xlimit : 450 );
int dx = (breakLines&ti.format) ? 0 : scaleLength(20); int dx = format != 10 ? 0 : scaleLength(20);
ti.realWidth = rc.right + dx; ti.realWidth = rc.right + dx;
DrawText(hDC, ti.text.c_str(), ti.text.length(), &rc, DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK); DrawText(hDC, ti.text.c_str(), ti.text.length(), &rc, DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
ti.textRect=rc; ti.textRect=rc;
@ -4937,12 +4999,14 @@ wstring gdioutput::getTimerText(int zeroTime, int format, bool timeInSeconds) {
wstring gdioutput::getTimerText(TextInfo *tit, DWORD T) wstring gdioutput::getTimerText(TextInfo *tit, DWORD T)
{ {
int rt=(int(T)-int(tit->zeroTime))/1000; int rt = (int(T) - int(tit->zeroTime)) / 1000;
int tenth = (abs(int(T)-int(tit->zeroTime))/100)%10; int tenth = (abs(int(T) - int(tit->zeroTime)) / 100) % 10;
wstring text; wstring text;
int t=abs(rt); int t=abs(rt);
wchar_t bf[16]; wchar_t bf[16];
if ((tit->format & time24HourClock) != 0 && t > 0)
t = t % (24 * timeConstSecPerHour);
if (tit->format & timeSeconds) { if (tit->format & timeSeconds) {
if (tit->format & timeWithTenth) if (tit->format & timeWithTenth)
@ -5431,30 +5495,75 @@ void gdioutput::restoreInternal(const RestoreInfo &ri)
} }
} }
void gdioutput::restore(const string &id, bool DoRefresh) void gdioutput::restore(const string &restorePointId, bool doRefresh) {
{ auto rp = restorePoints.find(restorePointId);
if (restorePoints.count(id)==0) if (rp == restorePoints.end())
return; return;
const RestoreInfo& ri = rp->second;
const RestoreInfo &ri=restorePoints[id];
restoreInternal(ri); restoreInternal(ri);
MaxX=ri.sMX; MaxX=ri.sMX;
MaxY=ri.sMY; MaxY=ri.sMY;
if (DoRefresh) if (doRefresh)
refresh(); refresh();
setOffset(ri.sOY, ri.sOY, false); setOffset(ri.sOY, ri.sOY, false);
} }
void gdioutput::restoreNoUpdate(const string &id) RECT gdioutput::getDimensionSince(const string& restorePointId) const {
{ auto rp = restorePoints.find(restorePointId);
if (restorePoints.count(id)==0) if (rp == restorePoints.end())
throw meosException("Internal error: " + restorePointId);
const RestoreInfo& ri = rp->second;
RECT out = {numeric_limits<int>::max(), numeric_limits<int>::max(), 0, 0};
auto grow = [&out](int x, int y, int w, int h) {
out.left = min<int>(out.left, x);
out.right = max<int>(out.right, x + w);
out.top = min<int>(out.top, y);
out.bottom = max<int>(out.bottom, y + h);
};
int lbiRemove = LBI.size() - ri.nLBI;
for (auto it = LBI.rbegin(); lbiRemove > 0; lbiRemove--, ++it) {
grow(it->getX(), it->getY(), it->getWidth(), it->getHeight());
}
int tlRemove = TL.size() - ri.nTL;
for (auto it = TL.rbegin(); tlRemove > 0; tlRemove--, ++it) {
grow(it->getX(), it->getY(), it->getWidth(), it->getHeight());
}
int biRemove = BI.size() - ri.nBI;
for (auto it = BI.rbegin(); biRemove > 0; biRemove--, ++it) {
int w, h;
it->getDimension(*this, w, h);
grow(it->getX(), it->getY(), w, h);
}
int iiRemove = II.size() - ri.nII;
for (auto it = II.rbegin(); iiRemove > 0; iiRemove--, ++it) {
grow(it->getX(), it->getY(), it->getWidth(), it->getHeight());
}
int rectRemove = Rectangles.size() - ri.nRect;
for (auto it = Rectangles.rbegin(); rectRemove > 0; rectRemove--, ++it) {
auto& rc = it->getRect();
grow(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
return out;
}
void gdioutput::restoreNoUpdate(const string &restorePointId) {
auto rp = restorePoints.find(restorePointId);
if (rp == restorePoints.end())
return; return;
const RestoreInfo &ri=restorePoints[id]; const RestoreInfo& ri = rp->second;
MaxX=ri.sMX; MaxX=ri.sMX;
MaxY=ri.sMY; MaxY=ri.sMY;
@ -5462,24 +5571,13 @@ void gdioutput::restoreNoUpdate(const string &id)
restoreInternal(ri); restoreInternal(ri);
} }
void gdioutput::setPostClearCb(GUICALLBACK cb)
{
postClear=cb;
}
void gdioutput::setOnClearCb(GUICALLBACK cb)
{
onClear=cb;
}
bool gdioutput::canClear() bool gdioutput::canClear()
{ {
if (!onClear) if (!onClear)
return true; return true;
try { try {
return onClear(this, GUI_CLEAR, 0)!=0; return onClear->makeEvent(*this, GUI_CLEAR)!=0;
} }
catch (const meosCancel&) { catch (const meosCancel&) {
return false; return false;
@ -5503,7 +5601,7 @@ int gdioutput::sendCtrlMessage(const string &id)
{ {
for (list<ButtonInfo>::iterator it=BI.begin(); it != BI.end(); ++it) { for (list<ButtonInfo>::iterator it=BI.begin(); it != BI.end(); ++it) {
if (id==it->id) { if (id==it->id) {
if (it->handler) if (it->hasEventHandler())
return it->handleEvent(*this, GUI_BUTTON); return it->handleEvent(*this, GUI_BUTTON);
else if (it->callBack) else if (it->callBack)
return it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here... return it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here...
@ -6065,6 +6163,7 @@ ToolInfo &gdioutput::updateToolTip(const string &id, const wstring &tip) {
for (ToolList::reverse_iterator it = toolTips.rbegin(); it != toolTips.rend(); ++it) { for (ToolList::reverse_iterator it = toolTips.rbegin(); it != toolTips.rend(); ++it) {
if (it->name == id && hWndToolTip) { if (it->name == id && hWndToolTip) {
it->tip = lang.tl(tip); it->tip = lang.tl(tip);
it->ti.lpszText = (LPWSTR)it->tip.c_str();
SendMessage(hWndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM) &it->ti); SendMessage(hWndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM) &it->ti);
return *it; return *it;
} }
@ -6100,11 +6199,10 @@ Table &gdioutput::getTable() const {
return *const_cast<Table *>(Tables.back().table.get()); return *const_cast<Table *>(Tables.back().table.get());
} }
static int gdiTableCB(gdioutput *gdi, int type, void *data) static int gdiTableCB(gdioutput *gdi, GuiEventType type, BaseInfo *data)
{ {
if (type == GUI_BUTTON) { if (type == GUI_BUTTON) {
ButtonInfo bi = *static_cast<ButtonInfo *>(data); ButtonInfo bi = *static_cast<ButtonInfo *>(data);
//gdi->tableCB(bi, static_cast<Table *>(bi.getExtra()));
gdi->tableCB(bi, &gdi->getTable()); gdi->tableCB(bi, &gdi->getTable());
} }
return 0; return 0;
@ -6112,8 +6210,6 @@ static int gdiTableCB(gdioutput *gdi, int type, void *data)
void gdioutput::tableCB(ButtonInfo &bu, Table *t) void gdioutput::tableCB(ButtonInfo &bu, Table *t)
{ {
#ifndef MEOSDB
if (bu.id=="tblPrint") { if (bu.id=="tblPrint") {
t->keyCommand(*this, KC_PRINT); t->keyCommand(*this, KC_PRINT);
} }
@ -6212,8 +6308,6 @@ void gdioutput::tableCB(ButtonInfo &bu, Table *t)
else if (bu.id == "tblInsert") { else if (bu.id == "tblInsert") {
t->keyCommand(*this, KC_INSERT); t->keyCommand(*this, KC_INSERT);
} }
#endif
} }
void gdioutput::enableTables() void gdioutput::enableTables()
@ -7084,7 +7178,7 @@ void gdioutput::copyToClipboard(const string &html, const wstring &txt) const {
} }
else { else {
// HTML table to text // HTML table to text
ostringstream result; std::ostringstream result;
bool started = false; bool started = false;
bool newline = false; bool newline = false;
bool dowrite = false; bool dowrite = false;
@ -7201,11 +7295,11 @@ string gdioutput::dbPress(const string &id, int extra) {
if (it->isCheckbox) { if (it->isCheckbox) {
check(id, !isChecked(id)); check(id, !isChecked(id));
} }
else if(!it->callBack && !it->handler) else if(!it->callBack && !it->hasEventHandler())
throw meosException("Button " + id + " is not active."); throw meosException("Button " + id + " is not active.");
wstring val = it->text; wstring val = it->text;
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_BUTTON); it->handleEvent(*this, GUI_BUTTON);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here... it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here...
@ -7229,11 +7323,11 @@ string gdioutput::dbPress(const string &id, const char *extra) {
if (it->isCheckbox) { if (it->isCheckbox) {
check(id, !isChecked(id)); check(id, !isChecked(id));
} }
else if(!it->callBack && !it->handler) else if(!it->callBack && !it->hasEventHandler())
throw meosException("Button " + id + " is not active."); throw meosException("Button " + id + " is not active.");
wstring val = it->text; wstring val = it->text;
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_BUTTON); it->handleEvent(*this, GUI_BUTTON);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here... it->callBack(this, GUI_BUTTON, &*it); //it may be destroyed here...
@ -7272,12 +7366,12 @@ string gdioutput::dbSelect(const string &id, int data) {
void gdioutput::internalSelect(ListBoxInfo &bi) { void gdioutput::internalSelect(ListBoxInfo &bi) {
bi.syncData(); bi.syncData();
if (bi.callBack || bi.handler) { if (bi.callBack || bi.handler || bi.managedHandler) {
setWaitCursor(true); setWaitCursor(true);
hasCleared = false; hasCleared = false;
try { try {
bi.writeLock = true; bi.writeLock = true;
if (bi.handler) if (bi.hasEventHandler())
bi.handleEvent(*this, GUI_LISTBOX); bi.handleEvent(*this, GUI_LISTBOX);
else else
bi.callBack(this, GUI_LISTBOX, &bi); //it may be destroyed here... Then hasCleared is set. bi.callBack(this, GUI_LISTBOX, &bi); //it may be destroyed here... Then hasCleared is set.
@ -7304,7 +7398,7 @@ void gdioutput::dbInput(const string &id, const string &text) {
SetWindowText(it->hWnd, widen(text).c_str()); SetWindowText(it->hWnd, widen(text).c_str());
it->text = widen(text); it->text = widen(text);
it->data = -1; it->data = -1;
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_COMBO); it->handleEvent(*this, GUI_COMBO);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_COMBO, &*it); //it may be destroyed here... it->callBack(this, GUI_COMBO, &*it); //it may be destroyed here...
@ -7319,7 +7413,7 @@ void gdioutput::dbInput(const string &id, const string &text) {
it->text = widen(text); it->text = widen(text);
SetWindowText(it->hWnd, widen(text).c_str()); SetWindowText(it->hWnd, widen(text).c_str());
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_INPUT); it->handleEvent(*this, GUI_INPUT);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_INPUT, &*it); it->callBack(this, GUI_INPUT, &*it);
@ -7357,7 +7451,7 @@ void gdioutput::dbDblClick(const string &id, int data) {
if (!IsWindowEnabled(it->hWnd)) if (!IsWindowEnabled(it->hWnd))
throw meosException("Selection " + id + " is not active."); throw meosException("Selection " + id + " is not active.");
selectItemByData(id, data); selectItemByData(id, data);
if (it->handler) if (it->hasEventHandler())
it->handleEvent(*this, GUI_LISTBOXSELECT); it->handleEvent(*this, GUI_LISTBOXSELECT);
else if (it->callBack) else if (it->callBack)
it->callBack(this, GUI_LISTBOXSELECT, &*it); //it may be destroyed here... it->callBack(this, GUI_LISTBOXSELECT, &*it); //it may be destroyed here...

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,25 +24,14 @@
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#if !defined(AFX_GDIOUTPUT_H__396F60F8_679F_498A_B759_DF8F6F346A4A__INCLUDED_)
#define AFX_GDIOUTPUT_H__396F60F8_679F_498A_B759_DF8F6F346A4A__INCLUDED_
#if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000
#include <set> #include <set>
#include <map> #include <map>
#include <vector> #include <vector>
#ifdef OLD
#include <hash_set>
#include <hash_map>
#else
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#endif
#include <algorithm> #include <algorithm>
#include "subcommand.h" #include "subcommand.h"
@ -65,8 +54,6 @@ struct PageInfo;
struct RenderedPage; struct RenderedPage;
class AnimationData; class AnimationData;
typedef int (*GUICALLBACK)(gdioutput *gdi, int type, void *data);
enum GDICOLOR; enum GDICOLOR;
enum KeyCommandCode; enum KeyCommandCode;
enum gdiFonts; enum gdiFonts;
@ -81,13 +68,7 @@ constexpr int baseButtonWidth = 150;
constexpr int GDI_BUTTON_SPACING = 8; constexpr int GDI_BUTTON_SPACING = 8;
typedef list<ToolInfo> ToolList; typedef list<ToolInfo> ToolList;
/*
enum FontEncoding {
ANSI, Russian, EastEurope, Hebrew
};*/
/*
FontEncoding interpetEncoding(const string &enc);
*/
struct FontInfo { struct FontInfo {
const wstring *name; const wstring *name;
HFONT normal; HFONT normal;
@ -171,8 +152,8 @@ protected:
map<string, RestoreInfo> restorePoints; map<string, RestoreInfo> restorePoints;
GUICALLBACK onClear; shared_ptr<GuiEvent> onClear;
GUICALLBACK postClear; shared_ptr<GuiEvent> postClear;
list<InfoBox> IBox; list<InfoBox> IBox;
@ -365,8 +346,8 @@ public:
static const string& toUTF8(const wstring& input); static const string& toUTF8(const wstring& input);
static const wstring& fromUTF8(const string& input); static const wstring& fromUTF8(const string& input);
//void setEncoding(FontEncoding encoding);
//FontEncoding getEncoding() const; void updateTabFont();
void getFontInfo(const TextInfo& ti, FontInfo& fi) const; void getFontInfo(const TextInfo& ti, FontInfo& fi) const;
@ -487,14 +468,32 @@ public:
int sendCtrlMessage(const string& id); int sendCtrlMessage(const string& id);
bool canClear(); bool canClear();
void setOnClearCb(GUICALLBACK cb);
void setPostClearCb(GUICALLBACK cb); template<typename H>
void setPostClearCb(H cb) {
postClear = make_shared<GuiEvent>(cb);
}
void restore(const string& id = "", bool DoRefresh = true); template<typename H>
void setOnClearCb(H cb) {
onClear = make_shared<GuiEvent>(cb);
}
void clearPostClearCb() {
postClear.reset();
}
void clearOnClearCb() {
onClear.reset();
}
void restore(const string& restorePointId = "", bool doRefresh = true);
/// Restore, but do not update client area size, /// Restore, but do not update client area size,
/// position, zoom, scrollbars, and do not refresh /// position, zoom, scrollbars, and do not refresh
void restoreNoUpdate(const string& id); void restoreNoUpdate(const string& restorePointId);
RECT getDimensionSince(const string& restorePointId) const;
void setRestorePoint(); void setRestorePoint();
void setRestorePoint(const string& id); void setRestorePoint(const string& id);
@ -644,7 +643,8 @@ public:
pair<int, bool> getSelectedItem(const char* id); pair<int, bool> getSelectedItem(const char* id);
bool addItem(const string& id, const wstring& text, size_t data = 0); bool addItem(const string& id, const wstring& text, size_t data = 0);
bool addItem(const string& id, const vector< pair<wstring, size_t> >& items); bool setItems(const string& id, const vector< pair<wstring, size_t> >& items);
bool modifyItemDescription(const string& id, size_t itemData, const wstring &description);
void filterOnData(const string& id, const unordered_set<int>& filter); void filterOnData(const string& id, const unordered_set<int>& filter);
@ -687,7 +687,7 @@ public:
BaseInfo* setTextTranslate(const string& id, const wstring& text, bool update = false); BaseInfo* setTextTranslate(const string& id, const wstring& text, bool update = false);
BaseInfo* setText(const char* id, const wstring& text, bool update = false, int requireExtraMatch = -1); BaseInfo* setText(const char* id, const wstring& text, bool update = false, int requireExtraMatch = -1, bool updateOriginal = true);
BaseInfo* setText(const wchar_t* id, const wstring& text, bool update = false) { BaseInfo* setText(const wchar_t* id, const wstring& text, bool update = false) {
return setText(narrow(id), text, update); return setText(narrow(id), text, update);
} }
@ -728,7 +728,13 @@ public:
GUICALLBACK cb = nullptr, const wstring& tooltop = L""); GUICALLBACK cb = nullptr, const wstring& tooltop = L"");
ButtonInfo& addButton(int x, int y, int w, const string& id, const wstring& text, ButtonInfo& addButton(int x, int y, int w, const string& id, const wstring& text,
GUICALLBACK cb, const wstring& tooltop, bool absPos, bool hasState); GUICALLBACK cb, const wstring& tooltip, bool absPos, bool hasState);
ButtonInfo& addButton(int x, int y, int width, int height,
const string& id, const wstring& text,
gdiFonts font, GUICALLBACK cb,
const wstring& tooltip,
bool absPos, bool hasState);
ButtonInfo& addCheckbox(const string& id, const wstring& text, GUICALLBACK cb = nullptr, ButtonInfo& addCheckbox(const string& id, const wstring& text, GUICALLBACK cb = nullptr,
bool Checked = true, const wstring& tooltip = L""); bool Checked = true, const wstring& tooltip = L"");
@ -838,4 +844,3 @@ public:
virtual ~gdioutput(); virtual ~gdioutput();
}; };
#endif // !defined(AFX_GDIOUTPUT_H__396F60F8_679F_498A_B759_DF8F6F346A4A__INCLUDED_)

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,15 +20,13 @@
************************************************************************/ ************************************************************************/
#ifndef GDI_STRUCTURES #pragma once
#define GDI_STRUCTURES
#include <cassert> #include <cassert>
#include "guihandler.h" #include "guihandler.h"
#include "gdifonts.h" #include "gdifonts.h"
class BaseInfo class BaseInfo {
{
protected: protected:
void *extra; void *extra;
GuiHandler *handler; GuiHandler *handler;
@ -88,8 +86,33 @@ public:
} }
}; };
class RestoreInfo : public BaseInfo class GuiEvent final : public BaseInfo {
{ GUICALLBACK callback = nullptr;
public:
bool makeEvent(gdioutput &gdi, GuiEventType type) {
if (callback)
return callback(&gdi, type, this) != 0;
else
return handleEvent(gdi, type);
return true;
}
GuiEvent(GUICALLBACK callback) : callback(callback) {}
GuiEvent(const shared_ptr<GuiHandler> &h) {
setHandler(h);
}
GuiEvent(const GuiHandler *h) {
setHandler(h);
}
HWND getControlWindow() const final { throw std::exception("Unsupported"); }
};
class RestoreInfo final : public BaseInfo {
public: public:
int nLBI; int nLBI;
int nBI; int nBI;
@ -109,8 +132,8 @@ public:
int nTooltip; int nTooltip;
int nTables; int nTables;
GUICALLBACK onClear; shared_ptr<GuiEvent> onClear;
GUICALLBACK postClear; shared_ptr<GuiEvent> postClear;
set<string> restorePoints; set<string> restorePoints;
@ -118,11 +141,10 @@ public:
return nLBI < r.nLBI || nBI < r.nBI || nII < r.nII || nTL < r.nTL || nRect < r.nRect || nData < r.nData; return nLBI < r.nLBI || nBI < r.nBI || nII < r.nII || nTL < r.nTL || nRect < r.nRect || nData < r.nData;
} }
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
}; };
class RectangleInfo : public BaseInfo class RectangleInfo final : public BaseInfo {
{
private: private:
DWORD color; DWORD color;
DWORD color2; DWORD color2;
@ -143,23 +165,20 @@ public:
RectangleInfo &changeDimension(gdioutput &gdi, int dx, int dy); RectangleInfo &changeDimension(gdioutput &gdi, int dx, int dy);
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
}; };
class TableInfo final: public BaseInfo {
class TableInfo : public BaseInfo
{
public: public:
TableInfo():xp(0), yp(0), table(0) {} TableInfo():xp(0), yp(0), table(0) {}
int xp; int xp;
int yp; int yp;
shared_ptr<Table> table; shared_ptr<Table> table;
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
}; };
class TextInfo final: public BaseInfo
class TextInfo : public BaseInfo
{ {
public: public:
@ -178,7 +197,11 @@ public:
bool isFormatInfo() const { return format == pageNewPage || format == pagePageInfo || format == pageNewChapter; } bool isFormatInfo() const { return format == pageNewPage || format == pagePageInfo || format == pageNewChapter; }
int getHeight() {return int(textRect.bottom-textRect.top);} int getHeight() const { return int(textRect.bottom - textRect.top); }
int getWidth() const { return realWidth; }
int getX() const { return xp; }
int getY() const { return yp; }
gdiFonts getGdiFont() const {return gdiFonts(format & 0xFF);} gdiFonts getGdiFont() const {return gdiFonts(format & 0xFF);}
// Sets absolute print coordinates in [mm] // Sets absolute print coordinates in [mm]
TextInfo &setAbsPrintPos(int x, int y) { TextInfo &setAbsPrintPos(int x, int y) {
@ -209,26 +232,25 @@ public:
bool active; bool active;
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
friend class gdioutput; friend class gdioutput;
}; };
class ButtonInfo : public BaseInfo class ButtonInfo final : public BaseInfo {
{
private: private:
bool originalState; bool originalState;
bool isEditControl; bool isEditControl;
bool checked; bool checked;
bool *updateLastData; bool* updateLastData;
void synchData() const {if (updateLastData) *updateLastData = checked;} void synchData() const { if (updateLastData) *updateLastData = checked; }
public:
ButtonInfo(): callBack(0), hWnd(0), AbsPos(false), fixedRightTop(false),
flags(0), storedFlags(0), originalState(false), isEditControl(false),
isCheckbox(false), checked(false), updateLastData(0) {}
ButtonInfo &isEdit(bool e) {isEditControl=e; return *this;} public:
ButtonInfo() : callBack(0), hWnd(0), AbsPos(false), fixedRightTop(false),
flags(0), storedFlags(0), originalState(false), isEditControl(false),
isCheckbox(false), checked(false), updateLastData(0) {}
ButtonInfo& isEdit(bool e) { isEditControl = e; return *this; }
int xp; int xp;
int yp; int yp;
@ -240,27 +262,28 @@ public:
int flags; int flags;
int storedFlags; int storedFlags;
bool isCheckbox; bool isCheckbox;
bool isDefaultButton() const {return (flags&1)==1;} bool isDefaultButton() const { return (flags & 1) == 1; }
bool isCancelButton() const {return (flags&2)==2;} bool isCancelButton() const { return (flags & 2) == 2; }
ButtonInfo &setSynchData(bool *variable) {updateLastData = variable; return *this;} ButtonInfo& setSynchData(bool* variable) { updateLastData = variable; return *this; }
int getX() const { return xp; }
int getY() const { return yp; }
void moveButton(gdioutput &gdi, int xp, int yp); void moveButton(gdioutput& gdi, int xp, int yp);
void getDimension(gdioutput &gdi, int &w, int &h); void getDimension(const gdioutput& gdi, int& w, int& h) const;
ButtonInfo &setDefault(); ButtonInfo& setDefault();
ButtonInfo &setCancel() {flags|=2, storedFlags|=2; return *this;} ButtonInfo& setCancel() { flags |= 2, storedFlags |= 2; return *this; }
ButtonInfo &fixedCorner() {fixedRightTop = true; return *this;} ButtonInfo& fixedCorner() { fixedRightTop = true; return *this; }
GUICALLBACK callBack; GUICALLBACK callBack;
friend class gdioutput; friend class gdioutput;
HWND getControlWindow() const {return hWnd;} HWND getControlWindow() const final { return hWnd; }
}; };
enum gdiFonts; enum gdiFonts;
class InputInfo : public BaseInfo class InputInfo final: public BaseInfo {
{
public: public:
InputInfo(); InputInfo();
wstring text; wstring text;
@ -278,13 +301,15 @@ public:
bool changedInput() const { return text != focusText; } bool changedInput() const { return text != focusText; }
InputInfo &setPassword(bool pwd); InputInfo &setPassword(bool pwd);
HWND getControlWindow() const {return hWnd;} HWND getControlWindow() const final {return hWnd;}
InputInfo &setSynchData(wstring *variable) {updateLastData = variable; return *this;} InputInfo &setSynchData(wstring *variable) {updateLastData = variable; return *this;}
int getX() const {return xp;} int getX() const {return xp;}
int getY() const {return yp;} int getY() const {return yp;}
int getWidth() const {return int(width);} int getWidth() const {return int(width);}
int getHeight() const { return int(height); }
private: private:
HWND hWnd; HWND hWnd;
GUICALLBACK callBack; GUICALLBACK callBack;
@ -305,37 +330,37 @@ private:
friend class gdioutput; friend class gdioutput;
}; };
class ListBoxInfo : public BaseInfo class ListBoxInfo final : public BaseInfo {
{
public: public:
ListBoxInfo() : hWnd(0), callBack(0), IsCombo(false), index(-1), ListBoxInfo() : hWnd(0), callBack(0), IsCombo(false), index(-1),
writeLock(false), ignoreCheck(false), isEditControl(true), writeLock(false), ignoreCheck(false), isEditControl(true),
originalProc(0), lbiSync(0), multipleSelection(false), originalProc(0), lbiSync(0), multipleSelection(false),
xp(0), yp(0), width(0), height(0), data(0), lastTabStop(0), xp(0), yp(0), width(0), height(0), data(0), lastTabStop(0),
updateLastData(0) {} updateLastData(0) {}
wstring text; wstring text;
size_t data; size_t data;
int getDataInt() const { return (int)data; } int getDataInt() const { return (int)data; }
int index; int index;
bool changed() const {return text!=original;} bool changed() const { return text != original; }
void ignore(bool ig) {ignoreCheck=ig;} void ignore(bool ig) { ignoreCheck = ig; }
ListBoxInfo &isEdit(bool e) {isEditControl=e; return *this;} ListBoxInfo& isEdit(bool e) { isEditControl = e; return *this; }
HWND getControlWindow() const {return hWnd;} HWND getControlWindow() const final { return hWnd; }
void copyUserData(ListBoxInfo &userLBI) const; void copyUserData(ListBoxInfo& userLBI) const;
ListBoxInfo &setSynchData(int *variable) {updateLastData = variable; return *this;} ListBoxInfo& setSynchData(int* variable) { updateLastData = variable; return *this; }
int getWidth() const {return int(width);} int getWidth() const { return int(width); }
int getX() const {return xp;} int getHeight() const { return int(height); }
int getY() const {return yp;} int getX() const { return xp; }
bool isCombo() const {return IsCombo;} int getY() const { return yp; }
bool isCombo() const { return IsCombo; }
private: private:
void syncData() const {if (updateLastData) *updateLastData = data;} void syncData() const { if (updateLastData) *updateLastData = data; }
bool IsCombo; bool IsCombo;
int *updateLastData; int* updateLastData;
GUICALLBACK callBack; GUICALLBACK callBack;
int xp; int xp;
int yp; int yp;
double width; double width;
@ -350,18 +375,20 @@ private:
size_t originalIdx; size_t originalIdx;
bool ignoreCheck; // True if changed-state should be ignored bool ignoreCheck; // True if changed-state should be ignored
map<size_t, int> data2Index; unordered_map<size_t, int> data2Index;
uint64_t computed_hash = 0;
static uint64_t computeItemHash(const vector<pair<wstring, size_t>>& items);
// Synchronize with other list box // Synchronize with other list box
WNDPROC originalProc; WNDPROC originalProc;
ListBoxInfo *lbiSync; ListBoxInfo* lbiSync;
friend LRESULT CALLBACK GetMsgProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); friend LRESULT CALLBACK GetMsgProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
friend class gdioutput; friend class gdioutput;
}; };
class DataStore class DataStore {
{
public: public:
DataStore() { DataStore() {
data = 0; data = 0;
@ -371,8 +398,7 @@ public:
string sdata; string sdata;
}; };
class EventInfo : public BaseInfo class EventInfo final: public BaseInfo {
{
private: private:
string origin; string origin;
DWORD data; DWORD data;
@ -386,17 +412,16 @@ public:
EventInfo(); EventInfo();
GUICALLBACK callBack; GUICALLBACK callBack;
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
}; };
class TimerInfo : public BaseInfo class TimerInfo final : public BaseInfo {
{
private: private:
static int globalTimerId; static int globalTimerId;
int timerId; int timerId;
DWORD dataInt; DWORD dataInt;
wstring dataString; wstring dataString;
gdioutput *parent; gdioutput* parent;
HWND setWnd; HWND setWnd;
public: public:
~TimerInfo(); ~TimerInfo();
@ -404,11 +429,11 @@ public:
TimerInfo(const TimerInfo&) = delete; TimerInfo(const TimerInfo&) = delete;
TimerInfo& operator=(const TimerInfo&) = delete; TimerInfo& operator=(const TimerInfo&) = delete;
int getId() const { return timerId; } int getId() const { return timerId; }
BaseInfo &setExtra(const wchar_t *e) {return BaseInfo::setExtra(e);} BaseInfo& setExtra(const wchar_t* e) { return BaseInfo::setExtra(e); }
BaseInfo &setExtra(int e) {return BaseInfo::setExtra(e);} BaseInfo& setExtra(int e) { return BaseInfo::setExtra(e); }
void setData(DWORD d, const wstring &s) {dataInt = d; dataString = s;} void setData(DWORD d, const wstring& s) { dataInt = d; dataString = s; }
const wstring &getDataString() { const wstring& getDataString() {
return dataString; return dataString;
} }
DWORD getData() { DWORD getData() {
@ -419,12 +444,10 @@ public:
friend class gdioutput; friend class gdioutput;
friend void CALLBACK gdiTimerProc(HWND hWnd, UINT a, UINT_PTR ptr, DWORD b); friend void CALLBACK gdiTimerProc(HWND hWnd, UINT a, UINT_PTR ptr, DWORD b);
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final { throw std::exception("Unsupported"); }
}; };
class InfoBox final: public BaseInfo {
class InfoBox : public BaseInfo
{
public: public:
InfoBox() : callBack(0), HasCapture(0), HasTCapture(0), TimeOut(0) {} InfoBox() : callBack(0), HasCapture(0), HasTCapture(0), TimeOut(0) {}
wstring text; wstring text;
@ -439,7 +462,7 @@ public:
DWORD TimeOut; DWORD TimeOut;
HWND getControlWindow() const {throw std::exception("Unsupported");} HWND getControlWindow() const final {throw std::exception("Unsupported");}
}; };
typedef list<TextInfo> TIList; typedef list<TextInfo> TIList;
@ -450,6 +473,3 @@ struct ToolInfo {
wstring tip; wstring tip;
uintptr_t id; uintptr_t id;
}; };
#endif

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -1007,6 +1007,12 @@ void DynamicResult::declareSymbols(DynamicMethods m, bool clear) const {
parser.declareSymbol("InputNumber", "User input number", false); parser.declareSymbol("InputNumber", "User input number", false);
parser.declareSymbol("Shorten", "Number of shortenings", false); parser.declareSymbol("Shorten", "Number of shortenings", false);
parser.declareSymbol("DataA", "Extra assigned data (A)", false);
parser.declareSymbol("DataB", "Extra assigned data (B)", false);
parser.declareSymbol("ClassDataA", "Extra assigned class data (A)", false);
parser.declareSymbol("ClassDataB", "Extra assigned class data (B)", false);
if (isRunner) { if (isRunner) {
parser.declareSymbol("CardPunches", "Runner's card, punch codes", true); parser.declareSymbol("CardPunches", "Runner's card, punch codes", true);
parser.declareSymbol("CardTimes", "Runner's card, punch times", true); parser.declareSymbol("CardTimes", "Runner's card, punch times", true);
@ -1040,6 +1046,9 @@ void DynamicResult::declareSymbols(DynamicMethods m, bool clear) const {
parser.declareSymbol("RunnerCardTimes", "Punch times for each team member", true, true); parser.declareSymbol("RunnerCardTimes", "Punch times for each team member", true, true);
parser.declareSymbol("RunnerCardControls", "Matched control ids (-1 for unmatched) for each team member", true, true); parser.declareSymbol("RunnerCardControls", "Matched control ids (-1 for unmatched) for each team member", true, true);
parser.declareSymbol("RunnerDataA", "Extra assigned data (A) for each team member", true);
parser.declareSymbol("RunnerDataB", "Extra assigned data (B) for each team member", true);
parser.declareSymbol("RunnerCourse", "Runner's course", true, true); parser.declareSymbol("RunnerCourse", "Runner's course", true, true);
parser.declareSymbol("RunnerSplitTimes", "Runner's split times", true, true); parser.declareSymbol("RunnerSplitTimes", "Runner's split times", true, true);
@ -1182,6 +1191,19 @@ void DynamicResult::prepareCommon(oAbstractRunner &runner, bool classResult) con
parser.addSymbol("InputPoints", runner.getInputPoints()); parser.addSymbol("InputPoints", runner.getInputPoints());
parser.addSymbol("Shorten", runner.getNumShortening()); parser.addSymbol("Shorten", runner.getNumShortening());
parser.addSymbol("DataA", runner.getDCI().getInt("DataA"));
parser.addSymbol("DataB", runner.getDCI().getInt("DataB"));
pClass cls = runner.getClassRef(true);
if (cls) {
parser.addSymbol("ClassDataA", cls->getDCI().getInt("DataA"));
parser.addSymbol("ClassDataB", cls->getDCI().getInt("DataB"));
}
else {
parser.addSymbol("ClassDataA", 0);
parser.addSymbol("ClassDataB", 0);
}
vector<RunnerStatus> inst; vector<RunnerStatus> inst;
vector<int> times; vector<int> times;
vector<int> points; vector<int> points;
@ -1222,7 +1244,7 @@ void DynamicResult::prepareCalculations(oTeam &team, bool classResult) const {
GeneralResult::prepareCalculations(team, classResult); GeneralResult::prepareCalculations(team, classResult);
prepareCommon(team, classResult); prepareCommon(team, classResult);
int nr = team.getNumRunners(); int nr = team.getNumRunners();
vector<int> status(nr), time(nr), start(nr), finish(nr), points(nr); vector<int> status(nr), time(nr), start(nr), finish(nr), points(nr), dataA(nr), dataB(nr);
vector< vector<int> > runnerOutputTimes(nr); vector< vector<int> > runnerOutputTimes(nr);
vector< vector<int> > runnerOutputNumbers(nr); vector< vector<int> > runnerOutputNumbers(nr);
@ -1243,6 +1265,8 @@ void DynamicResult::prepareCalculations(oTeam &team, bool classResult) const {
runnerOutputTimes[k] = res.outputTimes; runnerOutputTimes[k] = res.outputTimes;
runnerOutputNumbers[k] = res.outputNumbers; runnerOutputNumbers[k] = res.outputNumbers;
dataA[k] = r->getDCI().getInt("DataA");
dataB[k] = r->getDCI().getInt("DataB");
} }
} }
parser.removeSymbol("CardControls"); parser.removeSymbol("CardControls");
@ -1270,6 +1294,9 @@ void DynamicResult::prepareCalculations(oTeam &team, bool classResult) const {
parser.addSymbol("RunnerFinish", finish); parser.addSymbol("RunnerFinish", finish);
parser.addSymbol("RunnerPoints", points); parser.addSymbol("RunnerPoints", points);
parser.addSymbol("RunnerDataA", dataA);
parser.addSymbol("RunnerDataB", dataB);
parser.addSymbol("PatrolRogainingScore", team.getRogainingPatrolPoints(false)); parser.addSymbol("PatrolRogainingScore", team.getRogainingPatrolPoints(false));
parser.addSymbol("PatrolRogainingReduction", team.getRogainingPatrolReduction()); parser.addSymbol("PatrolRogainingReduction", team.getRogainingPatrolReduction());
parser.addSymbol("PatrolRogainingOvertime", team.getRogainingPatrolOvertime()); parser.addSymbol("PatrolRogainingOvertime", team.getRogainingPatrolOvertime());
@ -1416,7 +1443,7 @@ void DynamicResult::prepareCalculations(oRunner &runner, bool classResult) const
parser.addSymbol("AgeLowLimit", lowAgeLimit); parser.addSymbol("AgeLowLimit", lowAgeLimit);
parser.addSymbol("AgeHighLimit", highAgeLimit); parser.addSymbol("AgeHighLimit", highAgeLimit);
parser.addSymbol("CheckTime", runner.getCheckTime()); parser.addSymbol("CheckTime", runner.getCheckTime() / timeConstSecond);
} }
void DynamicResult::storeOutput(vector<int> &times, vector<int> &numbers) const { void DynamicResult::storeOutput(vector<int> &times, vector<int> &numbers) const {

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -22,8 +22,7 @@
************************************************************************/ ************************************************************************/
#ifndef MEOS_GUI_HANDLER #pragma once
#define MEOS_GUI_HANDLER
enum GuiEventType {GUI_BUTTON=1, GUI_INPUT=2, GUI_LISTBOX=3, enum GuiEventType {GUI_BUTTON=1, GUI_INPUT=2, GUI_LISTBOX=3,
GUI_INFOBOX=4, GUI_CLEAR=5, GUI_INPUTCHANGE=6, GUI_INFOBOX=4, GUI_CLEAR=5, GUI_INPUTCHANGE=6,
@ -34,6 +33,7 @@ enum GuiEventType {GUI_BUTTON=1, GUI_INPUT=2, GUI_LISTBOX=3,
class gdioutput; class gdioutput;
class BaseInfo; class BaseInfo;
typedef int (*GUICALLBACK)(gdioutput* gdi, GuiEventType type, BaseInfo* data);
class GuiHandler { class GuiHandler {
public: public:
@ -41,5 +41,3 @@ public:
virtual ~GuiHandler() = 0 {} virtual ~GuiHandler() = 0 {}
virtual void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) = 0; virtual void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) = 0;
}; };
#endif

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -230,11 +230,11 @@ uint64_t Image::computeHash(const vector<uint8_t>& data) {
} }
void Image::read_file(const wstring& filename, vector<uint8_t>& data) { void Image::read_file(const wstring& filename, vector<uint8_t>& data) {
ifstream fin; std::ifstream fin;
fin.open(filename, ios::binary); fin.open(filename, std::ios::binary);
fin.seekg(0, ios::end); fin.seekg(0, std::ios::end);
int p2 = (int)fin.tellg(); int p2 = (int)fin.tellg();
fin.seekg(0, ios::beg); fin.seekg(0, std::ios::beg);
data.resize(p2); data.resize(p2);
fin.read((char*)data.data(), data.size()); fin.read((char*)data.data(), data.size());
fin.close(); fin.close();

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -99,7 +99,7 @@ wstring ImportFormats::getExtension(ExportFormats fm) {
case HTML: case HTML:
return L"html"; return L"html";
} }
throw exception(); throw std::exception();
} }

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -205,7 +205,7 @@ class InfoCompetitor : public InfoBaseCompetitor {
class InfoTeam : public InfoBaseCompetitor { class InfoTeam : public InfoBaseCompetitor {
protected: protected:
// The outer level holds legs, the inner level holds (parallel/patrol) runners on each leg. // The outer level holds legs, the inner level holds (parallel/patrol) runners on each leg.
vector< vector<int> > competitors; vector<vector<int>> competitors;
public: public:
bool synchronize(oTeam &t); bool synchronize(oTeam &t);
void serialize(xmlbuffer &xml, bool diffOnly) const; void serialize(xmlbuffer &xml, bool diffOnly) const;

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -35,6 +35,8 @@
#include "meosException.h" #include "meosException.h"
#include "localizer.h" #include "localizer.h"
using namespace std;
wstring &getFirst(wstring &inout, int maxNames); wstring &getFirst(wstring &inout, int maxNames);
wstring getMeosCompectVersion(); wstring getMeosCompectVersion();
@ -2160,7 +2162,6 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
di.setInt("Paid", oe.interpretCurrency(paid, currency)); di.setInt("Paid", oe.interpretCurrency(paid, currency));
di.setInt("Taxable", oe.interpretCurrency(fee, currency)); di.setInt("Taxable", oe.interpretCurrency(fee, currency));
// StartTimeAllocationRequest // StartTimeAllocationRequest
xmlobject sar = xo.getObject("StartTimeAllocationRequest"); xmlobject sar = xo.getObject("StartTimeAllocationRequest");
if (sar) { if (sar) {
@ -2171,7 +2172,7 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
if (pRef) { if (pRef) {
wstring sid; wstring sid;
pRef.getObjectString("Id", sid); pRef.getObjectString("Id", sid);
__int64 extId = oBase::converExtIdentifierString(sid); int64_t extId = oBase::converExtIdentifierString(sid);
int pid = oBase::idFromExtId(extId); int pid = oBase::idFromExtId(extId);
pRunner rRef = oe.getRunner(pid, 0); pRunner rRef = oe.getRunner(pid, 0);
if (rRef && rRef->getExtIdentifier() == extId) { if (rRef && rRef->getExtIdentifier() == extId) {
@ -2417,17 +2418,20 @@ pRunner IOF30Interface::readPersonResult(gdioutput &gdi, pClass pc, xmlobject &x
wstring s; wstring s;
for (auto &split : splits) { for (auto &split : splits) {
int code = split.getObjectInt("ControlCode"); int code = split.getObjectInt("ControlCode");
int time = split.getObjectInt("Time"); wstring out;
split.getObjectString("Time", out);
double t = _wtof(out.c_str());
int time = int(t * timeConstSecond);
split.getObjectString("status", s); split.getObjectString("status", s);
if (s != L"missing") if (s != L"missing")
card->addPunch(code, st + time, 0, 0); card->addPunch(code, st + time, 0, 0, oCard::PunchOrigin::Original);
if (s != L"additional") if (s != L"additional")
controls.push_back(code); controls.push_back(code);
} }
if (ft > 0) if (ft > 0)
card->addPunch(oPunch::PunchFinish, ft, 0, 0); card->addPunch(oPunch::PunchFinish, ft, 0, 0, oCard::PunchOrigin::Original);
//Update to SQL-source //Update to SQL-source
card->synchronize(); card->synchronize();
@ -2461,25 +2465,35 @@ pRunner IOF30Interface::readPersonResult(gdioutput &gdi, pClass pc, xmlobject &x
return r; return r;
} }
void IOF30Interface::readId(const xmlobject &person, int &pid, __int64 &extId) const { void IOF30Interface::readId(const xmlobject &person, int &pid, int64_t& extId, int64_t& extId2) const {
wstring sid; wstring sid;
pid = 0; pid = 0;
extId = 0; extId = 0;
if (preferredIdProvider.empty()) { extId2 = 0;
if (preferredIdProvider.first.empty()) {
person.getObjectString("Id", sid); person.getObjectString("Id", sid);
} }
else { else {
xmlList sids; xmlList sids;
wstring bsid; wstring bsid, sid2;
person.getObjects("Id", sids); person.getObjects("Id", sids);
for (auto &x : sids) { for (auto &x : sids) {
auto type = x.getAttrib("type"); auto type = x.getAttrib("type");
if (type && type.getPtr() == preferredIdProvider) { if (type && type.getPtr() == preferredIdProvider.first) {
sid = x.getWStr(); sid = x.getWStr();
} }
else if (type && type.getPtr() == preferredIdProvider.second) {
sid2 = x.getWStr();
if (!sid2.empty())
bsid = sid2;
}
else if (bsid.empty()) else if (bsid.empty())
bsid = x.getWStr(); bsid = x.getWStr();
} }
if (!sid2.empty())
extId2 = oBase::converExtIdentifierString(sid2);
if (sid.empty()) if (sid.empty())
pid = oBase::idFromExtId(oBase::converExtIdentifierString(bsid)); pid = oBase::idFromExtId(oBase::converExtIdentifierString(bsid));
} }
@ -2504,34 +2518,8 @@ pRunner IOF30Interface::readPerson(gdioutput &gdi, const xmlobject &person) {
name = lang.tl("N.N."); name = lang.tl("N.N.");
} }
int pid = 0; int pid = 0;
__int64 extId = 0; int64_t extId = 0, extId2 = 0;
readId(person, pid, extId); readId(person, pid, extId, extId2);
/*
wstring sid;
int pid = 0;
__int64 extId = 0;
if (preferredIdProvider.empty()) {
person.getObjectString("Id", sid);
}
else {
xmlList sids;
wstring bsid;
person.getObjects("Id", sids);
for (auto &x : sids) {
auto type = x.getAttrib("type");
if (type && type.get() == preferredIdProvider) {
sid = x.getw();
}
else if (bsid.empty())
bsid = x.getw();
}
if (sid.empty())
pid = oBase::idFromExtId(oBase::converExtIdentifierString(bsid));
}
if (!sid.empty()) {
extId = oBase::converExtIdentifierString(sid);
pid = oBase::idFromExtId(extId);
}*/
pRunner r = 0; pRunner r = 0;
if (pid) { if (pid) {
@ -2580,6 +2568,8 @@ pRunner IOF30Interface::readPerson(gdioutput &gdi, const xmlobject &person) {
} }
r->setExtIdentifier(extId); r->setExtIdentifier(extId);
if (extId2 != 0)
r->setExtIdentifier2(extId2);
oDataInterface DI=r->getDI(); oDataInterface DI=r->getDI();
wstring tmp; wstring tmp;
@ -2602,7 +2592,7 @@ pClub IOF30Interface::readOrganization(gdioutput &gdi, const xmlobject &xclub, b
return 0; return 0;
wstring clubIdS; wstring clubIdS;
xclub.getObjectString("Id", clubIdS); xclub.getObjectString("Id", clubIdS);
__int64 extId = oBase::converExtIdentifierString(clubIdS); int64_t extId = oBase::converExtIdentifierString(clubIdS);
int clubId = oBase::idFromExtId(extId); int clubId = oBase::idFromExtId(extId);
wstring name, shortName; wstring name, shortName;
xclub.getObjectString("Name", name); xclub.getObjectString("Name", name);
@ -2870,7 +2860,7 @@ void IOF30Interface::getAgeLevels(const vector<FeeInfo> &fees, const vector<int>
int getAgeFromDate(const wstring &date) { int getAgeFromDate(const wstring &date) {
int y = getThisYear(); int y = getThisYear();
SYSTEMTIME st; SYSTEMTIME st;
convertDateYMS(date, st, false); convertDateYMD(date, st, false);
if (st.wYear > 1900) if (st.wYear > 1900)
return y - st.wYear; return y - st.wYear;
else else
@ -2887,8 +2877,8 @@ void IOF30Interface::FeeInfo::add(IOF30Interface::FeeInfo &fi) {
fi.toTime = fromTime; fi.toTime = fromTime;
if (!fi.toTime.empty()) { if (!fi.toTime.empty()) {
SYSTEMTIME st; SYSTEMTIME st;
convertDateYMS(fi.toTime, st, false); convertDateYMD(fi.toTime, st, false);
__int64 sec = SystemTimeToInt64TenthSecond(st); int64_t sec = SystemTimeToInt64TenthSecond(st);
sec -= timeConstHour; sec -= timeConstHour;
fi.toTime = convertSystemDate(Int64TenthSecondToSystemTime(sec)); fi.toTime = convertSystemDate(Int64TenthSecondToSystemTime(sec));
} }
@ -3183,7 +3173,7 @@ void IOF30Interface::getLocalDateTime(const string &date, const string &time,
memset(&st, 0, sizeof(SYSTEMTIME)); memset(&st, 0, sizeof(SYSTEMTIME));
int atime = convertAbsoluteTimeISO(wTime); int atime = convertAbsoluteTimeISO(wTime);
int idate = convertDateYMS(date, st, true); int idate = convertDateYMD(date, st, true);
if (idate != -1) { if (idate != -1) {
if (zone == "Z" || zone == "z") { if (zone == "Z" || zone == "z") {
st.wHour = atime / timeConstHour; st.wHour = atime / timeConstHour;
@ -3246,7 +3236,7 @@ void IOF30Interface::getLocalDateTime(const wstring &date, const wstring &time,
memset(&st, 0, sizeof(SYSTEMTIME)); memset(&st, 0, sizeof(SYSTEMTIME));
const int atime = convertAbsoluteTimeISO(wTime); const int atime = convertAbsoluteTimeISO(wTime);
int idate = convertDateYMS(date, st, true); int idate = convertDateYMD(date, st, true);
if (idate != -1) { if (idate != -1) {
if (zone == L"Z" || zone == L"z") { if (zone == L"Z" || zone == L"z") {
st.wHour = atime / timeConstHour; st.wHour = atime / timeConstHour;
@ -3665,7 +3655,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
} }
void IOF30Interface::writeFees(xmlparser &xml, const oRunner &r) const { void IOF30Interface::writeFees(xmlparser &xml, const oRunner &r) const {
int cardFee = max(0, r.getDCI().getInt("CardFee")); int cardFee = r.getRentalCardFee(false);
bool paidCard = r.getDCI().getInt("Paid") >= cardFee; bool paidCard = r.getDCI().getInt("Paid") >= cardFee;
writeAssignedFee(xml, r, paidCard ? cardFee : 0); writeAssignedFee(xml, r, paidCard ? cardFee : 0);
@ -3777,11 +3767,26 @@ void IOF30Interface::writeEvent(xmlparser &xml) {
void IOF30Interface::writePerson(xmlparser &xml, const oRunner &r) { void IOF30Interface::writePerson(xmlparser &xml, const oRunner &r) {
xml.startTag("Person"); xml.startTag("Person");
if (r.getExtIdentifier() != 0) if (externalIdTypes.empty()) {
xml.write("Id", r.getExtIdentifierString()); if (r.getExtIdentifier() != 0)
else if (r.getMainRunner()->getExtIdentifier() != 0) xml.write("Id", r.getExtIdentifierString());
xml.write("Id", r.getMainRunner()->getExtIdentifierString()); else if (r.getMainRunner()->getExtIdentifier() != 0)
xml.write("Id", r.getMainRunner()->getExtIdentifierString());
}
else if (!externalIdTypes[0].empty()) {
if (r.getExtIdentifier() != 0)
xml.write("Id", externalIdTypes[0], r.getExtIdentifierString());
else if (r.getMainRunner()->getExtIdentifier() != 0)
xml.write("Id", externalIdTypes[0], r.getMainRunner()->getExtIdentifierString());
}
if (externalIdTypes.size()>1 && !externalIdTypes[1].empty()) {
if (r.getExtIdentifier2() != 0)
xml.write("Id", externalIdTypes[1], r.getExtIdentifierString2());
else if (r.getMainRunner()->getExtIdentifier2() != 0)
xml.write("Id", externalIdTypes[1], r.getMainRunner()->getExtIdentifierString2());
}
xml.startTag("Name"); xml.startTag("Name");
xml.write("Family", r.getFamilyName()); xml.write("Family", r.getFamilyName());
xml.write("Given", r.getGivenName()); xml.write("Given", r.getGivenName());
@ -3804,7 +3809,7 @@ void IOF30Interface::writeClub(xmlparser &xml, const oClub &c, bool writeExtende
else { else {
xml.startTag("Organisation"); xml.startTag("Organisation");
} }
__int64 id = c.getExtIdentifier(); int64_t id = c.getExtIdentifier();
if (id != 0) if (id != 0)
xml.write("Id", c.getExtIdentifierString()); xml.write("Id", c.getExtIdentifierString());
@ -4143,8 +4148,9 @@ bool IOF30Interface::readXMLCompetitorDB(const xmlobject &xCompetitor,
if (!person) return false; if (!person) return false;
int pidI; int pidI;
long long pid; int64_t pid;
readId(person, pidI, pid); int64_t ext2; // Ignored
readId(person, pidI, pid, ext2);
xmlobject pname = person.getObject("Name"); xmlobject pname = person.getObject("Name");
if (!pname) return false; if (!pname) return false;
@ -4693,6 +4699,19 @@ void IOF30Interface::getIdTypes(vector<string> &types) {
types.insert(types.begin(), idProviders.begin(), idProviders.end()); types.insert(types.begin(), idProviders.begin(), idProviders.end());
} }
void IOF30Interface::setPreferredIdType(const string &type) { void IOF30Interface::setPreferredIdType(const pair<string, string> &type) {
preferredIdProvider = type; preferredIdProvider = type;
externalIdTypes.clear();
if (!type.first.empty() || !type.second.empty()) {
string stype = "type";
if (!type.first.empty())
externalIdTypes.emplace_back(vector<pair<string, wstring>>({
make_pair(stype, gdioutput::widen(type.first)) }));
else
externalIdTypes.emplace_back();
if (!type.second.empty())
externalIdTypes.emplace_back(vector<pair<string, wstring>>({
make_pair(stype, gdioutput::widen(type.second)) }));
}
} }

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -155,7 +155,8 @@ class IOF30Interface {
bool matchStageFilter(const set<int> &stageFilter, const xmlList &races); bool matchStageFilter(const set<int> &stageFilter, const xmlList &races);
set<string> idProviders; set<string> idProviders;
string preferredIdProvider; pair<string, string> preferredIdProvider;
vector<vector<pair<string, wstring>>> externalIdTypes;
void readEvent(gdioutput &gdi, const xmlobject &xo, void readEvent(gdioutput &gdi, const xmlobject &xo,
map<int, vector<LegInfo> > &teamClassConfig); map<int, vector<LegInfo> > &teamClassConfig);
@ -259,7 +260,7 @@ class IOF30Interface {
bool readXMLCompetitorDB(const xmlobject &xCompetitor, bool readXMLCompetitorDB(const xmlobject &xCompetitor,
bool onlyWithClub, bool onlyWithClub,
unordered_multimap<size_t, int> &duplicateCheck, std::unordered_multimap<size_t, int> &duplicateCheck,
int &duplicateCount); int &duplicateCount);
void writeXMLCompetitorDB(xmlparser &xml, const RunnerDB &db, const RunnerWDBEntry &rde) const; void writeXMLCompetitorDB(xmlparser &xml, const RunnerDB &db, const RunnerWDBEntry &rde) const;
@ -297,7 +298,7 @@ class IOF30Interface {
void writeFullCourse(xmlparser &xml, const oCourse &c, void writeFullCourse(xmlparser &xml, const oCourse &c,
const map<int, wstring> &ctrlId2ExportId); const map<int, wstring> &ctrlId2ExportId);
void readId(const xmlobject &person, int &pid, __int64 &extId) const; void readId(const xmlobject &person, int &pid, int64_t &extId, int64_t& extId2) const;
set<int> readCrsIds; set<int> readCrsIds;
@ -322,7 +323,7 @@ public:
string &dateOut, string &timeOut); string &dateOut, string &timeOut);
void getIdTypes(vector<string> &types); void getIdTypes(vector<string> &types);
void setPreferredIdType(const string &type); void setPreferredIdType(const pair<string, string>&type);
void readEventList(gdioutput &gdi, xmlobject &xo); void readEventList(gdioutput &gdi, xmlobject &xo);

Binary file not shown.

BIN
code/lib64_db/RestBed.lib Normal file

Binary file not shown.

BIN
code/lib64_db/libharu.lib Normal file

Binary file not shown.

BIN
code/lib64_db/libmysql.lib Normal file

Binary file not shown.

BIN
code/lib64_db/libpng.lib Normal file

Binary file not shown.

BIN
code/lib64_db/zlibstat.lib Normal file

Binary file not shown.

Binary file not shown.

View File

@ -7,7 +7,7 @@ Third Party Code. Additional copyright notices and license terms applicable to p
All trademarks and registered trademarks mentioned herein are the property of their respective owners. All trademarks and registered trademarks mentioned herein are the property of their respective owners.
------------------------------------ ------------------------------------
Copyright 2007-2023 Melin Software HB. Copyright 2007-2024 Melin Software HB.
------------------------------------ ------------------------------------

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -99,7 +99,7 @@ void ListEditor::show(TabBase *dst, gdioutput &gdi) {
show(gdi); show(gdi);
} }
int editListCB(gdioutput* gdi, int type, void* data); int editListCB(gdioutput* gdi, GuiEventType type, BaseInfo* data);
void ListEditor::show(gdioutput &gdi) { void ListEditor::show(gdioutput &gdi) {
@ -319,8 +319,7 @@ void ListEditor::renderListPreview(gdioutput &gdi) {
} }
} }
int editListCB(gdioutput *gdi, int type, void *data) int editListCB(gdioutput *gdi, GuiEventType type, BaseInfo* data) {
{
void *clz = gdi->getData("ListEditorClz"); void *clz = gdi->getData("ListEditorClz");
ListEditor *le = (ListEditor *)clz; ListEditor *le = (ListEditor *)clz;
BaseInfo *bi = (BaseInfo *)data; BaseInfo *bi = (BaseInfo *)data;
@ -393,7 +392,7 @@ static void getPosFromId(int id, int &groupIx, int &lineIx, int &ix) {
lineIx = lineIx % 100; lineIx = lineIx % 100;
} }
int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { int ListEditor::editList(gdioutput &gdi, GuiEventType type, BaseInfo &data) {
int lineIx, groupIx, ix; int lineIx, groupIx, ix;
if (type == GUI_EVENT) { if (type == GUI_EVENT) {
@ -778,7 +777,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
gdi.fillRight(); gdi.fillRight();
gdi.addSelection("OpenList", 250, 400, editListCB, L"Välj lista:"); gdi.addSelection("OpenList", 250, 400, editListCB, L"Välj lista:");
gdi.addItem("OpenList", lists); gdi.setItems("OpenList", lists);
gdi.selectFirstItem("OpenList"); gdi.selectFirstItem("OpenList");
@ -907,7 +906,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
gdi.getSelectedItem("SortOrder", mlbi); gdi.getSelectedItem("SortOrder", mlbi);
currentType = mlbi.data; currentType = mlbi.data;
} }
gdi.addItem("SortOrder", types); gdi.setItems("SortOrder", types);
gdi.selectItemByData("SortOrder", currentType); gdi.selectItemByData("SortOrder", currentType);
} }
else if (lbi.id == "OpenList") { else if (lbi.id == "OpenList") {
@ -1170,7 +1169,7 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
gdi.fillRight(); gdi.fillRight();
gdi.addSelection("Type", 290, 500, editListCB); gdi.addSelection("Type", 290, 500, editListCB);
gdi.dropLine(-1); gdi.dropLine(-1);
gdi.addItem("Type", types); gdi.setItems("Type", types);
gdi.selectItemByData("Type", currentType); gdi.selectItemByData("Type", currentType);
gdi.addInput("Text", mlp.getText(), 16, editListCB, gdi.addInput("Text", mlp.getText(), 16, editListCB,
L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data."); L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data.");
@ -1205,7 +1204,7 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
currentList->getAlignTypes(mlp, types, currentType); currentList->getAlignTypes(mlp, types, currentType);
sort(types.begin(), types.end()); sort(types.begin(), types.end());
gdi.addSelection("AlignType", 290, 500, editListCB, L"Justera mot:"); gdi.addSelection("AlignType", 290, 500, editListCB, L"Justera mot:");
gdi.addItem("AlignType", types); gdi.setItems("AlignType", types);
gdi.selectItemByData("AlignType", currentType); gdi.selectItemByData("AlignType", currentType);
gdi.addInput("AlignText", mlp.getAlignText(), 16, 0, L"Text:"); gdi.addInput("AlignText", mlp.getAlignText(), 16, 0, L"Text:");
@ -1259,7 +1258,7 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
mlp.getFonts(fonts, currentFont); mlp.getFonts(fonts, currentFont);
gdi.addSelection("Fonts", 200, 500, 0, L"Format:"); gdi.addSelection("Fonts", 200, 500, 0, L"Format:");
gdi.addItem("Fonts", fonts); gdi.setItems("Fonts", fonts);
gdi.selectItemByData("Fonts", currentFont); gdi.selectItemByData("Fonts", currentFont);
maxX = max(maxX, gdi.getCX()); maxX = max(maxX, gdi.getCX());
@ -1473,7 +1472,7 @@ int ListEditor::selectImage(gdioutput &gdi, uint64_t imgId) {
vector<pair<wstring, size_t>> img; vector<pair<wstring, size_t>> img;
image.enumerateImages(img); image.enumerateImages(img);
img.emplace(img.begin(), lang.tl("Ingen[bild]"), -2); img.emplace(img.begin(), lang.tl("Ingen[bild]"), -2);
gdi.addItem("Image", img); gdi.setItems("Image", img);
int ix = image.getEnumerationIxFromId(imgId); int ix = image.getEnumerationIxFromId(imgId);
if (ix >= 0) if (ix >= 0)
@ -1665,7 +1664,7 @@ bool ListEditor::legStageTypeIndex(gdioutput &gdi, EPostType type, int leg) {
for (int j = 1; j <= 50; j++) { for (int j = 1; j <= 50; j++) {
items.emplace_back(lang.tl("Sträcka X#" + itos(j)), j); items.emplace_back(lang.tl("Sträcka X#" + itos(j)), j);
} }
gdi.addItem("LegSel", items); gdi.setItems("LegSel", items);
if (leg >= -1) if (leg >= -1)
gdi.selectItemByData("LegSel", leg + 1); gdi.selectItemByData("LegSel", leg + 1);
else if (leg == -2) else if (leg == -2)
@ -1676,7 +1675,7 @@ bool ListEditor::legStageTypeIndex(gdioutput &gdi, EPostType type, int leg) {
for (int j = 1; j < 20; j++) { for (int j = 1; j < 20; j++) {
items.emplace_back(lang.tl("Etapp X#" + itos(j)), j); items.emplace_back(lang.tl("Etapp X#" + itos(j)), j);
} }
gdi.addItem("LegSel", items); gdi.setItems("LegSel", items);
gdi.selectItemByData("LegSel", leg >= 0 ? leg + 1 : -2); gdi.selectItemByData("LegSel", leg >= 0 ? leg + 1 : -2);
} }
} }
@ -1754,26 +1753,26 @@ void ListEditor::editListProp(gdioutput &gdi, bool newList) {
list.getBaseType(types, currentType); list.getBaseType(types, currentType);
gdi.addSelection("BaseType", 150, 400, 0, L"Listtyp:"); gdi.addSelection("BaseType", 150, 400, 0, L"Listtyp:");
gdi.addItem("BaseType", types); gdi.setItems("BaseType", types);
gdi.selectItemByData("BaseType", currentType); gdi.selectItemByData("BaseType", currentType);
gdi.autoGrow("BaseType"); gdi.autoGrow("BaseType");
list.getResultModule(*oe, types, currentType); list.getResultModule(*oe, types, currentType);
gdi.addSelection("ResultType", 150, 400, editListCB, L"Resultatuträkning:"); gdi.addSelection("ResultType", 150, 400, editListCB, L"Resultatuträkning:");
gdi.addItem("ResultType", types); gdi.setItems("ResultType", types);
gdi.autoGrow("ResultType"); gdi.autoGrow("ResultType");
gdi.selectItemByData("ResultType", currentType); gdi.selectItemByData("ResultType", currentType);
list.getSortOrder(false, types, currentType); list.getSortOrder(false, types, currentType);
gdi.addSelection("SortOrder", 170, 400, 0, L"Global sorteringsordning:"); gdi.addSelection("SortOrder", 170, 400, 0, L"Global sorteringsordning:");
gdi.addItem("SortOrder", types); gdi.setItems("SortOrder", types);
gdi.autoGrow("SortOrder"); gdi.autoGrow("SortOrder");
gdi.selectItemByData("SortOrder", currentType); gdi.selectItemByData("SortOrder", currentType);
list.getSubType(types, currentType); list.getSubType(types, currentType);
gdi.addSelection("SubType", 150, 400, editListCB, L"Sekundär typ:"); gdi.addSelection("SubType", 150, 400, editListCB, L"Sekundär typ:");
gdi.addItem("SubType", types); gdi.setItems("SubType", types);
gdi.selectItemByData("SubType", currentType); gdi.selectItemByData("SubType", currentType);
oListInfo::EBaseType subType = oListInfo::EBaseType(currentType); oListInfo::EBaseType subType = oListInfo::EBaseType(currentType);
@ -1849,7 +1848,7 @@ void ListEditor::editListProp(gdioutput &gdi, bool newList) {
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
string id("Font" + itos(k)); string id("Font" + itos(k));
gdi.addCombo(id, 200, 300, 0, expl[k]); gdi.addCombo(id, 200, 300, 0, expl[k]);
gdi.addItem(id, fonts); gdi.setItems(id, fonts);
gdi.setText(id, list.getFontFace(k)); gdi.setText(id, list.getFontFace(k));
gdi.setCX(gdi.getCX()+20); gdi.setCX(gdi.getCX()+20);
@ -1961,7 +1960,7 @@ void ListEditor::splitPrintList(gdioutput& gdi) {
for (int i = 60; i <= 100; i += 10) for (int i = 60; i <= 100; i += 10)
items.emplace_back(itow(i), i); items.emplace_back(itow(i), i);
items.emplace_back(lang.tl("Alla"), 1000); items.emplace_back(lang.tl("Alla"), 1000);
gdi.addItem("NumResult", items); gdi.setItems("NumResult", items);
gdi.selectItemByData("NumResult", isSP ? sp->numClassResults : 3); gdi.selectItemByData("NumResult", isSP ? sp->numClassResults : 3);
statusSplitPrint(gdi, isSP); statusSplitPrint(gdi, isSP);

View File

@ -2,7 +2,7 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2024 Melin Software HB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -51,7 +51,7 @@ private:
const wchar_t *getIndexDescription(EPostType type); const wchar_t *getIndexDescription(EPostType type);
wstring lastShownExampleText; wstring lastShownExampleText;
void showLine(gdioutput &gdi, const vector<MetaListPost> &line, int ix) const; void showLine(gdioutput &gdi, const vector<MetaListPost> &line, int ix) const;
int editList(gdioutput &gdi, int type, BaseInfo &data); int editList(gdioutput &gdi, GuiEventType type, BaseInfo &data);
void updateType(int iType, gdioutput &gdi); void updateType(int iType, gdioutput &gdi);
bool saveListPost(gdioutput &gdi, MetaListPost &mlp); bool saveListPost(gdioutput &gdi, MetaListPost &mlp);
@ -118,5 +118,5 @@ public:
MetaList *getCurrentList() const {return currentList;}; MetaList *getCurrentList() const {return currentList;};
void handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) final; void handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) final;
friend int editListCB(gdioutput*, int, void *); friend int editListCB(gdioutput*, GuiEventType type, BaseInfo* data);
}; };

BIN
code/lists24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

Some files were not shown because too many files have changed in this diff Show More