Subversion Repositories tpanel

Rev

Rev 463 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
486 andreas 2
 * Copyright (C) 2020 to 2025 by Andreas Theofilu <andreas@theosys.at>
446 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <unistd.h>
20
#include "tsettings.h"
21
#include "texpat++.h"
22
#include "terror.h"
486 andreas 23
#include "ttpinit.h"
446 andreas 24
 
25
#if __cplusplus < 201402L
26
#   error "This module requires at least C++14 standard!"
27
#else
28
#   if __cplusplus < 201703L
29
#       include <experimental/filesystem>
30
namespace fs = std::experimental::filesystem;
31
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
32
#   else
33
#       include <filesystem>
34
#       ifdef __ANDROID__
35
namespace fs = std::__fs::filesystem;
36
#       else
37
namespace fs = std::filesystem;
38
#       endif
39
#   endif
40
#endif
41
 
42
using std::string;
43
using std::vector;
44
using namespace Expat;
45
 
46
TSettings::TSettings(const string& path)
47
    : mPath(path)
48
{
49
    DECL_TRACER("TSettings::TSettings(const string& path)");
50
 
51
    MSG_DEBUG("Loading from path: " << path);
52
    loadSettings(true);
53
}
54
 
55
bool TSettings::loadSettings(bool initial)
56
{
57
    DECL_TRACER("TSettings::loadSettings()");
58
 
59
    if (!initial)
60
    {
61
        mResourceLists.clear();
62
    }
63
 
64
    TError::clear();
65
    string fname = makeFileName(mPath, "prj.xma");
66
 
67
    if (!isValidFile())
68
    {
69
        MSG_ERROR("Error: File " << fname << " doesn't exist or can't be opened!");
70
        TError::setError();
71
        return false;
72
    }
73
 
74
    TExpat xml(fname);
75
 
486 andreas 76
    if (!TTPInit::isTP5())
77
        xml.setEncoding(ENC_CP1250);
78
    else
79
        xml.setEncoding(ENC_UTF8);
80
 
446 andreas 81
    if (!xml.parse())
82
        return false;
83
 
84
    int depth = 0;
85
    size_t index = 0;
463 andreas 86
    MSG_DEBUG("Reading version info ...");
446 andreas 87
 
462 andreas 88
    if (xml.getElementIndex("versionInfo", &depth) == TExpat::npos)
89
    {
90
        MSG_ERROR("Couldn't find the project version information! Broken surface?");
91
        TError::setError();
92
        return false;
93
    }
94
 
95
    depth++;
96
    bool valid = false;
97
 
98
    mSetup.versionInfo.formatVersion = xml.getElementInt("formatVersion", depth);
99
    mSetup.versionInfo.graphicsVersion = xml.getElementInt("graphicsVersion", depth);
100
    mSetup.versionInfo.fileVersion = xml.getElement("fileVersion", depth);
101
    mSetup.versionInfo.designVersion = xml.getElement("designVersion", depth);
102
    mSetup.versionInfo.g5appsVersion = xml.getElementInt("g5appsVersion", depth, &valid);
103
 
104
    if (!valid)
463 andreas 105
    {
462 andreas 106
        mSetup.versionInfo.g5appsVersion = 0;   // No TP5 file
486 andreas 107
        mIsTp5 = false;
463 andreas 108
        MSG_INFO("Detected a TP4 file");
109
    }
110
    else
462 andreas 111
    {
486 andreas 112
        mIsTp5 = true;
463 andreas 113
        MSG_INFO("Detected a TP5 file");
462 andreas 114
    }
115
 
463 andreas 116
    MSG_DEBUG("Reading project info ...");
462 andreas 117
 
446 andreas 118
    if (xml.getElementIndex("projectInfo", &depth) == TExpat::npos)
119
    {
120
        MSG_ERROR("Couldn't find the project information! Broken surface?");
121
        TError::setError();
122
        return false;
123
    }
124
 
125
    depth++;
126
    mProject.protection = xml.getElement("protection", depth);
127
    mProject.password = xml.getElement("password", depth);
128
    vector<Expat::ATTRIBUTE_t> attr = xml.getAttributes();
129
    mProject.encrypted = xml.getAttributeInt("encrypted", attr);
130
    mProject.panelType = xml.getElement("panelType", depth);
131
    mProject.fileRevision = xml.getElement("fileRevision", depth);
132
    mProject.dealerID = xml.getElement("dealerId", depth);
133
    mProject.jobName = xml.getElement("jobName", depth);
134
    mProject.salesOrder = xml.getElement("salesOrder", depth);
135
    mProject.purchaseOrder = xml.getElement("purchaseOrder", depth);
136
    mProject.jobComment = xml.getElement("jobComment", depth);
137
    mProject.designerID = xml.getElement("designerId", depth);
138
    mProject.creationDate = xml.getElement("creationDate", depth);
139
    mProject.revisionDate = xml.getElement("revisionDate", depth);
140
    mProject.lastSaveDate = xml.getElement("lastSaveDate", depth);
141
    mProject.fileName = xml.getElement("fileName", depth);
142
    mProject.colorChoice = xml.getElement("colorChoice", depth);
143
    mProject.specifyPortCount = xml.getElementInt("specifyPortCount", depth);
144
    mProject.specifyChanCount = xml.getElementInt("specifyChanCount", depth);
145
 
463 andreas 146
    MSG_DEBUG("Reading support file list ...");
147
 
148
    if (xml.getElementIndex("supportFileList", &depth) == TExpat::npos)
149
    {
150
        MSG_ERROR("Couldn't find the support file list! Broken surface?");
151
        TError::setError();
152
        return false;
153
    }
154
 
155
    depth++;
156
    valid = false;
157
 
158
    mSetup.supportFiles.mapFile = xml.getElement("mapFile", depth);
159
    mSetup.supportFiles.colorFile = xml.getElement("colorFile", depth);
160
    mSetup.supportFiles.fontFile = xml.getElement("fontFile", depth);
161
    mSetup.supportFiles.themeFile = xml.getElement("themeFile", depth);
486 andreas 162
 
163
    if (!mIsTp5)
164
        mSetup.supportFiles.iconFile = xml.getElement("iconFile", depth);
165
 
463 andreas 166
    mSetup.supportFiles.externalButtonFile = xml.getElement("externalButtonFile", depth);
167
 
486 andreas 168
    if (mIsTp5)
169
    {
170
        mSetup.supportFiles.appFile = xml.getElement("appFile", depth);
171
        mSetup.supportFiles.logFile = xml.getElement("logFile", depth);
172
    }
173
 
463 andreas 174
    MSG_DEBUG("Map file:     " << mSetup.supportFiles.mapFile);
175
    MSG_DEBUG("Color file:   " << mSetup.supportFiles.colorFile);
176
    MSG_DEBUG("Font file:    " << mSetup.supportFiles.fontFile);
177
    MSG_DEBUG("Theme file:   " << mSetup.supportFiles.themeFile);
178
 
486 andreas 179
    if (!mIsTp5)
463 andreas 180
        MSG_DEBUG("IconFile:     " << mSetup.supportFiles.iconFile);
181
 
182
    MSG_DEBUG("Ext. buttons: " << mSetup.supportFiles.externalButtonFile);
183
 
486 andreas 184
    if (mIsTp5)
185
    {
463 andreas 186
        MSG_DEBUG("App file:     " << mSetup.supportFiles.appFile);
486 andreas 187
        MSG_DEBUG("Log file:     " << mSetup.supportFiles.logFile);
188
    }
463 andreas 189
 
190
    MSG_DEBUG("Reading panel setup ...");
191
 
446 andreas 192
    if ((index = xml.getElementIndex("panelSetup", &depth)) == TExpat::npos)
193
    {
194
        MSG_ERROR("Couldn't find the section \"panelSetup\" in file!");
195
        TError::setError();
196
        return false;
197
    }
198
 
199
    depth++;
200
    string value;
201
    mSetup.portCount = xml.getElementInt("portCount", depth);
202
    mSetup.setupPort = xml.getElementInt("setupPort", depth);
203
    mSetup.addressCount = xml.getElementInt("addressCount", depth);
204
    mSetup.channelCount = xml.getElementInt("channelCount", depth);
205
    mSetup.levelCount = xml.getElementInt("levelCount", depth);
206
    mSetup.powerUpPage = xml.getElement("powerUpPage", depth);
207
 
208
    value = xml.getElement("powerUpPopup", depth);
209
 
210
    if (!value.empty())
211
    {
212
        mSetup.powerUpPopup.push_back(value);
213
        bool valid;
214
 
215
        do
216
        {
217
            value = xml.getNextElement("powerUpPopup", depth, &valid);
218
 
219
            if (valid)
220
            {
221
                mSetup.powerUpPopup.push_back(value);
222
                MSG_DEBUG("powerUpPopup: " << value);
223
            }
224
        }
225
        while (valid);
226
    }
227
 
228
    xml.setIndex(index);
229
    mSetup.feedbackBlinkRate = xml.getElementInt("feedbackBlinkRate", depth);
230
    mSetup.startupString = xml.getElement("startupString", depth);
231
    mSetup.wakeupString = xml.getElement("wakeupString", depth);
232
    mSetup.sleepString = xml.getElement("sleepString", depth);
233
    mSetup.standbyString = xml.getElement("standbyString", depth);
234
    mSetup.shutdownString = xml.getElement("shutdownString", depth);
235
    mSetup.idlePage = xml.getElement("idlePage", depth);
236
    mSetup.idleTimeout = xml.getElementInt("idleTimeout", depth);
237
    mSetup.extButtonsKey = xml.getElementInt("extButtonsKey", depth);
238
    mSetup.screenWidth = xml.getElementInt("screenWidth", depth);
239
    mSetup.screenHeight = xml.getElementInt("screenHeight", depth);
240
    mSetup.screenRefresh = xml.getElementInt("screenRefresh", depth);
241
    mSetup.screenRotate = xml.getElementInt("screenRotate", depth);
242
    mSetup.screenDescription = xml.getElement("screenDescription", depth);
243
    mSetup.pageTracking = xml.getElementInt("pageTracking", depth);
244
    mSetup.cursor = xml.getElementInt("cursor", depth);
245
    mSetup.brightness = xml.getElementInt("brightness", depth);
246
    mSetup.lightSensorLevelPort = xml.getElementInt("lightSensorLevelPort", depth);
247
    mSetup.lightSensorLevelCode = xml.getElementInt("lightSensorLevelCode", depth);
248
    mSetup.lightSensorChannelPort = xml.getElementInt("lightSensorChannelPort", depth);
249
    mSetup.lightSensorChannelCode = xml.getElementInt("lightSensorChannelCode", depth);
250
    mSetup.motionSensorChannelPort = xml.getElementInt("motionSensorChannelPort", depth);
251
    mSetup.motionSensorChannelCode = xml.getElementInt("motionSensorChannelCode", depth);
252
    mSetup.batteryLevelPort = xml.getElementInt("batteryLevelPort", depth);
253
    mSetup.batteryLevelCode = xml.getElementInt("batteryLevelCode", depth);
254
    mSetup.irPortAMX38Emit = xml.getElementInt("irPortAMX38Emit", depth);
255
    mSetup.irPortAMX455Emit = xml.getElementInt("irPortAMX455Emit", depth);
256
    mSetup.irPortAMX38Recv = xml.getElementInt("irPortAMX38Recv", depth);
257
    mSetup.irPortAMX455Recv = xml.getElementInt("irPortAMX455Recv", depth);
258
    mSetup.irPortUser1 = xml.getElementInt("irPortUser1", depth);
259
    mSetup.irPortUser2 = xml.getElementInt("irPortUser2", depth);
260
    mSetup.cradleChannelPort = xml.getElementInt("cradleChannelPort", depth);
261
    mSetup.cradleChannelCode = xml.getElementInt("cradleChannelCode", depth);
262
    mSetup.uniqueID = xml.getElementInt("uniqueID", depth);
263
    mSetup.appCreated = xml.getElementInt("appCreated", depth);
264
    mSetup.buildNumber = xml.getElementInt("buildNumber", depth);
265
    mSetup.appModified = xml.getElement("appModified", depth);
266
    mSetup.buildNumberMod = xml.getElementInt("buildNumberMod", depth);
267
    mSetup.buildStatusMod = xml.getElement("buildStatusMod", depth);
268
    mSetup.activePalette = xml.getElementInt("activePalette", depth);
269
    mSetup.marqueeSpeed = xml.getElementInt("marqueeSpeed", depth);
270
    mSetup.setupPagesProject = xml.getElementInt("setupPagesProject", depth);
271
    mSetup.voipCommandPort = xml.getElementInt("voipCommandPort", depth);
272
 
463 andreas 273
    MSG_DEBUG("Reading resource list ...");
274
 
446 andreas 275
    if ((index = xml.getElementIndex("resourceList", &depth)) == TExpat::npos)
276
    {
277
        MSG_WARNING("Missing element \"resourceList\" in file!");
278
    }
279
 
280
    string name, content;
281
    vector<ATTRIBUTE_t> attrs;
282
 
283
    if (index != TExpat::npos)
284
    {
285
        depth++;
286
        size_t oldIndex = 0;
287
        MSG_DEBUG("Index " << index << " and depth " << depth << " and entity " << xml.getElementName());
288
 
289
        do
290
        {
291
            attrs = xml.getAttributes();
292
            string type = xml.getAttribute("type", attrs);
293
            RESOURCE_LIST_T list = findResourceType(type);
294
            MSG_DEBUG("resource type: " << type);
295
 
296
            if (mResourceLists.size() == 0 || list.type.empty())
297
            {
298
                list.type = type;
299
                list.ressource.clear();
300
                mResourceLists.push_back(list);
301
            }
302
 
303
            RESOURCE_T resource;
304
 
305
            while ((index = xml.getNextElementIndex("resource", depth)) != TExpat::npos)
306
            {
307
                while ((index = xml.getNextElementFromIndex(index, &name, &content, &attrs)) != TExpat::npos)
308
                {
309
                    string e = name;
310
 
311
                    if (e.compare("name") == 0)
312
                        resource.name = content;
313
                    else if (e.compare("protocol") == 0)
314
                        resource.protocol = content;
315
                    else if (e.compare("host") == 0)
316
                        resource.host = content;
317
                    else if (e.compare("file") == 0)
318
                        resource.file = content;
319
                    else if (e.compare("password") == 0)
320
                    {
321
                        resource.password = content;
322
                        int enc = xml.getAttributeInt("encrypted", attrs);
323
 
324
                        if (enc != 0)
325
                            resource.encrypted = true;
326
                        else
327
                            resource.encrypted = false;
328
                    }
329
                    else if (e.compare("user") == 0)
330
                        resource.user = content;
331
                    else if (e.compare("path") == 0)
332
                        resource.path = content;
333
                    else if (e.compare("refresh") == 0)
334
                        resource.refresh = xml.convertElementToInt(content);
335
                    else if (e.compare("dynamo") == 0)
336
                        resource.dynamo = ((xml.convertElementToInt(content) == 0) ? false : true);
337
                    else if (e.compare("preserve") == 0)
338
                        resource.preserve = ((xml.convertElementToInt(content) == 0) ? false : true);
339
 
340
                    oldIndex = index;
341
                }
342
 
343
                list.ressource.push_back(resource);
344
                MSG_DEBUG("Scheme: " << resource.protocol << ", Host: " << resource.host << ", Path: " << resource.path << ", File: " << resource.file << ", Name: " << resource.name);
345
                resource.clear();
346
 
347
                if (index == TExpat::npos)
348
                    index = oldIndex + 2;
349
            }
350
 
351
            vector<RESOURCE_LIST_T>::iterator itResList;
352
 
463 andreas 353
            for (itResList = mResourceLists.begin(); itResList != mResourceLists.end(); ++itResList)
446 andreas 354
            {
355
                if (itResList->type.compare(type) == 0)
356
                {
357
                    mResourceLists.erase(itResList);
358
                    mResourceLists.push_back(list);
359
                    break;
360
                }
361
            }
362
        }
363
        while ((index = xml.getNextElementIndex("resourceList", depth)) != TExpat::npos);
364
    }
365
 
463 andreas 366
    MSG_DEBUG("Reading palette list ...");
367
 
446 andreas 368
    if (xml.getElementIndex("paletteList", &depth) == TExpat::npos)
369
    {
462 andreas 370
        if (!isTP5())
371
        {
372
            MSG_WARNING("There exists no color palette! There will be only the system colors available.");
373
        }
374
        else
375
        {
376
            PALETTE_SETUP ps;
377
            ps.name = ps.file = mSetup.supportFiles.colorFile;
378
            ps.paletteID = 1;
379
            mSetup.palettes.push_back(ps);
380
        }
381
 
446 andreas 382
        return true;
383
    }
384
 
385
    depth++;
386
 
387
    while ((index = xml.getNextElementIndex("palette", depth)) != TExpat::npos)
388
    {
389
        PALETTE_SETUP ps;
390
 
391
        while ((index = xml.getNextElementFromIndex(index, &name, &content, &attrs)) != TExpat::npos)
392
        {
393
            if (name.compare("name") == 0)
394
                ps.name = content;
395
            else if (name.compare("file") == 0)
396
                ps.file = content;
397
            else if (name.compare("paletteID") == 0)
398
                ps.paletteID = xml.convertElementToInt(content);
399
        }
400
 
401
        mSetup.palettes.push_back(ps);
402
    }
403
 
404
    return true;
405
}
406
 
407
RESOURCE_LIST_T TSettings::findResourceType(const string& type)
408
{
409
    DECL_TRACER ("TSettings::findResourceType(const string& type)");
410
 
411
    vector<RESOURCE_LIST_T>::iterator iter;
412
 
413
    for (iter = mResourceLists.begin(); iter != mResourceLists.end(); iter++)
414
    {
415
        if (iter->type.compare(type) == 0)
416
            return *iter;
417
    }
418
 
419
    return RESOURCE_LIST_T();
420
}
421
 
422
bool TSettings::isPortrait()
423
{
424
    DECL_TRACER("TSettings::isPortrait()");
425
 
426
    return mSetup.screenWidth < mSetup.screenHeight;
427
}
428
 
429
bool TSettings::isLandscape()
430
{
431
    DECL_TRACER("TSettings::isLandscape()");
432
 
433
    return mSetup.screenWidth > mSetup.screenHeight;
434
}