Subversion Repositories tpanel

Rev

Rev 446 | Rev 463 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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