Subversion Repositories tpanel

Rev

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

Rev Author Line No. Line
480 andreas 1
/*
486 andreas 2
 * Copyright (C) 2024, 2025 by Andreas Theofilu <andreas@theosys.at>
480 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 "tapps.h"
20
#include "ttpinit.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
vector<APP_SETTINGS_t> TApps::mAppSettings;
46
vector<APP_WINDOW_FRAME_t> TApps::mWindowFrames;
47
 
48
TApps::TApps()
49
{
50
    DECL_TRACER("TApps::TApps()");
51
}
52
 
53
TApps::~TApps()
54
{
55
    DECL_TRACER("TApps::~TApps()");
56
}
57
 
58
bool TApps::parseApps()
59
{
60
    DECL_TRACER("TApps::parseApps()");
61
 
486 andreas 62
    if (!TTPInit::isTP5())
480 andreas 63
    {
64
        MSG_WARNING("Can't read app configs because it's not a TP5 format!");
65
        return false;
66
    }
67
 
68
    if (!mAppSettings.empty())
69
        mAppSettings.clear();
70
 
71
    string projectPath = TConfig::getProjectPath();
72
 
73
    if (!fs::exists(projectPath + "/G5Apps.xma"))
74
        return false;
75
 
76
    string path = makeFileName(projectPath, "G5Apps.xma");
77
 
78
    if (!isValidFile())
79
    {
80
        MSG_ERROR("File " << path << " doesn't exist or is not readable!");
81
        TError::setError();
82
        return false;
83
    }
84
 
85
    TExpat xml(path);
86
 
486 andreas 87
    if (!TTPInit::isTP5())
88
        xml.setEncoding(ENC_UTF8);
89
 
480 andreas 90
    if (!xml.parse())
91
        return false;
92
 
93
    int depth = 0;
94
    size_t index = 0;
486 andreas 95
    size_t oldIndex = 0;
480 andreas 96
 
97
    if ((index = xml.getElementIndex("Apps", &depth)) == TExpat::npos)
98
    {
486 andreas 99
        MSG_WARNING("File does not contain the element \"Apps\"!");
480 andreas 100
        TError::setError();
101
        return false;
102
    }
103
 
104
    depth++;
105
    string name, content;
106
    vector<ATTRIBUTE_t> attrs;
107
 
108
    while ((index = xml.getNextElementFromIndex(index, &name, &content, &attrs)) != TExpat::npos)
109
    {
110
        if (name.compare("App") == 0)
111
        {
112
            APP_SETTINGS_t app;
113
 
114
            app.appName = xml.getAttribute("name", attrs);
115
            app.packageName = xml.getAttribute("packageName", attrs);
116
            app.appID = xml.getAttribute("appID", attrs);
117
 
118
            string a;
119
 
120
            while ((index = xml.getNextElementFromIndex(index, &a, &content, &attrs)) != TExpat::npos)
121
            {
122
                if (a.compare("Info") == 0)
123
                    app.appInfo = content;
124
                else if (a.compare("Window") == 0)
125
                {
126
                    app.appWindow.aspectFixed = xml.getAttributeBool("aspectFixed", attrs);
127
                    string s;
128
 
129
                    while ((index = xml.getNextElementFromIndex(index, &s, &content, &attrs)) != TExpat::npos)
130
                    {
131
                        if (s.compare("AspectRatios") == 0)
132
                        {
133
                            APP_ASPECT_RATIO_t ar;
134
                            string r;
135
 
136
                            while ((index = xml.getNextElementFromIndex(index, &r, &content, &attrs)) != TExpat::npos)
137
                            {
138
                                if (r.compare("AspectRatio") == 0)
139
                                {
140
                                    ar.percent = xml.getAttributeDouble("percent", attrs);
141
                                    ar.ratioWidth = xml.getAttributeInt("ratioWidth", attrs);
142
                                    ar.ratioHeight = xml.getAttributeInt("ratioHeight", attrs);
143
                                    app.appWindow.aspectRatios.push_back(ar);
144
                                }
486 andreas 145
 
146
                                oldIndex = index;
480 andreas 147
                            }
486 andreas 148
 
149
                            index = oldIndex + 1;
480 andreas 150
                        }
151
                        else if (s.compare("AspectRatioLimits") == 0)
152
                        {
153
                            app.appWindow.aspectRatioLimits.minWidth = xml.getAttributeInt("minWidth", attrs);
154
                            app.appWindow.aspectRatioLimits.minHeight = xml.getAttributeInt("minHeight", attrs);
155
                        }
486 andreas 156
 
157
                        oldIndex = index;
480 andreas 158
                    }
486 andreas 159
 
160
                    index = oldIndex + 1;
480 andreas 161
                }
162
                else if (a.compare("Images") == 0)
163
                {
164
                    string i;
165
 
166
                    while ((index = xml.getNextElementFromIndex(index, &i, &content, &attrs)) != TExpat::npos)
167
                    {
168
                        if (i.compare("ThumbImage") == 0)
169
                            app.appImages.thumbImage = content;
170
                        else if (i.compare("WindowImage") == 0)
171
                            app.appImages.windowImage = content;
486 andreas 172
 
173
                        oldIndex = index;
480 andreas 174
                    }
486 andreas 175
 
176
                    index = oldIndex + 1;
480 andreas 177
                }
486 andreas 178
                else if (a.compare("Parameters") == 0)
480 andreas 179
                {
180
                    string p;
486 andreas 181
                    MSG_DEBUG("Section \"" << name << "\" entered");
480 andreas 182
 
183
                    while ((index = xml.getNextElementFromIndex(index, &p, &content, &attrs)) != TExpat::npos)
184
                    {
185
                        if (p.compare("Parameter") == 0)
186
                        {
486 andreas 187
                            APP_PARAMETER_t par;
188
 
480 andreas 189
                            par.name = xml.getAttribute("name", attrs);
486 andreas 190
                            par.fullName = xml.getAttribute("fullName", attrs);
480 andreas 191
                            par.eDataType = xml.getAttribute("eDataType", attrs);
192
                            par.value = xml.getAttribute("value", attrs);
193
                            par.info = xml.getAttribute("info", attrs);
486 andreas 194
                            par.valueRequired = xml.getAttributeBool("valueRequired", attrs);
480 andreas 195
 
486 andreas 196
                            if (!xml.isElementTypeAtomic(index))
480 andreas 197
                            {
486 andreas 198
                                APP_PAR_STRINGS_t val;
199
                                string v;
200
 
201
                                while ((index = xml.getNextElementFromIndex(index, &v, &content, &attrs)) != TExpat::npos)
480 andreas 202
                                {
486 andreas 203
                                    if (v.compare("StringValues") == 0)
204
                                    {
205
                                        string sv;
480 andreas 206
 
486 andreas 207
                                        while ((index = xml.getNextElementFromIndex(index, &sv, &content, &attrs)) != TExpat::npos)
480 andreas 208
                                        {
486 andreas 209
                                            if (sv.compare("StringValue") == 0)
210
                                            {
211
                                                val.key = xml.getAttribute("key", attrs);
212
                                                val.value = content;
213
                                                par.stringValues.push_back(val);
214
                                            }
215
 
216
                                            oldIndex = index;
480 andreas 217
                                        }
486 andreas 218
 
219
                                        index = oldIndex + 1;
480 andreas 220
                                    }
486 andreas 221
 
222
                                    oldIndex = index;
480 andreas 223
                                }
486 andreas 224
 
225
                                index = oldIndex + 1;
480 andreas 226
                            }
486 andreas 227
 
228
                            app.parameters.push_back(par);
480 andreas 229
                        }
486 andreas 230
 
231
                        oldIndex = index;
480 andreas 232
                    }
233
 
486 andreas 234
                    index = oldIndex + 1;
480 andreas 235
                }
486 andreas 236
 
237
                oldIndex = index;
480 andreas 238
            }
239
 
240
            mAppSettings.push_back(app);
486 andreas 241
            index = oldIndex + 1;
480 andreas 242
        }
486 andreas 243
    }
244
 
245
    if ((index = xml.getElementIndex("WindowFrames", &depth)) == TExpat::npos)
246
    {
247
        MSG_WARNING("File does not contain the element \"WindowFrames\"!");
248
        TError::setError();
249
        return false;
250
    }
251
 
252
    string w;
253
    APP_WINDOW_FRAME_t wf;
254
    depth++;
255
    oldIndex = 0;
256
 
257
    while ((index = xml.getNextElementFromIndex(index, &w, &content, &attrs)) != TExpat::npos)
258
    {
259
        if (w.compare("WindowFrame") == 0)
480 andreas 260
        {
486 andreas 261
            wf.eType = xml.getAttribute("eType", attrs);
262
            wf.edgeSize = xml.getAttributeInt("edgeSize", attrs);
263
            wf.barSize = xml.getAttributeInt("barSize", attrs);
264
            string b;
480 andreas 265
 
486 andreas 266
            while ((index = xml.getNextElementFromIndex(index, &b, &content, &attrs)) != TExpat::npos)
480 andreas 267
            {
486 andreas 268
                APP_BUTTON_t button;
269
 
270
                if (b.compare("Buttons") == 0)
480 andreas 271
                {
486 andreas 272
                    string a;
480 andreas 273
 
486 andreas 274
                    while ((index = xml.getNextElementFromIndex(index, &a, &content, &attrs)) != TExpat::npos)
480 andreas 275
                    {
486 andreas 276
                        if (a.compare("Button") == 0)
480 andreas 277
                        {
486 andreas 278
                            button.eLocation = xml.getAttribute("eLocation", attrs);
279
                            button.order = xml.getAttributeInt("order", attrs);
280
                            button.spacing = xml.getAttributeInt("spacing", attrs);
281
                            string i;
480 andreas 282
 
486 andreas 283
                            while ((index = xml.getNextElementFromIndex(index, &i, &content, &attrs)) != TExpat::npos)
480 andreas 284
                            {
486 andreas 285
                                if (i.compare("ButtonImage") == 0)
286
                                    button.buttonImage.push_back(content);
480 andreas 287
 
486 andreas 288
                                oldIndex = index;
480 andreas 289
                            }
290
 
486 andreas 291
                            index = oldIndex + 1;
480 andreas 292
                        }
486 andreas 293
 
294
                        oldIndex = index;
480 andreas 295
                    }
296
 
486 andreas 297
                    wf.buttons.push_back(button);
298
                    index = oldIndex + 1;
480 andreas 299
                }
486 andreas 300
 
301
                oldIndex = index;
480 andreas 302
            }
486 andreas 303
 
304
            mWindowFrames.push_back(wf);
305
            index = oldIndex + 1;
480 andreas 306
        }
307
    }
308
 
486 andreas 309
    if (TStreamError::checkFilter(HLOG_DEBUG))
310
    {
311
        MSG_DEBUG("Supported apps:");
312
 
313
        std::vector<APP_SETTINGS_t>::iterator iter;
314
 
315
        for (iter = mAppSettings.begin(); iter != mAppSettings.end(); ++iter)
316
        {
317
            MSG_DEBUG("     Application:   " << iter->appName);
318
            MSG_DEBUG("     App ID:        " << iter->appID);
319
            MSG_DEBUG("     App info:      " << iter->appInfo);
320
            MSG_DEBUG("     Parameters:    " << iter->parameters.size());
321
            MSG_DEBUG("     Thumb image:   " << iter->appImages.thumbImage);
322
            MSG_DEBUG("     Wind. image:   " << iter->appImages.windowImage);
323
            MSG_DEBUG("     Wind. aspect:  " << (iter->appWindow.aspectFixed ? "TRUE" : "FALSE"));
324
            MSG_DEBUG("     Aspect ratios: " << iter->appWindow.aspectRatios.size());
325
            MSG_DEBUG("     Aspect limits: " << iter->appWindow.aspectRatioLimits.minWidth << " x " << iter->appWindow.aspectRatioLimits.minHeight << "\n");
326
        }
327
 
328
        MSG_DEBUG("Defined window frames: ");
329
 
330
        std::vector<APP_WINDOW_FRAME_t>::iterator witer;
331
 
332
        for (witer = mWindowFrames.begin(); witer != mWindowFrames.end(); ++witer)
333
        {
334
            MSG_DEBUG("     Frame type: " << witer->eType);
335
            std::vector<APP_BUTTON_t>::iterator biter;
336
 
337
            for (biter = witer->buttons.begin(); biter != witer->buttons.end(); ++biter)
338
            {
339
                MSG_DEBUG("         Button order:    " << biter->order);
340
                MSG_DEBUG("         Button location: " << biter->eLocation);
341
            }
342
        }
343
    }
344
 
480 andreas 345
    return true;
346
}
347
 
348
APP_SETTINGS_t TApps::getApp(const string& name)
349
{
350
    DECL_TRACER("TApps::getApp(const string& name)");
351
 
352
    if (mAppSettings.empty())
353
        return APP_SETTINGS_t();
354
 
355
    vector<APP_SETTINGS_t>::iterator iter;
356
 
357
    for (iter = mAppSettings.begin(); iter != mAppSettings.end(); ++iter)
358
    {
359
        if (iter->appID == name)
360
            return *iter;
361
    }
362
 
363
    return APP_SETTINGS_t();
364
}
365
 
366
APP_WINDOW_FRAME_t TApps::getWindowFrame(const string& type)
367
{
368
    DECL_TRACER("TApps::getWindowFrame(const string& type)");
369
 
370
    if (mWindowFrames.empty())
371
        return APP_WINDOW_FRAME_t();
372
 
373
    vector<APP_WINDOW_FRAME_t>::iterator iter;
374
 
375
    for (iter = mWindowFrames.begin(); iter != mWindowFrames.end(); ++iter)
376
    {
377
        if (iter->eType == type)
378
            return *iter;
379
    }
380
 
381
    return APP_WINDOW_FRAME_t();
382
}