Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
72 andreas 1
/*
262 andreas 2
 * Copyright (C) 2021 to 2023 by Andreas Theofilu <andreas@theosys.at>
72 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 <fstream>
20
#include <functional>
21
 
22
#include <expat.h>
23
 
24
#include "tsystemdraw.h"
80 andreas 25
#include "tdirectory.h"
72 andreas 26
#include "tresources.h"
27
#include "terror.h"
28
 
415 andreas 29
#if __cplusplus < 201402L
30
#   error "This module requires at least C++14 standard!"
31
#else
32
#   if __cplusplus < 201703L
33
#       include <experimental/filesystem>
34
namespace fs = std::experimental::filesystem;
35
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
36
#   else
37
#       include <filesystem>
38
#       ifdef __ANDROID__
39
namespace fs = std::__fs::filesystem;
40
#       else
41
namespace fs = std::filesystem;
42
#       endif
43
#   endif
44
#endif
45
 
72 andreas 46
using std::string;
47
using std::vector;
48
using std::ifstream;
49
 
50
TSystemDraw::XELEMENTS_t TSystemDraw::mActData = TSystemDraw::X_NONE;
51
TSystemDraw::XELEMENTS_t TSystemDraw::mActFamily = TSystemDraw::X_NONE;
52
string TSystemDraw::mActElement;
53
 
54
TSystemDraw::TSystemDraw(const string &path)
55
    : mPath(path)
56
{
57
    DECL_TRACER("TSystemDraw::TSystemDraw(const string &path)");
58
 
59
    if (isValidDir(path))
60
        mValid = true;
61
    else
62
    {
63
        MSG_WARNING("No or invalid path!");
64
        return;
65
    }
66
 
67
    if (isValidDir(path + "/borders"))
115 andreas 68
        mHaveBorders = true;
69
    else
99 andreas 70
    {
71
        MSG_WARNING("Have no system border images");
72
    }
72 andreas 73
 
74
    if (isValidDir(path + "/cursors"))
115 andreas 75
        mHaveCursors = true;
76
    else
99 andreas 77
    {
78
        MSG_WARNING("Have no system cursor images");
79
    }
72 andreas 80
 
81
    if (isValidDir(path + "/fonts"))
115 andreas 82
        mHaveFonts = true;
330 andreas 83
    else
99 andreas 84
    {
85
        MSG_WARNING("Have no system fonts");
156 andreas 86
        string perms = getPermissions(path);
87
        MSG_PROTOCOL("Looked for system fonts at: " << path << "/fonts -- [" << perms << "]");
99 andreas 88
    }
72 andreas 89
 
90
    if (isValidDir(path + "/images"))
115 andreas 91
        mHaveImages = true;
92
    else
99 andreas 93
    {
94
        MSG_WARNING("Have no system images");
95
    }
72 andreas 96
 
97
    if (isValidDir(path + "/sliders"))
115 andreas 98
        mHaveSliders = true;
99
    else
99 andreas 100
    {
101
        MSG_WARNING("Have no system slider images");
102
    }
72 andreas 103
 
104
    if (isValidFile(path + "/draw.xma"))
105
        loadConfig();
99 andreas 106
    else
107
    {
108
        MSG_WARNING("Have no system configuration file draw.xma!");
109
    }
72 andreas 110
}
111
 
112
TSystemDraw::~TSystemDraw()
113
{
114
    DECL_TRACER("TSystemDraw::~TSystemDraw()");
115
}
116
 
117
bool TSystemDraw::loadConfig()
118
{
119
    DECL_TRACER("TSystemDraw::loadConfig()");
120
 
121
    string buf;
122
    string file = mPath + "/draw.xma";
123
    size_t size = 0;
124
 
125
    // First we read the whole XML file into a buffer
126
    try
127
    {
128
        ifstream stream(file, std::ios::in);
129
 
130
        if (!stream || !stream.is_open())
131
            return false;
132
 
133
        stream.seekg(0, stream.end);    // Find the end of the file
134
        size = stream.tellg();          // Get the position and save it
135
        stream.seekg(0, stream.beg);    // rewind to the beginning of the file
136
 
137
        buf.resize(size, '\0');         // Initialize the buffer with zeros
138
        char *begin = &*buf.begin();    // Assign the plain data buffer
139
        stream.read(begin, size);       // Read the whole file
140
        stream.close();                 // Close the file
141
    }
142
    catch (std::exception& e)
143
    {
144
        MSG_ERROR("File error: " << e.what());
145
        return false;
146
    }
147
 
148
    // Now we parse the file and write the relevant contents into our internal
149
    // variables.
150
    // First we initialialize the parser.
151
    int depth = 0;
152
    int done = 1;   // 1 = Buffer is complete
153
    XML_Parser parser = XML_ParserCreate(NULL);
154
    XML_SetUserData(parser, &depth);
155
    XML_SetElementHandler(parser, &TSystemDraw::startElement, &TSystemDraw::endElement);
156
    XML_SetCharacterDataHandler(parser, &TSystemDraw::CharacterDataHandler);
157
    XML_SetUserData(parser, &mDraw);
158
 
159
    if (XML_Parse(parser, buf.data(), size, done) == XML_STATUS_ERROR)
160
    {
161
        MSG_ERROR(XML_ErrorString(XML_GetErrorCode(parser)) << " at line " << XML_GetCurrentLineNumber(parser));
162
        XML_ParserFree(parser);
163
        return false;
164
    }
165
 
166
    XML_ParserFree(parser);
194 andreas 167
/*
73 andreas 168
    if (TStreamError::checkFilter(HLOG_DEBUG))
169
    {
170
        for (size_t i = 0; i < mDraw.borders.size(); i++)
171
        {
172
            MSG_DEBUG("Border family: " << mDraw.borders.at(i).name);
173
 
174
            for (size_t j = 0; j < mDraw.borders.at(i).member.size(); j++)
175
            {
176
                MSG_DEBUG("       Member: " << mDraw.borders.at(i).member.at(j));
177
                MSG_DEBUG("Border styles:");
178
 
179
                for (size_t x = 0; x < mDraw.borderStyles.size(); x++)
180
                {
181
                    if (mDraw.borderStyles.at(x).name.compare(mDraw.borders.at(i).member.at(j)) == 0)
182
                    {
183
                        MSG_DEBUG("         Name: " << mDraw.borderStyles.at(x).name);
184
                        MSG_DEBUG("          Off: " << mDraw.borderStyles.at(x).off);
185
                        MSG_DEBUG("           On: " << mDraw.borderStyles.at(x).on);
186
                        MSG_DEBUG("         Drag: " << mDraw.borderStyles.at(x).drag);
187
                        MSG_DEBUG("         Drop: " << mDraw.borderStyles.at(x).drop);
188
 
189
                        if (mDraw.borderStyles.at(x).g3Equiv.size() > 0)
190
                        {
191
                            for (size_t y = 0; y < mDraw.borderStyles.at(x).g3Equiv.size(); y++)
192
                                MSG_DEBUG("      g3Equiv: " << mDraw.borderStyles.at(x).g3Equiv.at(y));
193
                        }
194
 
79 andreas 195
                        vector<BORDER_DATA_t>::iterator bdIter;
73 andreas 196
 
79 andreas 197
                        for (bdIter = mDraw.borderData.begin(); bdIter != mDraw.borderData.end(); ++bdIter)
73 andreas 198
                        {
79 andreas 199
                            if (bdIter->name.compare(mDraw.borderStyles.at(x).name) == 0)
200
                            {
201
                                MSG_DEBUG("           Name: " << bdIter->name);
202
                                MSG_DEBUG("       baseFile: " << bdIter->baseFile);
203
                                MSG_DEBUG("     idealWidth: " << bdIter->idealWidth);
204
                                MSG_DEBUG("    idealHeight: " << bdIter->idealHeight);
205
                                break;
206
                            }
73 andreas 207
                        }
208
                    }
209
                }
210
            }
211
        }
99 andreas 212
 
213
        for (size_t i = 0; i < mDraw.sliders.size(); i++)
214
        {
215
            MSG_DEBUG("Slider family: " << mDraw.sliders.at(i).name);
216
 
217
            for (size_t j = 0; j < mDraw.sliders.at(i).member.size(); j++)
218
            {
219
                MSG_DEBUG("       Member: " << mDraw.sliders.at(i).member.at(j));
220
                MSG_DEBUG("Slider styles:");
221
 
222
                for (size_t x = 0; x < mDraw.sliderStyles.size(); x++)
223
                {
224
                    if (mDraw.sliderStyles.at(x).name.compare(mDraw.sliders.at(i).member.at(j)) == 0)
225
                    {
226
                        MSG_DEBUG("         Name: " << mDraw.sliderStyles.at(x).name);
227
                        MSG_DEBUG("     baseFile: " << mDraw.sliderStyles.at(x).baseFile);
228
                        MSG_DEBUG("   multiColor: " << mDraw.sliderStyles.at(x).multiColor);
229
                        MSG_DEBUG("    incRepeat: " << mDraw.sliderStyles.at(x).incRepeat);
230
                        MSG_DEBUG("      minSize: " << mDraw.sliderStyles.at(x).minSize);
231
                        MSG_DEBUG("    fixedSize: " << mDraw.sliderStyles.at(x).fixedSize);
232
                    }
233
                }
234
            }
235
        }
73 andreas 236
    }
194 andreas 237
*/
72 andreas 238
    return true;
239
}
240
 
73 andreas 241
void TSystemDraw::startElement(void *, const XML_Char *name, const XML_Char **)
72 andreas 242
{
243
    mActElement.assign(name);
244
 
245
    if (strCaseCompare(name, "borderData") == 0)
246
        mActData = X_BORDER_DATA;
247
 
79 andreas 248
    if (strCaseCompare(name, "border") == 0)
249
        mActFamily = X_BORDER;
250
 
72 andreas 251
    if (strCaseCompare(name, "borderFamily") == 0)
252
        mActFamily = X_BORDER_FAMILY;
73 andreas 253
 
254
    if (strCaseCompare(name, "borderStyle") == 0)
255
        mActFamily = X_BORDER_STYLE;
256
 
257
    if (strCaseCompare(name, "cursorData") == 0)
258
        mActData = X_CURSOR_DATA;
259
 
260
    if (strCaseCompare(name, "cursorFamily") == 0)
261
        mActFamily = X_CURSOR_FAMILY;
262
 
416 andreas 263
    if (strCaseCompare(name, "cursor") == 0 || strCaseCompare(name, "cursorStyle") == 0)
73 andreas 264
        mActFamily = X_CURSOR_STYLE;
265
 
266
    if (strCaseCompare(name, "sliderData") == 0)
267
        mActData = X_SLIDER_DATA;
268
 
269
    if (strCaseCompare(name, "sliderFamily") == 0)
270
        mActFamily = X_SLIDER_FAMILY;
271
 
99 andreas 272
    if (strCaseCompare(name, "slider") == 0)
73 andreas 273
        mActFamily = X_SLIDER_STYLE;
274
 
275
    if (strCaseCompare(name, "effectData") == 0)
276
        mActData = X_EFFECT_DATA;
277
 
278
    if (strCaseCompare(name, "effectFamily") == 0)
279
        mActFamily = X_EFFECT_FAMILY;
280
 
281
    if (strCaseCompare(name, "effect") == 0)
282
        mActFamily = X_EFFECT_STYLE;
283
 
284
    if (strCaseCompare(name, "popupEffectData") == 0)
285
        mActData = X_POPUP_EFFECT_DATA;
286
 
287
    if (strCaseCompare(name, "popupEffect") == 0)
288
        mActFamily = X_POPUP_EFFECT;
72 andreas 289
}
290
 
73 andreas 291
void TSystemDraw::endElement(void *, const XML_Char *name)
72 andreas 292
{
293
    if (strCaseCompare(name, "borderData") == 0)
294
        mActData = X_NONE;
295
 
79 andreas 296
    if (strCaseCompare(name, "border") == 0)
297
        mActFamily = X_NONE;
298
 
72 andreas 299
    if (strCaseCompare(name, "borderFamily") == 0)
300
        mActFamily = X_NONE;
73 andreas 301
 
302
    if (strCaseCompare(name, "borderStyle") == 0)
303
        mActFamily = X_NONE;
304
 
305
    if (strCaseCompare(name, "cursorData") == 0)
306
        mActData = X_NONE;
307
 
308
    if (strCaseCompare(name, "cursorFamily") == 0)
309
        mActFamily = X_NONE;
310
 
311
    if (strCaseCompare(name, "cursorStyle") == 0)
312
        mActFamily = X_NONE;
313
 
314
    if (strCaseCompare(name, "sliderData") == 0)
315
        mActData = X_NONE;
316
 
317
    if (strCaseCompare(name, "sliderFamily") == 0)
318
        mActFamily = X_NONE;
319
 
320
    if (strCaseCompare(name, "sliderStyle") == 0)
321
        mActFamily = X_NONE;
322
 
323
    if (strCaseCompare(name, "effectData") == 0)
324
        mActData = X_NONE;
325
 
326
    if (strCaseCompare(name, "effectFamily") == 0)
327
        mActFamily = X_NONE;
328
 
329
    if (strCaseCompare(name, "effect") == 0)
330
        mActFamily = X_NONE;
331
 
332
    if (strCaseCompare(name, "popupEffectData") == 0)
333
        mActData = X_NONE;
334
 
335
    if (strCaseCompare(name, "popupEffect") == 0)
336
        mActFamily = X_NONE;
72 andreas 337
}
338
 
339
void TSystemDraw::CharacterDataHandler(void *userData, const XML_Char *s, int len)
340
{
73 andreas 341
    if (len <= 0 || !userData || !s || mActData == X_NONE || mActFamily == X_NONE)
342
        return;
343
 
79 andreas 344
    DRAW_t *draw = (DRAW_t *)userData;
72 andreas 345
    string content(s, len);
73 andreas 346
    content = trim(content);
72 andreas 347
 
73 andreas 348
    if (content.empty())
349
        return;
72 andreas 350
 
73 andreas 351
    switch(mActData)
352
    {
353
        case X_BORDER_DATA:
354
            switch(mActFamily)
355
            {
356
                case X_BORDER_FAMILY:
357
                    if (mActElement.compare("name") == 0)
358
                    {
359
                        FAMILY_t bf;
360
                        bf.name = content;
361
                        draw->borders.push_back(bf);
362
                    }
363
                    else if (mActElement.compare("member") == 0)
364
                        draw->borders.back().member.push_back(content);
365
                break;
366
 
367
                case X_BORDER_STYLE:
368
                    if (mActElement.compare("name") == 0)
369
                    {
370
                        BORDER_STYLE_t bs;
371
                        bs.name = content;
372
                        draw->borderStyles.push_back(bs);
373
                    }
374
                    else if (mActElement.compare("off") == 0)
375
                        draw->borderStyles.back().off = content;
376
                    else if (mActElement.compare("on") == 0)
377
                        draw->borderStyles.back().on = content;
378
                    else if (mActElement.compare("drag") == 0)
379
                        draw->borderStyles.back().drag = content;
380
                    else if (mActElement.compare("drop") == 0)
381
                        draw->borderStyles.back().drop = content;
382
                    else if (mActElement.compare("g3Equiv") == 0)
79 andreas 383
                        draw->borderStyles.back().g3Equiv.push_back(atoi(content.c_str()));
384
                break;
385
 
386
                case X_BORDER:
387
                    if (mActElement.compare("name") == 0)
73 andreas 388
                    {
79 andreas 389
                        BORDER_DATA_t bd;
118 andreas 390
                        bd.init();
79 andreas 391
                        bd.name = content;
392
                        draw->borderData.push_back(bd);
73 andreas 393
                    }
79 andreas 394
                    else if (mActElement.compare("baseFile") == 0)
395
                        draw->borderData.back().baseFile = content;
396
                    else if (mActElement.compare("multiColor") == 0)
397
                        draw->borderData.back().multiColor = atoi(content.c_str());
398
                    else if (mActElement.compare("fillTop") == 0)
399
                        draw->borderData.back().fillTop = atoi(content.c_str());
400
                    else if (mActElement.compare("fillLeft") == 0)
401
                        draw->borderData.back().fillLeft = atoi(content.c_str());
402
                    else if (mActElement.compare("fillBottom") == 0)
403
                        draw->borderData.back().fillBottom = atoi(content.c_str());
404
                    else if (mActElement.compare("fillRight") == 0)
405
                        draw->borderData.back().fillRight = atoi(content.c_str());
406
                    else if (mActElement.compare("textTop") == 0)
407
                        draw->borderData.back().textTop = atoi(content.c_str());
408
                    else if (mActElement.compare("textLeft") == 0)
409
                        draw->borderData.back().textLeft = atoi(content.c_str());
410
                    else if (mActElement.compare("textBottom") == 0)
411
                        draw->borderData.back().textBottom = atoi(content.c_str());
412
                    else if (mActElement.compare("textRight") == 0)
413
                        draw->borderData.back().textRight = atoi(content.c_str());
414
                    else if (mActElement.compare("idealWidth") == 0)
415
                        draw->borderData.back().idealWidth = atoi(content.c_str());
416
                    else if (mActElement.compare("idealHeight") == 0)
417
                        draw->borderData.back().idealHeight = atoi(content.c_str());
418
                    else if (mActElement.compare("minHeight") == 0)
419
                        draw->borderData.back().minHeight = atoi(content.c_str());
420
                    else if (mActElement.compare("minWidth") == 0)
421
                        draw->borderData.back().minWidth = atoi(content.c_str());
422
                    else if (mActElement.compare("incHeight") == 0)
423
                        draw->borderData.back().incHeight = atoi(content.c_str());
424
                    else if (mActElement.compare("incWidth") == 0)
425
                        draw->borderData.back().incWidth = atoi(content.c_str());
73 andreas 426
                break;
427
 
428
                default:
429
                    MSG_WARNING("Unknown border element \"" << mActElement << "\" with content \"" << content << "\"");
430
            }
431
        break;
432
 
433
        case X_CURSOR_DATA:
434
            switch(mActFamily)
435
            {
436
                case X_CURSOR_FAMILY:
437
                    if (mActElement.compare("name") == 0)
438
                    {
439
                        DRAW_t *draw = (DRAW_t *)userData;
440
                        FAMILY_t cf;
441
                        cf.name = content;
442
                        draw->cursors.push_back(cf);
443
                    }
444
                    else if (mActElement.compare("member") == 0)
445
                    {
446
                        DRAW_t *draw = (DRAW_t *)userData;
447
                        draw->cursors.back().member.push_back(content);
448
                    }
449
                break;
450
 
451
                case X_CURSOR_STYLE:
452
                    if (mActElement.compare("name") == 0)
453
                    {
454
                        DRAW_t *draw = (DRAW_t *)userData;
455
                        CURSOR_STYLE_t cs;
118 andreas 456
                        cs.init();
73 andreas 457
                        cs.name = content;
458
                        draw->cursorStyles.push_back(cs);
459
                    }
460
                    else if (mActElement.compare("baseFile") == 0)
461
                    {
462
                        DRAW_t *draw = (DRAW_t *)userData;
463
                        draw->cursorStyles.back().baseFile = content;
464
                    }
465
                    else if (mActElement.compare("multiColor") == 0)
466
                    {
467
                        DRAW_t *draw = (DRAW_t *)userData;
468
                        draw->cursorStyles.back().multiColor = atoi(content.c_str());
469
                    }
470
                    else if (mActElement.compare("g3Equiv") == 0)
471
                    {
472
                        DRAW_t *draw = (DRAW_t *)userData;
473
                        draw->cursorStyles.back().g3Equiv.push_back(atoi(content.c_str()));
474
                    }
475
                break;
476
 
477
                default:
478
                    MSG_WARNING("Unknown cursor element \"" << mActElement << "\" with content \"" << content << "\"");
479
            }
480
        break;
481
 
482
        case X_SLIDER_DATA:
483
            switch(mActFamily)
484
            {
485
                case X_SLIDER_FAMILY:
486
                    if (mActElement.compare("name") == 0)
487
                    {
488
                        DRAW_t *draw = (DRAW_t *)userData;
489
                        FAMILY_t sf;
490
                        sf.name = content;
491
                        draw->sliders.push_back(sf);
492
                    }
493
                    else if (mActElement.compare("member") == 0)
494
                    {
495
                        DRAW_t *draw = (DRAW_t *)userData;
496
                        draw->sliders.back().member.push_back(content);
497
                    }
498
                break;
499
 
500
                case X_SLIDER_STYLE:
501
                    if (mActElement.compare("name") == 0)
502
                    {
503
                        DRAW_t *draw = (DRAW_t *)userData;
504
                        SLIDER_STYLE_t ss;
118 andreas 505
                        ss.init();
73 andreas 506
                        ss.name = content;
507
                        draw->sliderStyles.push_back(ss);
508
                    }
509
                    else if (mActElement.compare("baseFile") == 0)
510
                    {
511
                        DRAW_t *draw = (DRAW_t *)userData;
512
                        draw->sliderStyles.back().baseFile = content;
513
                    }
514
                    else if (mActElement.compare("multiColor") == 0)
515
                    {
516
                        DRAW_t *draw = (DRAW_t *)userData;
517
                        draw->sliderStyles.back().multiColor = atoi(content.c_str());
518
                    }
519
                    else if (mActElement.compare("incRepeat") == 0)
520
                    {
521
                        DRAW_t *draw = (DRAW_t *)userData;
522
                        draw->sliderStyles.back().incRepeat = atoi(content.c_str());
523
                    }
524
                    else if (mActElement.compare("minSize") == 0)
525
                    {
526
                        DRAW_t *draw = (DRAW_t *)userData;
527
                        draw->sliderStyles.back().minSize = atoi(content.c_str());
528
                    }
529
                    else if (mActElement.compare("fixedSize") == 0)
530
                    {
531
                        DRAW_t *draw = (DRAW_t *)userData;
532
                        draw->sliderStyles.back().fixedSize = atoi(content.c_str());
533
                    }
534
                    else if (mActElement.compare("g3Equiv") == 0)
535
                    {
536
                        DRAW_t *draw = (DRAW_t *)userData;
537
                        draw->sliderStyles.back().g3Equiv.push_back(atoi(content.c_str()));
538
                    }
539
                break;
540
 
541
                default:
542
                    MSG_WARNING("Unknown slider element \"" << mActElement << "\" with content \"" << content << "\"");
543
            }
544
        break;
545
 
546
        case X_EFFECT_DATA:
547
            switch(mActFamily)
548
            {
549
                case X_EFFECT_FAMILY:
550
                    if (mActElement.compare("name") == 0)
551
                    {
552
                        DRAW_t *draw = (DRAW_t *)userData;
553
                        FAMILY_t ef;
554
                        ef.name = content;
555
                        draw->effects.push_back(ef);
556
                    }
557
                    else if (mActElement.compare("member") == 0)
558
                    {
559
                        DRAW_t *draw = (DRAW_t *)userData;
560
                        draw->effects.back().member.push_back(content);
561
                    }
562
                break;
563
 
564
                case X_EFFECT_STYLE:
565
                    if (mActElement.compare("name") == 0)
566
                    {
567
                        DRAW_t *draw = (DRAW_t *)userData;
568
                        EFFECT_STYLE_t es;
118 andreas 569
                        es.init();
73 andreas 570
                        es.name = content;
571
                        draw->effectStyles.push_back(es);
572
                    }
573
                    else if (mActElement.compare("number") == 0)
574
                    {
575
                        DRAW_t *draw = (DRAW_t *)userData;
576
                        draw->effectStyles.back().number = atoi(content.c_str());
577
                    }
578
                    else if (mActElement.compare("startX") == 0)
579
                    {
580
                        DRAW_t *draw = (DRAW_t *)userData;
581
                        draw->effectStyles.back().startx = atoi(content.c_str());
582
                    }
583
                    else if (mActElement.compare("startY") == 0)
584
                    {
585
                        DRAW_t *draw = (DRAW_t *)userData;
586
                        draw->effectStyles.back().starty = atoi(content.c_str());
587
                    }
588
                    else if (mActElement.compare("height") == 0)
589
                    {
590
                        DRAW_t *draw = (DRAW_t *)userData;
591
                        draw->effectStyles.back().height = atoi(content.c_str());
592
                    }
593
                    else if (mActElement.compare("width") == 0)
594
                    {
595
                        DRAW_t *draw = (DRAW_t *)userData;
596
                        draw->effectStyles.back().width = atoi(content.c_str());
597
                    }
598
                    else if (mActElement.compare("cutout") == 0)
599
                    {
600
                        DRAW_t *draw = (DRAW_t *)userData;
601
                        draw->effectStyles.back().cutout = atoi(content.c_str());
602
                    }
603
                    else if (mActElement.compare("pixelMap") == 0)
604
                    {
605
                        DRAW_t *draw = (DRAW_t *)userData;
606
                        draw->effectStyles.back().pixelMap = content;
607
                    }
608
                break;
609
 
610
                default:
611
                    MSG_WARNING("Unknown effect element \"" << mActElement << "\" with content \"" << content << "\"");
612
            }
613
        break;
614
 
615
        case X_POPUP_EFFECT_DATA:
616
            if (mActFamily == X_POPUP_EFFECT)
617
            {
618
                if (mActElement.compare("name") == 0)
619
                {
620
                    DRAW_t *draw = (DRAW_t *)userData;
621
                    POPUP_EFFECT_t pe;
118 andreas 622
                    pe.init();
73 andreas 623
                    pe.name = content;
624
                    draw->popupEffects.push_back(pe);
625
                }
626
                else if (mActElement.compare("number") == 0)
627
                {
628
                    DRAW_t *draw = (DRAW_t *)userData;
629
                    draw->popupEffects.back().number = atoi(content.c_str());
630
                }
631
                else if (mActElement.compare("valueUsed") == 0)
632
                {
633
                    DRAW_t *draw = (DRAW_t *)userData;
634
                    draw->popupEffects.back().valueUsed = atoi(content.c_str());
635
                }
636
            }
637
        break;
638
 
639
        default:
640
            MSG_WARNING("Unknown data element \"" << mActElement << "\" with content \"" << content << "\"");
641
    }
72 andreas 642
}
79 andreas 643
 
159 andreas 644
string TSystemDraw::getDirEntry(dir::TDirectory* dir, const string& part, bool alpha)
645
{
646
    DECL_TRACER("TSystemDraw::getDirEntry(dir::TDirectory* dir, const string& part, bool precice)");
647
 
648
    string such = part;
649
 
650
    if (alpha)
651
        such += "_alpha";
652
 
653
    string dirEntry = dir->getEntryWithPart(such, true);
654
    such = part;
655
 
656
    if (dirEntry.empty())
657
        dirEntry = dir->getEntryWithPart(such, false);
658
 
659
    return dirEntry;
660
}
661
 
306 andreas 662
bool TSystemDraw::getBorder(const string &family, LINE_TYPE_t lt, BORDER_t *border, const string& family2, bool info)
79 andreas 663
{
306 andreas 664
    DECL_TRACER("TSystemDraw::getBorder(const string &family, LINE_TYPE_t lt, BORDER_t *border, const string& family2, bool info)");
79 andreas 665
 
99 andreas 666
    if (!border || family.empty() || mDraw.borders.size() == 0)
79 andreas 667
        return false;
668
 
404 andreas 669
    string basePath = mPath + "/borders/";
79 andreas 670
    // Find the border details
671
    vector<FAMILY_t>::iterator iter;
672
    bool found = false;
673
    string fullName;
674
 
675
    for (iter = mDraw.borders.begin(); iter != mDraw.borders.end(); ++iter)
676
    {
677
        vector<string>::iterator strIter;
678
 
679
        for (strIter = iter->member.begin(); strIter != iter->member.end(); ++strIter)
680
        {
222 andreas 681
            /*
682
             * In the table we've the "family" name in the first place while in
683
             * the configuration file for a page/subpage we have the whole name.
684
             * Because of this we must look if the whole name starts with the
685
             * family name. If so, we've found what we're looking for.
686
             * Example:
687
             * Whole name in the XML configuration: AMX Elite Raised -M
688
             * Family name: AMX Elite
689
             * Organization:
690
             * The entity "borderFamily" defines the family name (AMX Elite). A
691
             * family has members: "AMX Elite -S", "AMX Elite -M" and "AMX Elite -L"
692
             * in our example.
693
             * The entity "borderStyle" is named like the member. With this
694
             * information we'll find the correct border style and with it the
262 andreas 695
             * file names containing the border graphics.
222 andreas 696
             */
697
            vector<string>parts = StrSplit(*strIter, " ", true);
698
 
699
            if (evaluateName(parts, family))   // Here we find the wanted member
79 andreas 700
            {
701
                // Find the detailed name
702
                vector<BORDER_STYLE_t>::iterator styIter;
222 andreas 703
                // Here we search in the style table for an element with the
704
                // found member name
79 andreas 705
                for (styIter = mDraw.borderStyles.begin(); styIter != mDraw.borderStyles.end(); ++styIter)
706
                {
222 andreas 707
                    if (styIter->name.compare(*strIter) == 0)
79 andreas 708
                    {
709
                        found = true;
81 andreas 710
                        border->bdStyle = *styIter;
79 andreas 711
 
712
                        switch(lt)
713
                        {
714
                            case LT_OFF:    fullName = styIter->off; break;
715
                            case LT_ON:     fullName = styIter->on; break;
716
                            case LT_DRAG:   fullName = styIter->drag; break;
717
                            case LT_DROP:   fullName = styIter->drop; break;
718
                        }
719
 
169 andreas 720
 
79 andreas 721
                        break;
722
                    }
723
                }
724
            }
725
 
726
            if (found)
727
                break;
728
        }
729
 
730
        if (found)
731
            break;
732
    }
733
 
734
    if (!found || fullName.empty())
168 andreas 735
    {
736
        MSG_WARNING("Border " << family << " not found!");
79 andreas 737
        return false;
168 andreas 738
    }
79 andreas 739
 
307 andreas 740
    MSG_DEBUG("External system border " << family << " found.");
404 andreas 741
    dir::TDirectory dir(basePath);
80 andreas 742
    dir.setStripPath(true);
79 andreas 743
    vector<BORDER_DATA_t>::iterator brdIter;
169 andreas 744
    string dataName = (family2.length() > 0 ? family2 : fullName);
79 andreas 745
 
746
    for (brdIter = mDraw.borderData.begin(); brdIter != mDraw.borderData.end(); brdIter++)
747
    {
169 andreas 748
        if (brdIter->name.compare(dataName) == 0)
79 andreas 749
        {
306 andreas 750
            if (!info)
751
            {
339 andreas 752
                int num = dir.scanFiles(brdIter->baseFile + "_", true);
80 andreas 753
 
306 andreas 754
                if (num < 8)
755
                    continue;
80 andreas 756
 
404 andreas 757
                border->b = basePath + getDirEntry(&dir, "_b", false);
758
                border->bl = basePath + getDirEntry(&dir, "_bl", false);
759
                border->br = basePath + getDirEntry(&dir, "_br", false);
760
                border->l = basePath + getDirEntry(&dir, "_l", false);
761
                border->r = basePath + getDirEntry(&dir, "_r", false);
762
                border->t = basePath + getDirEntry(&dir, "_t", false);
763
                border->tl = basePath + getDirEntry(&dir, "_tl", false);
764
                border->tr = basePath + getDirEntry(&dir, "_tr", false);
765
                border->b_alpha = basePath + getDirEntry(&dir, "_b");
766
                border->bl_alpha = basePath + getDirEntry(&dir, "_bl");
767
                border->br_alpha = basePath + getDirEntry(&dir, "_br");
768
                border->l_alpha = basePath + getDirEntry(&dir, "_l");
769
                border->r_alpha = basePath + getDirEntry(&dir, "_r");
770
                border->t_alpha = basePath + getDirEntry(&dir, "_t");
771
                border->tl_alpha = basePath + getDirEntry(&dir, "_tl");
772
                border->tr_alpha = basePath + getDirEntry(&dir, "_tr");
306 andreas 773
                border->border = *brdIter;
404 andreas 774
                // Eliminate equal paths
775
                if (border->b == border->b_alpha)
776
                {
777
                    if (StrContains(border->b, "_alpha"))
778
                        border->b.clear();
779
                    else
780
                        border->b_alpha.clear();
781
                }
782
 
783
                if (border->t == border->t_alpha)
784
                {
785
                    if (StrContains(border->t, "_alpha"))
786
                        border->t.clear();
787
                    else
788
                        border->t_alpha.clear();
789
                }
790
 
791
                if (border->l == border->l_alpha)
792
                {
793
                    if (StrContains(border->l, "_alpha"))
794
                        border->l.clear();
795
                    else
796
                        border->l_alpha.clear();
797
                }
798
 
799
                if (border->r == border->r_alpha)
800
                {
801
                    if (StrContains(border->r, "_alpha"))
802
                        border->r.clear();
803
                    else
804
                        border->r_alpha.clear();
805
                }
806
 
807
                if (border->tl == border->tl_alpha)
808
                {
809
                    if (StrContains(border->tl, "_alpha"))
810
                        border->tl.clear();
811
                    else
812
                        border->tl_alpha.clear();
813
                }
814
 
815
                if (border->tr == border->tr_alpha)
816
                {
817
                    if (StrContains(border->tr, "_alpha"))
818
                        border->tr.clear();
819
                    else
820
                        border->tr_alpha.clear();
821
                }
822
 
823
                if (border->bl == border->bl_alpha)
824
                {
825
                    if (StrContains(border->bl, "_alpha"))
826
                        border->bl.clear();
827
                    else
828
                        border->bl_alpha.clear();
829
                }
830
 
831
                if (border->br == border->br_alpha)
832
                {
833
                    if (StrContains(border->br, "_alpha"))
834
                        border->br.clear();
835
                    else
836
                        border->br_alpha.clear();
837
                }
417 andreas 838
 
839
                MSG_DEBUG("Bottom        : " << border->b);
840
                MSG_DEBUG("Top           : " << border->t);
841
                MSG_DEBUG("Left          : " << border->l);
842
                MSG_DEBUG("Right         : " << border->r);
843
                MSG_DEBUG("Top left      : " << border->tl);
844
                MSG_DEBUG("Top right     : " << border->tr);
845
                MSG_DEBUG("Bottom left   : " << border->bl);
846
                MSG_DEBUG("Bottom right  : " << border->br);
847
                MSG_DEBUG("Bottom A      : " << border->b_alpha);
848
                MSG_DEBUG("Top A         : " << border->t_alpha);
849
                MSG_DEBUG("Left A        : " << border->l_alpha);
850
                MSG_DEBUG("Right A       : " << border->r_alpha);
851
                MSG_DEBUG("Top left A    : " << border->tl_alpha);
852
                MSG_DEBUG("Top right A   : " << border->tr_alpha);
853
                MSG_DEBUG("Bottom left A : " << border->bl_alpha);
854
                MSG_DEBUG("Bottom right A: " << border->br_alpha);
306 andreas 855
            }
856
            else
857
                border->border = *brdIter;
858
 
79 andreas 859
            return true;
860
        }
861
    }
862
 
863
    return false;
864
}
865
 
306 andreas 866
bool TSystemDraw::getBorderInfo(const std::string& family, LINE_TYPE_t lt, BORDER_t *border, const std::string& family2)
867
{
868
    DECL_TRACER("TSystemDraw::getBorderInfo(const std::string& family, LINE_TYPE_t lt, BORDER_t *border, const std::string& family2)");
869
 
870
    return getBorder(family, lt, border, family2, true);
871
}
872
 
79 andreas 873
bool TSystemDraw::existBorder(const string &family)
874
{
875
    DECL_TRACER("TSystemDraw::existBorder(const string &family)");
876
 
99 andreas 877
    if (family.empty() || mDraw.borders.size() == 0)
79 andreas 878
        return false;
879
 
880
    // Find the border details
881
    vector<FAMILY_t>::iterator iter;
882
 
883
    for (iter = mDraw.borders.begin(); iter != mDraw.borders.end(); ++iter)
884
    {
885
        vector<string>::iterator strIter;
886
 
887
        for (strIter = iter->member.begin(); strIter != iter->member.end(); ++strIter)
888
        {
222 andreas 889
            vector<string>parts = StrSplit(*strIter, " ", true);
890
 
891
            if (evaluateName(parts, family))
79 andreas 892
            {
893
                // Find the detailed name
894
                vector<BORDER_STYLE_t>::iterator styIter;
895
 
896
                for (styIter = mDraw.borderStyles.begin(); styIter != mDraw.borderStyles.end(); ++styIter)
897
                {
222 andreas 898
                    if (styIter->name.compare(*strIter) == 0)
79 andreas 899
                        return true;
900
                }
901
            }
902
        }
903
    }
904
 
905
    return false;
906
}
81 andreas 907
 
908
int TSystemDraw::getBorderWidth(const string &family, LINE_TYPE_t lt)
909
{
910
    DECL_TRACER("TSystemDraw::getBorderWidth(const string &family, LINE_TYPE_t lt)");
911
 
912
    if (family.empty())
913
        return 0;
914
 
915
    BORDER_t bd;
916
 
306 andreas 917
    if (!getBorderInfo(family, lt, &bd))
81 andreas 918
        return 0;
919
 
99 andreas 920
    MSG_DEBUG("Border width of \"" << family << "\" [" << lt << "]: " << bd.border.textLeft);
81 andreas 921
    return bd.border.textLeft;
922
}
923
 
924
int TSystemDraw::getBorderHeight(const string &family, LINE_TYPE_t lt)
925
{
926
    DECL_TRACER("TSystemDraw::getBorderHeight(const string &family, LINE_TYPE_t lt)");
927
 
928
    if (family.empty())
929
        return 0;
930
 
931
    BORDER_t bd;
932
 
306 andreas 933
    if (!getBorderInfo(family, lt, &bd))
81 andreas 934
        return 0;
935
 
936
    return bd.border.textTop;
937
}
99 andreas 938
 
939
bool TSystemDraw::existSlider(const string& slider)
940
{
941
    DECL_TRACER("TSystemDraw::existSlider(const string& slider)");
942
 
943
    if (slider.empty() || mDraw.sliderStyles.size() == 0)
944
    {
945
        MSG_ERROR("Slider " << slider << " has " << mDraw.sliderStyles.size() << " entries.");
946
        return false;
947
    }
948
 
949
    vector<SLIDER_STYLE_t>::iterator iter;
950
 
951
    for (iter = mDraw.sliderStyles.begin(); iter != mDraw.sliderStyles.end(); ++iter)
952
    {
953
        if (iter->name.compare(slider) == 0)
954
             return true;
955
    }
956
 
957
    return false;
958
}
959
 
960
bool TSystemDraw::getSlider(const string& slider, SLIDER_STYLE_t* style)
961
{
962
    DECL_TRACER("TSystemDraw::getSlider(const string& slider, SLIDER_STYLE_t* style)");
963
 
964
    if (slider.empty() || mDraw.sliderStyles.size() == 0)
965
        return false;
966
 
967
    if (!style)
968
        return existSlider(slider);
969
 
970
    vector<SLIDER_STYLE_t>::iterator iter;
971
 
972
    for (iter = mDraw.sliderStyles.begin(); iter != mDraw.sliderStyles.end(); ++iter)
973
    {
974
        if (iter->name.compare(slider) == 0)
975
        {
976
            *style = *iter;
977
            return true;
978
        }
979
    }
980
 
981
    return false;
982
}
983
 
984
vector<SLIDER_t> TSystemDraw::getSliderFiles(const string& slider)
985
{
986
    DECL_TRACER("TSystemDraw::getSliderFiles(const string& slider)");
987
 
988
    vector<SLIDER_t> list;
989
 
990
    if (slider.empty())
991
        return list;
992
 
993
    SLIDER_STYLE_t sst;
994
 
995
    if (!getSlider(slider, &sst))
996
        return list;
997
 
998
    string fbase = sst.baseFile;
999
    string myPath = mPath + "/sliders";
1000
    dir::TDirectory dir(myPath);
1001
    dir.setStripPath(true);
1002
    int num = dir.scanFiles(fbase + "_");
1003
 
1004
    if (num <= 0)
1005
        return list;
1006
 
1007
    myPath += "/";
1008
    SLIDER_t slid;
1009
 
1010
    slid.type = SGR_TOP;
100 andreas 1011
    slid.path = myPath + dir.getEntryWithPart(fbase+"_t");
99 andreas 1012
    slid.pathAlpha = myPath + dir.getEntryWithPart("_t_alpha");
1013
    list.push_back(slid);
1014
 
1015
    slid.type = SGR_BOTTOM;
100 andreas 1016
    slid.path = myPath + dir.getEntryWithPart(fbase+"_b");
99 andreas 1017
    slid.pathAlpha = myPath + dir.getEntryWithPart("_b_alpha");
1018
    list.push_back(slid);
1019
 
1020
    slid.type = SGR_LEFT;
100 andreas 1021
    slid.path = myPath + dir.getEntryWithPart(fbase+"_l");
99 andreas 1022
    slid.pathAlpha = myPath + dir.getEntryWithPart("_l_alpha");
1023
    list.push_back(slid);
1024
 
1025
    slid.type = SGR_RIGHT;
100 andreas 1026
    slid.path = myPath + dir.getEntryWithPart(fbase+"_r");
99 andreas 1027
    slid.pathAlpha = myPath + dir.getEntryWithPart("_r_alpha");
1028
    list.push_back(slid);
1029
 
1030
    slid.type = SGR_HORIZONTAL;
100 andreas 1031
    slid.path = myPath + dir.getEntryWithPart(fbase+"_h");
99 andreas 1032
    slid.pathAlpha = myPath + dir.getEntryWithPart("_h_alpha");
1033
    list.push_back(slid);
1034
 
1035
    slid.type = SGR_VERTICAL;
100 andreas 1036
    slid.path = myPath + dir.getEntryWithPart(fbase+"_v");
99 andreas 1037
    slid.pathAlpha = myPath + dir.getEntryWithPart("_v_alpha");
1038
    list.push_back(slid);
1039
 
1040
    return list;
1041
}
222 andreas 1042
 
415 andreas 1043
bool TSystemDraw::getCursor(const string& cursor, CURSOR_STYLE_t* style)
1044
{
1045
    DECL_TRACER("TSystemDraw::getCursor(const string& cursor, CURSOR_STYLE_t* style)");
1046
 
1047
    if (cursor.empty() || mDraw.cursorStyles.empty() || !style)
1048
        return false;
1049
 
1050
    vector<CURSOR_STYLE_t>::iterator iter;
1051
 
1052
    for (iter = mDraw.cursorStyles.begin(); iter != mDraw.cursorStyles.end(); ++iter)
1053
    {
1054
        if (iter->name.compare(cursor) == 0)
1055
        {
1056
            *style = *iter;
1057
            return true;
1058
        }
1059
    }
1060
 
1061
    return false;
1062
}
1063
 
1064
bool TSystemDraw::existCursor(const string& cursor)
1065
{
1066
    DECL_TRACER("TSystemDraw::existCursor(const string& cursor)");
1067
 
1068
    if (cursor.empty() || mDraw.cursors.empty())
1069
        return false;
1070
 
1071
    vector<FAMILY_t>::iterator iter;
1072
 
1073
    for (iter = mDraw.cursors.begin(); iter != mDraw.cursors.end(); ++iter)
1074
    {
1075
        if (iter->name == "Cursors")
1076
        {
1077
            vector<string>::iterator memIter;
1078
 
1079
            for (memIter = iter->member.begin(); memIter != iter->member.end(); ++memIter)
1080
            {
1081
                if (*memIter == cursor)
1082
                    return true;
1083
            }
1084
        }
1085
    }
1086
 
1087
    return false;
1088
}
1089
 
1090
CURSOR_t TSystemDraw::getCursorFiles(const CURSOR_STYLE_t& style)
1091
{
1092
    DECL_TRACER("TSystemDraw::getCursorFiles(const CURSOR_STYLE_t& style)");
1093
 
1094
    string path = mPath + "/cursors";
1095
    string f1 = path + "/" + style.baseFile + ".png";
1096
    string f2 = path + "/" + style.baseFile + "_alpha.png";
1097
    CURSOR_t cursor;
1098
 
1099
    if (fs::exists(f1))
1100
        cursor.imageBase = f1;
1101
 
1102
    if (fs::exists(f2))
1103
        cursor.imageAlpha = f2;
1104
 
1105
    return cursor;
1106
}
1107
 
222 andreas 1108
/**
1109
 * @brief TSystemDraw::evaluateName - Tests for all parts of \b parts in \b name
1110
 * The method tests if all strings in \b parts are contained in \b name.
1111
 *
1112
 * @param parts     A vector array containing one or more strings.
1113
 * @param name      A string which may contain all strings from \b parts.
1114
 *
1115
 * @return In case all strings from \b parts were found in \b name it returns
1116
 * TRUE. Otherwise FALSE.
1117
 */
1118
bool TSystemDraw::evaluateName(const std::vector<std::string>& parts, const std::string& name)
1119
{
429 andreas 1120
//    DECL_TRACER("TSystemDraw::evaluateName(const std::vector<std::string>& parts, const std::string& name)");
222 andreas 1121
 
1122
    if (parts.empty())
1123
        return false;
1124
 
1125
    size_t found = 0;
404 andreas 1126
    vector<string> nameParts = StrSplit(name, " ", true);
222 andreas 1127
    vector<string>::const_iterator iter;
1128
 
404 andreas 1129
    // First find the minimum number of parts who must match
1130
    size_t minParts = 0;
1131
 
1132
    for (size_t i = 0; i < nameParts.size(); ++i)
1133
    {
1134
        if (strCaseCompare(nameParts[i], "raised") == 0 ||
1135
            strCaseCompare(nameParts[i], "inset") == 0 ||
1136
            strCaseCompare(nameParts[i], "active") == 0 ||
1137
            strCaseCompare(nameParts[i], "inactive") == 0)
1138
            continue;
1139
 
1140
        minParts++;
1141
    }
1142
 
1143
    // Compare the parts and count the matching parts
222 andreas 1144
    for (iter = parts.begin(); iter != parts.end(); ++iter)
1145
    {
1146
        if (StrContains(name, *iter))
1147
            found++;
1148
    }
1149
 
404 andreas 1150
    if (found == nameParts.size() || found >= minParts)
222 andreas 1151
        return true;
1152
 
1153
    return false;
1154
}