Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
269 andreas 2
 * Copyright (C) 2020 to 2023 by Andreas Theofilu <andreas@theosys.at>
3 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
 
270 andreas 19
#include <QtGlobal>
20
 
3 andreas 21
#include <vector>
14 andreas 22
#include <thread>
23
#include <mutex>
186 andreas 24
 
36 andreas 25
#ifdef __ANDROID__
264 andreas 26
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 andreas 27
#       include <QtAndroidExtras/QAndroidJniObject>
28
#       include <QtAndroidExtras/QtAndroid>
216 andreas 29
#   else
30
#       include <QJniObject>
31
#       include <QCoreApplication>
183 andreas 32
#   endif
33
#   include <android/log.h>
182 andreas 34
#endif
134 andreas 35
#include <unistd.h>
36
#ifndef __ANDROID__
183 andreas 37
#   include <fstab.h>
134 andreas 38
#endif
14 andreas 39
 
186 andreas 40
#if __cplusplus < 201402L
41
#   error "This module requires at least C++14 standard!"
42
#else
43
#   if __cplusplus < 201703L
44
#       include <experimental/filesystem>
45
namespace fs = std::experimental::filesystem;
46
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
47
#   else
48
#       include <filesystem>
49
#       ifdef __ANDROID__
50
namespace fs = std::__fs::filesystem;
51
#       else
52
namespace fs = std::filesystem;
53
#       endif
54
#   endif
55
#endif
56
 
235 andreas 57
#ifdef __APPLE__
58
#   include <unistd.h>
59
#   ifndef HOST_NAME_MAX
60
#       ifdef MAXHOSTNAMELEN
61
#           define HOST_NAME_MAX    MAXHOSTNAMELEN
62
#       else
63
#           define HOST_NAME_MAX    64
64
#       endif   // MAXHOSTNAMELEN
65
#   endif       // HOST_NAME_MAX
66
#endif          // __APPLE__
67
 
3 andreas 68
#include "tpagemanager.h"
4 andreas 69
#include "tcolor.h"
3 andreas 70
#include "terror.h"
8 andreas 71
#include "ticons.h"
14 andreas 72
#include "tbutton.h"
8 andreas 73
#include "tprjresources.h"
11 andreas 74
#include "tresources.h"
271 andreas 75
#include "tresources.h"
71 andreas 76
#include "tsystemsound.h"
77
#include "tvalidatefile.h"
122 andreas 78
#include "ttpinit.h"
211 andreas 79
#include "tconfig.h"
299 andreas 80
#include "tlock.h"
336 andreas 81
#include "tintborder.h"
264 andreas 82
#ifdef Q_OS_IOS
83
#include "ios/tiosbattery.h"
84
#endif
326 andreas 85
#if TESTMODE == 1
86
#include "testmode.h"
87
#endif
3 andreas 88
 
89
using std::vector;
90
using std::string;
11 andreas 91
using std::map;
92
using std::pair;
93
using std::to_string;
14 andreas 94
using std::thread;
95
using std::atomic;
96
using std::mutex;
21 andreas 97
using std::bind;
3 andreas 98
 
8 andreas 99
TIcons *gIcons = nullptr;
100
TPrjResources *gPrjResources = nullptr;
14 andreas 101
TPageManager *gPageManager = nullptr;
169 andreas 102
//std::vector<amx::ANET_COMMAND> TPageManager::mCommands;
103
 
14 andreas 104
extern amx::TAmxNet *gAmxNet;
90 andreas 105
extern std::atomic<bool> _netRunning;
92 andreas 106
extern bool _restart_;                          //!< If this is set to true then the whole program will start over.
8 andreas 107
 
21 andreas 108
bool prg_stopped = false;
14 andreas 109
 
37 andreas 110
#ifdef __ANDROID__
255 andreas 111
string javaJStringToString(JNIEnv *env, jstring str)
112
{
113
    if (!str)
114
        return string();
115
 
116
    const jclass stringClass = env->GetObjectClass(str);
117
    const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
118
    const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(str, getBytes, env->NewStringUTF("UTF-8"));
119
 
120
    size_t length = (size_t) env->GetArrayLength(stringJbytes);
121
    jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
122
 
123
    string ret = std::string((char *)pBytes, length);
124
    env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
125
 
126
    env->DeleteLocalRef(stringJbytes);
127
    env->DeleteLocalRef(stringClass);
128
    return ret;
129
}
130
 
38 andreas 131
JNIEXPORT void JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)
132
{
61 andreas 133
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)");
134
 
38 andreas 135
    if (gPageManager)
136
        gPageManager->informBatteryStatus(level, charging, chargeType);
137
}
138
 
36 andreas 139
JNIEXPORT void JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)
140
{
61 andreas 141
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)");
365 andreas 142
 
143
    //Call native side conterpart
144
    if (gPageManager)
36 andreas 145
        gPageManager->informTPanelNetwork(conn, level, type);
146
}
47 andreas 147
 
61 andreas 148
JNIEXPORT void JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)
47 andreas 149
{
61 andreas 150
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)");
151
 
152
    string phoneNumber;
153
 
154
    if (pnumber)
255 andreas 155
        phoneNumber = javaJStringToString(env, pnumber);
61 andreas 156
 
157
    if (gPageManager)
158
        gPageManager->informPhoneState(call, phoneNumber);
47 andreas 159
}
160
 
61 andreas 161
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass, jint mode, jstring msg)
47 andreas 162
{
163
    if (!msg)
164
        return;
165
 
255 andreas 166
    string ret = javaJStringToString(env, msg);
47 andreas 167
 
61 andreas 168
    try
169
    {
170
        if (TStreamError::checkFilter(mode))
260 andreas 171
        {
172
            *TError::Current()->getStream() << TError::append(mode) << ret << std::endl;
173
            TStreamError::resetFlags();
174
        }
61 andreas 175
    }
176
    catch (std::exception& e)
177
    {
178
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", e.what());
179
    }
47 andreas 180
}
130 andreas 181
 
182
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)
183
{
184
    DECL_TRACER("Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)");
185
 
134 andreas 186
    if (!gPageManager)
187
        return;
188
 
189
    if (gPageManager->onOrientationChange())
130 andreas 190
        gPageManager->onOrientationChange()(orientation);
134 andreas 191
 
192
    gPageManager->setOrientation(orientation);
193
 
194
    if (gPageManager->getInformOrientation())
195
        gPageManager->sendOrientation();
130 andreas 196
}
255 andreas 197
 
198
/* -------- Settings -------- */
256 andreas 199
 
200
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)
255 andreas 201
{
256 andreas 202
    DECL_TRACER("Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)");
255 andreas 203
 
256 andreas 204
    Q_UNUSED(env);
255 andreas 205
    Q_UNUSED(clazz);
206
 
259 andreas 207
    TConfig::setTemporary(true);
208
    string oldNetlinx = TConfig::getController();
209
    int oldPort = TConfig::getPort();
210
    int oldChannelID = TConfig::getChannel();
211
    string oldSurface = TConfig::getFtpSurface();
212
    bool oldToolbarSuppress = TConfig::getToolbarSuppress();
213
    bool oldToolbarForce = TConfig::getToolbarForce();
214
    TConfig::setTemporary(false);
215
    MSG_DEBUG("Old values:\n" <<
216
              "   NetLinx: " << oldNetlinx << "\n" <<
217
              "   Port:    " << oldPort << "\n" <<
218
              "   Channel: " << oldChannelID << "\n" <<
219
              "   Surface: " << oldSurface << "\n" <<
220
              "   TB suppr:" << oldToolbarSuppress << "\n" <<
221
              "   TB force:" << oldToolbarForce);
256 andreas 222
    TConfig::saveSettings();
259 andreas 223
 
224
    MSG_DEBUG("New values:\n" <<
225
              "   NetLinx: " << TConfig::getController() << "\n" <<
226
              "   Port:    " << TConfig::getPort() << "\n" <<
227
              "   Channel: " << TConfig::getChannel() << "\n" <<
228
              "   Surface: " << TConfig::getFtpSurface() << "\n" <<
229
              "   TB suppr:" << TConfig::getToolbarSuppress() << "\n" <<
230
              "   TB force:" << TConfig::getToolbarForce());
231
 
232
    if (gPageManager && gPageManager->onSettingsChanged())
233
        gPageManager->onSettingsChanged()(oldNetlinx, oldPort, oldChannelID, oldSurface, oldToolbarSuppress, oldToolbarForce);
256 andreas 234
}
235
 
236
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)
237
{
238
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)");
239
 
240
    Q_UNUSED(clazz);
241
 
255 andreas 242
    string netlinxIp = javaJStringToString(env, ip);
243
 
244
    if (TConfig::getController() != netlinxIp)
245
        TConfig::saveController(netlinxIp);
246
}
247
 
256 andreas 248
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)
255 andreas 249
{
256 andreas 250
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)");
255 andreas 251
 
252
    Q_UNUSED(env);
253
    Q_UNUSED(clazz);
254
 
255
    if (port > 0 && port < 65535 && TConfig::getPort() != port)
256
        TConfig::savePort(port);
257
}
258
 
256 andreas 259
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)
255 andreas 260
{
256 andreas 261
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)");
255 andreas 262
 
263
    Q_UNUSED(env);
264
    Q_UNUSED(clazz);
265
 
266
    if (channel >= 10000 && channel < 20000 && TConfig::getChannel() != channel)
271 andreas 267
        TConfig::saveChannel(channel);
255 andreas 268
}
256 andreas 269
 
270
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)
271
{
272
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)");
273
 
274
    Q_UNUSED(clazz);
275
 
276
    string netlinxType = javaJStringToString(env, type);
277
 
278
    if (TConfig::getPanelType() != netlinxType)
279
        TConfig::savePanelType(netlinxType);
280
}
281
 
282
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)
283
{
284
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)");
285
 
286
    Q_UNUSED(clazz);
287
 
288
    string netlinxFtpUser = javaJStringToString(env, user);
289
 
290
    if (TConfig::getFtpUser() != netlinxFtpUser)
291
        TConfig::saveFtpUser(netlinxFtpUser);
292
}
293
 
294
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)
295
{
296
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)");
297
 
298
    Q_UNUSED(clazz);
299
 
300
    string netlinxPw = javaJStringToString(env, pw);
301
 
302
    if (TConfig::getFtpPassword() != netlinxPw)
303
        TConfig::saveFtpPassword(netlinxPw);
304
}
305
 
306
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxSurface(JNIEnv *env, jclass clazz, jstring surface)
307
{
308
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring surface)");
309
 
310
    Q_UNUSED(clazz);
311
 
312
    string netlinxSurface = javaJStringToString(env, surface);
313
 
314
    if (TConfig::getFtpSurface() != netlinxSurface)
315
        TConfig::saveFtpSurface(netlinxSurface);
316
}
317
 
318
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassive(JNIEnv *env, jclass clazz, jboolean passive)
319
{
320
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jboolean passive)");
321
 
322
    Q_UNUSED(env);
323
    Q_UNUSED(clazz);
324
 
325
    if (TConfig::getFtpPassive() != passive)
326
        TConfig::saveFtpPassive(passive);
327
}
328
 
329
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)
330
{
331
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)");
332
 
333
    Q_UNUSED(env);
334
    Q_UNUSED(clazz);
335
 
336
    if (TConfig::getScale() != scale)
337
        TConfig::saveScale(scale);
338
}
339
 
340
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)
341
{
342
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)");
343
 
344
    Q_UNUSED(env);
345
    Q_UNUSED(clazz);
346
 
260 andreas 347
    if (TConfig::getToolbarSuppress() == bar)
348
        TConfig::saveToolbarSuppress(!bar);
256 andreas 349
}
350
 
351
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)
352
{
353
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)");
354
 
355
    Q_UNUSED(env);
356
    Q_UNUSED(clazz);
357
 
358
    if (TConfig::getToolbarForce() != bar)
359
        TConfig::saveToolbarForce(bar);
360
}
361
 
362
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)
363
{
364
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)");
365
 
366
    Q_UNUSED(env);
367
    Q_UNUSED(clazz);
368
 
369
    if (TConfig::getRotationFixed() != rotate)
370
        TConfig::setRotationFixed(rotate);
371
}
372
 
373
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)
374
{
375
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)");
376
 
377
    Q_UNUSED(clazz);
378
 
379
    string s = javaJStringToString(env, sound);
380
 
381
    if (TConfig::getSystemSound() != s)
382
        TConfig::saveSystemSoundFile(s);
383
}
384
 
385
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)
386
{
387
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)");
388
 
389
    Q_UNUSED(clazz);
390
 
391
    string s = javaJStringToString(env, sound);
392
 
393
    if (TConfig::getSingleBeepSound() != s)
394
        TConfig::saveSingleBeepFile(s);
395
}
396
 
397
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)
398
{
399
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)");
400
 
401
    Q_UNUSED(clazz);
402
 
403
    string s = javaJStringToString(env, sound);
404
 
405
    if (TConfig::getDoubleBeepSound() != s)
406
        TConfig::saveDoubleBeepFile(s);
407
}
408
 
409
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)
410
{
411
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)");
412
 
413
    Q_UNUSED(env);
414
    Q_UNUSED(clazz);
415
 
416
    if (TConfig::getSystemSoundState() != sound)
417
        TConfig::saveSystemSoundState(sound);
418
}
419
 
420
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)
421
{
422
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)");
423
 
424
    Q_UNUSED(env);
425
    Q_UNUSED(clazz);
426
 
427
    if (TConfig::getSystemVolume() != sound)
428
        TConfig::saveSystemVolume(sound);
429
}
430
 
431
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundGain(JNIEnv *env, jclass clazz, jint sound)
432
{
433
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundGain(JNIEnv *env, jclass clazz, jint sound)");
434
 
435
    Q_UNUSED(env);
436
    Q_UNUSED(clazz);
437
 
438
    if (TConfig::getSystemGain() != sound)
439
        TConfig::saveSystemGain(sound);
440
}
257 andreas 441
 
442
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)
443
{
444
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)");
445
 
446
    Q_UNUSED(clazz);
447
 
448
    string sipStr = javaJStringToString(env, sip);
449
 
450
    if (TConfig::getSIPproxy() != sipStr)
451
        TConfig::setSIPproxy(sipStr);
452
}
453
 
454
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPort(JNIEnv *env, jclass clazz, jint sip)
455
{
456
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPort(JNIEnv *env, jclass clazz, jint sip)");
457
 
458
    Q_UNUSED(env);
459
    Q_UNUSED(clazz);
460
 
461
    if (TConfig::getSIPport() != sip)
462
        TConfig::setSIPport(sip);
463
}
464
 
465
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)
466
{
467
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)");
468
 
469
    Q_UNUSED(env);
470
    Q_UNUSED(clazz);
471
 
472
    if (TConfig::getSIPportTLS() != sip)
473
        TConfig::setSIPportTLS(sip);
474
}
475
 
476
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipStun(JNIEnv *env, jclass clazz, jstring sip)
477
{
478
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipStun(JNIEnv *env, jclass clazz, jstring sip)");
479
 
480
    Q_UNUSED(clazz);
481
 
482
    string sipStr = javaJStringToString(env, sip);
483
 
484
    if (TConfig::getSIPstun() != sipStr)
485
        TConfig::setSIPstun(sipStr);
486
}
487
 
488
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)
489
{
490
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)");
491
 
492
    Q_UNUSED(clazz);
493
 
494
    string sipStr = javaJStringToString(env, sip);
495
 
496
    if (TConfig::getSIPdomain() != sipStr)
497
        TConfig::setSIPdomain(sipStr);
498
}
499
 
500
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipUser(JNIEnv *env, jclass clazz, jstring sip)
501
{
502
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipUser(JNIEnv *env, jclass clazz, jstring sip)");
503
 
504
    Q_UNUSED(clazz);
505
 
506
    string sipStr = javaJStringToString(env, sip);
507
 
508
    if (TConfig::getSIPuser() != sipStr)
509
        TConfig::setSIPuser(sipStr);
510
}
511
 
512
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)
513
{
514
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)");
515
 
516
    Q_UNUSED(clazz);
517
 
518
    string sipStr = javaJStringToString(env, sip);
519
 
520
    if (TConfig::getSIPpassword() != sipStr)
521
        TConfig::setSIPpassword(sipStr);
522
}
523
 
524
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)
525
{
526
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)");
527
 
528
    Q_UNUSED(env);
529
    Q_UNUSED(clazz);
530
 
531
    if (TConfig::getSIPnetworkIPv4() != sip)
532
        TConfig::setSIPnetworkIPv4(sip);
533
}
534
 
535
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)
536
{
537
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)");
538
 
539
    Q_UNUSED(env);
540
    Q_UNUSED(clazz);
541
 
542
    if (TConfig::getSIPnetworkIPv6() != sip)
543
        TConfig::setSIPnetworkIPv6(sip);
544
}
545
 
546
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)
547
{
548
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)");
549
 
550
    Q_UNUSED(env);
551
    Q_UNUSED(clazz);
552
 
553
    if (TConfig::getSIPstatus() != sip)
554
        TConfig::setSIPstatus(sip);
555
}
556
 
557
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)
558
{
559
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)");
560
 
561
    Q_UNUSED(env);
562
    Q_UNUSED(clazz);
563
 
564
    if (TConfig::getSIPiphone() != sip)
565
        TConfig::setSIPiphone(sip);
566
}
567
 
568
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)
569
{
570
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)");
571
 
572
    Q_UNUSED(env);
573
    Q_UNUSED(clazz);
574
 
575
    uint logSwitch = (log ? HLOG_INFO : 0);
576
 
577
    if ((TConfig::getLogLevelBits() & HLOG_INFO) != logSwitch)
578
    {
579
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
580
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_INFO);
581
        else
582
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_INFO);
583
    }
584
}
585
 
586
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)
587
{
588
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)");
589
 
590
    Q_UNUSED(env);
591
    Q_UNUSED(clazz);
592
 
593
    uint logSwitch = (log ? HLOG_WARNING : 0);
594
 
595
    if ((TConfig::getLogLevelBits() & HLOG_WARNING) != logSwitch)
596
    {
597
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
598
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_WARNING);
599
        else
600
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_WARNING);
601
    }
602
}
603
 
604
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogError(JNIEnv *env, jclass clazz, jboolean log)
605
{
606
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogError(JNIEnv *env, jclass clazz, jboolean log)");
607
 
608
    Q_UNUSED(env);
609
    Q_UNUSED(clazz);
610
 
611
    uint logSwitch = (log ? HLOG_ERROR : 0);
612
 
613
    if ((TConfig::getLogLevelBits() & HLOG_ERROR) != logSwitch)
614
    {
615
        if (!(TConfig::getLogLevelBits() & HLOG_ERROR))
616
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_ERROR);
617
        else
618
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_ERROR);
619
    }
620
}
621
 
622
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)
623
{
624
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)");
625
 
626
    Q_UNUSED(env);
627
    Q_UNUSED(clazz);
628
 
629
    uint logSwitch = (log ? HLOG_TRACE : 0);
630
 
631
    if ((TConfig::getLogLevelBits() & HLOG_TRACE) != logSwitch)
632
    {
633
        if (!(TConfig::getLogLevelBits() & HLOG_TRACE))
634
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_TRACE);
635
        else
636
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_TRACE);
637
    }
638
}
639
 
640
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)
641
{
642
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)");
643
 
644
    Q_UNUSED(env);
645
    Q_UNUSED(clazz);
646
 
647
    uint logSwitch = (log ? HLOG_DEBUG : 0);
648
 
649
    if ((TConfig::getLogLevelBits() & HLOG_DEBUG) != logSwitch)
650
    {
651
        if (!(TConfig::getLogLevelBits() & HLOG_DEBUG))
652
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_DEBUG);
653
        else
654
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_DEBUG);
655
    }
656
}
657
 
658
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)
659
{
660
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)");
661
 
662
    Q_UNUSED(env);
663
    Q_UNUSED(clazz);
664
 
665
    if (TConfig::getProfiling() != log)
666
        TConfig::saveProfiling(log);
667
}
668
 
669
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)
670
{
671
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)");
672
 
673
    Q_UNUSED(env);
674
    Q_UNUSED(clazz);
675
 
676
    if (TConfig::isLongFormat() != log)
677
        TConfig::saveFormat(log);
678
}
679
 
680
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)
681
{
682
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)");
683
 
684
    Q_UNUSED(env);
685
    Q_UNUSED(clazz);
686
 
383 andreas 687
    TConfig::setLogFileEnabled(log);
688
 
689
    if (log && !TConfig::getLogFile().empty())
690
        TStreamError::setLogFile(TConfig::getLogFile());
691
 
692
    MSG_DEBUG("Logfile was " << (log ? "ENABLED" : "DISABLED"));
257 andreas 693
}
694
 
695
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogFile(JNIEnv *env, jclass clazz, jstring log)
696
{
697
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogFile(JNIEnv *env, jclass clazz, jstring sip)");
698
 
699
    Q_UNUSED(clazz);
700
 
701
    string logStr = javaJStringToString(env, log);
702
 
703
    if (TConfig::getLogFile() != logStr)
704
        TConfig::saveLogFile(logStr);
705
}
37 andreas 706
#endif
36 andreas 707
 
3 andreas 708
TPageManager::TPageManager()
709
{
299 andreas 710
    TLOCKER(surface_mutex);
3 andreas 711
    DECL_TRACER("TPageManager::TPageManager()");
712
 
14 andreas 713
    gPageManager = this;
122 andreas 714
    TTPInit *tinit = new TTPInit;
186 andreas 715
    string projectPath = TConfig::getProjectPath();
197 andreas 716
    string pp = projectPath + "/prj.xma";
186 andreas 717
 
718
    tinit->setPath(projectPath);
156 andreas 719
    bool haveSurface = false;
122 andreas 720
 
721
    if (tinit->isVirgin())
156 andreas 722
        haveSurface = tinit->loadSurfaceFromController();
723
    else
724
        haveSurface = true;
122 andreas 725
 
197 andreas 726
    if (!fs::exists(pp))
193 andreas 727
    {
197 andreas 728
        projectPath = TConfig::getSystemProjectPath();
729
        pp = projectPath + "/prj.xma";
193 andreas 730
        mSetupActive = true;
731
    }
186 andreas 732
 
156 andreas 733
    if (!haveSurface)
734
    {
271 andreas 735
        if (!isValidFile(pp))
736
            tinit->reinitialize();
156 andreas 737
    }
159 andreas 738
    else
739
        tinit->makeSystemFiles();
156 andreas 740
 
122 andreas 741
    delete tinit;
156 andreas 742
 
43 andreas 743
    // Read the AMX panel settings.
186 andreas 744
    mTSettings = new TSettings(projectPath);
3 andreas 745
 
746
    if (TError::isError())
14 andreas 747
    {
23 andreas 748
        MSG_ERROR("Settings were not read successfull!");
3 andreas 749
        return;
14 andreas 750
    }
3 andreas 751
 
193 andreas 752
    if (!mSetupActive)
753
    {
197 andreas 754
        mSystemSettings = new TSettings(TConfig::getSystemProjectPath());
193 andreas 755
 
756
        if (TError::isError())
757
        {
758
            MSG_ERROR("System settings were not read successfull!");
759
            delete mTSettings;
760
            mTSettings = nullptr;
761
            return;
762
        }
763
    }
764
    else
765
        mSystemSettings = mTSettings;
766
 
178 andreas 767
    // Set the panel type from the project information
193 andreas 768
    if (!mSetupActive)
769
        TConfig::savePanelType(mTSettings->getPanelType());
178 andreas 770
 
122 andreas 771
    readMap();  // Start the initialisation of the AMX part.
772
 
8 andreas 773
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
4 andreas 774
    mPalette = new TPalette();
775
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
776
 
83 andreas 777
    if (pal.size() > 0)
778
    {
779
        vector<PALETTE_SETUP>::iterator iterPal;
4 andreas 780
 
118 andreas 781
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 782
            mPalette->initialize(iterPal->file);
783
    }
784
 
4 andreas 785
    if (!TError::isError())
786
        TColor::setPalette(mPalette);
787
 
7 andreas 788
    mFonts = new TFont();
789
 
790
    if (TError::isError())
791
    {
792
        MSG_ERROR("Initializing fonts was not successfull!");
793
    }
794
 
8 andreas 795
    gIcons = new TIcons();
796
 
797
    if (TError::isError())
798
    {
799
        MSG_ERROR("Initializing icons was not successfull!");
800
    }
801
 
3 andreas 802
    mPageList = new TPageList();
32 andreas 803
    mExternal = new TExternal();
4 andreas 804
    PAGELIST_T page;
805
 
194 andreas 806
    if (!mSetupActive)
3 andreas 807
    {
194 andreas 808
        if (!mTSettings->getSettings().powerUpPage.empty())
14 andreas 809
        {
194 andreas 810
            if (readPage(mTSettings->getSettings().powerUpPage))
811
            {
812
                MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
813
                page = findPage(mTSettings->getSettings().powerUpPage);
814
                mActualPage = page.pageID;
815
            }
14 andreas 816
        }
194 andreas 817
        else
818
        {
819
            MSG_WARNING("No power up page defined! Setting default page to 1.");
820
            mActualPage = 1;
821
        }
3 andreas 822
    }
23 andreas 823
    else
824
    {
194 andreas 825
        if (!mSystemSettings->getSettings().powerUpPage.empty())
826
        {
827
            if (readPage(mSystemSettings->getSettings().powerUpPage))
828
            {
829
                MSG_TRACE("Found power up page " << mSystemSettings->getSettings().powerUpPage);
830
                page = findPage(mSystemSettings->getSettings().powerUpPage);
831
                mActualPage = page.pageID;
832
            }
833
        }
834
        else
835
        {
836
            MSG_WARNING("No power up page defined! Setting default page to 5001.");
837
            mActualPage = 5001;
838
        }
23 andreas 839
    }
3 andreas 840
 
4 andreas 841
    TPage *pg = getPage(mActualPage);
842
 
194 andreas 843
    vector<string> popups;
3 andreas 844
 
194 andreas 845
    if (!mSetupActive)
846
        popups = mTSettings->getSettings().powerUpPopup;
847
    else
848
        popups = mSystemSettings->getSettings().powerUpPopup;
849
 
83 andreas 850
    if (popups.size() > 0)
3 andreas 851
    {
83 andreas 852
        vector<string>::iterator iter;
853
 
118 andreas 854
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 855
        {
88 andreas 856
            if (readSubPage(*iter))
83 andreas 857
            {
88 andreas 858
                MSG_TRACE("Found power up popup " << *iter);
3 andreas 859
 
88 andreas 860
                if (pg)
861
                {
862
                    TSubPage *spage = getSubPage(*iter);
350 andreas 863
                    spage->setParent(pg->getHandle());
88 andreas 864
                    pg->addSubPage(spage);
865
                }
83 andreas 866
            }
4 andreas 867
        }
3 andreas 868
    }
11 andreas 869
 
73 andreas 870
    // Here we initialize the system resources like borders, cursors, sliders, ...
871
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
872
 
873
    // Here are the commands supported by this emulation.
13 andreas 874
    MSG_INFO("Registering commands ...");
318 andreas 875
    REG_CMD(doLEVON, "LEVON");  // Enable device to send level changes to the master.
876
    REG_CMD(doLEVOF, "LEVOF");  // Disable the device from sending level changes to the master.
877
    REG_CMD(doRXON, "RXON");    // Enable device to send STRING changes to the master.
878
    REG_CMD(doRXOF, "RXOF");    // Disable the device from sending STRING changes to the master.
147 andreas 879
    REG_CMD(doAFP, "@AFP");     // Flips to a page with the specified page name using an animated transition.
880
    REG_CMD(doAFP, "^AFP");     // Flips to a page with the specified page name using an animated transition.
38 andreas 881
    REG_CMD(doAPG, "@APG");     // Add a specific popup page to a specified popup group.
882
    REG_CMD(doCPG, "@CPG");     // Clear all popup pages from specified popup group.
883
    REG_CMD(doDPG, "@DPG");     // Delete a specific popup page from specified popup group if it exists
884
//    REG_CMD(doPDR, "@PDR");     // Set the popup location reset flag.
885
    REG_CMD(doPHE, "@PHE");     // Set the hide effect for the specified popup page to the named hide effect.
886
    REG_CMD(doPHP, "@PHP");     // Set the hide effect position.
887
    REG_CMD(doPHT, "@PHT");     // Set the hide effect time for the specified popup page.
888
    REG_CMD(doPPA, "@PPA");     // Close all popups on a specified page.
104 andreas 889
    REG_CMD(doPPA, "^PPA");     // G5: Close all popups on a specified page.
38 andreas 890
    REG_CMD(doPPF, "@PPF");     // Deactivate a specific popup page on either a specified page or the current page.
104 andreas 891
    REG_CMD(doPPF, "^PPF");     // G5: Deactivate a specific popup page on either a specified page or the current page.
38 andreas 892
    REG_CMD(doPPF, "PPOF");     // Deactivate a specific popup page on either a specified page or the current page
893
    REG_CMD(doPPG, "@PPG");     // Toggle a specific popup page on either a specified page or the current page.
104 andreas 894
    REG_CMD(doPPG, "^PPG");     // G5: Toggle a specific popup page on either a specified page or the current page.
38 andreas 895
    REG_CMD(doPPG, "PPOG");     // Toggle a specific popup page on either a specified page or the current page.
896
    REG_CMD(doPPK, "@PPK");     // Kill a specific popup page from all pages.
104 andreas 897
    REG_CMD(doPPK, "^PPK");     // G5: Kill a specific popup page from all pages.
38 andreas 898
    REG_CMD(doPPM, "@PPM");     // Set the modality of a specific popup page to Modal or NonModal.
104 andreas 899
    REG_CMD(doPPM, "^PPM");     // G5: Set the modality of a specific popup page to Modal or NonModal.
38 andreas 900
    REG_CMD(doPPN, "@PPN");     // Activate a specific popup page to launch on either a specified page or the current page.
104 andreas 901
    REG_CMD(doPPN, "^PPN");     // G5: Activate a specific popup page to launch on either a specified page or the current page.
38 andreas 902
    REG_CMD(doPPN, "PPON");     // Activate a specific popup page to launch on either a specified page or the current page.
903
    REG_CMD(doPPT, "@PPT");     // Set a specific popup page to timeout within a specified time.
104 andreas 904
    REG_CMD(doPPT, "^PPT");     // G5: Set a specific popup page to timeout within a specified time.
38 andreas 905
    REG_CMD(doPPX, "@PPX");     // Close all popups on all pages.
104 andreas 906
    REG_CMD(doPPX, "^PPX");     // G5: Close all popups on all pages.
38 andreas 907
    REG_CMD(doPSE, "@PSE");     // Set the show effect for the specified popup page to the named show effect.
908
    REG_CMD(doPSP, "@PSP");     // Set the show effect position.
909
    REG_CMD(doPST, "@PST");     // Set the show effect time for the specified popup page.
910
    REG_CMD(doPAGE, "PAGE");    // Flip to a specified page.
104 andreas 911
    REG_CMD(doPAGE, "^PGE");    // G5: Flip to a specified page.
11 andreas 912
 
38 andreas 913
    REG_CMD(doANI, "^ANI");     // Run a button animation (in 1/10 second).
914
    REG_CMD(doAPF, "^APF");     // Add page flip action to a button if it does not already exist.
43 andreas 915
    REG_CMD(doBAT, "^BAT");     // Append non-unicode text.
60 andreas 916
    REG_CMD(doBAU, "^BAU");     // Append unicode text. Same format as ^UNI.
43 andreas 917
    REG_CMD(doBCB, "^BCB");     // Set the border color.
82 andreas 918
    REG_CMD(getBCB, "?BCB");    // Get the current border color.
60 andreas 919
    REG_CMD(doBCF, "^BCF");     // Set the fill color to the specified color.
82 andreas 920
    REG_CMD(getBCF, "?BCF");    // Get the current fill color.
60 andreas 921
    REG_CMD(doBCT, "^BCT");     // Set the text color to the specified color.
82 andreas 922
    REG_CMD(getBCT, "?BCT");    // Get the current text color.
60 andreas 923
    REG_CMD(doBDO, "^BDO");     // Set the button draw order
924
    REG_CMD(doBFB, "^BFB");     // Set the feedback type of the button.
224 andreas 925
    REG_CMD(doBIM, "^BIM");     // Set the input mask for the specified address
149 andreas 926
    REG_CMD(doBMC, "^BMC");     // Button copy command.
927
    REG_CMD(doBMF, "^BMF");     // Button Modify Command - Set any/all button parameters by sending embedded codes and data.
106 andreas 928
//    REG_CMD(doBMI, "^BMI");    // Set the button mask image.
149 andreas 929
    REG_CMD(doBML, "^BML");     // Set the maximum length of the text area button.
38 andreas 930
    REG_CMD(doBMP, "^BMP");     // Assign a picture to those buttons with a defined addressrange.
82 andreas 931
    REG_CMD(getBMP, "?BMP");    // Get the current bitmap name.
38 andreas 932
    REG_CMD(doBOP, "^BOP");     // Set the button opacity.
106 andreas 933
    REG_CMD(getBOP, "?BOP");    // Get the button opacity.
60 andreas 934
    REG_CMD(doBOR, "^BOR");     // Set a border to a specific border style.
107 andreas 935
    REG_CMD(doBOS, "^BOS");     // Set the button to display either a Video or Non-Video window.
60 andreas 936
    REG_CMD(doBRD, "^BRD");     // Set the border of a button state/states.
107 andreas 937
    REG_CMD(getBRD, "?BRD");    // Get the border of a button state/states.
103 andreas 938
//    REG_CMD(doBSF, "^BSF");     // Set the focus to the text area.
38 andreas 939
    REG_CMD(doBSP, "^BSP");     // Set the button size and position.
107 andreas 940
    REG_CMD(doBSM, "^BSM");     // Submit text for text area buttons.
941
    REG_CMD(doBSO, "^BSO");     // Set the sound played when a button is pressed.
38 andreas 942
    REG_CMD(doBWW, "^BWW");     // Set the button word wrap feature to those buttons with a defined address range.
108 andreas 943
    REG_CMD(getBWW, "?BWW");    // Get the button word wrap feature to those buttons with a defined address range.
38 andreas 944
    REG_CMD(doCPF, "^CPF");     // Clear all page flips from a button.
945
    REG_CMD(doDPF, "^DPF");     // Delete page flips from button if it already exists.
946
    REG_CMD(doENA, "^ENA");     // Enable or disable buttons with a set variable text range.
947
    REG_CMD(doFON, "^FON");     // Set a font to a specific Font ID value for those buttons with a range.
108 andreas 948
    REG_CMD(getFON, "?FON");    // Get the current font index.
103 andreas 949
//    REG_CMD(doGDI, "^GDI");     // Change the bargraph drag increment.
950
//    REG_CMD(doGDV, "^GDV");     // Invert the joystick axis to move the origin to another corner.
60 andreas 951
    REG_CMD(doGLH, "^GLH");     // Change the bargraph upper limit.
952
    REG_CMD(doGLL, "^GLL");     // Change the bargraph lower limit.
361 andreas 953
    REG_CMD(doGSN, "^GSN");     // Set slider/cursor name.
108 andreas 954
    REG_CMD(doGSC, "^GSC");     // Change the bargraph slider color or joystick cursor color.
38 andreas 955
    REG_CMD(doICO, "^ICO");     // Set the icon to a button.
108 andreas 956
    REG_CMD(getICO, "?ICO");    // Get the current icon index.
957
    REG_CMD(doJSB, "^JSB");     // Set bitmap/picture alignment using a numeric keypad layout for those buttons with a defined address range.
958
    REG_CMD(getJSB, "?JSB");    // Get the current bitmap justification.
959
    REG_CMD(doJSI, "^JSI");     // Set icon alignment using a numeric keypad layout for those buttons with a defined address range.
960
    REG_CMD(getJSI, "?JSI");    // Get the current icon justification.
961
    REG_CMD(doJST, "^JST");     // Set text alignment using a numeric keypad layout for those buttons with a defined address range.
962
    REG_CMD(getJST, "?JST");    // Get the current text justification.
38 andreas 963
    REG_CMD(doSHO, "^SHO");     // Show or hide a button with a set variable text range.
108 andreas 964
    REG_CMD(doTEC, "^TEC");     // Set the text effect color for the specified addresses/states to the specified color.
965
    REG_CMD(getTEC, "?TEC");    // Get the current text effect color.
110 andreas 966
    REG_CMD(doTEF, "^TEF");     // Set the text effect. The Text Effect is specified by name and can be found in TPD4.
967
    REG_CMD(getTEF, "?TEF");    // Get the current text effect name.
103 andreas 968
//    REG_CMD(doTOP, "^TOP");     // Send events to the Master as string events.
38 andreas 969
    REG_CMD(doTXT, "^TXT");     // Assign a text string to those buttons with a defined address range.
110 andreas 970
    REG_CMD(getTXT, "?TXT");    // Get the current text information.
104 andreas 971
    REG_CMD(doUNI, "^UNI");     // Set Unicode text.
972
    REG_CMD(doUTF, "^UTF");     // G5: Set button state text using UTF-8 text command.
148 andreas 973
    REG_CMD(doVTP, "^VTP");     // Simulates a touch/release/pulse at the given coordinate
14 andreas 974
 
103 andreas 975
//    REG_CMD(doLPC, "^LPC");     // Clear all users from the User Access Passwords list on the Password Setup page.
976
//    REG_CMD(doLPR, "^LPR");     // Remove a given user from the User Access Passwords list on the Password Setup page.
977
//    REG_CMD(doLPS, "^LPS");     // Set the user name and password.
978
 
111 andreas 979
    REG_CMD(doKPS, "^KPS");     // Set the keyboard passthru.
980
    REG_CMD(doVKS, "^VKS");     // Send one or more virtual key strokes to the G4 application.
103 andreas 981
 
982
//    REG_CMD(doPWD, "@PWD");     // Set the page flip password.
983
//    REG_CMD(doPWD, "^PWD");     // Set the page flip password.
984
 
38 andreas 985
    REG_CMD(doBBR, "^BBR");     // Set the bitmap of a button to use a particular resource.
97 andreas 986
    REG_CMD(doRAF, "^RAF");     // Add new resources
987
    REG_CMD(doRFR, "^RFR");     // Force a refresh for a given resource.
38 andreas 988
    REG_CMD(doRMF, "^RMF");     // Modify an existing resource.
111 andreas 989
    REG_CMD(doRSR, "^RSR");     // Change the refresh rate for a given resource.
21 andreas 990
 
108 andreas 991
    REG_CMD(doABEEP, "ABEEP");  // Output a single beep even if beep is Off.
992
    REG_CMD(doADBEEP, "ADBEEP");// Output a double beep even if beep is Off.
62 andreas 993
    REG_CMD(doAKB, "@AKB");     // Pop up the keyboard icon and initialize the text string to that specified.
994
    REG_CMD(doAKEYB, "AKEYB");  // Pop up the keyboard icon and initialize the text string to that specified.
995
    REG_CMD(doAKP, "@AKP");     // Pop up the keypad icon and initialize the text string to that specified.
996
    REG_CMD(doAKEYP, "AKEYP");  // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 997
    REG_CMD(doAKEYR, "AKEYR");  // Remove the Keyboard/Keypad.
998
    REG_CMD(doAKR, "@AKR");     // Remove the Keyboard/Keypad.
71 andreas 999
    REG_CMD(doBEEP, "BEEP");    // Play a single beep.
104 andreas 1000
    REG_CMD(doBEEP, "^ABP");    // G5: Play a single beep.
71 andreas 1001
    REG_CMD(doDBEEP, "DBEEP");  // Play a double beep.
104 andreas 1002
    REG_CMD(doDBEEP, "^ADB");   // G5: Play a double beep.
62 andreas 1003
    REG_CMD(doEKP, "@EKP");     // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1004
    REG_CMD(doPKP, "@PKB");     // Present a private keyboard.
1005
    REG_CMD(doPKP, "PKEYP");    // Present a private keypad.
1006
    REG_CMD(doPKP, "@PKP");     // Present a private keypad.
64 andreas 1007
    REG_CMD(doSetup, "SETUP");  // Send panel to SETUP page.
104 andreas 1008
    REG_CMD(doSetup, "^STP");   // G5: Open setup page.
64 andreas 1009
    REG_CMD(doShutdown, "SHUTDOWN");// Shut down the App
82 andreas 1010
    REG_CMD(doSOU, "@SOU");     // Play a sound file.
104 andreas 1011
    REG_CMD(doSOU, "^SOU");     // G5: Play a sound file.
326 andreas 1012
    REG_CMD(doMUT, "^MUT");     // G5: Panel Volume Mute
63 andreas 1013
    REG_CMD(doTKP, "@TKP");     // Present a telephone keypad.
104 andreas 1014
    REG_CMD(doTKP, "^TKP");     // G5: Bring up a telephone keypad.
63 andreas 1015
    REG_CMD(doTKP, "@VKB");     // Present a virtual keyboard
104 andreas 1016
    REG_CMD(doTKP, "^VKB");     // G5: Bring up a virtual keyboard.
129 andreas 1017
#ifndef _NOSIP_
103 andreas 1018
    // Here the SIP commands will take place
123 andreas 1019
    REG_CMD(doPHN, "^PHN");     // SIP commands
127 andreas 1020
    REG_CMD(getPHN, "?PHN");    // SIP state commands
129 andreas 1021
#endif
300 andreas 1022
    // SubView commands
1023
//    REG_CMD(doEPR, "^EPR");     // Execute Push on Release.
1024
//    REG_CMD(doSCE, "^SCE");     // Configures subpage custom events.
1025
//    REG_CMD(doSDR, "^SDR");     // Enabling subpage dynamic reordering.
318 andreas 1026
    REG_CMD(doSHA, "^SHA");     // Subpage Hide All Command
1027
    REG_CMD(doSHD, "^SHD");     // Hides subpage
1028
    REG_CMD(doSPD, "^SPD");     //  Set the padding between subpages on a subpage viewer button
300 andreas 1029
    REG_CMD(doSSH, "^SSH");     // Subpage show command.
318 andreas 1030
    REG_CMD(doSTG, "^STG");     // Subpage toggle command
300 andreas 1031
 
225 andreas 1032
    // ListView commands (G5)
1033
    REG_CMD(doLVD, "^LVD");     // G5: Set Listview Data Source
230 andreas 1034
    REG_CMD(doLVE, "^LVE");     // G5: Set ListView custom event number
227 andreas 1035
    REG_CMD(doLVF, "^LVF");     // G5: Listview Filter
230 andreas 1036
    REG_CMD(doLVL, "^LVL");     // G5: ListView layout
233 andreas 1037
    REG_CMD(doLVM, "^LVM");     // G5: ListView map fields
1038
    REG_CMD(doLVN, "^LVN");     // G5: ListView navigate
1039
    REG_CMD(doLVR, "^LVR");     // G5: ListView refresh data
1040
    REG_CMD(doLVS, "^LVS");     // G5: ListView sort data
225 andreas 1041
 
103 andreas 1042
    // State commands
14 andreas 1043
    REG_CMD(doON, "ON");
1044
    REG_CMD(doOFF, "OFF");
15 andreas 1045
    REG_CMD(doLEVEL, "LEVEL");
1046
    REG_CMD(doBLINK, "BLINK");
127 andreas 1047
    REG_CMD(doVER, "^VER?");    // Return version string to master
279 andreas 1048
#ifndef _NOSIP_
127 andreas 1049
    REG_CMD(doWCN, "^WCN?");    // Return SIP phone number
279 andreas 1050
#endif
134 andreas 1051
    // TPControl commands
1052
    REG_CMD(doTPCCMD, "TPCCMD");    // Profile related options
1053
    REG_CMD(doTPCACC, "TPCACC");    // Device orientation
279 andreas 1054
#ifndef _NOSIP_
153 andreas 1055
    REG_CMD(doTPCSIP, "TPCSIP");    // Show the built in SIP phone
279 andreas 1056
#endif
134 andreas 1057
    // Virtual internal commands
26 andreas 1058
    REG_CMD(doFTR, "#FTR");     // File transfer (virtual internal command)
23 andreas 1059
 
123 andreas 1060
    // At least we must add the SIP client
129 andreas 1061
#ifndef _NOSIP_
127 andreas 1062
    mSIPClient = new TSIPClient;
123 andreas 1063
 
1064
    if (TError::isError())
1065
    {
1066
        MSG_ERROR("Error initializing the SIP client!");
1067
        TConfig::setSIPstatus(false);
1068
    }
129 andreas 1069
#endif
88 andreas 1070
    TError::clear();
299 andreas 1071
    runClickQueue();
303 andreas 1072
    runUpdateSubViewItem();
3 andreas 1073
}
1074
 
1075
TPageManager::~TPageManager()
1076
{
1077
    DECL_TRACER("TPageManager::~TPageManager()");
129 andreas 1078
#ifndef _NOSIP_
127 andreas 1079
    if (mSIPClient)
1080
    {
1081
        delete mSIPClient;
1082
        mSIPClient = nullptr;
1083
    }
129 andreas 1084
#endif
3 andreas 1085
    PCHAIN_T *p = mPchain;
1086
    PCHAIN_T *next = nullptr;
37 andreas 1087
#ifdef __ANDROID__
36 andreas 1088
    stopNetworkState();
37 andreas 1089
#endif
3 andreas 1090
    try
1091
    {
1092
        while (p)
1093
        {
1094
            next = p->next;
1095
 
1096
            if (p->page)
1097
                delete p->page;
1098
 
1099
            delete p;
1100
            p = next;
1101
        }
1102
 
1103
        SPCHAIN_T *sp = mSPchain;
1104
        SPCHAIN_T *snext = nullptr;
1105
 
1106
        while (sp)
1107
        {
1108
            snext = sp->next;
1109
 
1110
            if (sp->page)
1111
                delete sp->page;
1112
 
1113
            delete sp;
5 andreas 1114
            sp = snext;
3 andreas 1115
        }
1116
 
1117
        mPchain = nullptr;
1118
        mSPchain = nullptr;
14 andreas 1119
        setPChain(mPchain);
1120
        setSPChain(mSPchain);
3 andreas 1121
 
13 andreas 1122
        if (mAmxNet)
1123
        {
1124
            delete mAmxNet;
1125
            mAmxNet = nullptr;
1126
        }
1127
 
3 andreas 1128
        if (mTSettings)
1129
        {
1130
            delete mTSettings;
1131
            mTSettings = nullptr;
1132
        }
1133
 
1134
        if (mPageList)
1135
        {
1136
            delete mPageList;
1137
            mPageList = nullptr;
1138
        }
5 andreas 1139
 
1140
        if (mPalette)
1141
        {
1142
            delete mPalette;
1143
            mPalette = nullptr;
1144
        }
7 andreas 1145
 
1146
        if (mFonts)
1147
        {
1148
            delete mFonts;
1149
            mFonts = nullptr;
1150
        }
8 andreas 1151
 
1152
        if (gIcons)
1153
        {
1154
            delete gIcons;
1155
            gIcons = nullptr;
1156
        }
1157
 
1158
        if (gPrjResources)
1159
        {
1160
            delete gPrjResources;
1161
            gPrjResources = nullptr;
1162
        }
40 andreas 1163
 
33 andreas 1164
        if (mExternal)
1165
        {
1166
            delete mExternal;
1167
            mExternal = nullptr;
1168
        }
3 andreas 1169
    }
1170
    catch (std::exception& e)
1171
    {
1172
        MSG_ERROR("Memory error: " << e.what());
1173
    }
90 andreas 1174
 
1175
    gPageManager = nullptr;
3 andreas 1176
}
1177
 
11 andreas 1178
void TPageManager::initialize()
1179
{
1180
    DECL_TRACER("TPageManager::initialize()");
1181
 
14 andreas 1182
    surface_mutex.lock();
11 andreas 1183
    dropAllSubPages();
1184
    dropAllPages();
1185
 
186 andreas 1186
    string projectPath = TConfig::getProjectPath();
1187
 
1188
    if (!fs::exists(projectPath + "/prj.xma"))
1189
        projectPath += "/__system";
1190
 
90 andreas 1191
    if (mAmxNet && mAmxNet->isConnected())
1192
        mAmxNet->close();
88 andreas 1193
 
11 andreas 1194
    if (mTSettings)
1195
        mTSettings->loadSettings();
1196
    else
186 andreas 1197
        mTSettings = new TSettings(projectPath);
11 andreas 1198
 
1199
    if (TError::isError())
14 andreas 1200
    {
1201
        surface_mutex.unlock();
11 andreas 1202
        return;
14 andreas 1203
    }
11 andreas 1204
 
178 andreas 1205
    // Set the panel type from the project information
1206
    TConfig::savePanelType(mTSettings->getPanelType());
1207
 
88 andreas 1208
    if (gPrjResources)
1209
        delete gPrjResources;
11 andreas 1210
 
88 andreas 1211
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 1212
 
88 andreas 1213
    if (mPalette)
1214
        delete mPalette;
1215
 
1216
    mPalette = new TPalette();
1217
 
11 andreas 1218
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
1219
 
83 andreas 1220
    if (pal.size() > 0)
1221
    {
1222
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 1223
 
118 andreas 1224
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 1225
            mPalette->initialize(iterPal->file);
1226
    }
1227
 
11 andreas 1228
    if (!TError::isError())
1229
        TColor::setPalette(mPalette);
1230
 
88 andreas 1231
    if (mFonts)
1232
        delete mFonts;
11 andreas 1233
 
88 andreas 1234
    mFonts = new TFont();
1235
 
11 andreas 1236
    if (TError::isError())
1237
    {
1238
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 1239
        surface_mutex.unlock();
11 andreas 1240
        return;
1241
    }
1242
 
88 andreas 1243
    if (gIcons)
1244
        delete gIcons;
11 andreas 1245
 
88 andreas 1246
    gIcons = new TIcons();
1247
 
11 andreas 1248
    if (TError::isError())
1249
    {
1250
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 1251
        surface_mutex.unlock();
11 andreas 1252
        return;
1253
    }
1254
 
88 andreas 1255
    if (mPageList)
1256
        delete mPageList;
11 andreas 1257
 
88 andreas 1258
    mPageList = new TPageList();
11 andreas 1259
 
88 andreas 1260
    if (mExternal)
1261
        delete mExternal;
1262
 
1263
    mExternal = new TExternal();
1264
 
11 andreas 1265
    PAGELIST_T page;
1266
 
1267
    if (!mTSettings->getSettings().powerUpPage.empty())
1268
    {
88 andreas 1269
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 1270
        {
88 andreas 1271
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
1272
            page = findPage(mTSettings->getSettings().powerUpPage);
1273
            mActualPage = page.pageID;
14 andreas 1274
        }
11 andreas 1275
    }
1276
 
1277
    TPage *pg = getPage(mActualPage);
1278
 
1279
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
1280
 
83 andreas 1281
    if (popups.size() > 0)
11 andreas 1282
    {
83 andreas 1283
        vector<string>::iterator iter;
1284
 
118 andreas 1285
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 1286
        {
88 andreas 1287
            if (readSubPage(*iter))
83 andreas 1288
            {
88 andreas 1289
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 1290
 
88 andreas 1291
                if (pg)
1292
                {
1293
                    TSubPage *spage = getSubPage(*iter);
350 andreas 1294
                    spage->setParent(pg->getHandle());
88 andreas 1295
                    pg->addSubPage(spage);
1296
                }
83 andreas 1297
            }
11 andreas 1298
        }
1299
    }
1300
 
88 andreas 1301
    // Here we initialize the system resources like borders, cursors, sliders, ...
1302
    if (mSystemDraw)
1303
        delete mSystemDraw;
1304
 
1305
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
1306
 
1307
    TError::clear();        // Clear all errors who may be occured until here
1308
 
11 andreas 1309
    // Start the thread
92 andreas 1310
    startComm();
1311
 
1312
    surface_mutex.unlock();
1313
}
1314
 
1315
bool TPageManager::startComm()
1316
{
1317
    DECL_TRACER("TPageManager::startComm()");
1318
 
1319
    if (mAmxNet && mAmxNet->isNetRun())
1320
        return true;
1321
 
1322
    try
11 andreas 1323
    {
92 andreas 1324
        if (!mAmxNet)
13 andreas 1325
        {
92 andreas 1326
            if (_netRunning)
13 andreas 1327
            {
92 andreas 1328
                // Wait until previous connection thread ended
1329
                while (_netRunning)
1330
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 1331
            }
14 andreas 1332
 
92 andreas 1333
            mAmxNet = new amx::TAmxNet();
1334
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
1335
            mAmxNet->setPanelID(TConfig::getChannel());
134 andreas 1336
            mAmxNet->setSerialNum(V_SERIAL);
13 andreas 1337
        }
90 andreas 1338
 
1339
        if (!mAmxNet->isNetRun())
1340
            mAmxNet->Run();
85 andreas 1341
    }
92 andreas 1342
    catch (std::exception& e)
1343
    {
1344
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
1345
        return false;
1346
    }
14 andreas 1347
 
92 andreas 1348
    return true;
11 andreas 1349
}
1350
 
38 andreas 1351
void TPageManager::startUp()
1352
{
1353
    DECL_TRACER("TPageManager::startUp()");
1354
 
44 andreas 1355
    if (mAmxNet)
90 andreas 1356
    {
1357
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 1358
        return;
90 andreas 1359
    }
44 andreas 1360
 
92 andreas 1361
    if (!startComm())
1362
        return;
90 andreas 1363
 
38 andreas 1364
#ifdef __ANDROID__
130 andreas 1365
    initOrientation();
38 andreas 1366
    initNetworkState();
1367
#endif
1368
}
89 andreas 1369
 
1370
void TPageManager::reset()
1371
{
1372
    DECL_TRACER("TPageManager::reset()");
1373
 
100 andreas 1374
    // Freshly initialize everything.
89 andreas 1375
    initialize();
1376
}
1377
 
169 andreas 1378
void TPageManager::runCommands()
1379
{
1380
    DECL_TRACER("TPageManager::runCommands()");
1381
 
1382
    if (mBusy || cmdLoop_busy)
1383
        return;
1384
 
1385
    try
1386
    {
1387
        mThreadCommand = std::thread([=] { this->commandLoop(); });
1388
        mThreadCommand.detach();
1389
    }
1390
    catch (std::exception& e)
1391
    {
1392
        MSG_ERROR("Error starting thread for command loop: " << e.what());
1393
        _netRunning = false;
1394
    }
1395
}
1396
 
197 andreas 1397
void TPageManager::showSetup()
1398
{
1399
    DECL_TRACER("TPageManager::showSetup()");
251 andreas 1400
#ifdef Q_OS_ANDROID
260 andreas 1401
    // Scan Netlinx for TP4 files and update the list of setup.
1402
    if (TConfig::getController().compare("0.0.0.0") != 0)
1403
    {
1404
        if (_startWait)
1405
            _startWait(string("Please wait while I try to load the list of surface files from Netlinx (") + TConfig::getController() + ")");
1406
 
1407
        TTPInit tpinit;
1408
        std::vector<TTPInit::FILELIST_t> fileList;
1409
        tpinit.setPath(TConfig::getProjectPath());
1410
        fileList = tpinit.getFileList(".tp4");
1411
 
1412
        if (fileList.size() > 0)
1413
        {
1414
            vector<TTPInit::FILELIST_t>::iterator iter;
264 andreas 1415
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1416
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1417
#else
1418
            QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1419
#endif
1420
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
1421
            {
264 andreas 1422
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1423
                QAndroidJniObject str = QAndroidJniObject::fromString(iter->fname.c_str());
1424
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1425
#else
1426
                QJniObject str = QJniObject::fromString(iter->fname.c_str());
1427
                QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1428
#endif
1429
            }
1430
        }
1431
 
1432
        if (_stopWait)
1433
            _stopWait();
1434
    }
1435
 
367 andreas 1436
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1437
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(Ljava/lang/Integer;)V", TConfig::getLogLevelBits());
383 andreas 1438
    QAndroidJniObject strPath = QAndroidJniObject::fromString(TConfig::getLogFile().c_str());
1439
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogFileEnabled", "(Z)V", TConfig::getLogFileEnabled());
1440
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
367 andreas 1441
#else
1442
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(I)V", TConfig::getLogLevelBits());
383 andreas 1443
    QJniObject strPath = QJniObject::fromString(TConfig::getLogFile().c_str());
1444
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogFileEnabled", "(Z)V", TConfig::getLogFileEnabled());
1445
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
367 andreas 1446
#endif
1447
 
255 andreas 1448
    enterSetup();
1449
/*    if (mSetupActive)
197 andreas 1450
        return;
1451
 
1452
    mSetupActive = true;
1453
    mSavedPage = mActualPage;
1454
 
198 andreas 1455
    TPage *pg = getPage(mActualPage);
197 andreas 1456
 
198 andreas 1457
    if (pg)
1458
    {
1459
        TSubPage *spage = pg->getFirstSubPage();
1460
        mSavedSubpages.clear();
197 andreas 1461
 
198 andreas 1462
        while (spage)
197 andreas 1463
        {
198 andreas 1464
            if (spage->isVisible())
1465
                mSavedSubpages.push_back(spage->getNumber());
1466
 
1467
            spage = pg->getNextSubPage();
197 andreas 1468
        }
1469
    }
1470
 
209 andreas 1471
    setPage(SYSTEM_PAGE_CONTROLLER, true);    // Call the page "Controller" (NetLinx settings)
255 andreas 1472
*/
250 andreas 1473
#else
1474
        if (_callShowSetup)
1475
            _callShowSetup();
1476
#endif
197 andreas 1477
}
1478
 
1479
void TPageManager::hideSetup()
1480
{
1481
    DECL_TRACER("TPageManager::hideSetup()");
1482
 
206 andreas 1483
    if (!mSetupActive || mSavedPage >= SYSTEM_PAGE_START)
197 andreas 1484
        return;
1485
 
198 andreas 1486
    mSetupActive = false;
197 andreas 1487
 
198 andreas 1488
    if (!mSavedPage)
1489
    {
1490
        string sPage = mTSettings->getPowerUpPage();
197 andreas 1491
 
198 andreas 1492
        if (!setPage(sPage, true))
1493
            setPage(1, true);
197 andreas 1494
 
1495
        return;
1496
    }
1497
 
198 andreas 1498
    setPage(mSavedPage, true);
213 andreas 1499
    MSG_PROTOCOL("Activated page: " << mSavedPage);
197 andreas 1500
 
198 andreas 1501
    if (mSavedSubpages.size() > 0)
197 andreas 1502
    {
198 andreas 1503
        vector<int>::iterator iter;
197 andreas 1504
 
198 andreas 1505
        for (iter = mSavedSubpages.begin(); iter != mSavedSubpages.end(); ++iter)
1506
        {
1507
            showSubPage(*iter);
213 andreas 1508
            MSG_PROTOCOL("Activated subpage: " << *iter);
198 andreas 1509
        }
217 andreas 1510
 
1511
        mSavedSubpages.clear();
197 andreas 1512
    }
1513
}
1514
 
205 andreas 1515
int TPageManager::getSelectedRow(ulong handle)
1516
{
1517
    DECL_TRACER("TPageManager::getSelectedRow(ulong handle)");
1518
 
300 andreas 1519
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1520
 
206 andreas 1521
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1522
    {                                                   // Yes, then look on page
1523
        TPage *pg = getPage(nPage);
1524
 
1525
        if (!pg)
1526
            return -1;
1527
 
1528
        return pg->getSelectedRow(handle);
1529
    }
206 andreas 1530
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1531
    {
1532
        TSubPage *subPg = getSubPage(nPage);
1533
 
1534
        if (!subPg)
1535
            return -1;
1536
 
1537
        return subPg->getSelectedRow(handle);
1538
    }
1539
 
271 andreas 1540
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1541
    return -1;
1542
}
1543
 
1544
string TPageManager::getSelectedItem(ulong handle)
1545
{
1546
    DECL_TRACER("TPageManager::getSelectedItem(ulong handle)");
1547
 
300 andreas 1548
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1549
 
206 andreas 1550
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1551
    {                                                   // Yes, then look on page
1552
        TPage *pg = getPage(nPage);
1553
 
1554
        if (!pg)
1555
            return string();
1556
 
1557
        return pg->getSelectedItem(handle);
1558
    }
206 andreas 1559
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1560
    {
1561
        TSubPage *subPg = getSubPage(nPage);
1562
 
1563
        if (!subPg)
1564
            return string();
1565
 
1566
        return subPg->getSelectedItem(handle);
1567
    }
1568
 
271 andreas 1569
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1570
    return string();
1571
}
1572
 
206 andreas 1573
void TPageManager::setSelectedRow(ulong handle, int row, const std::string& text)
205 andreas 1574
{
1575
    DECL_TRACER("TPageManager::setSelectedRow(ulong handle, int row)");
1576
 
300 andreas 1577
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1578
 
206 andreas 1579
    if (TPage::isRegularPage(nPage) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1580
    {                                                   // Yes, then look on page
1581
        TPage *pg = getPage(nPage);
1582
 
1583
        if (!pg)
1584
            return;
1585
 
1586
        pg->setSelectedRow(handle, row);
1587
    }
206 andreas 1588
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))   // Do we have a subpage?
1589
    {                                                   // Yes, then look on subpage
205 andreas 1590
        TSubPage *subPg = getSubPage(nPage);
1591
 
1592
        if (!subPg)
1593
            return;
1594
 
1595
        subPg->setSelectedRow(handle, row);
206 andreas 1596
        // Check if this is a system list. If so we must set the selected
1597
        // text to the input line or "label".
1598
        TPage *mainPage = nullptr;
1599
 
1600
        if (nPage >= SYSTEM_SUBPAGE_START)  // System subpage?
1601
        {
1602
            switch(nPage)
1603
            {
1604
                case SYSTEM_SUBPAGE_SYSTEMSOUND:
1605
                case SYSTEM_SUBPAGE_SINGLEBEEP:
1606
                case SYSTEM_SUBPAGE_DOUBLEBEEP:
1607
                    mainPage = getPage(SYSTEM_PAGE_SOUND);
1608
                break;
1609
 
1610
                case SYSTEM_SUBPAGE_SURFACE:
1611
                    mainPage = getPage(SYSTEM_PAGE_CONTROLLER);
1612
                break;
1613
            }
1614
        }
1615
 
1616
        if (mainPage)
1617
        {
1618
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND)  // System sound beep
1619
            {
1620
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSYSSOUND);
1621
 
1622
                if (bt)
1623
                {
1624
                    bt->setText(text, -1);
1625
                    TConfig::setTemporary(true);
1626
                    TConfig::saveSystemSoundFile(text);
1627
                }
1628
            }
1629
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP) // System sound single beep
1630
            {
1631
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSINGLEBEEP);
1632
 
1633
                if (bt)
1634
                {
1635
                    bt->setText(text, -1);
1636
                    TConfig::setTemporary(true);
1637
                    TConfig::saveSingleBeepFile(text);
1638
                }
1639
            }
1640
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP) // System sound double beep
1641
            {
1642
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXDOUBLEBEEP);
1643
 
1644
                if (bt)
1645
                {
1646
                    bt->setText(text, -1);
1647
                    TConfig::setTemporary(true);
1648
                    TConfig::saveDoubleBeepFile(text);
1649
                }
1650
            }
1651
            else if (nPage == SYSTEM_SUBPAGE_SURFACE)   // System TP4 files (surface files)
1652
            {
1653
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_CTRL_SURFACE);
1654
 
1655
                if (bt)
1656
                {
1657
                    MSG_DEBUG("Setting text: " << text);
1658
                    bt->setText(text, -1);
1659
                    TConfig::setTemporary(true);
1660
                    TConfig::saveFtpSurface(text);
1661
                }
1662
            }
1663
 
1664
            // Close the list subpage
1665
            subPg->drop();
1666
        }
205 andreas 1667
    }
1668
}
1669
 
383 andreas 1670
void TPageManager::redrawObject(ulong handle)
1671
{
1672
    DECL_TRACER("TPageManager::redrawObject(ulong handle)");
1673
 
1674
    int pnumber = (int)((handle >> 16) & 0x0000ffff);
1675
    int btnumber = (int)(handle & 0x0000ffff);
1676
 
1677
    if (pnumber < REGULAR_SUBPAGE_START)    // Is it a page?
1678
    {
1679
        TPage *page = getPage(pnumber);
1680
 
1681
        if (!page)
1682
        {
1683
            MSG_WARNING("Page " << pnumber << " not found!");
1684
            return;
1685
        }
1686
 
1687
        if (!page->isVisilble())
1688
            return;
1689
 
1690
        if (btnumber == 0)
1691
        {
1692
            page->show();
1693
            return;
1694
        }
1695
 
1696
        Button::TButton *button = page->getButton(btnumber);
1697
 
1698
        if (!button)
1699
        {
1700
            MSG_WARNING("Button " << btnumber << " on page " << pnumber << " not found!");
1701
            return;
1702
        }
1703
 
1704
        button->showLastButton();
1705
    }
1706
    else if (pnumber >= REGULAR_SUBPAGE_START && pnumber < SYSTEM_PAGE_START)
1707
    {
1708
        TSubPage *spage = getSubPage(pnumber);
1709
 
1710
        if (!spage)
1711
        {
1712
            MSG_WARNING("Subpage " << pnumber << " not found!");
1713
            return;
1714
        }
1715
 
1716
        if (!spage->isVisible())
1717
            return;
1718
 
1719
        if (btnumber == 0)
1720
        {
1721
            spage->show();
1722
            return;
1723
        }
1724
 
1725
        Button::TButton *button = spage->getButton(btnumber);
1726
 
1727
        if (!button)
1728
        {
1729
            MSG_WARNING("Button " << btnumber << " on subpage " << pnumber << " not found!");
1730
            return;
1731
        }
1732
 
1733
        button->showLastButton();
1734
    }
1735
    else
1736
    {
1737
        MSG_WARNING("System pages are not handled by redraw method! Ignoring page " << pnumber << ".");
1738
    }
1739
}
1740
 
198 andreas 1741
#ifdef _SCALE_SKIA_
197 andreas 1742
void TPageManager::setSetupScaleFactor(double scale, double sw, double sh)
1743
{
1744
    DECL_TRACER("TPageManager::setSetupScaleFactor(double scale, double sw, double sh)");
1745
 
1746
    mScaleSystem = scale;
1747
    mScaleSystemWidth = sw;
1748
    mScaleSystemHeight = sh;
1749
}
198 andreas 1750
#endif
197 andreas 1751
 
11 andreas 1752
/*
1753
 * The following method is called by the class TAmxNet whenever an event from
169 andreas 1754
 * the Netlinx occured.
11 andreas 1755
 */
1756
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
1757
{
1758
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
1759
 
169 andreas 1760
    if (!cmdLoop_busy)
1761
        runCommands();
1762
 
11 andreas 1763
    mCommands.push_back(cmd);
169 andreas 1764
}
11 andreas 1765
 
169 andreas 1766
void TPageManager::commandLoop()
1767
{
1768
    DECL_TRACER("TPageManager::commandLoop()");
1769
 
1770
    if (mBusy || cmdLoop_busy)
11 andreas 1771
        return;
1772
 
169 andreas 1773
    mBusy = cmdLoop_busy = true;
11 andreas 1774
    string com;
1775
 
169 andreas 1776
    while (cmdLoop_busy && !killed && !_restart_)
11 andreas 1777
    {
169 andreas 1778
        while (mCommands.size() > 0)
11 andreas 1779
        {
169 andreas 1780
            amx::ANET_COMMAND bef = mCommands.at(0);
1781
            mCommands.erase(mCommands.begin());
11 andreas 1782
 
169 andreas 1783
            switch (bef.MC)
1784
            {
1785
                case 0x0006:
1786
                case 0x0018:	// feedback channel on
1787
                    com.assign("ON-");
1788
                    com.append(to_string(bef.data.chan_state.channel));
1789
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1790
                break;
11 andreas 1791
 
169 andreas 1792
                case 0x0007:
1793
                case 0x0019:	// feedback channel off
1794
                    com.assign("OFF-");
1795
                    com.append(to_string(bef.data.chan_state.channel));
1796
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1797
                break;
11 andreas 1798
 
169 andreas 1799
                case 0x000a:	// level value change
1800
                    com = "LEVEL-";
1801
                    com += to_string(bef.data.message_value.value);
1802
                    com += ",";
11 andreas 1803
 
169 andreas 1804
                    switch (bef.data.message_value.type)
1805
                    {
1806
                        case 0x10: com += to_string(bef.data.message_value.content.byte); break;
1807
                        case 0x11: com += to_string(bef.data.message_value.content.ch); break;
1808
                        case 0x20: com += to_string(bef.data.message_value.content.integer); break;
1809
                        case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
1810
                        case 0x40: com += to_string(bef.data.message_value.content.dword); break;
1811
                        case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
1812
                        case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
1813
                        case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
1814
                    }
11 andreas 1815
 
169 andreas 1816
                    parseCommand(bef.device1, bef.data.message_value.port, com);
1817
                break;
11 andreas 1818
 
169 andreas 1819
                case 0x000c:	// Command string
11 andreas 1820
                {
169 andreas 1821
                    amx::ANET_MSG_STRING msg = bef.data.message_string;
11 andreas 1822
 
169 andreas 1823
                    if (msg.length < strlen((char *)&msg.content))
1824
                    {
1825
                        mCmdBuffer.append((char *)&msg.content);
1826
                        break;
1827
                    }
1828
                    else if (mCmdBuffer.length() > 0)
1829
                    {
1830
                        mCmdBuffer.append((char *)&msg.content);
1831
                        size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
1832
                        strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
1833
                        msg.content[len] = 0;
1834
                    }
104 andreas 1835
 
169 andreas 1836
                    if (getCommand((char *)msg.content) == "^UTF")  // This is already UTF8!
1837
                        com.assign((char *)msg.content);
1838
                    else
1839
                        com.assign(cp1250ToUTF8((char *)&msg.content));
11 andreas 1840
 
169 andreas 1841
                    parseCommand(bef.device1, msg.port, com);
1842
                    mCmdBuffer.clear();
1843
                }
1844
                break;
15 andreas 1845
 
169 andreas 1846
                case 0x0502:    // Blink message (contains date and time)
1847
                    com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
1848
                    com += to_string(bef.data.blinkMessage.minute) + ":";
1849
                    com += to_string(bef.data.blinkMessage.second) + ",";
1850
                    com += to_string(bef.data.blinkMessage.year) + "-";
1851
                    com += to_string(bef.data.blinkMessage.month) + "-";
1852
                    com += to_string(bef.data.blinkMessage.day) + ",";
1853
                    com += to_string(bef.data.blinkMessage.weekday) + ",";
1854
                    com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
1855
                    parseCommand(0, 0, com);
1856
                break;
11 andreas 1857
 
169 andreas 1858
                case 0x1000:	// Filetransfer
11 andreas 1859
                {
169 andreas 1860
                    amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
1861
 
1862
                    if (ftr.ftype == 0)
11 andreas 1863
                    {
169 andreas 1864
                        switch(ftr.function)
1865
                        {
1866
                            case 0x0100:	// Syncing directory
1867
                                com = "#FTR-SYNC:0:";
1868
                                com.append((char*)&ftr.data[0]);
1869
                                parseCommand(bef.device1, bef.port1, com);
1870
                            break;
11 andreas 1871
 
169 andreas 1872
                            case 0x0104:	// Delete file
1873
                                com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
1874
                                parseCommand(bef.device1, bef.port1, com);
1875
                            break;
11 andreas 1876
 
169 andreas 1877
                            case 0x0105:	// start filetransfer
1878
                                com = "#FTR-START";
1879
                                parseCommand(bef.device1, bef.port1, com);
1880
                            break;
1881
                        }
11 andreas 1882
                    }
169 andreas 1883
                    else
11 andreas 1884
                    {
169 andreas 1885
                        switch(ftr.function)
1886
                        {
1887
                            case 0x0003:	// Received part of file
1888
                            case 0x0004:	// End of file
1889
                                com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
1890
                                parseCommand(bef.device1, bef.port1, com);
1891
                            break;
11 andreas 1892
 
169 andreas 1893
                            case 0x0007:	// End of file transfer
1894
                            {
1895
                                com = "#FTR-END";
1896
                                parseCommand(bef.device1, bef.port1, com);
1897
                            }
1898
                            break;
1899
 
1900
                            case 0x0102:	// Receiving file
1901
                                com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
1902
                                com.append((char*)&ftr.data[0]);
1903
                                parseCommand(bef.device1, bef.port1, com);
1904
                            break;
11 andreas 1905
                        }
1906
                    }
1907
                }
169 andreas 1908
                break;
11 andreas 1909
            }
1910
        }
169 andreas 1911
 
1912
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
11 andreas 1913
    }
1914
 
1915
    mBusy = false;
169 andreas 1916
    cmdLoop_busy = false;
11 andreas 1917
}
1918
 
26 andreas 1919
void TPageManager::deployCallbacks()
1920
{
1921
    DECL_TRACER("TPageManager::deployCallbacks()");
1922
 
1923
    PCHAIN_T *p = mPchain;
1924
 
1925
    while (p)
1926
    {
1927
        if (p->page)
1928
        {
1929
            if (_setBackground)
1930
                p->page->registerCallback(_setBackground);
1931
 
1932
            if (_callPlayVideo)
1933
                p->page->regCallPlayVideo(_callPlayVideo);
1934
        }
1935
 
1936
        p = p->next;
1937
    }
1938
 
1939
    SPCHAIN_T *sp = mSPchain;
1940
 
1941
    while (sp)
1942
    {
1943
        if (sp->page)
1944
        {
1945
            if (_setBackground)
1946
                sp->page->registerCallback(_setBackground);
1947
 
1948
            if (_callPlayVideo)
1949
                sp->page->regCallPlayVideo(_callPlayVideo);
1950
        }
1951
 
1952
        sp = sp->next;
1953
    }
1954
}
36 andreas 1955
 
1956
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
1957
{
1958
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
1959
 
1960
    if (handle == 0)
1961
        return;
1962
 
1963
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
1964
}
1965
 
1966
void TPageManager::unregCallbackNetState(ulong handle)
1967
{
1968
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
1969
 
83 andreas 1970
    if (mNetCalls.size() == 0)
1971
        return;
1972
 
300 andreas 1973
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find((int)handle);
36 andreas 1974
 
1975
    if (iter != mNetCalls.end())
1976
        mNetCalls.erase(iter);
1977
}
247 andreas 1978
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
251 andreas 1979
#ifdef Q_OS_ANDROID
38 andreas 1980
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
1981
{
1982
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
1983
 
1984
    if (handle == 0)
1985
        return;
1986
 
1987
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
1988
}
247 andreas 1989
#endif
1990
#ifdef Q_OS_IOS
1991
void TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)
1992
{
1993
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)");
38 andreas 1994
 
247 andreas 1995
    if (handle == 0)
1996
        return;
1997
 
1998
    mBatteryCalls.insert(std::pair<int, std::function<void (int, int)> >(handle, callBatteryState));
264 andreas 1999
#ifdef Q_OS_IOS
2000
    mLastBatteryLevel = TIOSBattery::getBatteryLeft();
2001
    mLastBatteryState = TIOSBattery::getBatteryState();
247 andreas 2002
 
264 andreas 2003
#endif
247 andreas 2004
    if (mLastBatteryLevel > 0 || mLastBatteryState > 0)
2005
        informBatteryStatus(mLastBatteryLevel, mLastBatteryState);
2006
}
2007
#endif
38 andreas 2008
void TPageManager::unregCallbackBatteryState(ulong handle)
2009
{
2010
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
2011
 
83 andreas 2012
    if (mBatteryCalls.size() == 0)
2013
        return;
247 andreas 2014
#ifdef Q_OS_ANDROID
38 andreas 2015
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
247 andreas 2016
#endif
2017
#ifdef Q_OS_IOS
300 andreas 2018
    std::map<int, std::function<void (int, int)> >::iterator iter = mBatteryCalls.find((int)handle);
247 andreas 2019
#endif
38 andreas 2020
    if (iter != mBatteryCalls.end())
2021
        mBatteryCalls.erase(iter);
2022
}
247 andreas 2023
#endif  // defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
11 andreas 2024
/*
2025
 * The following function must be called to start the "panel".
2026
 */
5 andreas 2027
bool TPageManager::run()
2028
{
2029
    DECL_TRACER("TPageManager::run()");
2030
 
2031
    if (mActualPage <= 0)
2032
        return false;
2033
 
154 andreas 2034
    TPage *pg = getPage(mActualPage);
2035
 
2036
    if (!pg || !_setPage || !mTSettings)
2037
        return false;
2038
 
14 andreas 2039
    surface_mutex.lock();
7 andreas 2040
    pg->setFonts(mFonts);
5 andreas 2041
    pg->registerCallback(_setBackground);
21 andreas 2042
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 2043
 
26 andreas 2044
    int width, height;
217 andreas 2045
    width = mTSettings->getWidth();
26 andreas 2046
    height = mTSettings->getHeight();
43 andreas 2047
#ifdef _SCALE_SKIA_
26 andreas 2048
    if (mScaleFactor != 1.0)
2049
    {
2050
        width = (int)((double)width * mScaleFactor);
2051
        height = (int)((double)height * mScaleFactor);
2052
    }
43 andreas 2053
#endif
26 andreas 2054
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 2055
    pg->show();
2056
 
2057
    TSubPage *subPg = pg->getFirstSubPage();
2058
 
2059
    while (subPg)
2060
    {
7 andreas 2061
        subPg->setFonts(mFonts);
2062
        subPg->registerCallback(_setBackground);
2063
        subPg->registerCallbackDB(_displayButton);
11 andreas 2064
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 2065
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 2066
 
5 andreas 2067
        if (_setSubPage)
6 andreas 2068
        {
2069
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 2070
            width = subPg->getWidth();
2071
            height = subPg->getHeight();
2072
            int left = subPg->getLeft();
2073
            int top = subPg->getTop();
43 andreas 2074
#ifdef _SCALE_SKIA_
26 andreas 2075
            if (mScaleFactor != 1.0)
2076
            {
2077
                width = (int)((double)width * mScaleFactor);
2078
                height = (int)((double)height * mScaleFactor);
2079
                left = (int)((double)left * mScaleFactor);
2080
                top = (int)((double)top * mScaleFactor);
2081
            }
43 andreas 2082
#endif
41 andreas 2083
            ANIMATION_t ani;
2084
            ani.showEffect = subPg->getShowEffect();
2085
            ani.showTime = subPg->getShowTime();
42 andreas 2086
            ani.hideEffect = subPg->getHideEffect();
2087
            ani.hideTime = subPg->getHideTime();
162 andreas 2088
 
2089
            subPg->setZOrder(pg->getNextZOrder());
217 andreas 2090
            _setSubPage(subPg->getHandle(), pg->getHandle(), left, top, width, height, ani);
6 andreas 2091
            subPg->show();
2092
        }
5 andreas 2093
 
2094
        subPg = pg->getNextSubPage();
2095
    }
2096
 
14 andreas 2097
    surface_mutex.unlock();
5 andreas 2098
    return true;
2099
}
2100
 
4 andreas 2101
TPage *TPageManager::getPage(int pageID)
2102
{
2103
    DECL_TRACER("TPageManager::getPage(int pageID)");
2104
 
209 andreas 2105
    if (pageID <= 0)
2106
        return nullptr;
2107
 
4 andreas 2108
    PCHAIN_T *p = mPchain;
2109
 
2110
    while (p)
2111
    {
349 andreas 2112
        if (p->page && p->page->getNumber() == pageID)
4 andreas 2113
            return p->page;
2114
 
2115
        p = p->next;
2116
    }
2117
 
2118
    return nullptr;
2119
}
2120
 
2121
TPage *TPageManager::getPage(const string& name)
2122
{
2123
    DECL_TRACER("TPageManager::getPage(const string& name)");
2124
 
349 andreas 2125
    if (name.empty())
2126
        return nullptr;
2127
 
4 andreas 2128
    PCHAIN_T *p = mPchain;
2129
 
2130
    while (p)
2131
    {
349 andreas 2132
        if (p->page && p->page->getName().compare(name) == 0)
4 andreas 2133
            return p->page;
2134
 
2135
        p = p->next;
2136
    }
2137
 
2138
    return nullptr;
2139
}
2140
 
209 andreas 2141
TPage *TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)
15 andreas 2142
{
209 andreas 2143
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)");
15 andreas 2144
 
209 andreas 2145
    if (refresh)
2146
        *refresh = false;
2147
 
15 andreas 2148
    if (!pl.isValid)
2149
        return nullptr;
2150
 
2151
    TPage *pg = getPage(pl.pageID);
2152
 
2153
    if (!pg)
2154
    {
2155
        if (!readPage(pl.pageID))
2156
            return nullptr;
2157
 
2158
        pg = getPage(pl.pageID);
2159
 
2160
        if (!pg)
2161
        {
2162
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
2163
            return nullptr;
2164
        }
209 andreas 2165
 
2166
        if (refresh)
213 andreas 2167
            *refresh = true;        // Indicate that the page was freshly loaded
15 andreas 2168
    }
2169
 
2170
    return pg;
2171
}
2172
 
209 andreas 2173
void TPageManager::reloadSystemPage(TPage *page)
2174
{
2175
    DECL_TRACER("TPageManager::reloadSystemPage(TPage *page)");
2176
 
2177
    if (!page)
2178
        return;
2179
 
2180
    vector<Button::TButton *> buttons = page->getAllButtons();
2181
    vector<Button::TButton *>::iterator iter;
210 andreas 2182
    TConfig::setTemporary(false);
209 andreas 2183
 
2184
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
2185
    {
2186
        Button::TButton *bt = *iter;
2187
 
2188
        if (bt->getAddressPort() == 0 && bt->getAddressChannel() > 0)
2189
        {
2190
            switch(bt->getAddressChannel())
2191
            {
2192
                case SYSTEM_ITEM_LOGLOGFILE:        bt->setTextOnly(TConfig::getLogFile(), -1); break;
2193
 
2194
                case SYSTEM_ITEM_NETLINX_IP:        bt->setTextOnly(TConfig::getController(), -1); break;
2195
                case SYSTEM_ITEM_NETLINX_PORT:      bt->setTextOnly(std::to_string(TConfig::getPort()), -1); break;
2196
                case SYSTEM_ITEM_NETLINX_CHANNEL:   bt->setTextOnly(std::to_string(TConfig::getChannel()), -1); break;
2197
                case SYSTEM_ITEM_NETLINX_PTYPE:     bt->setTextOnly(TConfig::getPanelType(), -1); break;
2198
                case SYSTEM_ITEM_FTPUSER:           bt->setTextOnly(TConfig::getFtpUser(), -1); break;
2199
                case SYSTEM_ITEM_FTPPASSWORD:       bt->setTextOnly(TConfig::getFtpPassword(), -1); break;
2200
                case SYSTEM_ITEM_FTPSURFACE:        bt->setTextOnly(TConfig::getFtpSurface(), -1); break;
210 andreas 2201
 
2202
                case SYSTEM_ITEM_SIPPROXY:          bt->setTextOnly(TConfig::getSIPproxy(), -1); break;
2203
                case SYSTEM_ITEM_SIPPORT:           bt->setTextOnly(std::to_string(TConfig::getSIPport()), -1); break;
2204
                case SYSTEM_ITEM_SIPSTUN:           bt->setTextOnly(TConfig::getSIPstun(), -1); break;
2205
                case SYSTEM_ITEM_SIPDOMAIN:         bt->setTextOnly(TConfig::getSIPdomain(), -1); break;
2206
                case SYSTEM_ITEM_SIPUSER:           bt->setTextOnly(TConfig::getSIPuser(), -1); break;
2207
                case SYSTEM_ITEM_SIPPASSWORD:       bt->setTextOnly(TConfig::getSIPpassword(), -1); break;
2208
 
2209
                case SYSTEM_ITEM_SYSTEMSOUND:       bt->setTextOnly(TConfig::getSystemSound(), -1); break;
2210
                case SYSTEM_ITEM_SINGLEBEEP:        bt->setTextOnly(TConfig::getSingleBeepSound(), -1); break;
2211
                case SYSTEM_ITEM_DOUBLEBEEP:        bt->setTextOnly(TConfig::getDoubleBeepSound(), -1); break;
209 andreas 2212
            }
2213
        }
210 andreas 2214
        else if (bt->getChannelPort() == 0 && bt->getChannelNumber() > 0)
2215
        {
2216
            switch(bt->getChannelNumber())
2217
            {
2218
                case SYSTEM_ITEM_DEBUGINFO:         bt->setActiveInstance(IS_LOG_INFO() ? 1 : 0); break;
2219
                case SYSTEM_ITEM_DEBUGWARNING:      bt->setActiveInstance(IS_LOG_WARNING() ? 1 : 0); break;
2220
                case SYSTEM_ITEM_DEBUGERROR:        bt->setActiveInstance(IS_LOG_ERROR() ? 1 : 0); break;
2221
                case SYSTEM_ITEM_DEBUGTRACE:        bt->setActiveInstance(IS_LOG_TRACE() ? 1 : 0); break;
2222
                case SYSTEM_ITEM_DEBUGDEBUG:        bt->setActiveInstance(IS_LOG_DEBUG() ? 1 : 0); break;
2223
                case SYSTEM_ITEM_DEBUGPROTOCOL:     bt->setActiveInstance(IS_LOG_PROTOCOL() ? 1 : 0); break;
2224
                case SYSTEM_ITEM_DEBUGALL:          bt->setActiveInstance(IS_LOG_ALL() ? 1 : 0); break;
2225
                case SYSTEM_ITEM_DEBUGLONG:         bt->setActiveInstance(TConfig::isLongFormat() ? 1 : 0); break;
2226
                case SYSTEM_ITEM_DEBUGPROFILE:      bt->setActiveInstance(TConfig::getProfiling() ? 1 : 0); break;
2227
 
2228
                case SYSTEM_ITEM_FTPPASSIVE:        bt->setActiveInstance(TConfig::getFtpPassive() ? 1 : 0); break;
2229
 
2230
                case SYSTEM_ITEM_SIPIPV4:           bt->setActiveInstance(TConfig::getSIPnetworkIPv4() ? 1 : 0); break;
2231
                case SYSTEM_ITEM_SIPIPV6:           bt->setActiveInstance(TConfig::getSIPnetworkIPv6() ? 1 : 0); break;
2232
                case SYSTEM_ITEM_SIPENABLE:         bt->setActiveInstance(TConfig::getSIPstatus() ? 1 : 0); break;
2233
                case SYSTEM_ITEM_SIPIPHONE:         bt->setActiveInstance(TConfig::getSIPiphone() ? 1 : 0); break;
2234
 
2235
                case SYSTEM_ITEM_SOUNDSWITCH:       bt->setActiveInstance(TConfig::getSystemSoundState() ? 1 : 0); break;
2236
 
2237
                case SYSTEM_ITEM_VIEWSCALEFIT:      bt->setActiveInstance(TConfig::getScale() ? 1 : 0); break;
2238
                case SYSTEM_ITEM_VIEWBANNER:        bt->setActiveInstance(TConfig::showBanner() ? 1 : 0); break;
2239
                case SYSTEM_ITEM_VIEWNOTOOLBAR:     bt->setActiveInstance(TConfig::getToolbarSuppress() ? 1 : 0); break;
2240
                case SYSTEM_ITEM_VIEWTOOLBAR:       bt->setActiveInstance(TConfig::getToolbarForce() ? 1 : 0); break;
2241
                case SYSTEM_ITEM_VIEWROTATE:        bt->setActiveInstance(TConfig::getRotationFixed() ? 1 : 0); break;
2242
            }
2243
        }
2244
        else if (bt->getLevelPort() == 0 && bt->getLevelValue() > 0)
2245
        {
2246
            switch(bt->getLevelValue())
2247
            {
2248
                case SYSTEM_ITEM_SYSVOLUME:         bt->drawBargraph(0, TConfig::getSystemVolume(), false); break;
2249
                case SYSTEM_ITEM_SYSGAIN:           bt->drawBargraph(0, TConfig::getSystemGain(), false); break;
2250
            }
2251
        }
209 andreas 2252
    }
2253
}
2254
 
198 andreas 2255
bool TPageManager::setPage(int PageID, bool forget)
15 andreas 2256
{
198 andreas 2257
    DECL_TRACER("TPageManager::setPage(int PageID, bool forget)");
15 andreas 2258
 
295 andreas 2259
    return _setPageDo(PageID, "", forget);
15 andreas 2260
}
2261
 
168 andreas 2262
bool TPageManager::setPage(const string& name, bool forget)
15 andreas 2263
{
190 andreas 2264
    DECL_TRACER("TPageManager::setPage(const string& name, bool forget)");
15 andreas 2265
 
295 andreas 2266
    return _setPageDo(0, name, forget);
15 andreas 2267
}
2268
 
295 andreas 2269
bool TPageManager::_setPageDo(int pageID, const string& name, bool forget)
2270
{
2271
    DECL_TRACER("TPageManager::_setPageDo(int pageID, const string& name, bool forget)");
2272
 
2273
    TPage *pg = nullptr;
2274
 
2275
    if (pageID > 0 && mActualPage == pageID)
343 andreas 2276
    {
2277
#if TESTMODE == 1
2278
        __success = true;
2279
        setScreenDone();
2280
#endif
295 andreas 2281
        return true;
343 andreas 2282
    }
295 andreas 2283
    else if (!name.empty())
2284
    {
2285
        pg = getPage(mActualPage);
2286
 
2287
        if (pg && pg->getName().compare(name) == 0)
343 andreas 2288
        {
2289
#if TESTMODE == 1
2290
            __success = true;
2291
            setScreenDone();
2292
#endif
295 andreas 2293
            return true;
343 andreas 2294
        }
295 andreas 2295
    }
2296
    else if (pageID > 0)
2297
        pg = getPage(mActualPage);
2298
    else
343 andreas 2299
    {
2300
#if TESTMODE == 1
2301
        setScreenDone();
2302
#endif
295 andreas 2303
        return false;
343 andreas 2304
    }
295 andreas 2305
 
2306
    // FIXME: Make this a vector array to hold a larger history!
2307
    if (!forget)
2308
        mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
2309
 
2310
    if (pg)
2311
        pg->drop();
2312
 
2313
    mActualPage = 0;
2314
    PAGELIST_T listPg;
2315
 
2316
    if (pageID > 0)
2317
        listPg = findPage(pageID);
2318
    else
2319
        listPg = findPage(name);
2320
 
2321
    bool refresh = false;
2322
 
2323
    if ((pg = loadPage(listPg, &refresh)) == nullptr)
343 andreas 2324
    {
2325
#if TESTMODE == 1
2326
        setScreenDone();
2327
#endif
295 andreas 2328
        return false;
343 andreas 2329
    }
295 andreas 2330
 
2331
    mActualPage = pg->getNumber();
2332
 
2333
    if (mActualPage >= SYSTEM_PAGE_START && !refresh)
2334
        reloadSystemPage(pg);
2335
 
2336
    int width = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getWidth() : mTSettings->getWidth());
2337
    int height = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getHeight() : mTSettings->getHeight());
2338
 
2339
    if (_setPage)
2340
        _setPage((mActualPage << 16) & 0xffff0000, width, height);
2341
 
2342
    pg->show();
2343
    return true;
2344
}
2345
 
2346
 
4 andreas 2347
TSubPage *TPageManager::getSubPage(int pageID)
2348
{
2349
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
2350
 
2351
    SPCHAIN_T *p = mSPchain;
2352
 
2353
    while(p)
2354
    {
2355
        if (p->page->getNumber() == pageID)
2356
            return p->page;
2357
 
2358
        p = p->next;
2359
    }
2360
 
2361
    return nullptr;
2362
}
2363
 
2364
TSubPage *TPageManager::getSubPage(const std::string& name)
2365
{
2366
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
2367
 
2368
    SPCHAIN_T *p = mSPchain;
2369
 
2370
    while (p)
2371
    {
2372
        if (p->page->getName().compare(name) == 0)
2373
            return p->page;
2374
 
2375
        p = p->next;
2376
    }
2377
 
146 andreas 2378
    MSG_DEBUG("Page " << name << " not found in cache.");
4 andreas 2379
    return nullptr;
2380
}
2381
 
96 andreas 2382
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
2383
{
198 andreas 2384
    DECL_TRACER("TPageManager::deliverSubPage(const string& name, TPage **pg)");
96 andreas 2385
 
2386
    TPage *page = getActualPage();
2387
 
2388
    if (!page)
2389
    {
2390
        MSG_ERROR("No actual page loaded!");
2391
        return nullptr;
2392
    }
2393
 
2394
    if (pg)
2395
        *pg = page;
2396
 
2397
    TSubPage *subPage = getSubPage(name);
2398
 
2399
    if (!subPage)
2400
    {
2401
        if (!readSubPage(name))
2402
        {
2403
            MSG_ERROR("Error reading subpage " << name);
2404
            return nullptr;
2405
        }
2406
 
2407
        subPage = getSubPage(name);
2408
 
2409
        if (!subPage)
2410
        {
2411
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
2412
            return nullptr;
2413
        }
350 andreas 2414
 
2415
        subPage->setParent(page->getHandle());
96 andreas 2416
    }
2417
 
2418
    return subPage;
2419
}
2420
 
198 andreas 2421
TSubPage *TPageManager::deliverSubPage(int number, TPage **pg)
2422
{
2423
    DECL_TRACER("TPageManager::deliverSubPage(int number, TPage **pg)");
2424
 
2425
    TPage *page = getActualPage();
2426
 
2427
    if (!page)
2428
    {
2429
        MSG_ERROR("No actual page loaded!");
2430
        return nullptr;
2431
    }
2432
 
2433
    if (pg)
2434
        *pg = page;
2435
 
2436
    TSubPage *subPage = getSubPage(number);
2437
 
2438
    if (!subPage)
2439
    {
2440
        if (!readSubPage(number))
2441
        {
2442
            MSG_ERROR("Error reading subpage " << number);
2443
            return nullptr;
2444
        }
2445
 
2446
        subPage = getSubPage(number);
2447
 
2448
        if (!subPage)
2449
        {
2450
            MSG_ERROR("Fatal: A page with name " << number << " does not exist!");
2451
            return nullptr;
2452
        }
350 andreas 2453
 
2454
        subPage->setParent(page->getHandle());
198 andreas 2455
    }
2456
 
2457
    return subPage;
2458
}
2459
 
3 andreas 2460
bool TPageManager::readPages()
2461
{
2462
    DECL_TRACER("TPageManager::readPages()");
2463
 
2464
    if (!mPageList)
2465
    {
2466
        MSG_ERROR("Page list is not initialized!");
2467
        TError::setError();
2468
        return false;
2469
    }
2470
 
2471
    // Read all pages
2472
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
2473
 
83 andreas 2474
    if (pageList.size() > 0)
3 andreas 2475
    {
83 andreas 2476
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 2477
 
118 andreas 2478
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 2479
        {
83 andreas 2480
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 2481
 
83 andreas 2482
            if (TError::isError())
2483
            {
2484
                delete page;
2485
                return false;
2486
            }
3 andreas 2487
 
83 andreas 2488
            page->setPalette(mPalette);
2489
            page->setFonts(mFonts);
2490
            page->registerCallback(_setBackground);
2491
            page->registerCallbackDB(_displayButton);
2492
            page->regCallPlayVideo(_callPlayVideo);
2493
 
2494
            if (!addPage(page))
2495
                return false;
2496
        }
3 andreas 2497
    }
2498
 
348 andreas 2499
    vector<SUBPAGELIST_T> subPageList = mPageList->getSubPageList();
3 andreas 2500
 
83 andreas 2501
    if (subPageList.size() > 0)
3 andreas 2502
    {
83 andreas 2503
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 2504
 
118 andreas 2505
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 2506
        {
83 andreas 2507
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 2508
 
83 andreas 2509
            if (TError::isError())
2510
            {
2511
                delete page;
2512
                return false;
2513
            }
3 andreas 2514
 
83 andreas 2515
            page->setPalette(mPalette);
2516
            page->setFonts(mFonts);
2517
            page->registerCallback(_setBackground);
2518
            page->registerCallbackDB(_displayButton);
2519
            page->regCallDropSubPage(_callDropSubPage);
2520
            page->regCallPlayVideo(_callPlayVideo);
2521
            page->setGroup(spgIter->group);
2522
 
2523
            if (!addSubPage(page))
2524
                return false;
2525
        }
3 andreas 2526
    }
2527
 
2528
    return true;
2529
}
2530
 
2531
bool TPageManager::readPage(const std::string& name)
2532
{
2533
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
2534
 
2535
    PAGELIST_T page = findPage(name);
2536
 
206 andreas 2537
    if ((page.pageID <= 0 || page.pageID >= MAX_PAGE_ID) && page.pageID < SYSTEM_PAGE_START && page.pageID >= SYSTEM_SUBPAGE_START)
3 andreas 2538
    {
2539
        MSG_ERROR("Page " << name << " not found!");
2540
        return false;
2541
    }
2542
 
43 andreas 2543
    TPage *pg;
14 andreas 2544
 
43 andreas 2545
    if (name.compare("_progress") == 0)
2546
        pg = new TPage(name);
2547
    else
2548
        pg = new TPage(page.name+".xml");
2549
 
14 andreas 2550
    if (TError::isError())
2551
    {
2552
        delete pg;
2553
        return false;
2554
    }
2555
 
4 andreas 2556
    pg->setPalette(mPalette);
7 andreas 2557
    pg->setFonts(mFonts);
2558
    pg->registerCallback(_setBackground);
2559
    pg->registerCallbackDB(_displayButton);
21 andreas 2560
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2561
 
2562
    if (!addPage(pg))
2563
        return false;
2564
 
2565
    return true;
2566
}
2567
 
2568
bool TPageManager::readPage(int ID)
2569
{
2570
    DECL_TRACER("TPageManager::readPage(int ID)");
2571
 
16 andreas 2572
    TError::clear();
3 andreas 2573
    PAGELIST_T page = findPage(ID);
2574
 
2575
    if (page.pageID <= 0)
2576
    {
2577
        MSG_ERROR("Page with ID " << ID << " not found!");
2578
        return false;
2579
    }
2580
 
43 andreas 2581
    TPage *pg;
14 andreas 2582
 
43 andreas 2583
    if (ID == 300)      // Progress page of system?
2584
        pg = new TPage("_progress");
2585
    else
2586
        pg = new TPage(page.name+".xml");
2587
 
14 andreas 2588
    if (TError::isError())
2589
    {
2590
        delete pg;
2591
        return false;
2592
    }
2593
 
4 andreas 2594
    pg->setPalette(mPalette);
7 andreas 2595
    pg->setFonts(mFonts);
2596
    pg->registerCallback(_setBackground);
2597
    pg->registerCallbackDB(_displayButton);
21 andreas 2598
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2599
 
2600
    if (!addPage(pg))
2601
        return false;
2602
 
2603
    return true;
2604
}
2605
 
2606
bool TPageManager::readSubPage(const std::string& name)
2607
{
2608
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
2609
 
16 andreas 2610
    TError::clear();
3 andreas 2611
    SUBPAGELIST_T page = findSubPage(name);
2612
 
206 andreas 2613
    if (page.pageID < MAX_PAGE_ID || (page.pageID >= SYSTEM_PAGE_START && page.pageID < SYSTEM_SUBPAGE_START))
3 andreas 2614
    {
2615
        MSG_ERROR("Subpage " << name << " not found!");
2616
        return false;
2617
    }
2618
 
14 andreas 2619
    if (haveSubPage(name))
2620
        return true;
2621
 
3 andreas 2622
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2623
 
2624
    if (TError::isError())
2625
    {
2626
        delete pg;
2627
        return false;
2628
    }
2629
 
4 andreas 2630
    pg->setPalette(mPalette);
7 andreas 2631
    pg->setFonts(mFonts);
2632
    pg->registerCallback(_setBackground);
2633
    pg->registerCallbackDB(_displayButton);
11 andreas 2634
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2635
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2636
    pg->setGroup(page.group);
3 andreas 2637
 
2638
    if (!addSubPage(pg))
14 andreas 2639
    {
2640
        delete pg;
3 andreas 2641
        return false;
14 andreas 2642
    }
3 andreas 2643
 
2644
    return true;
2645
}
2646
 
2647
bool TPageManager::readSubPage(int ID)
2648
{
2649
    DECL_TRACER("TPageManager::readSubPage(int ID)");
2650
 
16 andreas 2651
    TError::clear();
3 andreas 2652
    SUBPAGELIST_T page = findSubPage(ID);
2653
 
154 andreas 2654
    if (page.pageID <= MAX_PAGE_ID)
3 andreas 2655
    {
2656
        MSG_ERROR("Subpage with ID " << ID << " not found!");
2657
        return false;
2658
    }
2659
 
2660
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2661
 
2662
    if (TError::isError())
2663
    {
2664
        delete pg;
2665
        return false;
2666
    }
2667
 
4 andreas 2668
    pg->setPalette(mPalette);
7 andreas 2669
    pg->setFonts(mFonts);
2670
    pg->registerCallback(_setBackground);
2671
    pg->registerCallbackDB(_displayButton);
11 andreas 2672
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2673
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2674
    pg->setGroup(page.group);
3 andreas 2675
 
2676
    if (!addSubPage(pg))
2677
        return false;
2678
 
2679
    return true;
2680
}
2681
 
279 andreas 2682
vector<TSubPage *> TPageManager::createSubViewList(int id)
2683
{
2684
    DECL_TRACER("TPageManager::createSubViewList(int id)");
2685
 
2686
    vector<TSubPage *> subviews;
2687
 
2688
    if (id <= 0)
2689
        return subviews;
2690
 
2691
    if (!mPageList)
2692
    {
2693
        MSG_WARNING("Missing page list and because of this can't make a subview list!");
2694
        return subviews;
2695
    }
2696
 
2697
    SUBVIEWLIST_T slist = mPageList->findSubViewList(id);
2698
 
2699
    if (slist.id <= 0 || slist.items.empty())
2700
    {
2701
        if (slist.id <= 0)
2702
        {
2703
            MSG_WARNING("Found no subview list with ID " << id);
2704
        }
2705
        else
2706
        {
300 andreas 2707
            MSG_WARNING("Subview list " << id << " has no items!");
279 andreas 2708
        }
2709
 
2710
        return subviews;
2711
    }
2712
 
2713
    vector<SUBVIEWITEM_T>::iterator iter;
2714
 
2715
    for (iter = slist.items.begin(); iter != slist.items.end(); ++iter)
2716
    {
2717
        if (!haveSubPage(iter->pageID))
2718
        {
2719
            if (!readSubPage(iter->pageID))
2720
                return vector<TSubPage *>();
2721
        }
2722
 
284 andreas 2723
        TSubPage *pg = getSubPage(iter->pageID);
279 andreas 2724
 
2725
        if (pg)
2726
            subviews.push_back(pg);
284 andreas 2727
        else
2728
        {
2729
            MSG_DEBUG("No subpage with ID " << id);
2730
        }
279 andreas 2731
    }
2732
 
300 andreas 2733
    MSG_DEBUG("Found " << subviews.size() << " subview items.");
279 andreas 2734
    return subviews;
2735
}
2736
 
280 andreas 2737
void TPageManager::showSubViewList(int id, Button::TButton *bt)
279 andreas 2738
{
280 andreas 2739
    DECL_TRACER("TPageManager::showSubViewList(int id, Button::TButton *bt)");
279 andreas 2740
 
2741
    vector<TSubPage *> subviews = createSubViewList(id);
2742
 
303 andreas 2743
    if (subviews.empty() || !_addViewButtonItems || !bt)
284 andreas 2744
    {
2745
        MSG_DEBUG("Number views: " << subviews.size() << (_addViewButtonItems ? ", addView" : ", NO addView") << (_displayViewButton ? " display" : " NO display"));
279 andreas 2746
        return;
284 andreas 2747
    }
279 andreas 2748
 
293 andreas 2749
    ulong btHandle = bt->getHandle();
2750
    MSG_DEBUG("Working on button " << handleToString(btHandle) << " (" << bt->getName() << ") with " << subviews.size() << " pages.");
289 andreas 2751
    TBitmap bm = bt->getLastBitmap();
2752
    TColor::COLOR_T fillColor = TColor::getAMXColor(bt->getFillColor());
293 andreas 2753
    _displayViewButton(btHandle, bt->getParent(), bt->isSubViewVertical(), bm, bt->getWidth(), bt->getHeight(), bt->getLeftPosition(), bt->getTopPosition(), bt->getSubViewSpace(), fillColor);
280 andreas 2754
 
2755
    vector<PGSUBVIEWITEM_T> items;
2756
    PGSUBVIEWITEM_T svItem;
2757
    PGSUBVIEWATOM_T svAtom;
279 andreas 2758
    vector<TSubPage *>::iterator iter;
2759
 
2760
    for (iter = subviews.begin(); iter != subviews.end(); ++iter)
2761
    {
280 andreas 2762
        TSubPage *sub = *iter;
306 andreas 2763
        sub->setParent(btHandle);
279 andreas 2764
 
289 andreas 2765
        svItem.clear();
2766
        Button::TButton *button = sub->getFirstButton();
2767
        SkBitmap bitmap = sub->getBgImage();
280 andreas 2768
 
2769
        svItem.handle = sub->getHandle();
289 andreas 2770
        svItem.parent = btHandle;
280 andreas 2771
        svItem.width = sub->getWidth();
2772
        svItem.height = sub->getHeight();
281 andreas 2773
        svItem.bgcolor = TColor::getAMXColor(sub->getFillColor());
300 andreas 2774
        svItem.scrollbar = bt->getSubViewScrollbar();
2775
        svItem.scrollbarOffset = bt->getSubViewScrollbarOffset();
2776
        svItem.position = bt->getSubViewAnchor();
302 andreas 2777
        svItem.wrap = bt->getWrapSubViewPages();
280 andreas 2778
 
289 andreas 2779
        if (!bitmap.empty())
2780
            svItem.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
280 andreas 2781
 
289 andreas 2782
        while (button)
280 andreas 2783
        {
300 andreas 2784
            button->drawButton(0, false, true);
289 andreas 2785
            svAtom.clear();
2786
            svAtom.handle = button->getHandle();
280 andreas 2787
            svAtom.parent = sub->getHandle();
289 andreas 2788
            svAtom.width = button->getWidth();
2789
            svAtom.height = button->getHeight();
2790
            svAtom.left = button->getLeftPosition();
2791
            svAtom.top = button->getTopPosition();
300 andreas 2792
            svAtom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
293 andreas 2793
            svAtom.bounding = button->getBounding();
289 andreas 2794
            Button::BITMAP_t bmap = button->getLastImage();
280 andreas 2795
 
289 andreas 2796
            if (bmap.buffer)
300 andreas 2797
                svAtom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
289 andreas 2798
 
280 andreas 2799
            svItem.atoms.push_back(svAtom);
289 andreas 2800
            button = sub->getNextButton();
280 andreas 2801
        }
2802
 
2803
        items.push_back(svItem);
279 andreas 2804
    }
281 andreas 2805
 
285 andreas 2806
    _addViewButtonItems(bt->getHandle(), items);
284 andreas 2807
 
2808
    if (_pageFinished)
306 andreas 2809
        _pageFinished(bt->getHandle());
279 andreas 2810
}
2811
 
300 andreas 2812
void TPageManager::updateSubViewItem(Button::TButton *bt)
2813
{
2814
    DECL_TRACER("TPageManager::updateSubViewItem(Button::TButton *bt)");
2815
 
303 andreas 2816
    if (!bt)
300 andreas 2817
        return;
2818
 
303 andreas 2819
    updview_mutex.lock();
2820
    mUpdateViews.push_back(bt);
2821
    updview_mutex.unlock();
2822
}
2823
 
2824
void TPageManager::_updateSubViewItem(Button::TButton *bt)
2825
{
2826
    DECL_TRACER("TPageManager::_updateSubViewItem(Button::TButton *bt)");
2827
 
2828
    if (!mPageList || !_updateViewButtonItem)
2829
        return;
2830
 
300 andreas 2831
    // The parent of this kind of button is always the button of type subview.
2832
    // If we take the parent handle and extract the page ID (upper 16 bits)
2833
    // we get the page ID of the subpage or page ID of the page the button is
2834
    // ordered to.
2835
    int pageID = (bt->getParent() >> 16) & 0x0000ffff;
306 andreas 2836
    ulong parent = 0;
300 andreas 2837
    Button::TButton *button = nullptr;
2838
    PGSUBVIEWITEM_T item;
2839
    PGSUBVIEWATOM_T atom;
2840
    SkBitmap bitmap;
2841
    TPage *pg = nullptr;
2842
    TSubPage *sub = nullptr;
2843
 
2844
    if (pageID < REGULAR_SUBPAGE_START)     // Is it a page?
2845
    {
2846
        pg = getPage(pageID);
2847
 
2848
        if (!pg)
2849
        {
2850
            MSG_WARNING("Invalid page " << pageID << "!");
2851
            return;
2852
        }
2853
 
2854
        button = pg->getFirstButton();
2855
        bitmap = pg->getBgImage();
2856
 
2857
        item.handle = pg->getHandle();
2858
        item.parent = bt->getParent();
2859
        item.width = pg->getWidth();
2860
        item.height = pg->getHeight();
2861
        item.bgcolor = TColor::getAMXColor(pg->getFillColor());
2862
    }
2863
    else
2864
    {
2865
        sub = getSubPage(pageID);
2866
 
2867
        if (!sub)
2868
        {
2869
            MSG_WARNING("Couldn't find the subpage " << pageID << "!");
2870
            return;
2871
        }
2872
 
306 andreas 2873
        parent = sub->getParent();
300 andreas 2874
        button = sub->getFirstButton();
2875
        bitmap = sub->getBgImage();
2876
 
2877
        item.handle = sub->getHandle();
2878
        item.parent = bt->getParent();
2879
        item.width = sub->getWidth();
2880
        item.height = sub->getHeight();
303 andreas 2881
        item.position = bt->getSubViewAnchor();
300 andreas 2882
        item.bgcolor = TColor::getAMXColor(sub->getFillColor());
2883
    }
2884
 
2885
 
2886
    if (!bitmap.empty())
2887
        item.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
2888
 
2889
    while (button)
2890
    {
2891
        atom.clear();
2892
        atom.handle = button->getHandle();
303 andreas 2893
        atom.parent = item.handle;
300 andreas 2894
        atom.width = button->getWidth();
2895
        atom.height = button->getHeight();
2896
        atom.left = button->getLeftPosition();
2897
        atom.top = button->getTopPosition();
2898
        atom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
2899
        atom.bounding = button->getBounding();
2900
        Button::BITMAP_t bmap = button->getLastImage();
2901
 
2902
        if (bmap.buffer)
2903
            atom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
2904
 
2905
        item.atoms.push_back(atom);
2906
        button = (pg ? pg->getNextButton() : sub->getNextButton());
2907
    }
2908
 
306 andreas 2909
    _updateViewButtonItem(item, parent);
300 andreas 2910
}
2911
 
192 andreas 2912
void TPageManager::updateActualPage()
2913
{
2914
    DECL_TRACER("TPageManager::updateActualPage()");
2915
 
2916
    if (!mActualPage)
2917
        return;
2918
 
2919
    TPage *pg = getPage(mActualPage);
2920
    Button::TButton *bt = pg->getFirstButton();
2921
 
2922
    while (bt)
2923
    {
2924
        bt->refresh();
2925
        bt = pg->getNextButton();
2926
    }
2927
}
2928
 
2929
void TPageManager::updateSubpage(int ID)
2930
{
2931
    DECL_TRACER("TPageManager::updateSubpage(int ID)");
2932
 
2933
    TSubPage *pg = getSubPage(ID);
2934
 
2935
    if (!pg)
2936
        return;
2937
 
2938
    vector<Button::TButton *> blist = pg->getAllButtons();
2939
    vector<Button::TButton *>::iterator iter;
2940
 
2941
    if (blist.empty())
2942
        return;
2943
 
2944
    for (iter = blist.begin(); iter != blist.end(); ++iter)
2945
    {
2946
        Button::TButton *bt = *iter;
2947
        bt->refresh();
2948
    }
2949
}
2950
 
2951
void TPageManager::updateSubpage(const std::string &name)
2952
{
2953
    DECL_TRACER("TPageManager::updateSubpage(const std::string &name)");
2954
 
2955
    TSubPage *pg = getSubPage(name);
2956
 
2957
    if (!pg)
2958
        return;
2959
 
2960
    vector<Button::TButton *> blist = pg->getAllButtons();
2961
    vector<Button::TButton *>::iterator iter;
2962
 
2963
    if (blist.empty())
2964
        return;
2965
 
2966
    for (iter = blist.begin(); iter != blist.end(); ++iter)
2967
    {
2968
        Button::TButton *bt = *iter;
2969
        bt->refresh();
2970
    }
2971
}
2972
 
3 andreas 2973
/******************** Internal private methods *********************/
2974
 
2975
PAGELIST_T TPageManager::findPage(const std::string& name)
2976
{
2977
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
2978
 
194 andreas 2979
    vector<PAGELIST_T> pageList;
3 andreas 2980
 
194 andreas 2981
    if (!mSetupActive)
2982
        pageList = mPageList->getPagelist();
2983
    else
2984
        pageList = mPageList->getSystemPagelist();
2985
 
83 andreas 2986
    if (pageList.size() > 0)
3 andreas 2987
    {
83 andreas 2988
        vector<PAGELIST_T>::iterator pgIter;
2989
 
118 andreas 2990
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 2991
        {
2992
            if (pgIter->name.compare(name) == 0)
2993
                return *pgIter;
2994
        }
3 andreas 2995
    }
2996
 
194 andreas 2997
    MSG_WARNING("Page " << name << " not found!");
3 andreas 2998
    return PAGELIST_T();
2999
}
3000
 
3001
PAGELIST_T TPageManager::findPage(int ID)
3002
{
3003
    DECL_TRACER("TPageManager::findPage(int ID)");
3004
 
206 andreas 3005
    vector<PAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getPagelist() : mPageList->getSystemPagelist());
3 andreas 3006
 
83 andreas 3007
    if (pageList.size() > 0)
3 andreas 3008
    {
83 andreas 3009
        vector<PAGELIST_T>::iterator pgIter;
3010
 
118 andreas 3011
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3012
        {
3013
            if (pgIter->pageID == ID)
3014
                return *pgIter;
3015
        }
3 andreas 3016
    }
3017
 
3018
    return PAGELIST_T();
3019
}
3020
 
3021
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
3022
{
3023
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
3024
 
348 andreas 3025
    vector<SUBPAGELIST_T> pageList = (mSetupActive ? mPageList->getSystemSupPageList() : mPageList->getSubPageList());
3 andreas 3026
 
83 andreas 3027
    if (pageList.size() > 0)
3 andreas 3028
    {
83 andreas 3029
        vector<SUBPAGELIST_T>::iterator pgIter;
3030
 
118 andreas 3031
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3032
        {
3033
            if (pgIter->name.compare(name) == 0)
3034
                return *pgIter;
3035
        }
3 andreas 3036
    }
3037
 
3038
    return SUBPAGELIST_T();
3039
}
3040
 
3041
SUBPAGELIST_T TPageManager::findSubPage(int ID)
3042
{
3043
    DECL_TRACER("TPageManager::findSubPage(int ID)");
3044
 
348 andreas 3045
    vector<SUBPAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getSubPageList() : mPageList->getSystemSupPageList());
3 andreas 3046
 
83 andreas 3047
    if (pageList.size() > 0)
3 andreas 3048
    {
83 andreas 3049
        vector<SUBPAGELIST_T>::iterator pgIter;
3050
 
118 andreas 3051
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3052
        {
3053
            if (pgIter->pageID == ID)
3054
                return *pgIter;
3055
        }
3 andreas 3056
    }
3057
 
3058
    return SUBPAGELIST_T();
3059
}
3060
 
3061
bool TPageManager::addPage(TPage* pg)
3062
{
3063
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
3064
 
3065
    if (!pg)
3066
    {
3067
        MSG_ERROR("Parameter is NULL!");
3068
        TError::setError();
3069
        return false;
3070
    }
3071
 
3072
    PCHAIN_T *chain = new PCHAIN_T;
3073
    chain->page = pg;
5 andreas 3074
    chain->next = nullptr;
3 andreas 3075
 
3076
    if (mPchain)
3077
    {
3078
        PCHAIN_T *p = mPchain;
3079
 
3080
        while (p->next)
3081
            p = p->next;
3082
 
3083
        p->next = chain;
3084
    }
3085
    else
14 andreas 3086
    {
3 andreas 3087
        mPchain = chain;
14 andreas 3088
        setPChain(mPchain);
3089
    }
3 andreas 3090
 
156 andreas 3091
//    MSG_DEBUG("Added page " << chain->page->getName());
3 andreas 3092
    return true;
3093
}
3094
 
3095
bool TPageManager::addSubPage(TSubPage* pg)
3096
{
3097
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
3098
 
3099
    if (!pg)
3100
    {
3101
        MSG_ERROR("Parameter is NULL!");
3102
        TError::setError();
3103
        return false;
3104
    }
3105
 
14 andreas 3106
    if (haveSubPage(pg->getNumber()))
3107
    {
3108
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
3109
        return false;
3110
    }
3111
 
3 andreas 3112
    SPCHAIN_T *chain = new SPCHAIN_T;
3113
    chain->page = pg;
5 andreas 3114
    chain->next = nullptr;
3 andreas 3115
 
3116
    if (mSPchain)
3117
    {
3118
        SPCHAIN_T *p = mSPchain;
3119
 
3120
        while (p->next)
3121
            p = p->next;
3122
 
3123
        p->next = chain;
3124
    }
3125
    else
14 andreas 3126
    {
3 andreas 3127
        mSPchain = chain;
14 andreas 3128
        setSPChain(mSPchain);
3129
    }
3 andreas 3130
 
3131
    return true;
3132
}
4 andreas 3133
 
11 andreas 3134
void TPageManager::dropAllPages()
3135
{
3136
    DECL_TRACER("TPageManager::dropAllPages()");
3137
 
3138
    PCHAIN_T *pg = mPchain;
3139
    PCHAIN_T *next = nullptr;
3140
 
3141
    while (pg)
3142
    {
3143
        next = pg->next;
3144
 
3145
        if (pg->page)
3146
        {
3147
            if (_callDropPage)
3148
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
3149
 
3150
            delete pg->page;
3151
        }
3152
 
3153
        delete pg;
3154
        pg = next;
3155
    }
14 andreas 3156
 
3157
    mPchain = nullptr;
3158
    setPChain(mPchain);
11 andreas 3159
}
3160
 
3161
void TPageManager::dropAllSubPages()
3162
{
3163
    DECL_TRACER("TPageManager::dropAllSubPages()");
3164
 
3165
    SPCHAIN_T *spg = mSPchain;
3166
    SPCHAIN_T *next;
3167
 
3168
    while (spg)
3169
    {
3170
        next = spg->next;
3171
 
3172
        if (spg->page)
3173
        {
3174
            if (_callDropSubPage)
350 andreas 3175
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000, spg->page->getParent());
11 andreas 3176
 
3177
            delete spg->page;
3178
        }
3179
 
3180
        delete spg;
3181
        spg = next;
3182
    }
14 andreas 3183
 
3184
    mSPchain = nullptr;
3185
    setSPChain(mSPchain);
11 andreas 3186
}
3187
 
44 andreas 3188
bool TPageManager::destroyAll()
3189
{
3190
    DECL_TRACER("TPageManager::destroyAll()");
3191
 
3192
    dropAllSubPages();
3193
    dropAllPages();
3194
    mActualPage = 0;
3195
    mPreviousPage = 0;
3196
    mActualGroupName.clear();
3197
 
3198
    if (mPageList)
3199
    {
3200
        delete mPageList;
3201
        mPageList = nullptr;
3202
    }
3203
 
3204
    if (mTSettings)
3205
    {
3206
        delete mTSettings;
3207
        mTSettings = nullptr;
3208
    }
3209
 
194 andreas 3210
    if (mSystemSettings)
3211
    {
3212
        delete mSystemSettings;
3213
        mSystemSettings = nullptr;
3214
    }
3215
 
44 andreas 3216
    if (mPalette)
3217
    {
3218
        delete mPalette;
3219
        mPalette = nullptr;
3220
    }
3221
 
3222
    if (mFonts)
3223
    {
3224
        delete mFonts;
3225
        mFonts = nullptr;
3226
    }
3227
 
3228
    if (mExternal)
3229
    {
3230
        delete mExternal;
3231
        mExternal = nullptr;
3232
    }
3233
 
3234
    if (gPrjResources)
3235
    {
3236
        delete gPrjResources;
3237
        gPrjResources = nullptr;
3238
    }
3239
 
3240
    if (gIcons)
3241
    {
3242
        delete gIcons;
3243
        gIcons = nullptr;
3244
    }
3245
 
3246
    if (TError::isError())
3247
        return false;
3248
 
3249
    return true;
3250
}
3251
 
150 andreas 3252
bool TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
3253
{
3254
    DECL_TRACER("TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)");
3255
 
3256
    struct point
3257
    {
3258
        int x;
3259
        int y;
3260
    };
3261
 
3262
    struct point l1, r1, l2, r2;
3263
 
3264
    l1.x = x1;
3265
    l1.y = y1;
3266
    r1.x = x1 + w1;
3267
    r1.y = y1 + h1;
3268
 
3269
    l2.x = x2;
3270
    l2.y = y2;
3271
    r2.x = x2 + w2;
3272
    r2.y = y2 + h2;
3273
 
3274
    if (l1.x == r1.x || l1.y == r1.y || l2.x == r2.x || l2.y == r2.y)
3275
    {
3276
        // the line cannot have positive overlap
3277
        return false;
3278
    }
3279
 
183 andreas 3280
    return std::max(l1.x, l2.x) < std::min(r1.x, r2.x) &&
150 andreas 3281
           std::max(l1.y, l2.y) < std::min(r1.y, r2.y);
3282
}
3283
 
51 andreas 3284
Button::TButton *TPageManager::findButton(ulong handle)
3285
{
3286
    DECL_TRACER("TPageManager::findButton(ulong handle)");
3287
 
209 andreas 3288
    if (!handle)
3289
        return nullptr;
3290
 
51 andreas 3291
    TPage *pg = getPage(mActualPage);
3292
 
3293
    if (!pg)
3294
        return nullptr;
3295
 
3296
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
3297
    vector<Button::TButton *>::iterator iter;
83 andreas 3298
 
3299
    if (pgBtList.size() > 0)
51 andreas 3300
    {
83 andreas 3301
        // First we look into the elements of the page
3302
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3303
        {
3304
            Button::TButton *bt = *iter;
51 andreas 3305
 
83 andreas 3306
            if (bt->getHandle() == handle)
3307
                return bt;
3308
        }
51 andreas 3309
    }
3310
 
3311
    // We've not found the wanted element in the elements of the page. So
3312
    // we're looking at the elements of the subpages.
3313
    TSubPage *sp = pg->getFirstSubPage();
3314
 
3315
    if (!sp)
3316
        return nullptr;
3317
 
3318
    while (sp)
3319
    {
3320
        vector<Button::TButton *> spBtList = sp->getAllButtons();
3321
 
83 andreas 3322
        if (spBtList.size() > 0)
51 andreas 3323
        {
83 andreas 3324
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3325
            {
3326
                Button::TButton *bt = *iter;
51 andreas 3327
 
83 andreas 3328
                if (bt->getHandle() == handle)
3329
                    return bt;
3330
            }
51 andreas 3331
        }
3332
 
3333
        sp = pg->getNextSubPage();
3334
    }
3335
 
3336
    return nullptr;
3337
}
3338
 
4 andreas 3339
TPage *TPageManager::getActualPage()
3340
{
168 andreas 3341
    DECL_TRACER("TPageManager::getActualPage()");
3342
 
4 andreas 3343
    return getPage(mActualPage);
3344
}
3345
 
3346
TSubPage *TPageManager::getFirstSubPage()
3347
{
3348
    DECL_TRACER("TPageManager::getFirstSubPage()");
168 andreas 3349
 
349 andreas 3350
    mLastSubPage = 0;
4 andreas 3351
    TPage *pg = getPage(mActualPage);
3352
 
3353
    if (!pg)
3354
        return nullptr;
3355
 
349 andreas 3356
    map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3357
 
3358
    if (!sp.empty())
3359
    {
3360
        map<int, TSubPage *>::iterator iter = sp.begin();
3361
        mLastSubPage = iter->first;
3362
        return iter->second;
3363
    }
3364
 
3365
    return nullptr;
4 andreas 3366
}
3367
 
3368
TSubPage *TPageManager::getNextSubPage()
3369
{
3370
    DECL_TRACER("TPageManager::getNextSubPage()");
3371
 
3372
    TPage *pg = getPage(mActualPage);
3373
 
3374
    if (pg)
349 andreas 3375
    {
3376
        map<int, TSubPage *> sp = pg->getSortedSubpages();
4 andreas 3377
 
349 andreas 3378
        if (sp.empty())
3379
        {
3380
            mLastSubPage = 0;
3381
            return nullptr;
3382
        }
3383
        else
3384
        {
3385
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3386
 
3387
            if (iter != sp.end())
3388
            {
3389
                iter++;
3390
 
3391
                if (iter != sp.end())
3392
                {
3393
                    mLastSubPage = iter->first;
3394
                    return iter->second;
3395
                }
3396
            }
3397
        }
3398
    }
3399
 
3400
    mLastSubPage = 0;
4 andreas 3401
    return nullptr;
3402
}
10 andreas 3403
 
154 andreas 3404
TSubPage *TPageManager::getPrevSubPage()
3405
{
3406
    DECL_TRACER("TPageManager::getPrevSubPage()");
3407
 
3408
    TPage *pg = getPage(mActualPage);
3409
 
3410
    if (pg)
349 andreas 3411
    {
3412
        map<int, TSubPage *> sp = pg->getSortedSubpages();
154 andreas 3413
 
349 andreas 3414
        if (sp.empty())
3415
        {
3416
            mLastSubPage = 0;
3417
            return nullptr;
3418
        }
3419
        else
3420
        {
3421
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3422
 
3423
            if (iter != sp.end() && iter != sp.begin())
3424
            {
3425
                iter--;
3426
                mLastSubPage = iter->first;
3427
                return iter->second;
3428
            }
3429
 
3430
            MSG_DEBUG("Page " << mLastSubPage << " not found!");
3431
        }
3432
    }
3433
 
3434
    mLastSubPage = 0;
154 andreas 3435
    return nullptr;
3436
}
3437
 
3438
TSubPage *TPageManager::getLastSubPage()
3439
{
3440
    DECL_TRACER("TPageManager::getLastSubPage()");
3441
 
349 andreas 3442
    mLastSubPage = 0;
154 andreas 3443
    TPage *pg = getPage(mActualPage);
3444
 
3445
    if (pg)
3446
    {
349 andreas 3447
        map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3448
 
3449
        if (sp.empty())
3450
            return nullptr;
3451
        else
3452
        {
3453
            map<int, TSubPage *>::iterator iter = sp.end();
3454
            iter--;
3455
            mLastSubPage = iter->first;
3456
            return iter->second;
3457
        }
154 andreas 3458
    }
3459
    else
3460
    {
3461
        MSG_WARNING("Actual page " << mActualPage << " not found!");
3462
    }
3463
 
3464
    return nullptr;
3465
}
3466
 
11 andreas 3467
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
3468
{
3469
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
3470
 
14 andreas 3471
    if (group.empty())
3472
    {
3473
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
3474
        mActualGroupName.clear();
3475
        mActualGroupPage = nullptr;
3476
        return nullptr;
3477
    }
3478
 
11 andreas 3479
    mActualGroupName = group;
3480
    TSubPage *pg = getFirstSubPage();
3481
 
3482
    while (pg)
3483
    {
14 andreas 3484
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3485
 
11 andreas 3486
        if (pg->getGroupName().compare(group) == 0)
3487
        {
3488
            mActualGroupPage = pg;
3489
            return pg;
3490
        }
3491
 
3492
        pg = getNextSubPage();
3493
    }
3494
 
3495
    mActualGroupName.clear();
3496
    mActualGroupPage = nullptr;
3497
    return nullptr;
3498
}
3499
 
3500
TSubPage *TPageManager::getNextSubPageGroup()
3501
{
3502
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
3503
 
3504
    if (mActualGroupName.empty())
3505
        return nullptr;
3506
 
3507
    TSubPage *pg = getFirstSubPage();
3508
    bool found = false;
3509
 
3510
    while (pg)
3511
    {
14 andreas 3512
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
3513
 
3514
        if (!found && pg == mActualGroupPage)
11 andreas 3515
        {
3516
            pg = getNextSubPage();
14 andreas 3517
            found = true;
11 andreas 3518
            continue;
3519
        }
3520
 
14 andreas 3521
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 3522
        {
3523
            mActualGroupPage = pg;
3524
            return pg;
3525
        }
3526
 
3527
        pg = getNextSubPage();
3528
    }
3529
 
3530
    mActualGroupName.clear();
3531
    mActualGroupPage = nullptr;
3532
    return nullptr;
3533
}
3534
 
3535
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
3536
{
3537
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
3538
 
3539
    if (group.empty() || !pg)
3540
        return nullptr;
3541
 
3542
    TSubPage *page = getFirstSubPage();
3543
    bool found = false;
3544
 
3545
    while (page)
3546
    {
14 andreas 3547
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3548
 
3549
        if (!found && pg == page)
11 andreas 3550
        {
3551
            page = getNextSubPage();
14 andreas 3552
            found = true;
11 andreas 3553
            continue;
3554
        }
3555
 
14 andreas 3556
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 3557
            return page;
3558
 
3559
        page = getNextSubPage();
3560
    }
3561
 
3562
    return nullptr;
3563
}
3564
 
3565
TSubPage *TPageManager::getTopPage()
3566
{
3567
    DECL_TRACER("TPageManager::getTopPage()");
3568
 
3569
    // Scan for all occupied regions
3570
    vector<RECT_T> regions;
3571
 
3572
    TSubPage *pg = getFirstSubPage();
3573
 
3574
    while (pg)
3575
    {
3576
        RECT_T r = pg->getRegion();
3577
        regions.push_back(r);
3578
        pg = getNextSubPage();
3579
    }
3580
 
3581
    // Now scan all pages against all regions to find the top most
3582
    pg = getFirstSubPage();
3583
    TSubPage *top = nullptr;
3584
    int zPos = 0;
3585
 
3586
    while (pg)
3587
    {
3588
        RECT_T r = pg->getRegion();
3589
 
83 andreas 3590
        if (regions.size() > 0)
11 andreas 3591
        {
83 andreas 3592
            vector<RECT_T>::iterator iter;
3593
            int zo = 0;
11 andreas 3594
 
118 andreas 3595
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 3596
            {
3597
                if (doOverlap(*iter, r) && zPos > zo)
3598
                    top = pg;
3599
 
3600
                zo++;
3601
            }
11 andreas 3602
        }
3603
 
3604
        pg = getNextSubPage();
3605
        zPos++;
3606
    }
3607
 
3608
    return top;
3609
}
3610
 
3611
TSubPage *TPageManager::getCoordMatch(int x, int y)
3612
{
3613
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
3614
 
26 andreas 3615
    int realX = x;
3616
    int realY = y;
3617
 
11 andreas 3618
    // Reverse order of pages
154 andreas 3619
    TSubPage *pg = getLastSubPage();
11 andreas 3620
 
154 andreas 3621
    // Iterate in reverse order through array
11 andreas 3622
    while (pg)
3623
    {
154 andreas 3624
        if (!pg->isVisible() || pg->getZOrder() == ZORDER_INVALID)
151 andreas 3625
        {
154 andreas 3626
            pg = getPrevSubPage();
3627
            continue;
151 andreas 3628
        }
14 andreas 3629
 
154 andreas 3630
        MSG_DEBUG("Scanning subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ", " << pg->getName());
3631
        RECT_T r = pg->getRegion();
11 andreas 3632
 
154 andreas 3633
        if (r.left <= realX && (r.left + r.width) >= realX &&
3634
            r.top <= realY && (r.top + r.height) >= realY)
11 andreas 3635
        {
154 andreas 3636
            MSG_DEBUG("Click matches subpage " << pg->getNumber() << " (" << pg->getName() << ")");
3637
            return pg;
3638
        }
83 andreas 3639
 
154 andreas 3640
        pg = getPrevSubPage();
11 andreas 3641
    }
3642
 
3643
    return nullptr;
3644
}
3645
 
40 andreas 3646
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
3647
{
3648
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
3649
 
3650
    TPage *page = getActualPage();
3651
 
3652
    if (page)
3653
    {
150 andreas 3654
        Button::TButton *bt = page->getLastButton();
40 andreas 3655
 
3656
        while (bt)
3657
        {
150 andreas 3658
            bool clickable = bt->isClickable();
3659
            MSG_DEBUG("Button: " << bt->getButtonIndex() << ", l: " << bt->getLeftPosition() << ", t: " << bt->getTopPosition() << ", r: " << (bt->getLeftPosition() + bt->getWidth()) << ", b: " << (bt->getTopPosition() + bt->getHeight()) << ", x: " << x << ", y: " << y << ", " << (clickable ? "CLICKABLE" : "NOT CLICKABLE"));
40 andreas 3660
 
150 andreas 3661
            if (!clickable)
146 andreas 3662
            {
150 andreas 3663
                bt = page->getPreviousButton();
146 andreas 3664
                continue;
3665
            }
3666
 
40 andreas 3667
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
3668
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
3669
            {
154 andreas 3670
                if (!bt->isClickable(x - bt->getLeftPosition(), y - bt->getTopPosition()))
3671
                {
3672
                    bt = page->getPreviousButton();
3673
                    continue;
3674
                }
3675
 
40 andreas 3676
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
3677
                return bt;
3678
            }
3679
 
150 andreas 3680
            bt = page->getPreviousButton();
40 andreas 3681
        }
3682
    }
3683
 
3684
    return nullptr;
3685
}
3686
 
11 andreas 3687
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
3688
{
3689
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
3690
 
3691
    // If one rectangle is on left side of other
3692
    if (r1.left >= r2.left || r2.left >= r1.left)
3693
        return false;
3694
 
3695
    // If one rectangle is above other
3696
    if (r1.top <= r2.top || r2.top <= r1.top)
3697
        return false;
3698
 
3699
    return true;
3700
}
3701
 
14 andreas 3702
bool TPageManager::havePage(const string& name)
11 andreas 3703
{
14 andreas 3704
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 3705
 
14 andreas 3706
    if (name.empty())
3707
        return false;
3708
 
3709
    PCHAIN_T *pg = mPchain;
3710
 
3711
    while (pg)
3712
    {
3713
        if (pg->page && pg->page->getName().compare(name) == 0)
3714
            return true;
3715
 
3716
        pg = pg->next;
3717
    }
3718
 
3719
    return false;
3720
}
3721
 
3722
bool TPageManager::haveSubPage(const string& name)
3723
{
3724
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
3725
 
3726
    if (name.empty())
3727
        return false;
3728
 
11 andreas 3729
    SPCHAIN_T *pg = mSPchain;
3730
 
3731
    while (pg)
3732
    {
14 andreas 3733
        if (pg->page && pg->page->getName().compare(name) == 0)
3734
        {
3735
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
3736
            return true;
3737
        }
3738
 
3739
        pg = pg->next;
3740
    }
3741
 
3742
    MSG_DEBUG("Subpage " << name << " not found.");
3743
    return false;
3744
}
3745
 
3746
bool TPageManager::haveSubPage(int id)
3747
{
3748
    DECL_TRACER("TPageManager::haveSubPage(int id)");
3749
 
3750
    SPCHAIN_T *pg = mSPchain;
3751
 
3752
    while (pg)
3753
    {
3754
        if (pg->page && pg->page->getNumber() == id)
3755
        {
3756
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
3757
            return true;
3758
        }
3759
 
3760
        pg = pg->next;
3761
    }
3762
 
3763
    MSG_DEBUG("Subpage " << id << " not found.");
3764
    return false;
3765
}
3766
 
3767
bool TPageManager::haveSubPage(const string& page, const string& name)
3768
{
3769
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
3770
 
3771
    TPage *pg = getPage(page);
3772
 
3773
    if (!pg)
3774
        return false;
3775
 
3776
    TSubPage *spg = pg->getFirstSubPage();
3777
 
3778
    while (spg)
3779
    {
3780
        if (spg->getName().compare(name) == 0)
3781
        {
3782
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
3783
            return true;
3784
        }
3785
 
3786
        spg = pg->getNextSubPage();
3787
    }
3788
 
3789
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
3790
    return false;
3791
}
3792
 
3793
bool TPageManager::haveSubPage(const string& page, int id)
3794
{
3795
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
3796
 
3797
    TPage *pg = getPage(page);
3798
 
3799
    if (!pg)
3800
        return false;
3801
 
3802
    TSubPage *spg = pg->getFirstSubPage();
3803
 
3804
    while (spg)
3805
    {
3806
        if (spg->getNumber() == id)
3807
        {
3808
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
3809
            return true;
3810
        }
3811
 
3812
        spg = pg->getNextSubPage();
3813
    }
3814
 
3815
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
3816
    return false;
3817
}
3818
 
3819
void TPageManager::closeGroup(const string& group)
3820
{
3821
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
3822
 
3823
    SPCHAIN_T *pg = mSPchain;
3824
 
3825
    while (pg)
3826
    {
11 andreas 3827
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
3828
        {
3829
            pg->page->regCallDropSubPage(_callDropSubPage);
3830
            pg->page->drop();
3831
            break;
3832
        }
3833
 
3834
        pg = pg->next;
3835
    }
3836
}
3837
 
14 andreas 3838
void TPageManager::showSubPage(const string& name)
3839
{
3840
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
3841
 
3842
    if (name.empty())
349 andreas 3843
    {
3844
#if TESTMODE == 1
3845
        setScreenDone();
3846
#endif
14 andreas 3847
        return;
349 andreas 3848
    }
275 andreas 3849
 
152 andreas 3850
    TPage *page = nullptr;
3851
    TSubPage *pg = deliverSubPage(name, &page);
14 andreas 3852
 
96 andreas 3853
    if (!pg)
349 andreas 3854
    {
3855
#if TESTMODE == 1
3856
        setScreenDone();
3857
#endif
14 andreas 3858
        return;
349 andreas 3859
    }
14 andreas 3860
 
152 andreas 3861
    if (page)
350 andreas 3862
    {
3863
        pg->setParent(page->getHandle());
152 andreas 3864
        page->addSubPage(pg);
350 andreas 3865
    }
152 andreas 3866
 
14 andreas 3867
    string group = pg->getGroupName();
3868
 
3869
    if (!group.empty())
3870
    {
3871
        TSubPage *sub = getFirstSubPageGroup(group);
3872
 
3873
        while(sub)
3874
        {
3875
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
3876
                sub->drop();
3877
 
3878
            sub = getNextSubPageGroup(group, sub);
3879
        }
3880
    }
3881
 
150 andreas 3882
    if (pg->isVisible())
3883
    {
152 andreas 3884
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
150 andreas 3885
 
3886
        TSubPage *sub = getFirstSubPage();
3887
        bool redraw = false;
3888
 
3889
        while (sub)
3890
        {
151 andreas 3891
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
3892
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
150 andreas 3893
                pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
3894
            {
3895
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
3896
                redraw = true;
3897
                break;
3898
            }
3899
 
3900
            sub = getNextSubPage();
3901
        }
3902
 
151 andreas 3903
        if (redraw && _toFront)
3904
        {
300 andreas 3905
            _toFront((uint)pg->getHandle());
151 andreas 3906
            pg->setZOrder(page->getNextZOrder());
349 andreas 3907
//            page->sortSubpages();
154 andreas 3908
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
151 andreas 3909
        }
154 andreas 3910
        else if (redraw && !_toFront)
150 andreas 3911
            pg->drop();
3912
    }
3913
 
14 andreas 3914
    if (!pg->isVisible())
3915
    {
3916
        if (!page)
3917
        {
198 andreas 3918
            page = getPage(mActualPage);
3919
 
3920
            if (!page)
3921
            {
3922
                MSG_ERROR("No active page found! Internal error.");
3923
                return;
3924
            }
14 andreas 3925
        }
3926
 
3927
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
3928
            return;
3929
 
3930
        pg->setZOrder(page->getNextZOrder());
3931
 
3932
        if (_setSubPage)
26 andreas 3933
        {
3934
            int left = pg->getLeft();
3935
            int top = pg->getTop();
3936
            int width = pg->getWidth();
3937
            int height = pg->getHeight();
43 andreas 3938
#ifdef _SCALE_SKIA_
26 andreas 3939
            if (mScaleFactor != 1.0)
3940
            {
3941
                left = (int)((double)left * mScaleFactor);
3942
                top = (int)((double)top * mScaleFactor);
3943
                width = (int)((double)width * mScaleFactor);
3944
                height = (int)((double)height * mScaleFactor);
28 andreas 3945
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 3946
            }
43 andreas 3947
#endif
41 andreas 3948
            ANIMATION_t ani;
3949
            ani.showEffect = pg->getShowEffect();
3950
            ani.showTime = pg->getShowTime();
42 andreas 3951
            ani.hideEffect = pg->getHideEffect();
3952
            ani.hideTime = pg->getHideTime();
54 andreas 3953
            // Test for a timer on the page
3954
            if (pg->getTimeout() > 0)
3955
                pg->startTimer();
3956
 
217 andreas 3957
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
26 andreas 3958
        }
293 andreas 3959
 
3960
        pg->show();
14 andreas 3961
    }
3962
}
3963
 
198 andreas 3964
void TPageManager::showSubPage(int number, bool force)
3965
{
3966
    DECL_TRACER("TPageManager::showSubPage(int number, bool force)");
3967
 
3968
    if (number <= 0)
3969
        return;
3970
 
3971
    TPage *page = nullptr;
3972
    TSubPage *pg = deliverSubPage(number, &page);
3973
 
3974
    if (!pg)
3975
        return;
3976
 
3977
    if (page)
350 andreas 3978
    {
3979
        pg->setParent(page->getHandle());
198 andreas 3980
        page->addSubPage(pg);
350 andreas 3981
    }
198 andreas 3982
 
3983
    string group = pg->getGroupName();
3984
 
3985
    if (!group.empty())
3986
    {
3987
        TSubPage *sub = getFirstSubPageGroup(group);
3988
 
3989
        while(sub)
3990
        {
3991
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
3992
                sub->drop();
3993
 
3994
            sub = getNextSubPageGroup(group, sub);
3995
        }
3996
    }
3997
 
3998
    if (pg->isVisible() && !force)
3999
    {
4000
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
4001
 
4002
        TSubPage *sub = getFirstSubPage();
4003
        bool redraw = false;
4004
 
4005
        while (sub)
4006
        {
4007
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4008
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
4009
                        pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4010
            {
4011
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4012
                redraw = true;
4013
                break;
4014
            }
4015
 
4016
            sub = getNextSubPage();
4017
        }
4018
 
4019
        if (redraw && _toFront)
4020
        {
300 andreas 4021
            _toFront((uint)pg->getHandle());
198 andreas 4022
            pg->setZOrder(page->getNextZOrder());
4023
            page->sortSubpages();
4024
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
4025
        }
4026
        else if (redraw && !_toFront)
4027
            pg->drop();
4028
    }
4029
 
4030
    if (!pg->isVisible() || force)
4031
    {
4032
        if (!page)
4033
        {
4034
            MSG_ERROR("No active page found! Internal error.");
4035
            return;
4036
        }
4037
 
4038
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4039
            return;
4040
 
4041
        if (!pg->isVisible())
4042
            pg->setZOrder(page->getNextZOrder());
4043
 
4044
        if (_setSubPage)
4045
        {
4046
            int left = pg->getLeft();
4047
            int top = pg->getTop();
4048
            int width = pg->getWidth();
4049
            int height = pg->getHeight();
262 andreas 4050
#ifdef _SCALE_SKIA_
198 andreas 4051
            if (mScaleFactor != 1.0)
4052
            {
4053
                left = (int)((double)left * mScaleFactor);
4054
                top = (int)((double)top * mScaleFactor);
4055
                width = (int)((double)width * mScaleFactor);
4056
                height = (int)((double)height * mScaleFactor);
4057
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
4058
            }
262 andreas 4059
#endif
198 andreas 4060
            ANIMATION_t ani;
4061
            ani.showEffect = pg->getShowEffect();
4062
            ani.showTime = pg->getShowTime();
4063
            ani.hideEffect = pg->getHideEffect();
4064
            ani.hideTime = pg->getHideTime();
4065
            // Test for a timer on the page
4066
            if (pg->getTimeout() > 0)
4067
                pg->startTimer();
4068
 
217 andreas 4069
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
198 andreas 4070
        }
4071
    }
4072
 
4073
    pg->show();
4074
}
4075
 
14 andreas 4076
void TPageManager::hideSubPage(const string& name)
4077
{
4078
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
4079
 
4080
    if (name.empty())
335 andreas 4081
    {
4082
#if TESTMODE == 1
4083
        setScreenDone();
4084
#endif
14 andreas 4085
        return;
335 andreas 4086
    }
14 andreas 4087
 
4088
    TPage *page = getPage(mActualPage);
4089
 
4090
    if (!page)
4091
    {
4092
        MSG_ERROR("No active page found! Internal error.");
335 andreas 4093
#if TESTMODE == 1
4094
        setScreenDone();
4095
#endif
14 andreas 4096
        return;
4097
    }
4098
 
4099
    TSubPage *pg = getSubPage(name);
4100
 
4101
    if (pg)
4102
    {
4103
        pg->drop();
154 andreas 4104
        page->decZOrder();
14 andreas 4105
    }
4106
}
4107
 
299 andreas 4108
/**
4109
 * @brief TPageManager::runClickQueue - Processing mouse clicks
4110
 * The following method is starting a thread which tests a queue containing
4111
 * the mouse clicks. To not drain the CPU, it sleeps for a short time if there
4112
 * are no more events in the queue.
4113
 * If there is an entry in the queue, it copies it to a local struct and
4114
 * deletes it from the queue. It take always the oldest antry (first entry)
4115
 * and removes this entry from the queue until the queue is empty. This makes
4116
 * it to a FIFO (first in, first out).
4117
 * Depending on the state of the variable "coords" the method for mouse
4118
 * coordinate click is executed or the method for a handle.
4119
 * The thread runs as long as the variable "mClickQueueRun" is TRUE and the
4120
 * variable "prg_stopped" is FALSE.
4121
 */
4122
void TPageManager::runClickQueue()
4123
{
4124
    DECL_TRACER("TPageManager::runClickQueue()");
4125
 
4126
    if (mClickQueueRun)
4127
        return;
4128
 
4129
    mClickQueueRun = true;
4130
 
4131
    try
4132
    {
4133
        std::thread thr = std::thread([=] {
300 andreas 4134
            MSG_PROTOCOL("Thread \"TPageManager::runClickQueue()\" was started.");
4135
 
299 andreas 4136
            while (mClickQueueRun && !prg_stopped)
4137
            {
300 andreas 4138
                while (!mClickQueue.empty())
299 andreas 4139
                {
4140
#ifdef QT_DEBUG
300 andreas 4141
                    if (mClickQueue[0].coords)
4142
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << mClickQueue[0].x << ", " << mClickQueue[0].y << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4143
                    else
300 andreas 4144
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << handleToString(mClickQueue[0].handle) << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4145
#endif
300 andreas 4146
                    if (mClickQueue[0].coords)
4147
                        _mouseEvent(mClickQueue[0].x, mClickQueue[0].y, mClickQueue[0].pressed);
4148
                    else
4149
                        _mouseEvent(mClickQueue[0].handle, mClickQueue[0].handle);
4150
 
299 andreas 4151
                    mClickQueue.erase(mClickQueue.begin()); // Remove first entry
4152
                }
4153
 
4154
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4155
            }
4156
 
303 andreas 4157
            mClickQueueRun = false;
299 andreas 4158
            return;
4159
        });
4160
 
4161
        thr.detach();
4162
    }
4163
    catch (std::exception& e)
4164
    {
300 andreas 4165
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
299 andreas 4166
        mClickQueueRun = false;
4167
    }
4168
}
4169
 
303 andreas 4170
void TPageManager::runUpdateSubViewItem()
4171
{
4172
    DECL_TRACER("TPageManager::runUpdateSubViewItem()");
299 andreas 4173
 
303 andreas 4174
    if (mUpdateViewsRun)
4175
        return;
4176
 
4177
    mUpdateViewsRun = true;
4178
 
4179
    try
4180
    {
4181
        std::thread thr = std::thread([=] {
4182
            MSG_PROTOCOL("Thread \"TPageManager::runUpdateSubViewItem()\" was started.");
4183
 
4184
            while (mUpdateViewsRun && !prg_stopped)
4185
            {
4186
                while (!mUpdateViews.empty())
4187
                {
4188
                    _updateSubViewItem(mUpdateViews[0]);
4189
                    mUpdateViews.erase(mUpdateViews.begin()); // Remove first entry
4190
                }
4191
 
4192
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4193
            }
4194
 
4195
            mUpdateViewsRun = false;
4196
            return;
4197
        });
4198
 
4199
        thr.detach();
4200
    }
4201
    catch (std::exception& e)
4202
    {
4203
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
4204
        mUpdateViewsRun = false;
4205
    }
4206
}
4207
 
11 andreas 4208
/*
4209
 * Catch the mouse presses and scan all pages and subpages for an element to
4210
 * receive the klick.
4211
 */
10 andreas 4212
void TPageManager::mouseEvent(int x, int y, bool pressed)
4213
{
4214
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
4215
 
316 andreas 4216
    TTRYLOCK(click_mutex);
299 andreas 4217
 
4218
    _CLICK_QUEUE_t cq;
4219
    cq.x = x;
4220
    cq.y = y;
4221
    cq.pressed = pressed;
4222
    cq.coords = true;
4223
    mClickQueue.push_back(cq);
334 andreas 4224
#if TESTMODE == 1
4225
    setScreenDone();
4226
#endif
299 andreas 4227
}
4228
 
4229
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4230
{
4231
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4232
 
16 andreas 4233
    TError::clear();
334 andreas 4234
#if TESTMODE == 1
4235
    if (_gTestMode)
4236
        _gTestMode->setMouseClick(x, y, pressed);
4237
#endif
11 andreas 4238
    int realX = x - mFirstLeftPixel;
4239
    int realY = y - mFirstTopPixel;
263 andreas 4240
 
31 andreas 4241
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4242
#ifdef _SCALE_SKIA_
100 andreas 4243
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4244
    {
4245
        realX = (int)((double)realX / mScaleFactor);
4246
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4247
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4248
    }
43 andreas 4249
#endif
70 andreas 4250
 
154 andreas 4251
    TSubPage *subPage = nullptr;
11 andreas 4252
 
154 andreas 4253
    if (pressed)
4254
        subPage = getCoordMatch(realX, realY);
318 andreas 4255
    else if (mLastPagePush)
154 andreas 4256
        subPage = getSubPage(mLastPagePush);
4257
    else
4258
        subPage = getCoordMatch(realX, realY);
4259
 
11 andreas 4260
    if (!subPage)
14 andreas 4261
    {
146 andreas 4262
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4263
 
4264
        if (bt)
4265
        {
4266
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4267
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4268
        }
4269
 
11 andreas 4270
        return;
14 andreas 4271
    }
11 andreas 4272
 
154 andreas 4273
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4274
 
4275
    if (pressed)
4276
        mLastPagePush = subPage->getNumber();
4277
    else
4278
        mLastPagePush = 0;
4279
 
11 andreas 4280
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4281
}
11 andreas 4282
 
289 andreas 4283
void TPageManager::mouseEvent(ulong handle, bool pressed)
4284
{
4285
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4286
 
320 andreas 4287
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4288
        return;
4289
 
299 andreas 4290
    TLOCKER(click_mutex);
293 andreas 4291
 
299 andreas 4292
    _CLICK_QUEUE_t cq;
4293
    cq.handle = handle;
4294
    cq.pressed = pressed;
4295
    mClickQueue.push_back(cq);
4296
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4297
}
4298
 
4299
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4300
{
4301
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4302
 
293 andreas 4303
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4304
 
289 andreas 4305
    if (!handle)
4306
        return;
4307
 
4308
    int pageID = (handle >> 16) & 0x0000ffff;
4309
    int buttonID = (handle & 0x0000ffff);
4310
 
318 andreas 4311
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4312
        return;
4313
 
4314
    TSubPage *subPage = getSubPage(pageID);
4315
 
4316
    if (subPage)
4317
    {
4318
        Button::TButton *bt = subPage->getButton(buttonID);
4319
 
4320
        if (bt)
4321
        {
318 andreas 4322
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4323
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4324
        }
4325
    }
4326
}
4327
 
192 andreas 4328
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4329
{
4330
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4331
 
4332
    Button::TButton *bt = findButton(handle);
4333
 
4334
    if (!bt)
4335
    {
271 andreas 4336
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4337
        return;
4338
    }
4339
 
4340
    bt->setTextOnly(content, -1);
4341
}
4342
 
309 andreas 4343
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4344
{
4345
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4346
 
4347
    Button::TButton *bt = findButton(handle);
4348
 
4349
    if (!bt)
4350
    {
4351
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4352
        return;
4353
    }
4354
 
310 andreas 4355
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4356
 
4357
    if (pageID < REGULAR_SUBPAGE_START)
4358
    {
368 andreas 4359
        TPage *pg = getPage((int)pageID);
309 andreas 4360
 
4361
        if (!pg)
4362
            return;
4363
 
4364
        pg->setCursorPosition(handle, oldPos, newPos);
4365
    }
4366
    else
4367
    {
368 andreas 4368
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4369
 
4370
        if (!pg)
4371
            return;
4372
 
4373
        pg->setCursorPosition(handle, oldPos, newPos);
4374
    }
4375
}
4376
 
4377
void TPageManager::inputFocusChanged(ulong handle, bool in)
4378
{
4379
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4380
 
4381
    Button::TButton *bt = findButton(handle);
4382
 
4383
    if (!bt)
4384
    {
4385
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4386
        return;
4387
    }
4388
 
310 andreas 4389
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4390
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4391
 
4392
    if (pageID < REGULAR_SUBPAGE_START)
4393
    {
368 andreas 4394
        TPage *pg = getPage((int)pageID);
309 andreas 4395
 
4396
        if (!pg)
4397
            return;
4398
 
4399
        pg->setInputFocus(handle, in);
4400
    }
4401
    else
4402
    {
368 andreas 4403
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4404
 
4405
        if (!pg)
4406
            return;
4407
 
4408
        pg->setInputFocus(handle, in);
4409
    }
4410
}
4411
 
208 andreas 4412
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4413
{
208 andreas 4414
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4415
 
4416
    // First we search for the button the handle points to
4417
    Button::TButton *button = findButton(handle);
4418
 
4419
    if (!button)
4420
    {
271 andreas 4421
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4422
        return;
4423
    }
4424
 
4425
    // Now we search for all buttons with the same channel and port number
4426
    vector<int> channels;
4427
    channels.push_back(button->getAddressChannel());
193 andreas 4428
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4429
 
4430
    if (TError::isError() || map.empty())
4431
        return;
4432
 
4433
    // Here we load all buttons found.
4434
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4435
 
4436
    if (buttons.size() > 0)
51 andreas 4437
    {
83 andreas 4438
        vector<Button::TButton *>::iterator mapIter;
4439
        // Finaly we iterate through all found buttons and set the text
118 andreas 4440
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4441
        {
4442
            Button::TButton *bt = *mapIter;
51 andreas 4443
 
208 andreas 4444
            if (redraw)
4445
                bt->setText(txt, -1);
4446
            else
4447
                bt->setTextOnly(txt, -1);
83 andreas 4448
        }
51 andreas 4449
    }
4450
}
4451
 
193 andreas 4452
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4453
{
193 andreas 4454
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4455
 
4456
    vector<Button::TButton *> buttons;
83 andreas 4457
 
4458
    if (map.size() == 0)
4459
        return buttons;
4460
 
193 andreas 4461
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4462
 
118 andreas 4463
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4464
    {
209 andreas 4465
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4466
        {
4467
            TPage *page;
4468
 
4469
            if ((page = getPage(iter->pg)) == nullptr)
4470
            {
4471
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4472
 
4473
                if (!readPage(iter->pg))
4474
                    return buttons;
4475
 
4476
                page = getPage(iter->pg);
4477
            }
4478
 
4479
            Button::TButton *bt = page->getButton(iter->bt);
4480
 
4481
            if (bt)
4482
                buttons.push_back(bt);
4483
        }
4484
        else
4485
        {
4486
            TSubPage *subpage;
4487
 
4488
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4489
            {
4490
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4491
 
4492
                if (!readSubPage(iter->pg))
4493
                    return buttons;
4494
 
4495
                subpage = getSubPage(iter->pg);
4496
                TPage *page = getActualPage();
4497
 
4498
                if (!page)
4499
                {
4500
                    MSG_ERROR("No actual page loaded!");
4501
                    return buttons;
4502
                }
4503
            }
4504
 
4505
            Button::TButton *bt = subpage->getButton(iter->bt);
4506
 
4507
            if (bt)
4508
                buttons.push_back(bt);
4509
        }
4510
    }
4511
 
4512
    return buttons;
4513
}
4514
 
11 andreas 4515
/****************************************************************************
36 andreas 4516
 * Calls from a Java activity. This is only available for Android OS.
4517
 ****************************************************************************/
182 andreas 4518
#ifdef Q_OS_ANDROID
36 andreas 4519
void TPageManager::initNetworkState()
4520
{
4521
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4522
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4523
    QAndroidJniObject activity = QtAndroid::androidActivity();
4524
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4525
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4526
#else
4527
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4528
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4529
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4530
#endif
36 andreas 4531
}
4532
 
4533
void TPageManager::stopNetworkState()
4534
{
4535
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4536
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4537
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4538
#else
4539
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4540
#endif
36 andreas 4541
}
38 andreas 4542
 
4543
void TPageManager::initBatteryState()
4544
{
4545
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4546
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4547
    QAndroidJniObject activity = QtAndroid::androidActivity();
4548
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4549
#else
4550
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4551
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4552
#endif
38 andreas 4553
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4554
}
4555
 
61 andreas 4556
void TPageManager::initPhoneState()
4557
{
4558
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4559
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4560
    QAndroidJniObject activity = QtAndroid::androidActivity();
4561
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4562
#else
4563
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4564
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4565
#endif
61 andreas 4566
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4567
}
4568
 
38 andreas 4569
void TPageManager::stopBatteryState()
4570
{
4571
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4572
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4573
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4574
#else
4575
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4576
#endif
38 andreas 4577
}
4578
 
36 andreas 4579
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4580
{
250 andreas 4581
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4582
 
4583
    int l = 0;
4584
    string sType;
4585
 
4586
    switch (type)
4587
    {
4588
        case 1: sType = "Wifi"; break;
4589
        case 2: sType = "Mobile"; break;
4590
 
4591
        default:
4592
            sType = "Unknown"; break;
4593
    }
4594
 
4595
    if (conn)
4596
        l = level;
4597
 
93 andreas 4598
    if (mNetState && mNetState != type)     // Has the connection type changed?
4599
    {
4600
        if (gAmxNet)
4601
            gAmxNet->reconnect();
4602
    }
4603
 
4604
    mNetState = type;
4605
 
36 andreas 4606
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4607
 
83 andreas 4608
    if (mNetCalls.size() > 0)
36 andreas 4609
    {
83 andreas 4610
        std::map<int, std::function<void (int level)> >::iterator iter;
4611
 
4612
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4613
            iter->second(l);
36 andreas 4614
    }
4615
}
38 andreas 4616
 
4617
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4618
{
4619
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4620
 
59 andreas 4621
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4622
 
83 andreas 4623
    if (mBatteryCalls.size() > 0)
38 andreas 4624
    {
83 andreas 4625
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4626
 
4627
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4628
            iter->second(level, charging, chargeType);
38 andreas 4629
    }
4630
}
61 andreas 4631
 
4632
void TPageManager::informPhoneState(bool call, const string &pnumber)
4633
{
4634
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4635
 
4636
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4637
 
4638
    if (!gAmxNet)
4639
    {
4640
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4641
        return;
4642
    }
4643
}
130 andreas 4644
 
4645
void TPageManager::initOrientation()
4646
{
4647
    DECL_TRACER("TPageManager::initOrientation()");
4648
 
131 andreas 4649
    int rotate = getSettings()->getRotate();
264 andreas 4650
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4651
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4652
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4653
#else
4654
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4655
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4656
#endif
130 andreas 4657
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4658
}
255 andreas 4659
 
4660
void TPageManager::enterSetup()
4661
{
260 andreas 4662
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4663
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4664
    QAndroidJniObject activity = QtAndroid::androidActivity();
4665
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4666
#else
4667
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4668
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4669
#endif
4670
}
59 andreas 4671
#endif  // __ANDROID__
247 andreas 4672
#ifdef Q_OS_IOS
4673
void TPageManager::informBatteryStatus(int level, int state)
4674
{
4675
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4676
 
247 andreas 4677
    MSG_INFO("Battery status: level: " << level << ", " << state);
4678
 
4679
    if (mBatteryCalls.size() > 0)
4680
    {
4681
        std::map<int, std::function<void (int, int)> >::iterator iter;
4682
 
4683
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4684
            iter->second(level, state);
4685
    }
4686
}
250 andreas 4687
 
4688
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4689
{
4690
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4691
 
4692
    int l = 0;
4693
    string sType;
4694
 
4695
    switch (type)
4696
    {
4697
        case 1: sType = "Ethernet"; break;
4698
        case 2: sType = "Mobile"; break;
4699
        case 3: sType = "WiFi"; break;
4700
        case 4: sType = "Bluetooth"; break;
4701
 
4702
        default:
4703
            sType = "Unknown"; break;
4704
    }
4705
 
4706
    if (conn)
4707
        l = level;
4708
 
4709
    if (mNetState && mNetState != type)     // Has the connection type changed?
4710
    {
4711
        if (gAmxNet)
4712
            gAmxNet->reconnect();
4713
    }
4714
 
4715
    mNetState = type;
4716
 
4717
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4718
 
4719
    if (mNetCalls.size() > 0)
4720
    {
4721
        std::map<int, std::function<void (int level)> >::iterator iter;
4722
 
4723
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4724
            iter->second(l);
4725
    }
4726
}
4727
 
247 andreas 4728
#endif
4729
 
60 andreas 4730
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4731
{
227 andreas 4732
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4733
 
162 andreas 4734
    if (!bt)
4735
        return;
4736
 
60 andreas 4737
    bt->registerCallback(_displayButton);
4738
    bt->regCallPlayVideo(_callPlayVideo);
4739
    bt->setFonts(mFonts);
4740
    bt->setPalette(mPalette);
4741
}
4742
 
4743
void TPageManager::externalButton(extButtons_t bt, bool checked)
4744
{
4745
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4746
 
4747
    if (!mExternal)
4748
        return;
4749
 
4750
    EXTBUTTON_t button = mExternal->getButton(bt);
4751
 
4752
    if (button.type == EXT_NOBUTTON)
4753
        return;
4754
 
4755
    if (button.cp && button.ch)
4756
    {
4757
        amx::ANET_SEND scmd;
4758
 
4759
        scmd.device = TConfig::getChannel();
4760
        scmd.port = button.cp;
4761
        scmd.channel = button.ch;
4762
 
4763
        if (checked)
4764
            scmd.MC = 0x0084;   // push button
134 andreas 4765
        else
4766
            scmd.MC = 0x0085;   // release button
60 andreas 4767
 
134 andreas 4768
        MSG_DEBUG("Sending to device <" << scmd.device << ":" << scmd.port << ":0> channel " << scmd.channel << " value 0x" << std::setw(2) << std::setfill('0') << std::hex << scmd.MC << " (" << (checked?"PUSH":"RELEASE") << ")");
60 andreas 4769
 
134 andreas 4770
        if (gAmxNet)
4771
            gAmxNet->sendCommand(scmd);
4772
        else
4773
        {
4774
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
4775
        }
60 andreas 4776
    }
4777
}
4778
 
62 andreas 4779
void TPageManager::sendKeyboard(const std::string& text)
4780
{
4781
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
4782
 
4783
    amx::ANET_SEND scmd;
4784
    scmd.port = 1;
4785
    scmd.channel = 0;
4786
    scmd.msg = UTF8ToCp1250(text);
4787
    scmd.MC = 0x008b;
4788
 
4789
    if (gAmxNet)
4790
        gAmxNet->sendCommand(scmd);
4791
    else
4792
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4793
}
4794
 
4795
void TPageManager::sendKeypad(const std::string& text)
4796
{
4797
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
4798
 
269 andreas 4799
    sendKeyboard(text);
62 andreas 4800
}
4801
 
4802
void TPageManager::sendString(uint handle, const std::string& text)
4803
{
4804
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
4805
 
4806
    Button::TButton *bt = findButton(handle);
4807
 
4808
    if (!bt)
4809
    {
271 andreas 4810
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 4811
        return;
4812
    }
4813
 
4814
    amx::ANET_SEND scmd;
4815
    scmd.port = bt->getAddressPort();
4816
    scmd.channel = bt->getAddressChannel();
4817
    scmd.msg = UTF8ToCp1250(text);
4818
    scmd.MC = 0x008b;
4819
 
4820
    if (gAmxNet)
4821
        gAmxNet->sendCommand(scmd);
4822
    else
4823
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4824
}
4825
 
134 andreas 4826
void TPageManager::sendGlobalString(const string& text)
4827
{
4828
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4829
 
4830
    if (text.empty() || text.find("-") == string::npos)
4831
        return;
4832
 
4833
    amx::ANET_SEND scmd;
4834
    scmd.port = 1;
4835
    scmd.channel = 0;
4836
    scmd.msg = text;
4837
    scmd.MC = 0x008b;
4838
 
4839
    if (gAmxNet)
4840
        gAmxNet->sendCommand(scmd);
4841
    else
4842
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4843
}
4844
 
147 andreas 4845
void TPageManager::sendCommandString(int port, const string& cmd)
4846
{
4847
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4848
 
4849
    if (cmd.empty())
4850
        return;
4851
 
4852
    amx::ANET_SEND scmd;
4853
    scmd.port = port;
4854
    scmd.channel = 0;
4855
    scmd.msg = cmd;
4856
    scmd.MC = 0x008c;
4857
 
4858
    if (gAmxNet)
4859
        gAmxNet->sendCommand(scmd);
4860
    else
4861
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4862
}
4863
 
123 andreas 4864
void TPageManager::sendPHNcommand(const std::string& cmd)
4865
{
4866
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
4867
 
4868
    amx::ANET_SEND scmd;
144 andreas 4869
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 4870
    scmd.channel = TConfig::getChannel();
4871
    scmd.msg = "^PHN-" + cmd;
127 andreas 4872
    scmd.MC = 0x008c;
4873
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 4874
 
4875
    if (gAmxNet)
4876
        gAmxNet->sendCommand(scmd);
4877
    else
4878
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
4879
}
4880
 
111 andreas 4881
void TPageManager::sendKeyStroke(char key)
4882
{
4883
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
4884
 
4885
    if (!key)
4886
        return;
4887
 
4888
    char msg[2];
4889
    msg[0] = key;
4890
    msg[1] = 0;
4891
 
4892
    amx::ANET_SEND scmd;
4893
    scmd.port = 1;
4894
    scmd.channel = 0;
4895
    scmd.msg.assign(msg);
127 andreas 4896
    scmd.MC = 0x008c;
111 andreas 4897
 
4898
    if (gAmxNet)
4899
        gAmxNet->sendCommand(scmd);
4900
    else
4901
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4902
}
4903
 
110 andreas 4904
/**
4905
 * Sending a custom event is identical in all cases. Because of this I
4906
 * implemented this method to send a custom event. This is called in all cases
4907
 * where a ?XXX command is received.
4908
 *
4909
 * @param value1    The instance of the button.
4910
 * @param value2    The value of a numeric request or the length of the string.
4911
 * @param value3    Always 0
4912
 * @param msg       In case of a string this contains the string.
4913
 * @param evType    This is the event type, a number between 1001 and 1099.
4914
 * @param cp        Channel port of button.
4915
 * @param cn        Channel number. of button.
4916
 *
4917
 * @return If all parameters are valid it returns TRUE.
4918
 */
4919
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
4920
{
4921
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
4922
 
4923
    if (value1 < 1)
4924
        return false;
4925
 
4926
    amx::ANET_SEND scmd;
4927
    scmd.port = cp;
4928
    scmd.channel = cn;
4929
    scmd.ID = scmd.channel;
4930
    scmd.flag = 0;
4931
    scmd.type = evType;
4932
    scmd.value1 = value1;   // instance
4933
    scmd.value2 = value2;
4934
    scmd.value3 = value3;
4935
    scmd.msg = msg;
4936
 
4937
    if (!msg.empty())
4938
        scmd.dtype = 0x0001;// Char array
4939
 
4940
    scmd.MC = 0x008d;       // custom event
4941
 
4942
    if (gAmxNet)
4943
        gAmxNet->sendCommand(scmd);
4944
    else
4945
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4946
 
4947
    return true;
4948
}
129 andreas 4949
#ifndef _NOSIP_
127 andreas 4950
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
4951
{
4952
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
4953
 
4954
    switch(s)
4955
    {
4956
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
4957
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
4958
        case TSIPClient::SIP_HOLD:          return "HOLD";
4959
        case TSIPClient::SIP_RINGING:       return "RINGING";
4960
        case TSIPClient::SIP_TRYING:        return "TRYING";
4961
 
4962
        default:
4963
            return "IDLE";
4964
    }
4965
 
4966
    return "IDLE";
4967
}
129 andreas 4968
#endif
134 andreas 4969
void TPageManager::sendOrientation()
4970
{
4971
    string ori;
4972
 
4973
    switch(mOrientation)
4974
    {
4975
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
4976
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
4977
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
4978
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
4979
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
4980
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
4981
        default:
4982
            return;
4983
    }
4984
 
4985
    sendGlobalString("TPCACC-" + ori);
4986
}
4987
 
153 andreas 4988
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
4989
{
4990
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
4991
 
4992
    // Swipes are defined in "external".
4993
    if (!mExternal)
4994
        return;
4995
 
4996
    extButtons_t eBt;
4997
    string dbg;
4998
 
4999
    switch(sw)
5000
    {
5001
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
5002
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
5003
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
5004
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
5005
 
5006
        default:
5007
            return;
5008
    }
5009
 
5010
    int pgNum = getActualPageNumber();
5011
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
5012
 
5013
    if (bt.bi == 0)
5014
        return;
5015
 
5016
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
5017
 
5018
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
5019
    {                                           // Yes, then feed it into command queue.
5020
        MSG_DEBUG("Button has a self feed command");
5021
 
5022
        int channel = TConfig::getChannel();
5023
        int system = TConfig::getSystem();
5024
 
5025
        amx::ANET_COMMAND cmd;
5026
        cmd.MC = 0x000c;
5027
        cmd.device1 = channel;
5028
        cmd.port1 = bt.ap;
5029
        cmd.system = system;
5030
        cmd.data.message_string.device = channel;
5031
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
5032
        cmd.data.message_string.system = system;
5033
        cmd.data.message_string.type = 1;   // 8 bit char string
5034
 
5035
        vector<string>::iterator iter;
5036
 
5037
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5038
        {
5039
            cmd.data.message_string.length = iter->length();
5040
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
5041
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
5042
            doCommand(cmd);
5043
        }
5044
    }
5045
    else if (!bt.cm.empty())
5046
    {
5047
        MSG_DEBUG("Button sends a command on port " << bt.co);
5048
 
5049
        vector<string>::iterator iter;
5050
 
5051
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5052
            sendCommandString(bt.co, *iter);
5053
    }
5054
}
5055
 
36 andreas 5056
/****************************************************************************
11 andreas 5057
 * The following functions implements one of the commands the panel accepts.
5058
 ****************************************************************************/
43 andreas 5059
 
5060
/**
5061
 * This is a special function handling the progress bars when the files of the
5062
 * panel are updated. Instead of simply displaying a ready page, it fakes one
5063
 * with the actual dimensions of the main page. This is possible, because we've
5064
 * always a main page even if the panel is started for the first time.
5065
 */
5066
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 5067
{
43 andreas 5068
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 5069
 
23 andreas 5070
    if (pars.empty())
5071
    {
5072
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
5073
        return;
5074
    }
5075
 
96 andreas 5076
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 5077
    {
96 andreas 5078
        for (size_t i = 0; i < pars.size(); i++)
5079
        {
5080
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
5081
        }
23 andreas 5082
    }
43 andreas 5083
 
5084
    if (pars.at(0).compare("START") == 0)
5085
    {
5086
        // Here we have to drop all pages and subpages first and then display
5087
        // the faked page with the progress bars.
5088
        MSG_DEBUG("Starting file transfer ...");
5089
        doPPX(port, channels, pars);
5090
        TPage *pg = getPage("_progress");
5091
 
5092
        if (!pg)
5093
        {
5094
            if (!readPage("_progress"))
5095
            {
5096
                MSG_ERROR("Error creating the system page _progress!");
5097
                return;
5098
            }
5099
 
5100
            pg = getPage("_progress");
5101
 
5102
            if (!pg)
5103
            {
5104
                MSG_ERROR("Error getting system page _progress!");
5105
                return;
5106
            }
5107
        }
5108
 
5109
        pg->setFonts(mFonts);
5110
        pg->registerCallback(_setBackground);
5111
        pg->regCallPlayVideo(_callPlayVideo);
5112
 
5113
        if (!pg || !_setPage || !mTSettings)
5114
            return;
5115
 
5116
        int width, height;
217 andreas 5117
        width = mTSettings->getWidth();
43 andreas 5118
        height = mTSettings->getHeight();
5119
#ifdef _SCALE_SKIA_
5120
        if (mScaleFactor != 1.0)
5121
        {
5122
            width = (int)((double)width * mScaleFactor);
5123
            height = (int)((double)height * mScaleFactor);
5124
        }
5125
#endif
5126
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5127
        pg->show();
5128
        MSG_DEBUG("Page _progress on screen");
5129
    }
5130
    else if (pars.at(0).compare("SYNC") == 0)
5131
    {
5132
        TPage *pg = getPage("_progress");
5133
 
5134
        if (!pg)
5135
        {
5136
            MSG_ERROR("Page _progress not found!");
5137
            return;
5138
        }
5139
 
5140
        Button::TButton *bt = pg->getButton(1);   // Line 1
5141
 
5142
        if (!bt)
5143
        {
5144
            MSG_ERROR("Button 160 of page _progress not found!");
5145
            return;
5146
        }
5147
 
5148
        bt->setText(pars.at(2), 0);
5149
        bt->show();
5150
    }
5151
    else if (pars.at(0).compare("FTRSTART") == 0)
5152
    {
5153
        TPage *pg = getPage("_progress");
5154
 
5155
        if (!pg)
5156
        {
5157
            MSG_ERROR("Page _progress not found!");
5158
            return;
5159
        }
5160
 
5161
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5162
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5163
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5164
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5165
 
5166
        if (!bt1 || !bt2 || !bt3 || !bt4)
5167
        {
5168
            MSG_ERROR("Buttons of page _progress not found!");
5169
            return;
5170
        }
5171
 
5172
        bt1->setText("Transfering files ...", 0);
5173
        bt1->show();
5174
        bt2->setText(pars.at(3), 0);
5175
        bt2->show();
5176
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5177
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5178
    }
5179
    else if (pars.at(0).compare("FTRPART") == 0)
5180
    {
5181
        TPage *pg = getPage("_progress");
5182
 
5183
        if (!pg)
5184
        {
5185
            MSG_ERROR("Page _progress not found!");
5186
            return;
5187
        }
5188
 
5189
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5190
 
5191
        if (!bt)
5192
        {
5193
            MSG_ERROR("Buttons of page _progress not found!");
5194
            return;
5195
        }
5196
 
5197
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5198
    }
5199
    else if (pars.at(0).compare("END") == 0)
5200
    {
5201
        MSG_TRACE("End of file transfer reached.");
44 andreas 5202
 
155 andreas 5203
        // To make sure the new surface will not be deleted and replaced by the
5204
        // default build in surface, we must delete the "virgin" marker first.
5205
        // This is a file called <project path>/.system.
5206
        string virgin = TConfig::getProjectPath() + "/.system";
5207
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5208
 
44 andreas 5209
        if (_resetSurface)
5210
            _resetSurface();
5211
        else
5212
        {
5213
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5214
        }
43 andreas 5215
    }
23 andreas 5216
}
5217
 
318 andreas 5218
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5219
{
5220
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5221
 
5222
    mLevelSend = true;
343 andreas 5223
#if TESTMODE == 1
5224
    __success = true;
5225
    setAllDone();
5226
#endif
318 andreas 5227
}
5228
 
5229
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5230
{
5231
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5232
 
5233
    mLevelSend = false;
343 andreas 5234
#if TESTMODE == 1
5235
    __success = true;
5236
    setAllDone();
5237
#endif
318 andreas 5238
}
5239
 
5240
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5241
{
5242
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5243
 
5244
    mRxOn = true;
343 andreas 5245
#if TESTMODE == 1
5246
    __success = true;
5247
    setAllDone();
5248
#endif
318 andreas 5249
}
5250
 
5251
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5252
{
5253
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5254
 
5255
    mRxOn = false;
343 andreas 5256
#if TESTMODE == 1
5257
    __success = true;
5258
    setAllDone();
5259
#endif
318 andreas 5260
}
5261
 
22 andreas 5262
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5263
{
5264
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5265
 
5266
    if (pars.empty())
5267
    {
5268
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
343 andreas 5269
#if TESTMODE == 1
5270
        setAllDone();
5271
#endif
14 andreas 5272
        return;
5273
    }
5274
 
16 andreas 5275
    TError::clear();
14 andreas 5276
    int c = atoi(pars[0].c_str());
5277
 
5278
    if (c <= 0)
5279
    {
5280
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5281
#if TESTMODE == 1
5282
        setAllDone();
5283
#endif
14 andreas 5284
        return;
5285
    }
5286
 
5287
    vector<int> chans = { c };
193 andreas 5288
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5289
 
5290
    if (TError::isError() || map.empty())
343 andreas 5291
    {
5292
#if TESTMODE == 1
5293
        setAllDone();
5294
#endif
14 andreas 5295
        return;
343 andreas 5296
    }
14 andreas 5297
 
5298
    vector<Button::TButton *> buttons = collectButtons(map);
5299
 
83 andreas 5300
    if (buttons.size() > 0)
14 andreas 5301
    {
83 andreas 5302
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5303
 
118 andreas 5304
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5305
        {
5306
            Button::TButton *bt = *mapIter;
5307
 
195 andreas 5308
            if (bt->getButtonType() == GENERAL)
343 andreas 5309
            {
83 andreas 5310
                bt->setActive(1);
343 andreas 5311
#if TESTMODE == 1
5312
                if (_gTestMode)
5313
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5314
#endif
5315
            }
83 andreas 5316
        }
14 andreas 5317
    }
343 andreas 5318
#if TESTMODE == 1
5319
    setDone();
5320
#endif
14 andreas 5321
}
5322
 
22 andreas 5323
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5324
{
5325
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5326
 
5327
    if (pars.empty())
5328
    {
5329
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
343 andreas 5330
#if TESTMODE == 1
5331
        setAllDone();
5332
#endif
14 andreas 5333
        return;
5334
    }
5335
 
16 andreas 5336
    TError::clear();
14 andreas 5337
    int c = atoi(pars[0].c_str());
5338
 
5339
    if (c <= 0)
5340
    {
5341
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5342
#if TESTMODE == 1
5343
        setAllDone();
5344
#endif
14 andreas 5345
        return;
5346
    }
5347
 
5348
    vector<int> chans = { c };
193 andreas 5349
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5350
 
5351
    if (TError::isError() || map.empty())
5352
        return;
5353
 
5354
    vector<Button::TButton *> buttons = collectButtons(map);
5355
 
83 andreas 5356
    if (buttons.size() > 0)
14 andreas 5357
    {
83 andreas 5358
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5359
 
118 andreas 5360
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5361
        {
5362
            Button::TButton *bt = *mapIter;
5363
 
195 andreas 5364
            if (bt->getButtonType() == GENERAL)
83 andreas 5365
                bt->setActive(0);
343 andreas 5366
#if TESTMODE == 1
5367
                if (_gTestMode)
5368
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5369
#endif
83 andreas 5370
        }
14 andreas 5371
    }
343 andreas 5372
#if TESTMODE == 1
5373
    setDone();
5374
#endif
14 andreas 5375
}
5376
 
22 andreas 5377
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5378
{
5379
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5380
 
5381
    if (pars.size() < 2)
5382
    {
5383
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
343 andreas 5384
#if TESTMODE == 1
5385
        setAllDone();
5386
#endif
15 andreas 5387
        return;
5388
    }
5389
 
16 andreas 5390
    TError::clear();
15 andreas 5391
    int c = atoi(pars[0].c_str());
5392
    int level = atoi(pars[1].c_str());
5393
 
5394
    if (c <= 0)
5395
    {
5396
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5397
#if TESTMODE == 1
5398
        setAllDone();
5399
#endif
15 andreas 5400
        return;
5401
    }
5402
 
5403
    vector<int> chans = { c };
193 andreas 5404
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5405
 
5406
    if (TError::isError() || map.empty())
5407
    {
5408
        MSG_WARNING("No bargraphs found!");
343 andreas 5409
#if TESTMODE == 1
5410
        setAllDone();
5411
#endif
15 andreas 5412
        return;
5413
    }
5414
 
5415
    vector<Button::TButton *> buttons = collectButtons(map);
5416
 
83 andreas 5417
    if (buttons.size() > 0)
15 andreas 5418
    {
83 andreas 5419
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5420
 
118 andreas 5421
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5422
        {
83 andreas 5423
            Button::TButton *bt = *mapIter;
5424
 
195 andreas 5425
            if (bt->getButtonType() == BARGRAPH)
343 andreas 5426
            {
83 andreas 5427
                bt->drawBargraph(bt->getActiveInstance(), level);
343 andreas 5428
#if TESTMODE == 1
5429
                if (_gTestMode)
5430
                    _gTestMode->setResult(intToString(bt->getLevelValue()));
5431
#endif
5432
            }
195 andreas 5433
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH)
83 andreas 5434
            {
5435
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5436
                bt->setActive(state);
343 andreas 5437
#if TESTMODE == 1
5438
                if (_gTestMode)
5439
                    _gTestMode->setResult(intToString(bt->getActiveInstance()));
5440
#endif
83 andreas 5441
            }
15 andreas 5442
        }
5443
    }
343 andreas 5444
#if TESTMODE == 1
5445
    setDone();
5446
#endif
15 andreas 5447
}
5448
 
22 andreas 5449
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5450
{
5451
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5452
 
5453
    if (pars.size() < 4)
5454
    {
5455
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
343 andreas 5456
#if TESTMODE == 1
5457
        setAllDone();
5458
#endif
15 andreas 5459
        return;
5460
    }
5461
 
16 andreas 5462
    TError::clear();
15 andreas 5463
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5464
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5465
 
5466
    if (TError::isError() || map.empty())
5467
    {
5468
        MSG_WARNING("No system buttons found.");
343 andreas 5469
#if TESTMODE == 1
5470
        setAllDone();
5471
#endif
15 andreas 5472
        return;
5473
    }
5474
 
5475
    vector<Button::TButton *> buttons = collectButtons(map);
5476
    vector<Button::TButton *>::iterator mapIter;
5477
 
5478
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5479
    {
5480
        Button::TButton *bt = *mapIter;
5481
        bt->setActive(0);
343 andreas 5482
#if TESTMODE == 1
5483
                if (_gTestMode)
5484
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5485
#endif
15 andreas 5486
    }
343 andreas 5487
#if TESTMODE == 1
5488
    setDone();
5489
#endif
15 andreas 5490
}
5491
 
162 andreas 5492
/**
5493
 * Send the version of the panel to the NetLinx. This is the real application
5494
 * version.
5495
 */
127 andreas 5496
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5497
{
5498
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5499
 
5500
    amx::ANET_SEND scmd;
5501
    scmd.port = 1;
5502
    scmd.channel = 0;
5503
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5504
    scmd.MC = 0x008c;
5505
 
5506
    if (gAmxNet)
343 andreas 5507
    {
127 andreas 5508
        gAmxNet->sendCommand(scmd);
343 andreas 5509
#if TESTMODE == 1
5510
        __success = true;
347 andreas 5511
 
5512
        if (_gTestMode)
5513
            _gTestMode->setResult(VERSION_STRING());
343 andreas 5514
#endif
5515
    }
127 andreas 5516
    else
5517
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5518
#if TESTMODE == 1
5519
    setAllDone();
5520
#endif
127 andreas 5521
}
5522
 
162 andreas 5523
/**
5524
 * Returns the user name used to connect to a SIP server. An empty string is
5525
 * returned if there is no user defined.
5526
 */
279 andreas 5527
#ifndef _NOSIP_
127 andreas 5528
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5529
{
5530
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5531
 
5532
    if (!TConfig::getSIPstatus())
343 andreas 5533
    {
5534
#if TESTMODE == 1
5535
        setAllDone();
5536
#endif
127 andreas 5537
        return;
343 andreas 5538
    }
127 andreas 5539
 
5540
    amx::ANET_SEND scmd;
5541
    scmd.port = 1;
5542
    scmd.channel = 0;
5543
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5544
    scmd.MC = 0x008c;
5545
 
5546
    if (gAmxNet)
343 andreas 5547
    {
127 andreas 5548
        gAmxNet->sendCommand(scmd);
343 andreas 5549
#if TESTMODE == 1
5550
        __success = true;
347 andreas 5551
 
5552
        if (_gTestMode)
5553
            _gTestMode->setResult(TConfig::getSIPuser());
343 andreas 5554
#endif
5555
    }
127 andreas 5556
    else
5557
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5558
#if TESTMODE == 1
5559
        setAllDone();
5560
#endif
127 andreas 5561
}
279 andreas 5562
#endif
14 andreas 5563
/**
147 andreas 5564
 * Flip to specified page using the named animation.
5565
 * FIXME: Implement animation for pages.
5566
 */
5567
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
5568
{
5569
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
5570
 
5571
    if (pars.size() < 4)
5572
    {
5573
        MSG_ERROR("Less than 4 parameters!");
343 andreas 5574
#if TESTMODE == 1
5575
        setAllDone();
5576
#endif
147 andreas 5577
        return;
5578
    }
5579
 
5580
    TError::clear();
5581
    string pname = pars[0];
5582
//    string ani = pars[1];
5583
//    int origin = atoi(pars[2].c_str());
5584
//    int duration = atoi(pars[3].c_str());
5585
 
5586
    // FIXME: Animation of pages is currently not implemented.
5587
 
5588
    if (!pname.empty())
5589
        setPage(pname);
5590
    else if (mPreviousPage)
5591
        setPage(mPreviousPage);
343 andreas 5592
#if TESTMODE == 1
5593
    if (_gTestMode)
5594
        _gTestMode->setResult(getActualPage()->getName());
5595
 
5596
    setDone();
5597
#endif
147 andreas 5598
}
5599
 
5600
/**
14 andreas 5601
 * Add a specific popup page to a specified popup group if it does not already
5602
 * exist. If the new popup is added to a group which has a popup displayed on
5603
 * the current page along with the new pop-up, the displayed popup will be
5604
 * hidden and the new popup will be displayed.
5605
 */
22 andreas 5606
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5607
{
5608
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5609
 
5610
    if (pars.size() < 2)
5611
    {
5612
        MSG_ERROR("Less than 2 parameters!");
343 andreas 5613
#if TESTMODE == 1
5614
        setAllDone();
5615
#endif
11 andreas 5616
        return;
5617
    }
5618
 
16 andreas 5619
    TError::clear();
11 andreas 5620
    closeGroup(pars[1]);
14 andreas 5621
 
96 andreas 5622
    TPage *page = nullptr;
5623
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 5624
 
11 andreas 5625
    if (!subPage)
5626
    {
5627
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
343 andreas 5628
#if TESTMODE == 1
5629
        setAllDone();
5630
#endif
11 andreas 5631
        return;
5632
    }
5633
 
162 andreas 5634
    if (!page)
5635
    {
5636
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
343 andreas 5637
#if TESTMODE == 1
5638
        setAllDone();
5639
#endif
162 andreas 5640
        return;
5641
    }
5642
 
152 andreas 5643
    page->addSubPage(subPage);
11 andreas 5644
    subPage->setGroup(pars[1]);
14 andreas 5645
    subPage->setZOrder(page->getNextZOrder());
152 andreas 5646
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 5647
    subPage->show();
343 andreas 5648
#if TESTMODE == 1
347 andreas 5649
    if (_gTestMode)
5650
        _gTestMode->setResult(subPage->getGroupName() + ":" + subPage->getName());
5651
 
343 andreas 5652
    setDone();
5653
#endif
11 andreas 5654
}
5655
 
14 andreas 5656
/**
5657
 * Clear all popup pages from specified popup group.
5658
 */
22 andreas 5659
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5660
{
5661
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5662
 
5663
    if (pars.size() < 1)
5664
    {
5665
        MSG_ERROR("Expecting 1 parameter but got only 1!");
343 andreas 5666
#if TESTMODE == 1
5667
        setAllDone();
5668
#endif
11 andreas 5669
        return;
5670
    }
5671
 
16 andreas 5672
    TError::clear();
348 andreas 5673
    vector<SUBPAGELIST_T> pageList = mPageList->getSubPageList();
11 andreas 5674
 
83 andreas 5675
    if (pageList.size() > 0)
11 andreas 5676
    {
83 andreas 5677
        vector<SUBPAGELIST_T>::iterator pgIter;
5678
 
5679
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 5680
        {
83 andreas 5681
            if (pgIter->group.compare(pars[0]) == 0)
5682
            {
5683
                pgIter->group.clear();
5684
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 5685
 
83 andreas 5686
                if (pg)
5687
                    pg->setGroup(pgIter->group);
343 andreas 5688
#if TESTMODE == 1
5689
                __success = true;
5690
#endif
83 andreas 5691
            }
11 andreas 5692
        }
5693
    }
343 andreas 5694
#if TESTMODE == 1
5695
    setDone();
5696
#endif
11 andreas 5697
}
5698
 
14 andreas 5699
/**
5700
 * Delete a specific popup page from specified popup group if it exists.
5701
 */
22 andreas 5702
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5703
{
5704
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5705
 
5706
    if (pars.size() < 2)
5707
    {
5708
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5709
#if TESTMODE == 1
5710
        setAllDone();
5711
#endif
11 andreas 5712
        return;
5713
    }
5714
 
16 andreas 5715
    TError::clear();
11 andreas 5716
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
5717
 
5718
    if (!listPg.isValid)
348 andreas 5719
    {
5720
#if TESTMODE == 1
5721
        setAllDone();
5722
#endif
11 andreas 5723
        return;
348 andreas 5724
    }
11 andreas 5725
 
5726
    if (listPg.group.compare(pars[1]) == 0)
5727
    {
5728
        listPg.group.clear();
5729
        TSubPage *pg = getSubPage(listPg.pageID);
5730
 
5731
        if (pg)
5732
            pg->setGroup(listPg.group);
348 andreas 5733
#if TESTMODE == 1
5734
        __success = true;
5735
#endif
11 andreas 5736
    }
348 andreas 5737
#if TESTMODE == 1
5738
    setDone();
5739
#endif
11 andreas 5740
}
5741
 
14 andreas 5742
/**
15 andreas 5743
 * Set the hide effect for the specified popup page to the named hide effect.
5744
 */
22 andreas 5745
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 5746
{
5747
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
5748
 
5749
    if (pars.size() < 2)
5750
    {
5751
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5752
#if TESTMODE == 1
5753
        setAllDone();
5754
#endif
15 andreas 5755
        return;
5756
    }
5757
 
16 andreas 5758
    TError::clear();
96 andreas 5759
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5760
 
5761
    if (!pg)
348 andreas 5762
    {
5763
#if TESTMODE == 1
5764
        setAllDone();
5765
#endif
96 andreas 5766
        return;
348 andreas 5767
    }
15 andreas 5768
 
162 andreas 5769
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5770
        pg->setHideEffect(SE_FADE);
162 andreas 5771
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5772
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 5773
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5774
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 5775
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5776
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 5777
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5778
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 5779
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5780
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5781
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5782
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5783
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5784
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 5785
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5786
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
5787
    else
5788
        pg->setHideEffect(SE_NONE);
348 andreas 5789
#if TESTMODE == 1
5790
    if (_gTestMode)
5791
        _gTestMode->setResult(intToString(pg->getHideEffect()));
5792
 
5793
    __success = true;
5794
    setAllDone();
5795
#endif
15 andreas 5796
}
5797
 
5798
/**
5799
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
5800
 * however, the command will specify both. This command sets the location at
5801
 * which the effect will end at.
5802
 */
22 andreas 5803
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 5804
{
5805
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
5806
 
5807
    if (pars.size() < 2)
5808
    {
5809
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5810
#if TESTMODE == 1
5811
        setAllDone();
5812
#endif
15 andreas 5813
        return;
5814
    }
5815
 
16 andreas 5816
    TError::clear();
15 andreas 5817
    size_t pos = pars[1].find(",");
5818
    int x, y;
5819
 
5820
    if (pos == string::npos)
5821
    {
5822
        x = atoi(pars[1].c_str());
5823
        y = 0;
5824
    }
5825
    else
5826
    {
5827
        x = atoi(pars[1].substr(0, pos).c_str());
5828
        y = atoi(pars[1].substr(pos+1).c_str());
5829
    }
5830
 
96 andreas 5831
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5832
 
5833
    if (!pg)
348 andreas 5834
    {
5835
#if TESTMODE == 1
5836
        setAllDone();
5837
#endif
96 andreas 5838
        return;
348 andreas 5839
    }
15 andreas 5840
 
5841
    pg->setHideEndPosition(x, y);
348 andreas 5842
#if TESTMODE == 1
5843
    if (_gTestMode)
5844
    {
5845
        int x, y;
5846
        pg->getHideEndPosition(&x, &y);
5847
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
5848
    }
5849
 
5850
    __success = true;
5851
    setAllDone();
5852
#endif
15 andreas 5853
}
5854
 
5855
/**
5856
 * Set the hide effect time for the specified popup page.
5857
 */
22 andreas 5858
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 5859
{
5860
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
5861
 
5862
    if (pars.size() < 2)
5863
    {
5864
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5865
#if TESTMODE == 1
5866
        setAllDone();
5867
#endif
15 andreas 5868
        return;
5869
    }
5870
 
16 andreas 5871
    TError::clear();
96 andreas 5872
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5873
 
5874
    if (!pg)
348 andreas 5875
    {
5876
#if TESTMODE == 1
5877
        setAllDone();
5878
#endif
96 andreas 5879
        return;
348 andreas 5880
    }
15 andreas 5881
 
5882
    pg->setHideTime(atoi(pars[1].c_str()));
348 andreas 5883
#if TESTMODE == 1
5884
    if (_gTestMode)
5885
        _gTestMode->setResult(intToString(pg->getHideTime()));
5886
 
5887
    __success = true;
5888
    setAllDone();
5889
#endif
15 andreas 5890
}
5891
 
5892
/**
14 andreas 5893
 * Close all popups on a specified page. If the page name is empty, the current
5894
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
5895
 */
22 andreas 5896
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5897
{
5898
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5899
 
16 andreas 5900
    TError::clear();
11 andreas 5901
    TPage *pg;
5902
 
5903
    if (pars.size() == 0)
5904
        pg = getPage(mActualPage);
5905
    else
5906
        pg = getPage(pars[0]);
5907
 
5908
    if (!pg)
348 andreas 5909
    {
5910
#if TESTMODE == 1
5911
        setAllDone();
5912
#endif
11 andreas 5913
        return;
348 andreas 5914
    }
11 andreas 5915
 
12 andreas 5916
    pg->drop();
14 andreas 5917
    pg->resetZOrder();
348 andreas 5918
#if TESTMODE == 1
5919
    setDone();
5920
#endif
11 andreas 5921
}
5922
 
14 andreas 5923
/**
5924
 * Deactivate a specific popup page on either a specified page or the current
5925
 * page. If the page name is empty, the current page is used. If the popup page
5926
 * is part of a group, the whole group is deactivated. This command works in
5927
 * the same way as the ’Hide Popup’ command in TPDesign4.
5928
 */
22 andreas 5929
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5930
{
5931
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5932
 
5933
    if (pars.size() < 1)
5934
    {
5935
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 5936
#if TESTMODE == 1
5937
        setAllDone();
5938
#endif
12 andreas 5939
        return;
5940
    }
5941
 
16 andreas 5942
    TError::clear();
14 andreas 5943
    hideSubPage(pars[0]);
335 andreas 5944
#if TESTMODE == 1
5945
    setDone();
5946
#endif
12 andreas 5947
}
5948
 
14 andreas 5949
/**
5950
 * Toggle a specific popup page on either a specified page or the current page.
5951
 * If the page name is empty, the current page is used. Toggling refers to the
5952
 * activating/deactivating (On/Off) of a popup page. This command works in the
5953
 * same way as the ’Toggle Popup’ command in TPDesign4.
5954
 */
22 andreas 5955
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5956
{
5957
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5958
 
12 andreas 5959
    if (pars.size() < 1)
5960
    {
5961
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 5962
#if TESTMODE == 1
5963
        setAllDone();
5964
#endif
12 andreas 5965
        return;
5966
    }
5967
 
16 andreas 5968
    TError::clear();
14 andreas 5969
    TPage *page = getPage(mActualPage);
5970
 
5971
    if (!page)
5972
    {
5973
        MSG_ERROR("No active page found! Internal error.");
349 andreas 5974
#if TESTMODE == 1
5975
        setAllDone();
5976
#endif
14 andreas 5977
        return;
5978
    }
5979
 
12 andreas 5980
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 5981
 
12 andreas 5982
    if (!pg)
349 andreas 5983
    {
5984
#if TESTMODE == 1
5985
        setAllDone();
5986
#endif
12 andreas 5987
        return;
349 andreas 5988
    }
14 andreas 5989
 
12 andreas 5990
    if (pg->isVisible())
5991
    {
5992
        pg->drop();
162 andreas 5993
        page->decZOrder();
349 andreas 5994
#if TESTMODE == 1
5995
        setDone();
5996
#endif
12 andreas 5997
        return;
5998
    }
5999
 
6000
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 6001
 
12 andreas 6002
    while(sub)
6003
    {
6004
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
6005
            sub->drop();
14 andreas 6006
 
12 andreas 6007
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
6008
    }
6009
 
152 andreas 6010
    pg->setZOrder(page->getNextZOrder());
6011
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 6012
    pg->show();
349 andreas 6013
#if TESTMODE == 1
6014
    setDone();
6015
#endif
12 andreas 6016
}
6017
 
14 andreas 6018
/**
6019
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
6020
 * the pop-up page is part of a group, the whole group is deactivated. This
6021
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
6022
 */
22 andreas 6023
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6024
{
6025
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6026
 
12 andreas 6027
    if (pars.size() < 1)
6028
    {
6029
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6030
#if TESTMODE == 1
6031
        setAllDone();
6032
#endif
12 andreas 6033
        return;
6034
    }
6035
 
16 andreas 6036
    TError::clear();
14 andreas 6037
    TPage *page = getPage(mActualPage);
6038
 
6039
    if (!page)
6040
    {
6041
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6042
#if TESTMODE == 1
6043
        setAllDone();
6044
#endif
14 andreas 6045
        return;
6046
    }
6047
 
12 andreas 6048
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6049
 
12 andreas 6050
    if (pg)
14 andreas 6051
    {
6052
        pg->drop();
162 andreas 6053
        page->decZOrder();
14 andreas 6054
    }
349 andreas 6055
#if TESTMODE == 1
6056
        setDone();
6057
#endif
12 andreas 6058
}
6059
 
14 andreas 6060
/**
6061
 * Set the modality of a specific popup page to Modal or NonModal.
6062
 * A Modal popup page, when active, only allows you to use the buttons and
6063
 * features on that popup page. All other buttons on the panel page are
6064
 * inactivated.
6065
 */
22 andreas 6066
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6067
{
6068
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6069
 
12 andreas 6070
    if (pars.size() < 2)
6071
    {
6072
        MSG_ERROR("Expecting 2 parameters!");
349 andreas 6073
#if TESTMODE == 1
6074
        setAllDone();
6075
#endif
12 andreas 6076
        return;
6077
    }
14 andreas 6078
 
16 andreas 6079
    TError::clear();
12 andreas 6080
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6081
 
12 andreas 6082
    if (pg)
6083
    {
162 andreas 6084
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 6085
            pg->setModal(1);
6086
        else
6087
            pg->setModal(0);
349 andreas 6088
#if TESTMODE == 1
6089
        if (_gTestMode)
6090
            _gTestMode->setResult(pg->isModal() ? "TRUE" : "FALSE");
6091
#endif
12 andreas 6092
    }
349 andreas 6093
#if TESTMODE == 1
6094
        setAllDone();
6095
#endif
12 andreas 6096
}
6097
 
14 andreas 6098
/**
6099
 * Activate a specific popup page to launch on either a specified page or the
6100
 * current page. If the page name is empty, the current page is used. If the
6101
 * popup page is already on, do not re-draw it. This command works in the same
6102
 * way as the ’Show Popup’ command in TPDesign4.
6103
 */
22 andreas 6104
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6105
{
6106
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6107
 
6108
    if (pars.size() < 1)
6109
    {
6110
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6111
#if TESTMODE == 1
6112
        setAllDone();
6113
#endif
12 andreas 6114
        return;
6115
    }
6116
 
16 andreas 6117
    TError::clear();
14 andreas 6118
    showSubPage(pars[0]);
349 andreas 6119
#if TESTMODE == 1
6120
    setDone();
6121
#endif
12 andreas 6122
}
6123
 
14 andreas 6124
/**
15 andreas 6125
 * Set a specific popup page to timeout within a specified time. If timeout is
6126
 * empty, popup page will clear the timeout.
6127
 */
22 andreas 6128
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 6129
{
6130
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
6131
 
6132
    if (pars.size() < 2)
6133
    {
6134
        MSG_ERROR("Expecting 2 parameters!");
351 andreas 6135
#if TESTMODE == 1
6136
        setAllDone();
6137
#endif
15 andreas 6138
        return;
6139
    }
6140
 
16 andreas 6141
    TError::clear();
96 andreas 6142
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6143
 
6144
    if (!pg)
351 andreas 6145
    {
6146
#if TESTMODE == 1
6147
        setAllDone();
6148
#endif
96 andreas 6149
        return;
351 andreas 6150
    }
15 andreas 6151
 
6152
    pg->setTimeout(atoi(pars[1].c_str()));
351 andreas 6153
#if TESTMODE == 1
6154
    if (_gTestMode)
6155
        _gTestMode->setResult(intToString(pg->getTimeout()));
6156
 
6157
    __success = true;
6158
    setAllDone();
6159
#endif
15 andreas 6160
}
6161
 
6162
/**
14 andreas 6163
 * Close all popups on all pages. This command works in the same way as the
6164
 * 'Clear All' command in TPDesign 4.
6165
 */
22 andreas 6166
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 6167
{
6168
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6169
 
16 andreas 6170
    TError::clear();
12 andreas 6171
    PCHAIN_T *chain = mPchain;
14 andreas 6172
 
12 andreas 6173
    while(chain)
6174
    {
6175
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 6176
 
12 andreas 6177
        while (sub)
6178
        {
351 andreas 6179
            MSG_DEBUG("Dropping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 6180
            sub->drop();
6181
            sub = chain->page->getNextSubPage();
6182
        }
14 andreas 6183
 
12 andreas 6184
        chain = chain->next;
6185
    }
14 andreas 6186
 
6187
    TPage *page = getPage(mActualPage);
6188
 
6189
    if (!page)
6190
    {
6191
        MSG_ERROR("No active page found! Internal error.");
351 andreas 6192
#if TESTMODE == 1
6193
        setAllDone();
6194
#endif
14 andreas 6195
        return;
6196
    }
6197
 
6198
    page->resetZOrder();
351 andreas 6199
#if TESTMODE == 1
6200
    setDone();
6201
#endif
12 andreas 6202
}
6203
 
14 andreas 6204
/**
15 andreas 6205
 * Set the show effect for the specified popup page to the named show effect.
6206
 */
22 andreas 6207
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 6208
{
6209
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
6210
 
6211
    if (pars.size() < 2)
6212
    {
6213
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6214
#if TESTMODE == 1
6215
        setAllDone();
6216
#endif
15 andreas 6217
        return;
6218
    }
6219
 
16 andreas 6220
    TError::clear();
96 andreas 6221
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6222
 
6223
    if (!pg)
351 andreas 6224
    {
6225
#if TESTMODE == 1
6226
        setAllDone();
6227
#endif
96 andreas 6228
        return;
351 andreas 6229
    }
15 andreas 6230
 
162 andreas 6231
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6232
        pg->setShowEffect(SE_FADE);
162 andreas 6233
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6234
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 6235
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6236
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 6237
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6238
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 6239
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6240
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 6241
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6242
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6243
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6244
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6245
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6246
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 6247
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6248
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
6249
    else
6250
        pg->setShowEffect(SE_NONE);
351 andreas 6251
#if TESTMODE == 1
6252
    if (_gTestMode)
6253
        _gTestMode->setResult(intToString(pg->getShowEffect()));
6254
 
6255
    __success = true;
6256
    setAllDone();
6257
#endif
15 andreas 6258
}
6259
 
162 andreas 6260
/**
6261
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
6262
 * however, the command will specify both. This command sets the location at
6263
 * which the effect will begin.
6264
 */
22 andreas 6265
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 6266
{
6267
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
6268
 
6269
    if (pars.size() < 2)
6270
    {
6271
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6272
#if TESTMODE == 1
6273
        setAllDone();
6274
#endif
15 andreas 6275
        return;
6276
    }
6277
 
16 andreas 6278
    TError::clear();
15 andreas 6279
    size_t pos = pars[1].find(",");
6280
    int x, y;
6281
 
6282
    if (pos == string::npos)
6283
    {
6284
        x = atoi(pars[1].c_str());
6285
        y = 0;
6286
    }
6287
    else
6288
    {
6289
        x = atoi(pars[1].substr(0, pos).c_str());
6290
        y = atoi(pars[1].substr(pos+1).c_str());
6291
    }
6292
 
96 andreas 6293
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6294
 
6295
    if (!pg)
351 andreas 6296
    {
6297
#if TESTMODE == 1
6298
        setAllDone();
6299
#endif
96 andreas 6300
        return;
351 andreas 6301
    }
15 andreas 6302
 
6303
    pg->setShowEndPosition(x, y);
351 andreas 6304
#if TESTMODE == 1
6305
    pg->getShowEndPosition(&x, &y);
6306
 
6307
    if (_gTestMode)
6308
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6309
 
6310
    __success = true;
6311
    setAllDone();
6312
#endif
15 andreas 6313
}
6314
 
6315
/**
6316
 * Set the show effect time for the specified popup page.
6317
 */
22 andreas 6318
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 6319
{
6320
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
6321
 
6322
    if (pars.size() < 2)
6323
    {
6324
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6325
#if TESTMODE == 1
6326
        setAllDone();
6327
#endif
15 andreas 6328
        return;
6329
    }
6330
 
16 andreas 6331
    TError::clear();
96 andreas 6332
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6333
 
6334
    if (!pg)
351 andreas 6335
    {
6336
#if TESTMODE == 1
6337
        setAllDone();
6338
#endif
96 andreas 6339
        return;
351 andreas 6340
    }
15 andreas 6341
 
6342
    pg->setShowTime(atoi(pars[1].c_str()));
351 andreas 6343
#if TESTMODE == 1
6344
    if (_gTestMode)
6345
        _gTestMode->setResult(intToString(pg->getShowTime()));
6346
 
6347
    __success = 1;
6348
    setAllDone();
6349
#endif
15 andreas 6350
}
6351
 
6352
/**
14 andreas 6353
 * Flips to a page with a specified page name. If the page is currently active,
6354
 * it will not redraw the page.
6355
 */
22 andreas 6356
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6357
{
6358
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6359
 
15 andreas 6360
    if (pars.empty())
6361
    {
6362
        MSG_WARNING("Got no page parameter!");
351 andreas 6363
#if TESTMODE == 1
6364
        setAllDone();
6365
#endif
15 andreas 6366
        return;
6367
    }
14 andreas 6368
 
16 andreas 6369
    TError::clear();
15 andreas 6370
    setPage(pars[0]);
351 andreas 6371
#if TESTMODE == 1
6372
    if (_gTestMode)
6373
        _gTestMode->setResult(intToString(getActualPageNumber()));
6374
 
6375
    setDone();
6376
#endif
15 andreas 6377
}
6378
 
6379
/**
38 andreas 6380
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
6381
 * Syntax:
6382
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
6383
 * Variable:
6384
 *      variable text address range = 1 - 4000.
6385
 *      start state = Beginning of button state (0= current state).
6386
 *      end state = End of button state.
6387
 *      time = In 1/10 second intervals.
6388
 * Example:
6389
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
6390
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
6391
 *
6392
 * @param port      The port number
6393
 * @param channels  The channels of the buttons
6394
 * @param pars      The parameters
6395
 */
6396
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
6397
{
6398
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
6399
 
6400
    if (pars.size() < 3)
6401
    {
6402
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
6403
        return;
6404
    }
6405
 
6406
    TError::clear();
6407
    int stateStart = atoi(pars[0].c_str());
6408
    int endState = atoi(pars[1].c_str());
6409
    int runTime = atoi(pars[2].c_str());
6410
 
193 andreas 6411
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 6412
 
6413
    if (TError::isError() || map.empty())
6414
        return;
6415
 
6416
    vector<Button::TButton *> buttons = collectButtons(map);
6417
 
83 andreas 6418
    if (buttons.size() > 0)
38 andreas 6419
    {
83 andreas 6420
        vector<Button::TButton *>::iterator mapIter;
6421
 
6422
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6423
        {
6424
            Button::TButton *bt = *mapIter;
6425
            bt->startAnimation(stateStart, endState, runTime);
6426
        }
38 andreas 6427
    }
351 andreas 6428
#if TESTMODE == 1
6429
    if (_gTestMode)
6430
        _gTestMode->setResult(intToString(stateStart) + "," + intToString(endState) + "," + intToString(runTime));
6431
 
6432
    setDone();
6433
#endif
38 andreas 6434
}
6435
 
6436
/**
15 andreas 6437
 * Add page flip action to a button if it does not already exist.
6438
 */
6439
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
6440
{
6441
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
6442
 
6443
    if (pars.size() < 2)
6444
    {
6445
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
351 andreas 6446
#if TESTMODE == 1
6447
        setAllDone();
6448
#endif
14 andreas 6449
        return;
15 andreas 6450
    }
14 andreas 6451
 
16 andreas 6452
    TError::clear();
15 andreas 6453
    string action = pars[0];
6454
    string pname = pars[1];
14 andreas 6455
 
193 andreas 6456
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 6457
 
15 andreas 6458
    if (TError::isError() || map.empty())
351 andreas 6459
    {
6460
#if TESTMODE == 1
6461
        setAllDone();
6462
#endif
15 andreas 6463
        return;
351 andreas 6464
    }
15 andreas 6465
 
6466
    vector<Button::TButton *> buttons = collectButtons(map);
6467
 
83 andreas 6468
    if (buttons.size() > 0)
12 andreas 6469
    {
83 andreas 6470
        vector<Button::TButton *>::iterator mapIter;
6471
 
6472
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6473
        {
6474
            Button::TButton *bt = *mapIter;
6475
            bt->addPushFunction(action, pname);
6476
        }
15 andreas 6477
    }
351 andreas 6478
#if TESTMODE == 1
6479
    if (_gTestMode)
6480
        _gTestMode->setResult(toUpper(action) + "," + toUpper(pname));
6481
 
6482
    __success = true;
6483
    setAllDone();
6484
#endif
15 andreas 6485
}
12 andreas 6486
 
15 andreas 6487
/**
43 andreas 6488
 * Append non-unicode text.
6489
 */
6490
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
6491
{
6492
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
6493
 
6494
    if (pars.size() < 1)
6495
    {
6496
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6497
#if TESTMODE == 1
334 andreas 6498
        setAllDone();
330 andreas 6499
#endif
43 andreas 6500
        return;
6501
    }
6502
 
6503
    TError::clear();
6504
    int btState = atoi(pars[0].c_str());
6505
    string text;
6506
 
6507
    if (pars.size() > 1)
6508
        text = pars[1];
6509
 
193 andreas 6510
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6511
 
6512
    if (TError::isError() || map.empty())
330 andreas 6513
    {
6514
#if TESTMODE == 1
334 andreas 6515
        setAllDone();
330 andreas 6516
#endif
43 andreas 6517
        return;
330 andreas 6518
    }
43 andreas 6519
 
6520
    vector<Button::TButton *> buttons = collectButtons(map);
6521
 
162 andreas 6522
    if (buttons.empty())
330 andreas 6523
    {
6524
#if TESTMODE == 1
334 andreas 6525
        setAllDone();
330 andreas 6526
#endif
162 andreas 6527
        return;
330 andreas 6528
    }
162 andreas 6529
 
6530
    vector<Button::TButton *>::iterator mapIter;
6531
 
6532
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6533
    {
162 andreas 6534
        Button::TButton *bt = *mapIter;
43 andreas 6535
 
331 andreas 6536
        bt->appendText(text, btState - 1);
330 andreas 6537
#if TESTMODE == 1
331 andreas 6538
        if (_gTestMode)
330 andreas 6539
        {
331 andreas 6540
            int st = (btState > 0 ? (btState - 1) : 0);
6541
            _gTestMode->setResult(bt->getText(st));
333 andreas 6542
        }
330 andreas 6543
 
331 andreas 6544
        __success = true;
330 andreas 6545
#endif
43 andreas 6546
    }
334 andreas 6547
#if TESTMODE == 1
6548
    setDone();
6549
#endif
43 andreas 6550
}
6551
 
6552
/**
60 andreas 6553
 * @brief Append unicode text. Same format as ^UNI.
6554
 * This command allows to set up to 50 characters of ASCII code. The unicode
6555
 * characters must be set as hex numbers.
6556
 */
6557
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6558
{
6559
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
6560
 
6561
    if (pars.size() < 1)
6562
    {
6563
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6564
#if TESTMODE == 1
6565
        setAllDone();
6566
#endif
60 andreas 6567
        return;
6568
    }
6569
 
6570
    TError::clear();
6571
    int btState = atoi(pars[0].c_str());
6572
    string text;
6573
    char ch[3];
6574
 
331 andreas 6575
    if (pars.size() > 1)
6576
        text = pars[1];
6577
 
6578
    if ((text.size() % 4) == 0)
60 andreas 6579
    {
162 andreas 6580
        try
60 andreas 6581
        {
162 andreas 6582
            text = pars[1];
331 andreas 6583
            MSG_DEBUG("Processing UTF16 string: " << text);
162 andreas 6584
            // Because the unicode characters are hex numbers, we scan the text
6585
            // and convert the hex numbers into real numbers.
6586
            size_t len = text.length();
6587
            bool inHex = false;
6588
            int lastChar = 0;
331 andreas 6589
            uint16_t *numstr = new uint16_t[len / 4];
162 andreas 6590
            int uniPos = 0;
331 andreas 6591
            int cntCount = 0;
60 andreas 6592
 
162 andreas 6593
            for (size_t i = 0; i < len; i++)
60 andreas 6594
            {
162 andreas 6595
                int c = text.at(i);
60 andreas 6596
 
162 andreas 6597
                if (!inHex && isHex(c))
6598
                {
6599
                    inHex = true;
6600
                    lastChar = c;
6601
                    continue;
6602
                }
6603
 
6604
                if (inHex && !isHex(c))
6605
                    break;
6606
 
6607
                if (inHex && isHex(c))
6608
                {
6609
                    ch[0] = lastChar;
6610
                    ch[1] = c;
6611
                    ch[2] = 0;
6612
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
331 andreas 6613
 
6614
                    if ((cntCount % 2) != 0)
6615
                    {
6616
                        numstr[uniPos] |= num;
6617
                        uniPos++;
6618
                    }
6619
                    else
6620
                        numstr[uniPos] = (num << 8) & 0xff00;
6621
 
6622
                    cntCount++;
162 andreas 6623
                    inHex = false;
6624
 
6625
                    if (uniPos >= 50)
6626
                        break;
331 andreas 6627
                }
6628
            }
162 andreas 6629
 
331 andreas 6630
            text.clear();
6631
            // Here we make from the real numbers a UTF8 string
6632
            for (size_t i = 0; i < len / 4; ++i)
6633
            {
6634
                if (numstr[i] <= 0x00ff)
6635
                {
6636
                    ch[0] = numstr[i];
6637
                    ch[1] = 0;
6638
                    text.append(ch);
162 andreas 6639
                }
331 andreas 6640
                else
6641
                {
6642
                    ch[0] = (numstr[i] >> 8) & 0x00ff;
6643
                    ch[1] = numstr[i] & 0x00ff;
6644
                    ch[2] = 0;
6645
                    text.append(ch);
6646
                }
60 andreas 6647
            }
6648
 
331 andreas 6649
            delete[] numstr;
60 andreas 6650
        }
162 andreas 6651
        catch (std::exception const & e)
6652
        {
6653
            MSG_ERROR("Character conversion error: " << e.what());
351 andreas 6654
#if TESTMODE == 1
6655
            setAllDone();
6656
#endif
162 andreas 6657
            return;
6658
        }
60 andreas 6659
    }
331 andreas 6660
    else
6661
    {
6662
        MSG_WARNING("No or invalid UTF16 string: " << text);
351 andreas 6663
#if TESTMODE == 1
6664
        setAllDone();
6665
#endif
331 andreas 6666
        return;
6667
    }
60 andreas 6668
 
193 andreas 6669
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6670
 
6671
    if (TError::isError() || map.empty())
351 andreas 6672
    {
6673
#if TESTMODE == 1
6674
        setAllDone();
6675
#endif
60 andreas 6676
        return;
351 andreas 6677
    }
60 andreas 6678
 
6679
    vector<Button::TButton *> buttons = collectButtons(map);
6680
 
83 andreas 6681
    if (buttons.size() > 0)
60 andreas 6682
    {
83 andreas 6683
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6684
 
83 andreas 6685
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6686
        {
83 andreas 6687
            Button::TButton *bt = *mapIter;
60 andreas 6688
 
331 andreas 6689
            bt->appendText(text, btState - 1);
330 andreas 6690
#if TESTMODE == 1
331 andreas 6691
            if (_gTestMode)
6692
                _gTestMode->setResult(bt->getText(btState - 1));
330 andreas 6693
 
331 andreas 6694
            __success = true;
330 andreas 6695
#endif
60 andreas 6696
        }
6697
    }
330 andreas 6698
#if TESTMODE == 1
334 andreas 6699
    setDone();
330 andreas 6700
#endif
60 andreas 6701
}
6702
 
6703
/**
43 andreas 6704
 * @brief TPageManager::doBCB Set the border color.
6705
 * Set the border color to the specified color. Only if the specified border
6706
 * color is not the same as the current color.
6707
 * Note: Color can be assigned by color name (without spaces), number or
6708
 * R,G,B value (RRGGBB or RRGGBBAA).
6709
 */
6710
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
6711
{
6712
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
6713
 
6714
    if (pars.size() < 1)
6715
    {
6716
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6717
#if TESTMODE == 1
6718
        setAllDone();
6719
#endif
43 andreas 6720
        return;
6721
    }
6722
 
6723
    TError::clear();
6724
    int btState = atoi(pars[0].c_str());
6725
    string color;
6726
 
6727
    if (pars.size() > 1)
6728
        color = pars[1];
6729
 
193 andreas 6730
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6731
 
6732
    if (TError::isError() || map.empty())
351 andreas 6733
    {
6734
#if TESTMODE == 1
6735
        setAllDone();
6736
#endif
43 andreas 6737
        return;
351 andreas 6738
    }
43 andreas 6739
 
6740
    vector<Button::TButton *> buttons = collectButtons(map);
6741
 
83 andreas 6742
    if (buttons.size() > 0)
43 andreas 6743
    {
83 andreas 6744
        vector<Button::TButton *>::iterator mapIter;
43 andreas 6745
 
83 andreas 6746
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6747
        {
83 andreas 6748
            Button::TButton *bt = *mapIter;
351 andreas 6749
            bt->setBorderColor(color, btState - 1);
6750
#if TESTMODE == 1
6751
            if (_gTestMode)
6752
                _gTestMode->setResult(bt->getBorderColor(btState == 0 ? 0 : btState - 1));
6753
#endif
43 andreas 6754
        }
6755
    }
351 andreas 6756
#if TESTMODE == 1
6757
    setDone();
6758
#endif
43 andreas 6759
}
60 andreas 6760
 
351 andreas 6761
/*
6762
 * Get the border color and send it as a custom event.
6763
 */
82 andreas 6764
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
6765
{
6766
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
6767
 
6768
    if (pars.size() < 1)
6769
    {
6770
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6771
#if TESTMODE == 1
6772
        setAllDone();
6773
#endif
82 andreas 6774
        return;
6775
    }
6776
 
6777
    TError::clear();
6778
    int btState = atoi(pars[0].c_str());
6779
    string color;
6780
 
193 andreas 6781
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6782
 
6783
    if (TError::isError() || map.empty())
351 andreas 6784
    {
6785
#if TESTMODE == 1
6786
        setAllDone();
6787
#endif
82 andreas 6788
        return;
351 andreas 6789
    }
82 andreas 6790
 
6791
    vector<Button::TButton *> buttons = collectButtons(map);
6792
 
351 andreas 6793
    if (buttons.empty())
82 andreas 6794
    {
351 andreas 6795
#if TESTMODE == 1
6796
        setAllDone();
6797
#endif
6798
        return;
6799
    }
82 andreas 6800
 
351 andreas 6801
    vector<Button::TButton *>::iterator iter;
6802
 
6803
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6804
    {
6805
        Button::TButton *bt = *iter;
6806
 
110 andreas 6807
        if (btState == 0)       // All instances?
82 andreas 6808
        {
110 andreas 6809
            int bst = bt->getNumberInstances();
82 andreas 6810
 
110 andreas 6811
            for (int i = 0; i < bst; i++)
82 andreas 6812
            {
110 andreas 6813
                color = bt->getBorderColor(i);
82 andreas 6814
 
110 andreas 6815
                if (color.empty())
6816
                    continue;
83 andreas 6817
 
300 andreas 6818
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6819
#if TESTMODE == 1
6820
                __success = true;
6821
 
6822
                if (_gTestMode)
6823
                    _gTestMode->setResult(color);
6824
#endif
83 andreas 6825
            }
110 andreas 6826
        }
6827
        else
6828
        {
6829
            color = bt->getBorderColor(btState - 1);
83 andreas 6830
 
110 andreas 6831
            if (color.empty())
351 andreas 6832
                continue;
82 andreas 6833
 
300 andreas 6834
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6835
#if TESTMODE == 1
6836
            __success = true;
6837
 
6838
            if (_gTestMode)
6839
                _gTestMode->setResult(color);
6840
#endif
82 andreas 6841
        }
6842
    }
351 andreas 6843
#if TESTMODE == 1
6844
    setAllDone();
6845
#endif
82 andreas 6846
}
6847
 
43 andreas 6848
/**
60 andreas 6849
 * @brief Set the fill color to the specified color.
6850
 * Only if the specified fill color is not the same as the current color.
6851
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 6852
 */
60 andreas 6853
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 6854
{
60 andreas 6855
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 6856
 
60 andreas 6857
    if (pars.size() < 1)
15 andreas 6858
    {
60 andreas 6859
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6860
#if TESTMODE == 1
6861
        setAllDone();
6862
#endif
12 andreas 6863
        return;
6864
    }
14 andreas 6865
 
16 andreas 6866
    TError::clear();
15 andreas 6867
    int btState = atoi(pars[0].c_str());
60 andreas 6868
    string color;
14 andreas 6869
 
60 andreas 6870
    if (pars.size() > 1)
6871
        color = pars[1];
6872
 
193 andreas 6873
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 6874
 
6875
    if (TError::isError() || map.empty())
351 andreas 6876
    {
6877
#if TESTMODE == 1
6878
        setAllDone();
6879
#endif
15 andreas 6880
        return;
351 andreas 6881
    }
15 andreas 6882
 
6883
    vector<Button::TButton *> buttons = collectButtons(map);
6884
 
83 andreas 6885
    if (buttons.size() > 0)
15 andreas 6886
    {
83 andreas 6887
        vector<Button::TButton *>::iterator mapIter;
15 andreas 6888
 
83 andreas 6889
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 6890
        {
83 andreas 6891
            Button::TButton *bt = *mapIter;
351 andreas 6892
            bt->setFillColor(color, btState - 1);
6893
#if TESTMODE == 1
6894
            if (_gTestMode)
6895
                _gTestMode->setResult(bt->getFillColor(btState == 0 ? 0 : btState - 1));
6896
#endif
15 andreas 6897
        }
6898
    }
351 andreas 6899
#if TESTMODE == 1
6900
    setDone();
6901
#endif
12 andreas 6902
}
6903
 
351 andreas 6904
/*
6905
 * Get the fill color and send it via a custom event to the NetLinx.
6906
 */
82 andreas 6907
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
6908
{
6909
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
6910
 
6911
    if (pars.size() < 1)
6912
    {
6913
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6914
#if TESTMODE == 1
6915
        setAllDone();
6916
#endif
82 andreas 6917
        return;
6918
    }
6919
 
6920
    TError::clear();
6921
    int btState = atoi(pars[0].c_str());
6922
    string color;
6923
 
193 andreas 6924
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6925
 
6926
    if (TError::isError() || map.empty())
351 andreas 6927
    {
6928
#if TESTMODE == 1
6929
        setAllDone();
6930
#endif
82 andreas 6931
        return;
351 andreas 6932
    }
82 andreas 6933
 
6934
    vector<Button::TButton *> buttons = collectButtons(map);
6935
 
351 andreas 6936
    if (buttons.empty())
82 andreas 6937
    {
351 andreas 6938
#if TESTMODE == 1
6939
        setAllDone();
6940
#endif
6941
        return;
6942
    }
82 andreas 6943
 
351 andreas 6944
    vector<Button::TButton *>::iterator iter;
6945
 
6946
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6947
    {
6948
        Button::TButton *bt = *iter;
6949
 
110 andreas 6950
        if (btState == 0)       // All instances?
82 andreas 6951
        {
110 andreas 6952
            int bst = bt->getNumberInstances();
82 andreas 6953
 
110 andreas 6954
            for (int i = 0; i < bst; i++)
82 andreas 6955
            {
110 andreas 6956
                color = bt->getFillColor(i);
82 andreas 6957
 
110 andreas 6958
                if (color.empty())
6959
                    continue;
82 andreas 6960
 
300 andreas 6961
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6962
#if TESTMODE == 1
6963
                __success = true;
6964
 
6965
                if (_gTestMode)
6966
                    _gTestMode->setResult(color);
6967
#endif
83 andreas 6968
            }
82 andreas 6969
        }
110 andreas 6970
        else
6971
        {
6972
            color = bt->getFillColor(btState-1);
351 andreas 6973
 
6974
            if (color.empty())
6975
                continue;
6976
 
300 andreas 6977
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6978
#if TESTMODE == 1
6979
            __success = true;
6980
 
6981
            if (_gTestMode)
6982
                _gTestMode->setResult(color);
6983
#endif
110 andreas 6984
        }
82 andreas 6985
    }
351 andreas 6986
#if TESTMODE == 1
6987
    setAllDone();
6988
#endif
82 andreas 6989
}
6990
 
60 andreas 6991
/**
6992
 * @brief Set the text color to the specified color.
6993
 * Only if the specified text color is not the same as the current color.
6994
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
6995
 */
6996
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 6997
{
60 andreas 6998
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
6999
 
7000
    if (pars.size() < 1)
7001
    {
7002
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7003
#if TESTMODE == 1
7004
        setAllDone();
7005
#endif
60 andreas 7006
        return;
7007
    }
7008
 
7009
    TError::clear();
7010
    int btState = atoi(pars[0].c_str());
7011
    string color;
7012
 
7013
    if (pars.size() > 1)
7014
        color = pars[1];
7015
 
193 andreas 7016
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7017
 
7018
    if (TError::isError() || map.empty())
351 andreas 7019
    {
7020
#if TESTMODE == 1
7021
        setAllDone();
7022
#endif
60 andreas 7023
        return;
351 andreas 7024
    }
60 andreas 7025
 
7026
    vector<Button::TButton *> buttons = collectButtons(map);
7027
 
83 andreas 7028
    if (buttons.size() > 0)
60 andreas 7029
    {
83 andreas 7030
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7031
 
83 andreas 7032
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7033
        {
83 andreas 7034
            Button::TButton *bt = *mapIter;
351 andreas 7035
            bt->setTextColor(color, btState - 1);
7036
#if TESTMODE == 1
7037
            if (_gTestMode)
7038
                _gTestMode->setResult(bt->getTextColor(btState == 0 ? 0 : btState - 1));
7039
#endif
60 andreas 7040
        }
7041
    }
351 andreas 7042
#if TESTMODE == 1
7043
    setDone();
7044
#endif
18 andreas 7045
}
7046
 
351 andreas 7047
/*
7048
 * Get the text color of a button and send it via a custom event to the NetLinx.
7049
 */
82 andreas 7050
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
7051
{
7052
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
7053
 
7054
    if (pars.size() < 1)
7055
    {
7056
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7057
#if TESTMODE == 1
7058
        setAllDone();
7059
#endif
82 andreas 7060
        return;
7061
    }
7062
 
7063
    TError::clear();
7064
    int btState = atoi(pars[0].c_str());
7065
    string color;
7066
 
193 andreas 7067
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7068
 
7069
    if (TError::isError() || map.empty())
351 andreas 7070
    {
7071
#if TESTMODE == 1
7072
        setAllDone();
7073
#endif
82 andreas 7074
        return;
351 andreas 7075
    }
82 andreas 7076
 
7077
    vector<Button::TButton *> buttons = collectButtons(map);
7078
 
351 andreas 7079
    if (buttons.empty())
82 andreas 7080
    {
351 andreas 7081
#if TESTMODE == 1
7082
        setAllDone();
7083
#endif
7084
        return;
7085
    }
82 andreas 7086
 
351 andreas 7087
    vector<Button::TButton *>::iterator iter;
7088
 
7089
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7090
    {
7091
        Button::TButton *bt = *iter;
7092
 
110 andreas 7093
        if (btState == 0)       // All instances?
82 andreas 7094
        {
110 andreas 7095
            int bst = bt->getNumberInstances();
82 andreas 7096
 
110 andreas 7097
            for (int i = 0; i < bst; i++)
82 andreas 7098
            {
110 andreas 7099
                color = bt->getTextColor(i);
82 andreas 7100
 
110 andreas 7101
                if (color.empty())
7102
                    continue;
82 andreas 7103
 
300 andreas 7104
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7105
#if TESTMODE == 1
7106
                __success = true;
7107
 
7108
                if (_gTestMode)
7109
                    _gTestMode->setResult(color);
7110
#endif
83 andreas 7111
            }
82 andreas 7112
        }
110 andreas 7113
        else
7114
        {
7115
            color = bt->getTextColor(btState - 1);
351 andreas 7116
 
7117
            if (color.empty())
7118
                continue;
7119
 
300 andreas 7120
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7121
#if TESTMODE == 1
7122
            __success = true;
7123
 
7124
            if (_gTestMode)
7125
                _gTestMode->setResult(color);
7126
#endif
110 andreas 7127
        }
82 andreas 7128
    }
351 andreas 7129
#if TESTMODE == 1
7130
    setAllDone();
7131
#endif
82 andreas 7132
}
7133
 
60 andreas 7134
/**
7135
 * Set the button draw order
7136
 * Determines what order each layer of the button is drawn.
7137
 */
7138
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 7139
{
60 andreas 7140
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7141
 
60 andreas 7142
    if (pars.size() < 1)
7143
    {
7144
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7145
#if TESTMODE == 1
7146
        setAllDone();
7147
#endif
32 andreas 7148
        return;
60 andreas 7149
    }
32 andreas 7150
 
60 andreas 7151
    TError::clear();
7152
    int btState = atoi(pars[0].c_str());
7153
    string order;
32 andreas 7154
 
60 andreas 7155
    if (pars.size() > 1)
7156
    {
7157
        string ord = pars[1];
7158
        // Convert the numbers into the expected draw order
7159
        for (size_t i = 0; i < ord.length(); i++)
7160
        {
7161
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
7162
            {
7163
                char hv0[32];
7164
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
7165
                order.append(hv0);
7166
            }
7167
            else
7168
            {
7169
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
7170
                return;
7171
            }
7172
        }
7173
 
7174
        if (order.length() != 10)
7175
        {
7176
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
7177
            return;
7178
        }
7179
    }
7180
 
193 andreas 7181
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7182
 
7183
    if (TError::isError() || map.empty())
351 andreas 7184
    {
7185
#if TESTMODE == 1
7186
        setAllDone();
7187
#endif
32 andreas 7188
        return;
351 andreas 7189
    }
32 andreas 7190
 
60 andreas 7191
    vector<Button::TButton *> buttons = collectButtons(map);
7192
 
83 andreas 7193
    if (buttons.size() > 0)
32 andreas 7194
    {
83 andreas 7195
        vector<Button::TButton *>::iterator mapIter;
32 andreas 7196
 
83 andreas 7197
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7198
        {
83 andreas 7199
            Button::TButton *bt = *mapIter;
351 andreas 7200
            bt->setDrawOrder(order, btState - 1);
7201
#if TESTMODE == 1
7202
            if (_gTestMode)
7203
                _gTestMode->setResult(bt->getDrawOrder(btState == 0 ? 0 : btState - 1));
7204
#endif
60 andreas 7205
        }
7206
    }
351 andreas 7207
#if TESTMODE == 1
7208
    setDone();
7209
#endif
60 andreas 7210
}
32 andreas 7211
 
60 andreas 7212
/**
7213
 * Set the feedback type of the button.
7214
 * ONLY works on General-type buttons.
7215
 */
7216
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
7217
{
7218
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7219
 
60 andreas 7220
    if (pars.size() < 1)
7221
    {
7222
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7223
#if TESTMODE == 1
7224
        setAllDone();
7225
#endif
60 andreas 7226
        return;
7227
    }
7228
 
7229
    TError::clear();
7230
    Button::FEEDBACK type = Button::FB_NONE;
7231
    string stype = pars[0];
7232
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
7233
    vector<string>::iterator iter;
7234
    int i = 0;
7235
 
7236
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
7237
    {
7238
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 7239
        {
60 andreas 7240
            type = (Button::FEEDBACK)i;
7241
            break;
32 andreas 7242
        }
60 andreas 7243
 
7244
        i++;
32 andreas 7245
    }
7246
 
193 andreas 7247
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7248
 
7249
    if (TError::isError() || map.empty())
351 andreas 7250
    {
7251
#if TESTMODE == 1
7252
        setAllDone();
7253
#endif
60 andreas 7254
        return;
351 andreas 7255
    }
60 andreas 7256
 
7257
    vector<Button::TButton *> buttons = collectButtons(map);
7258
 
83 andreas 7259
    if (buttons.size() > 0)
60 andreas 7260
    {
83 andreas 7261
        vector<Button::TButton *>::iterator mapIter;
7262
 
7263
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7264
        {
7265
            Button::TButton *bt = *mapIter;
7266
            bt->setFeedback(type);
351 andreas 7267
#if TESTMODE == 1
7268
            if (_gTestMode)
7269
                _gTestMode->setResult(intToString(bt->getFeedback()));
7270
#endif
83 andreas 7271
        }
60 andreas 7272
    }
335 andreas 7273
#if TESTMODE == 1
7274
    setDone();
7275
#endif
32 andreas 7276
}
7277
 
224 andreas 7278
/*
7279
 * Set the input mask for the specified address.
7280
 */
7281
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
7282
{
7283
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
7284
 
7285
    if (pars.size() < 1)
7286
    {
7287
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7288
#if TESTMODE == 1
7289
        setAllDone();
7290
#endif
224 andreas 7291
        return;
7292
    }
7293
 
7294
    TError::clear();
7295
    string mask = pars[0];
7296
    vector<TMap::MAP_T> map = findButtons(port, channels);
7297
 
7298
    if (TError::isError() || map.empty())
351 andreas 7299
    {
7300
#if TESTMODE == 1
7301
        setAllDone();
7302
#endif
224 andreas 7303
        return;
351 andreas 7304
    }
224 andreas 7305
 
7306
    vector<Button::TButton *> buttons = collectButtons(map);
7307
 
7308
    if (buttons.size() > 0)
7309
    {
7310
        vector<Button::TButton *>::iterator mapIter;
7311
 
7312
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7313
        {
7314
            Button::TButton *bt = *mapIter;
7315
            bt->setInputMask(mask);
351 andreas 7316
#if TESTMODE == 1
7317
            if (_gTestMode)
7318
                _gTestMode->setResult(bt->getInputMask());
7319
#endif
224 andreas 7320
        }
7321
    }
351 andreas 7322
#if TESTMODE == 1
7323
    setDone();
7324
#endif
224 andreas 7325
}
7326
 
351 andreas 7327
/**
7328
 * @brief Button copy command.
7329
 * Copy attributes of the source button to all the
7330
 * destination buttons. Note that the source is a single button state. Each
7331
 * state must be copied as a separate command. The <codes> section represents
7332
 * what attributes will be copied. All codes are 2 char pairs that can be
7333
 * separated by comma, space, percent or just ran together.
7334
 */
106 andreas 7335
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
7336
{
7337
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
7338
 
7339
    if (pars.size() < 5)
7340
    {
7341
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
351 andreas 7342
#if TESTMODE == 1
7343
        setAllDone();
7344
#endif
106 andreas 7345
        return;
7346
    }
7347
 
7348
    TError::clear();
7349
    int btState = atoi(pars[0].c_str());
7350
    int src_port = atoi(pars[1].c_str());
7351
    int src_addr = atoi(pars[2].c_str());
7352
    int src_state = atoi(pars[3].c_str());
7353
    string src_codes = pars[4];
7354
    vector<int> src_channel;
7355
    src_channel.push_back(src_addr);
7356
 
193 andreas 7357
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 7358
 
7359
    if (src_map.size() == 0)
7360
    {
7361
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7362
#if TESTMODE == 1
7363
        setAllDone();
7364
#endif
106 andreas 7365
        return;
7366
    }
7367
 
7368
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
7369
 
7370
    if (src_buttons.size() == 0)
7371
    {
7372
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7373
#if TESTMODE == 1
7374
        setAllDone();
7375
#endif
106 andreas 7376
        return;
7377
    }
7378
 
7379
    if (src_buttons[0]->getNumberInstances() < src_state)
7380
    {
7381
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
351 andreas 7382
#if TESTMODE == 1
7383
        setAllDone();
7384
#endif
106 andreas 7385
        return;
7386
    }
7387
 
7388
    if (src_state < 1)
7389
    {
7390
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
351 andreas 7391
#if TESTMODE == 1
7392
        setAllDone();
7393
#endif
106 andreas 7394
        return;
7395
    }
7396
 
7397
    src_state--;
7398
 
7399
    if (btState > 0)
7400
        btState--;
7401
 
193 andreas 7402
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7403
    vector<Button::TButton *> buttons = collectButtons(map);
7404
    //                        0     1     2     3     4     5     6     7
7405
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
7406
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
7407
                            "VI", "WW" };   // 16, 17
7408
 
7409
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
7410
    {
7411
        vector<string>::iterator iter;
7412
        int idx = 0;
7413
 
7414
        for (iter = codes.begin(); iter != codes.end(); ++iter)
7415
        {
7416
            if (src_codes.find(*iter) != string::npos)
7417
            {
7418
                int j, x, y;
7419
 
7420
                switch(idx)
7421
                {
7422
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
7423
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
7424
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
7425
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
7426
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
7427
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
7428
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
7429
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 7430
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 7431
 
7432
                    case 9:
7433
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
7434
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
7435
                    break;
7436
 
7437
                    case 10:
7438
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
7439
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
7440
                    break;
7441
 
7442
                    case 11:
7443
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
7444
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
7445
                    break;
7446
 
7447
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
7448
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
7449
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
7450
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
7451
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
7452
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
7453
                }
7454
            }
7455
 
7456
            idx++;
7457
        }
7458
    }
7459
}
7460
 
149 andreas 7461
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
7462
{
7463
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
7464
 
7465
    if (pars.size() < 2)
332 andreas 7466
    {
7467
        MSG_ERROR("Less then 2 parameters!");
7468
#if TESTMODE == 1
334 andreas 7469
        setAllDone();
332 andreas 7470
#endif
149 andreas 7471
        return;
332 andreas 7472
    }
149 andreas 7473
 
7474
    TError::clear();
7475
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 7476
    string commands;
149 andreas 7477
 
150 andreas 7478
    for (size_t i = 1; i < pars.size(); ++i)
7479
    {
7480
        if (i > 1)
7481
            commands += ",";
7482
 
7483
        commands += pars[i];
7484
    }
7485
 
193 andreas 7486
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 7487
 
7488
    if (TError::isError() || map.empty())
332 andreas 7489
    {
7490
#if TESTMODE == 1
334 andreas 7491
        setAllDone();
332 andreas 7492
#endif
149 andreas 7493
        return;
332 andreas 7494
    }
149 andreas 7495
 
7496
    // Start of parsing the command line
162 andreas 7497
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 7498
    vector<string> parts = StrSplit(commands, "%");
7499
 
162 andreas 7500
    if (parts.empty())
332 andreas 7501
        parts.push_back(commands);
334 andreas 7502
 
149 andreas 7503
    // Search for all buttons who need to be updated
7504
    vector<Button::TButton *> buttons = collectButtons(map);
7505
 
7506
    if (buttons.size() > 0)
7507
    {
7508
        vector<Button::TButton *>::iterator mapIter;
7509
 
7510
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7511
        {
7512
            Button::TButton *bt = *mapIter;
162 andreas 7513
 
7514
            if (!bt)
7515
            {
7516
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
7517
                continue;
7518
            }
7519
 
149 andreas 7520
            // Iterate through commands and apply them to button
7521
            vector<string>::iterator iter;
7522
 
7523
            for (iter = parts.begin(); iter != parts.end(); ++iter)
7524
            {
7525
                char cmd = iter->at(0);
7526
                char cmd2;
7527
                string content;
7528
 
7529
                switch(cmd)
7530
                {
7531
                    case 'B':   // Border style
361 andreas 7532
                        if (iter->at(1) == ',')
7533
                            content = iter->substr(2);
7534
                        else
7535
                            content = iter->substr(1);
332 andreas 7536
 
7537
                        if (!content.empty() && isdigit(content[0]))
334 andreas 7538
                            bt->setBorderStyle(atoi(content.c_str()), btState);
332 andreas 7539
                        else
7540
                            bt->setBorderStyle(content, btState);
7541
#if TESTMODE == 1
7542
                        if (_gTestMode)
7543
                            _gTestMode->setResult(bt->getBorderStyle(btState < 0 ? 0 : btState));
7544
#endif
149 andreas 7545
                    break;
7546
 
7547
                    case 'C':   // Colors
7548
                        cmd2 = iter->at(1);
7549
                        content = iter->substr(2);
7550
 
7551
                        switch(cmd2)
7552
                        {
7553
                            case 'B':   // Border color
7554
                                bt->setBorderColor(content, btState);
332 andreas 7555
#if TESTMODE == 1
7556
                                if (_gTestMode)
7557
                                    _gTestMode->setResult(bt->getBorderColor(btState < 0 ? 0 : btState));
7558
#endif
149 andreas 7559
                            break;
7560
 
7561
                            case 'F':   // Fill color
7562
                                bt->setFillColor(content, btState);
332 andreas 7563
#if TESTMODE == 1
7564
                                if (_gTestMode)
7565
                                    _gTestMode->setResult(bt->getFillColor(btState < 0 ? 0 : btState));
7566
#endif
149 andreas 7567
                            break;
7568
 
7569
                            case 'T':   // Text color
7570
                                bt->setTextColor(content, btState);
332 andreas 7571
#if TESTMODE == 1
7572
                                if (_gTestMode)
7573
                                    _gTestMode->setResult(bt->getTextColor(btState < 0 ? 0 : btState));
7574
#endif
149 andreas 7575
                            break;
7576
                        }
7577
                    break;
7578
 
150 andreas 7579
                    case 'D':   // Draw order
7580
                        cmd2 = iter->at(1);
7581
                        content = iter->substr(2);
7582
 
7583
                        if (cmd2 == 'O')
332 andreas 7584
                        {
150 andreas 7585
                            bt->setDrawOrder(content, btState);
332 andreas 7586
#if TESTMODE == 1
7587
                            if (_gTestMode)
7588
                                _gTestMode->setResult(bt->getDrawOrder(btState < 0 ? 0 : btState));
7589
#endif
7590
                        }
150 andreas 7591
                    break;
7592
 
149 andreas 7593
                    case 'E':   // Text effect
7594
                        cmd2 = iter->at(1);
7595
                        content = iter->substr(2);
7596
 
7597
                        switch(cmd2)
7598
                        {
7599
                            case 'C':   // Text effect color
7600
                                bt->setTextEffectColor(content, btState);
332 andreas 7601
#if TESTMODE == 1
7602
                                if (_gTestMode)
7603
                                    _gTestMode->setResult(bt->getTextEffectColor(btState < 0 ? 0 : btState));
7604
#endif
149 andreas 7605
                            break;
7606
 
7607
                            case 'F':   // Text effect name
7608
                                bt->setTextEffectName(content, btState);
332 andreas 7609
#if TESTMODE == 1
7610
                                if (_gTestMode)
7611
                                    _gTestMode->setResult(bt->getTextEffectName(btState < 0 ? 0 : btState));
7612
#endif
149 andreas 7613
                            break;
7614
 
7615
                            case 'N':   // Enable/disable button
7616
                                bt->setEnable((content[0] == '1' ? true : false));
332 andreas 7617
#if TESTMODE == 1
7618
                                if (_gTestMode)
334 andreas 7619
                                {
332 andreas 7620
                                    _gTestMode->setResult(bt->isEnabled() ? "TRUE" : "FALSE");
334 andreas 7621
                                    __success = true;
7622
                                    setScreenDone();
7623
                                }
332 andreas 7624
#endif
149 andreas 7625
                            break;
7626
                        }
7627
                    break;
7628
 
7629
                    case 'F':   // Set font file name
361 andreas 7630
                        if (iter->at(1) == ',')
7631
                            content = iter->substr(2);
7632
                        else
7633
                            content = iter->substr(1);
150 andreas 7634
 
7635
                        if (!isdigit(content[0]))
334 andreas 7636
                            bt->setFontName(content, btState);
150 andreas 7637
                        else
7638
                            bt->setFontIndex(atoi(content.c_str()), btState);
334 andreas 7639
#if TESTMODE == 1
7640
                        if (_gTestMode)
7641
                            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
7642
#endif
149 andreas 7643
                    break;
7644
 
7645
                    case 'G':   // Bargraphs
7646
                        cmd2 = iter->at(1);
7647
                        content = iter->substr(2);
7648
 
7649
                        switch(cmd2)
7650
                        {
7651
                            case 'C':   // Bargraph slider color
7652
                                bt->setBargraphSliderColor(content);
7653
                            break;
7654
 
7655
                            case 'D':   // Ramp down time
7656
                                // FIXME: Add function to set ramp time
7657
                            break;
7658
 
7659
                            case 'G':   // Drag increment
7660
                                // FIXME: Add function to set drag increment
7661
                            break;
7662
 
7663
                            case 'H':   // Upper limit
7664
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
7665
                            break;
7666
 
7667
                            case 'I':   // Invert/noninvert
7668
                                // FIXME: Add function to set inverting
7669
                            break;
7670
 
7671
                            case 'L':   // Lower limit
7672
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
7673
                            break;
7674
 
7675
                            case 'N':   // Slider name
361 andreas 7676
                                bt->setBargraphSliderName(content);
149 andreas 7677
                            break;
7678
 
7679
                            case 'R':   // Repeat interval
7680
                                // FIXME: Add function to set repeat interval
7681
                            break;
7682
 
7683
                            case 'U':   // Ramp up time
7684
                                // FIXME: Add function to set ramp up time
7685
                            break;
7686
 
7687
                            case 'V':   // Bargraph value
7688
                                // FIXME: Add function to set level value
7689
                            break;
7690
                        }
7691
                    break;
7692
 
152 andreas 7693
                    case 'I':   // Set the icon
7694
                        content = iter->substr(1);
7695
                        bt->setIcon(atoi(content.c_str()), btState);
332 andreas 7696
#if TESTMODE == 1
7697
                        if (_gTestMode)
7698
                            _gTestMode->setResult(intToString(bt->getIconIndex()));
7699
#endif
152 andreas 7700
                    break;
7701
 
149 andreas 7702
                    case 'J':   // Set text justification
150 andreas 7703
                        cmd2 = iter->at(1);
7704
 
361 andreas 7705
                        if (cmd2 == ',')
150 andreas 7706
                        {
7707
                            content = iter->substr(1);
152 andreas 7708
                            int just = atoi(content.c_str());
7709
                            int x = 0, y = 0;
7710
 
7711
                            if (just == 0)
7712
                            {
7713
                                vector<string> coords = StrSplit(content, ",");
7714
 
7715
                                if (coords.size() >= 3)
7716
                                {
7717
                                    x = atoi(coords[1].c_str());
7718
                                    y = atoi(coords[2].c_str());
7719
                                }
7720
                            }
7721
 
7722
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7723
#if TESTMODE == 1
7724
                            if (_gTestMode)
7725
                            {
7726
                                just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7727
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7728
                                _gTestMode->setResult(s);
7729
                            }
7730
#endif
150 andreas 7731
                        }
361 andreas 7732
                        else if (cmd2 == 'T' || cmd2 == 'B' || cmd2 == 'I')
150 andreas 7733
                        {
7734
                            content = iter->substr(2);
152 andreas 7735
                            int x = 0, y = 0;
7736
                            int just = atoi(content.c_str());
150 andreas 7737
 
152 andreas 7738
                            if (just == 0)
7739
                            {
7740
                                vector<string> coords = StrSplit(content, ",");
7741
 
7742
                                if (coords.size() >= 3)
7743
                                {
7744
                                    x = atoi(coords[1].c_str());
7745
                                    y = atoi(coords[2].c_str());
7746
                                }
7747
                            }
7748
 
150 andreas 7749
                            switch(cmd2)
7750
                            {
7751
                                case 'B':   // Alignment of bitmap
152 andreas 7752
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7753
#if TESTMODE == 1
7754
                                    just = bt->getBitmapJustification(&x, &y, btState < 0 ? 0 : btState);
7755
#endif
150 andreas 7756
                                break;
7757
 
7758
                                case 'I':   // Alignment of icon
152 andreas 7759
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7760
#if TESTMODE == 1
7761
                                    just = bt->getIconJustification(&x, &y, btState < 0 ? 0 : btState);
7762
#endif
150 andreas 7763
                                break;
7764
 
7765
                                case 'T':   // Alignment of text
152 andreas 7766
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7767
#if TESTMODE == 1
7768
                                    just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7769
#endif
150 andreas 7770
                                break;
7771
                            }
334 andreas 7772
#if TESTMODE == 1
7773
                            if (_gTestMode)
7774
                            {
7775
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7776
                                _gTestMode->setResult(s);
7777
                            }
7778
#endif
150 andreas 7779
                        }
7780
                    break;
7781
 
7782
                    case 'M':   // Text area
7783
                        cmd2 = iter->at(1);
7784
                        content = iter->substr(2);
7785
 
7786
                        switch(cmd2)
7787
                        {
152 andreas 7788
                            case 'I':   // Set mask image
7789
                                // FIXME: Add code for image mask
7790
                            break;
7791
 
150 andreas 7792
                            case 'K':   // Input mask of text area
7793
                                // FIXME: Add input mask
7794
                            break;
7795
 
7796
                            case 'L':   // Maximum length of text area
7797
                                // FIXME: Add code to set maximum length
7798
                            break;
7799
                        }
7800
                    break;
7801
 
7802
                    case 'O':   // Set feedback typ, opacity
7803
                        cmd2 = iter->at(1);
7804
 
7805
                        switch(cmd2)
7806
                        {
7807
                            case 'P':   // Set opacity
7808
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
7809
                            break;
7810
 
7811
                            case 'T':   // Set feedback type
7812
                                content = iter->substr(2);
7813
                                content = toUpper(content);
7814
 
7815
                                if (content == "NONE")
7816
                                    bt->setFeedback(Button::FB_NONE);
7817
                                else if (content == "CHANNEL")
7818
                                    bt->setFeedback(Button::FB_CHANNEL);
7819
                                else if (content == "INVERT")
7820
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
7821
                                else if (content == "ON")
7822
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
7823
                                else if (content == "MOMENTARY")
7824
                                    bt->setFeedback(Button::FB_MOMENTARY);
7825
                                else if (content == "BLINK")
7826
                                    bt->setFeedback(Button::FB_BLINK);
7827
                                else
7828
                                {
7829
                                    MSG_WARNING("Unknown feedback type " << content);
7830
                                }
335 andreas 7831
#if TESTMODE == 1
7832
                                if (_gTestMode)
7833
                                    _gTestMode->setResult(intToString(bt->getFeedback()));
7834
#endif
150 andreas 7835
                            break;
7836
 
7837
                            default:
7838
                                content = iter->substr(1);
7839
                                // FIXME: Add code to set the feedback type
7840
                        }
7841
                    break;
7842
 
152 andreas 7843
                    case 'P':   // Set picture/bitmap file name
7844
                        content = iter->substr(1);
165 andreas 7845
 
7846
                        if (content.find(".") == string::npos)  // If the image has no extension ...
7847
                        {                                       // we must find the image in the map
7848
                            string iname = findImage(content);
7849
 
7850
                            if (!iname.empty())
7851
                                content = iname;
7852
                        }
7853
 
152 andreas 7854
                        bt->setBitmap(content, btState);
7855
                    break;
7856
 
7857
                    case 'R':   // Set rectangle
7858
                    {
7859
                        content = iter->substr(1);
7860
                        vector<string> corners = StrSplit(content, ",");
7861
 
7862
                        if (corners.size() > 0)
7863
                        {
7864
                            vector<string>::iterator itcorn;
7865
                            int pos = 0;
7866
                            int left, top, right, bottom;
7867
                            left = top = right = bottom = 0;
7868
 
7869
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
7870
                            {
7871
                                switch(pos)
7872
                                {
7873
                                    case 0: left   = atoi(itcorn->c_str()); break;
7874
                                    case 1: top    = atoi(itcorn->c_str()); break;
7875
                                    case 2: right  = atoi(itcorn->c_str()); break;
7876
                                    case 3: bottom = atoi(itcorn->c_str()); break;
7877
                                }
7878
 
7879
                                pos++;
7880
                            }
7881
 
7882
                            if (pos >= 4)
334 andreas 7883
                            {
152 andreas 7884
                                bt->setRectangle(left, top, right, bottom);
334 andreas 7885
                                bt->refresh();
7886
                            }
152 andreas 7887
                        }
334 andreas 7888
#if TESTMODE == 1
7889
                        if (_gTestMode)
7890
                        {
7891
                            int left, top, width, height;
7892
                            bt->getRectangle(&left, &top, &height, &width);
7893
                            string res(intToString(left) + "," + intToString(top) + "," + intToString(width) + "," + intToString(height));
7894
                            _gTestMode->setResult(res);
7895
                        }
7896
#endif
152 andreas 7897
                    }
7898
                    break;
7899
 
150 andreas 7900
                    case 'S':   // show/hide, style, sound
7901
                        cmd2 = iter->at(1);
7902
                        content = iter->substr(2);
7903
 
7904
                        switch(cmd2)
7905
                        {
7906
                            case 'F':   // Set focus of text area button
7907
                                // FIXME: Add code to set the focus of text area button
7908
                            break;
7909
 
7910
                            case 'M':   // Submit text
169 andreas 7911
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
7912
                                {
7913
                                    size_t pos = 0;
7914
 
7915
                                    while ((pos = content.find("|")) != string::npos)
7916
                                        content = content.replace(pos, 1, "\n");
7917
                                }
7918
 
150 andreas 7919
                                bt->setText(content, btState);
7920
                            break;
7921
 
7922
                            case 'O':   // Sound
7923
                                bt->setSound(content, btState);
335 andreas 7924
#if TESTMODE == 1
7925
                                if (_gTestMode)
7926
                                    _gTestMode->setResult(bt->getSound(btState < 0 ? 0 : btState));
7927
#endif
150 andreas 7928
                            break;
7929
 
7930
                            case 'T':   // Button style
7931
                                // FIXME: Add code to set the button style
7932
                            break;
7933
 
7934
                            case 'W':   // Show / hide button
7935
                                if (content[0] == '0')
334 andreas 7936
                                    bt->hide(true);
150 andreas 7937
                                else
7938
                                    bt->show();
334 andreas 7939
#if TESTMODE == 1
7940
                                if (_gTestMode)
7941
                                    _gTestMode->setResult(bt->isVisible() ? "TRUE" : "FALSE");
7942
#endif
150 andreas 7943
                            break;
7944
                        }
7945
                    break;
7946
 
152 andreas 7947
                    case 'T':   // Set text
7948
                        content = iter->substr(1);
169 andreas 7949
 
7950
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
7951
                        {
7952
                            size_t pos = 0;
7953
 
7954
                            while ((pos = content.find("|")) != string::npos)
7955
                                content = content.replace(pos, 1, "\n");
7956
                        }
7957
 
152 andreas 7958
                        bt->setText(content, btState);
334 andreas 7959
#if TESTMODE == 1
7960
                        if (_gTestMode)
7961
                            _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
7962
#endif
152 andreas 7963
                    break;
7964
 
150 andreas 7965
                    case 'U':   // Set the unicode text
7966
                        if (iter->at(1) == 'N')
7967
                        {
7968
                            content = iter->substr(2);
152 andreas 7969
                            string byte, text;
7970
                            size_t pos = 0;
7971
 
7972
                            while (pos < content.length())
7973
                            {
7974
                                byte = content.substr(pos, 2);
7975
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
7976
                                text += ch;
7977
                                pos += 2;
7978
                            }
7979
 
169 andreas 7980
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
7981
                            {
7982
                                size_t pos = 0;
7983
 
7984
                                while ((pos = text.find("|")) != string::npos)
7985
                                    text = text.replace(pos, 1, "\n");
7986
                            }
7987
 
152 andreas 7988
                            bt->setText(text, btState);
150 andreas 7989
                        }
7990
                    break;
7991
 
7992
                    case 'V':   // Video on / off
7993
                        cmd2 = iter->at(1);
7994
                        // Controlling a computer remotely is not supported.
7995
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
7996
                        {
7997
                            content = iter->substr(2);
7998
                            // FIXME: Add code to switch video on or off
7999
                        }
8000
                    break;
8001
 
8002
                    case 'W':   // Word wrap
152 andreas 8003
                        if (iter->at(1) == 'W')
8004
                        {
8005
                            content = iter->substr(2);
8006
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
8007
                        }
149 andreas 8008
                    break;
8009
                }
8010
            }
8011
        }
8012
    }
332 andreas 8013
#if TESTMODE == 1
334 andreas 8014
    setDone();
332 andreas 8015
#endif
149 andreas 8016
}
8017
 
14 andreas 8018
/**
110 andreas 8019
 * Set the maximum length of the text area button. If this value is set to
8020
 * zero (0), the text area has no max length. The maximum length available is
8021
 * 2000. This is only for a Text area input button and not for a Text area input
8022
 * masking button.
8023
 */
8024
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
8025
{
8026
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
8027
 
8028
    if (pars.size() < 1)
8029
    {
8030
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8031
        return;
8032
    }
8033
 
8034
    TError::clear();
8035
    int maxLen = atoi(pars[0].c_str());
8036
 
8037
    if (maxLen < 0 || maxLen > 2000)
8038
    {
8039
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
8040
        return;
8041
    }
8042
 
193 andreas 8043
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8044
 
8045
    if (TError::isError() || map.empty())
8046
        return;
8047
 
8048
    vector<Button::TButton *> buttons = collectButtons(map);
8049
 
8050
    if (buttons.size() > 0)
8051
    {
8052
        vector<Button::TButton *>::iterator mapIter;
8053
 
8054
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8055
        {
8056
            Button::TButton *bt = *mapIter;
8057
            bt->setTextMaxChars(maxLen);
8058
        }
8059
    }
8060
}
8061
 
8062
/**
60 andreas 8063
 * Assign a picture to those buttons with a defined address range.
8064
 */
8065
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
8066
{
8067
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
8068
 
8069
    if (pars.size() < 2)
8070
    {
8071
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8072
        return;
8073
    }
8074
 
8075
    TError::clear();
8076
    int btState = atoi(pars[0].c_str());
8077
    string bitmap = pars[1];
104 andreas 8078
    // If this is a G5 command, we may have up to 2 additional parameters.
8079
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 8080
 
104 andreas 8081
    if (pars.size() > 2)
8082
    {
8083
        slot = atoi(pars[2].c_str());
8084
 
8085
        if (pars.size() >= 4)
8086
        {
8087
            justify = atoi(pars[4].c_str());
8088
 
8089
            if (justify == 0)
8090
            {
8091
                if (pars.size() >= 5)
8092
                    jx = atoi(pars[5].c_str());
8093
 
8094
                if (pars.size() >= 6)
8095
                    jy = atoi(pars[6].c_str());
8096
            }
8097
        }
8098
    }
8099
 
193 andreas 8100
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8101
 
8102
    if (TError::isError() || map.empty())
8103
        return;
8104
 
8105
    vector<Button::TButton *> buttons = collectButtons(map);
8106
 
83 andreas 8107
    if (buttons.size() > 0)
60 andreas 8108
    {
83 andreas 8109
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8110
 
83 andreas 8111
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8112
        {
83 andreas 8113
            Button::TButton *bt = *mapIter;
252 andreas 8114
//            setButtonCallbacks(bt);
60 andreas 8115
 
83 andreas 8116
            if (btState == 0)       // All instances?
8117
            {
8118
                int bst = bt->getNumberInstances();
96 andreas 8119
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 8120
 
8121
                for (int i = 0; i < bst; i++)
104 andreas 8122
                {
8123
                    if (justify >= 0)
8124
                    {
8125
                        if (slot == 2)
8126
                            bt->setIconJustification(justify, jx, jy, i);
8127
                        else
106 andreas 8128
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 8129
                    }
8130
 
8131
                    if (slot >= 0)
8132
                    {
8133
                        switch(slot)
8134
                        {
8135
                            case 0: bt->setCameleon(bitmap, i); break;
8136
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8137
                            default:
8138
                                bt->setBitmap(bitmap, i);
8139
                        }
8140
                    }
8141
                    else
8142
                        bt->setBitmap(bitmap, i);
8143
                }
83 andreas 8144
            }
8145
            else
104 andreas 8146
            {
8147
                if (justify >= 0)
8148
                {
8149
                    if (slot == 2)
8150
                        bt->setIconJustification(justify, jx, jy, btState);
8151
                    else
106 andreas 8152
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 8153
                }
8154
 
8155
                if (slot >= 0)
8156
                {
8157
                    switch(slot)
8158
                    {
8159
                        case 0: bt->setCameleon(bitmap, btState); break;
8160
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8161
                        default:
8162
                            bt->setBitmap(bitmap, btState);
8163
                    }
8164
                }
8165
                else
8166
                    bt->setBitmap(bitmap, btState);
8167
            }
60 andreas 8168
        }
8169
    }
8170
}
8171
 
82 andreas 8172
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
8173
{
8174
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
8175
 
8176
    if (pars.size() < 1)
8177
    {
8178
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8179
        return;
8180
    }
8181
 
8182
    TError::clear();
8183
    int btState = atoi(pars[0].c_str());
8184
    string bmp;
8185
 
193 andreas 8186
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 8187
 
8188
    if (TError::isError() || map.empty())
8189
        return;
8190
 
8191
    vector<Button::TButton *> buttons = collectButtons(map);
8192
 
83 andreas 8193
    if (buttons.size() > 0)
82 andreas 8194
    {
110 andreas 8195
        Button::TButton *bt = buttons[0];
82 andreas 8196
 
110 andreas 8197
        if (btState == 0)       // All instances?
82 andreas 8198
        {
110 andreas 8199
            int bst = bt->getNumberInstances();
82 andreas 8200
 
110 andreas 8201
            for (int i = 0; i < bst; i++)
82 andreas 8202
            {
110 andreas 8203
                bmp = bt->getBitmapName(i);
82 andreas 8204
 
110 andreas 8205
                if (bmp.empty())
8206
                    continue;
82 andreas 8207
 
300 andreas 8208
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 8209
            }
82 andreas 8210
        }
110 andreas 8211
        else
8212
        {
8213
            bmp = bt->getTextColor(btState-1);
300 andreas 8214
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8215
        }
82 andreas 8216
    }
8217
}
8218
 
60 andreas 8219
/**
16 andreas 8220
 * Set the button opacity. The button opacity can be specified as a decimal
8221
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
8222
 * HEX code, as used in the color commands by preceding the HEX code with
8223
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
8224
 * If the opacity is set to zero (0), this does not make the button inactive,
8225
 * only invisible.
8226
 */
8227
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
8228
{
8229
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
8230
 
8231
    if (pars.size() < 2)
8232
    {
8233
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
335 andreas 8234
#if TESTMODE == 1
8235
        setAllDone();
8236
#endif
16 andreas 8237
        return;
8238
    }
8239
 
8240
    TError::clear();
335 andreas 8241
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 8242
    int btOpacity = 0;
8243
 
8244
    if (pars[1].at(0) == '#')
8245
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
8246
    else
8247
        btOpacity = atoi(pars[1].c_str());
8248
 
193 andreas 8249
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8250
 
8251
    if (TError::isError() || map.empty())
335 andreas 8252
    {
8253
#if TESTMODE == 1
8254
        setAllDone();
8255
#endif
16 andreas 8256
        return;
335 andreas 8257
    }
16 andreas 8258
 
8259
    vector<Button::TButton *> buttons = collectButtons(map);
8260
 
83 andreas 8261
    if (buttons.size() > 0)
16 andreas 8262
    {
83 andreas 8263
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8264
 
83 andreas 8265
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8266
        {
83 andreas 8267
            Button::TButton *bt = *mapIter;
335 andreas 8268
            bt->setOpacity(btOpacity, btState);
8269
#if TESTMODE == 1
8270
            if (_gTestMode)
8271
                _gTestMode->setResult(intToString(bt->getOpacity(btState < 0 ? 0 : btState)));
342 andreas 8272
#endif
16 andreas 8273
        }
8274
    }
335 andreas 8275
#if TESTMODE == 1
8276
    setDone();
8277
#endif
16 andreas 8278
}
8279
 
106 andreas 8280
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
8281
{
8282
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
8283
 
8284
    if (pars.size() < 1)
8285
    {
8286
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8287
        return;
8288
    }
8289
 
8290
    TError::clear();
8291
    int btState = atoi(pars[0].c_str());
8292
 
193 andreas 8293
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 8294
 
8295
    if (TError::isError() || map.empty())
8296
        return;
8297
 
8298
    vector<Button::TButton *> buttons = collectButtons(map);
8299
 
8300
    if (buttons.size() > 0)
8301
    {
110 andreas 8302
        Button::TButton *bt = buttons[0];
106 andreas 8303
 
110 andreas 8304
        if (btState == 0)       // All instances?
106 andreas 8305
        {
110 andreas 8306
            int bst = bt->getNumberInstances();
106 andreas 8307
 
110 andreas 8308
            for (int i = 0; i < bst; i++)
106 andreas 8309
            {
110 andreas 8310
                int oo = bt->getOpacity(i);
8311
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 8312
            }
8313
        }
110 andreas 8314
        else
8315
        {
8316
            int oo = bt->getOpacity(btState-1);
8317
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
8318
        }
106 andreas 8319
    }
8320
}
8321
 
60 andreas 8322
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
8323
{
8324
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
8325
 
8326
    if (pars.size() < 1)
8327
    {
8328
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
335 andreas 8329
#if TESTMODE == 1
8330
        setAllDone();
8331
#endif
60 andreas 8332
        return;
8333
    }
8334
 
8335
    TError::clear();
8336
    // Numbers of styles from 0 to 41
8337
    string bor = pars[0];
8338
    string border = "None";
8339
    int ibor = -1;
336 andreas 8340
    Border::TIntBorder borders;
60 andreas 8341
 
8342
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
336 andreas 8343
    {
60 andreas 8344
        ibor = atoi(bor.c_str());
8345
 
336 andreas 8346
        if (ibor >= 0 && ibor <= 41)
8347
            border = borders.getTP4BorderName(ibor);
8348
        else
60 andreas 8349
        {
336 andreas 8350
            MSG_WARNING("Invalid border style ID " << ibor);
8351
#if TESTMODE == 1
8352
            setAllDone();
8353
#endif
8354
            return;
8355
        }
60 andreas 8356
 
336 andreas 8357
        MSG_DEBUG("Id " << ibor << " is border " << border);
60 andreas 8358
    }
336 andreas 8359
    else
60 andreas 8360
    {
336 andreas 8361
        if (!borders.isTP4BorderValid(bor))
8362
        {
8363
            MSG_WARNING("Unknown border style " << bor);
335 andreas 8364
#if TESTMODE == 1
336 andreas 8365
            setAllDone();
335 andreas 8366
#endif
336 andreas 8367
            return;
8368
        }
60 andreas 8369
 
336 andreas 8370
        border = bor;
60 andreas 8371
    }
8372
 
193 andreas 8373
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8374
 
8375
    if (TError::isError() || map.empty())
335 andreas 8376
    {
8377
#if TESTMODE == 1
8378
        setAllDone();
8379
#endif
60 andreas 8380
        return;
335 andreas 8381
    }
60 andreas 8382
 
8383
    vector<Button::TButton *> buttons = collectButtons(map);
8384
 
83 andreas 8385
    if (buttons.size() > 0)
60 andreas 8386
    {
83 andreas 8387
        vector<Button::TButton *>::iterator mapIter;
8388
 
8389
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8390
        {
8391
            Button::TButton *bt = *mapIter;
8392
            bt->setBorderStyle(border);
335 andreas 8393
#if TESTMODE == 1
8394
            if (_gTestMode)
8395
                _gTestMode->setResult(bt->getBorderStyle(0));
8396
#endif
83 andreas 8397
        }
60 andreas 8398
    }
335 andreas 8399
#if TESTMODE == 1
8400
    setDone();
8401
#endif
60 andreas 8402
}
8403
 
107 andreas 8404
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
8405
{
8406
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
8407
 
8408
    if (pars.size() < 2)
8409
    {
8410
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
8411
        return;
8412
    }
8413
 
8414
    TError::clear();
8415
    int btState = atoi(pars[0].c_str());
8416
    int videoState = atoi(pars[1].c_str());
8417
 
193 andreas 8418
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8419
 
8420
    if (TError::isError() || map.empty())
8421
        return;
8422
 
8423
    vector<Button::TButton *> buttons = collectButtons(map);
8424
 
8425
    if (buttons.size() > 0)
8426
    {
8427
        vector<Button::TButton *>::iterator mapIter;
8428
 
8429
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8430
        {
8431
            Button::TButton *bt = *mapIter;
8432
 
8433
            if (btState == 0)       // All instances?
8434
                bt->setDynamic(videoState);
8435
            else
8436
                bt->setDynamic(videoState, btState-1);
8437
        }
8438
    }
8439
}
8440
 
16 andreas 8441
/**
60 andreas 8442
 * Set the border of a button state/states.
8443
 * The border names are available through the TPDesign4 border-name drop-down
8444
 * list.
8445
 */
8446
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
8447
{
8448
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
8449
 
8450
    if (pars.size() < 1)
8451
    {
8452
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8453
        return;
8454
    }
8455
 
8456
    TError::clear();
8457
    int btState = atoi(pars[0].c_str());
8458
    string border = "None";
8459
 
8460
    if (pars.size() > 1)
8461
        border = pars[1];
8462
 
193 andreas 8463
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8464
 
8465
    if (TError::isError() || map.empty())
8466
        return;
8467
 
8468
    vector<Button::TButton *> buttons = collectButtons(map);
8469
 
83 andreas 8470
    if (buttons.size() > 0)
60 andreas 8471
    {
83 andreas 8472
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8473
 
83 andreas 8474
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8475
        {
83 andreas 8476
            Button::TButton *bt = *mapIter;
252 andreas 8477
//            setButtonCallbacks(bt);
60 andreas 8478
 
83 andreas 8479
            if (btState == 0)       // All instances?
8480
            {
8481
                int bst = bt->getNumberInstances();
8482
 
8483
                for (int i = 0; i < bst; i++)
106 andreas 8484
                    bt->setBorderStyle(border, i+1);
83 andreas 8485
            }
8486
            else
106 andreas 8487
                bt->setBorderStyle(border, btState);
60 andreas 8488
        }
8489
    }
8490
}
8491
 
107 andreas 8492
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
8493
{
8494
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
8495
 
8496
    if (pars.size() < 1)
8497
    {
8498
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8499
        return;
8500
    }
8501
 
8502
    TError::clear();
8503
    int btState = atoi(pars[0].c_str());
8504
 
193 andreas 8505
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8506
 
8507
    if (TError::isError() || map.empty())
8508
        return;
8509
 
8510
    vector<Button::TButton *> buttons = collectButtons(map);
8511
 
8512
    if (buttons.size() > 0)
8513
    {
110 andreas 8514
        Button::TButton *bt = buttons[0];
107 andreas 8515
 
110 andreas 8516
        if (btState == 0)       // All instances?
107 andreas 8517
        {
110 andreas 8518
            int bst = bt->getNumberInstances();
107 andreas 8519
 
110 andreas 8520
            for (int i = 0; i < bst; i++)
107 andreas 8521
            {
110 andreas 8522
                string bname = bt->getBorderStyle(i);
300 andreas 8523
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 8524
            }
8525
        }
110 andreas 8526
        else
8527
        {
8528
            string bname = bt->getBorderStyle(btState-1);
300 andreas 8529
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8530
        }
107 andreas 8531
    }
8532
}
8533
 
60 andreas 8534
/**
16 andreas 8535
 * Set the button size and its position on the page.
8536
 */
8537
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
8538
{
8539
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
8540
 
8541
    if (pars.size() < 1)
8542
    {
8543
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
341 andreas 8544
#if TESTMODE == 1
8545
        setAllDone();
8546
#endif
16 andreas 8547
        return;
8548
    }
8549
 
8550
    TError::clear();
8551
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
8552
    int x, y;
8553
 
83 andreas 8554
    if (pars.size() > 0)
16 andreas 8555
    {
83 andreas 8556
        vector<string>::iterator iter;
8557
 
8558
        for (iter = pars.begin(); iter != pars.end(); iter++)
8559
        {
8560
            if (iter->compare("left") == 0)
8561
                bLeft = true;
8562
            else if (iter->compare("top") == 0)
8563
                bTop = true;
8564
            else if (iter->compare("right") == 0)
8565
                bRight = true;
8566
            else if (iter->compare("bottom") == 0)
8567
                bBottom = true;
8568
        }
16 andreas 8569
    }
8570
 
193 andreas 8571
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8572
 
8573
    if (TError::isError() || map.empty())
8574
        return;
8575
 
8576
    vector<Button::TButton *> buttons = collectButtons(map);
8577
 
83 andreas 8578
    if (buttons.size() > 0)
16 andreas 8579
    {
83 andreas 8580
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8581
 
83 andreas 8582
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8583
        {
8584
            Button::TButton *bt = *mapIter;
341 andreas 8585
//            setButtonCallbacks(bt);
16 andreas 8586
 
83 andreas 8587
            if (bLeft)
8588
                x = 0;
16 andreas 8589
 
83 andreas 8590
            if (bTop)
8591
                y = 0;
16 andreas 8592
 
341 andreas 8593
            if (bRight || bBottom)
16 andreas 8594
            {
83 andreas 8595
                ulong handle = bt->getHandle();
8596
                int parentID = (handle >> 16) & 0x0000ffff;
8597
                int pwidth = 0;
341 andreas 8598
                int pheight = 0;
16 andreas 8599
 
83 andreas 8600
                if (parentID < 500)
16 andreas 8601
                {
83 andreas 8602
                    TPage *pg = getPage(parentID);
8603
 
8604
                    if (!pg)
8605
                    {
8606
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
8607
                        return;
8608
                    }
8609
 
8610
                    pwidth = pg->getWidth();
341 andreas 8611
                    pheight = pg->getHeight();
16 andreas 8612
                }
83 andreas 8613
                else
8614
                {
8615
                    TSubPage *spg = getSubPage(parentID);
16 andreas 8616
 
83 andreas 8617
                    if (!spg)
8618
                    {
8619
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
8620
                        return;
8621
                    }
16 andreas 8622
 
83 andreas 8623
                    pwidth = spg->getWidth();
341 andreas 8624
                    pheight = spg->getHeight();
16 andreas 8625
                }
8626
 
341 andreas 8627
                if (bRight)
8628
                    x = pwidth - bt->getWidth();
8629
 
8630
                if (bBottom)
8631
                    y = pheight - bt->getHeight();
16 andreas 8632
            }
8633
 
341 andreas 8634
            bt->setLeftTop(x, y);
8635
#if TESTMODE == 1
8636
            if (_gTestMode)
83 andreas 8637
            {
341 andreas 8638
                int left = bt->getLeftPosition();
8639
                int top = bt->getTopPosition();
8640
                string res = intToString(left) + "," + intToString(top);
8641
                _gTestMode->setResult(res);
16 andreas 8642
            }
341 andreas 8643
#endif
16 andreas 8644
        }
8645
    }
341 andreas 8646
#if TESTMODE == 1
8647
    setDone();
8648
#endif
16 andreas 8649
}
8650
 
8651
/**
107 andreas 8652
 * Submit text for text area buttons. This command causes the text areas to
8653
 * send their text as strings to the NetLinx Master.
8654
 */
8655
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
8656
{
8657
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
8658
 
8659
    TError::clear();
193 andreas 8660
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8661
 
8662
    if (TError::isError() || map.empty())
341 andreas 8663
    {
8664
#if TESTMODE == 1
8665
        setAllDone();
8666
#endif
107 andreas 8667
        return;
341 andreas 8668
    }
107 andreas 8669
 
8670
    vector<Button::TButton *> buttons = collectButtons(map);
8671
 
8672
    if (buttons.size() > 0)
8673
    {
8674
        vector<Button::TButton *>::iterator mapIter;
8675
 
8676
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8677
        {
8678
            Button::TButton *bt = *mapIter;
8679
 
195 andreas 8680
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
341 andreas 8681
            {
8682
#if TESTMODE == 1
8683
                setAllDone();
8684
#endif
107 andreas 8685
                return;
341 andreas 8686
            }
107 andreas 8687
 
8688
            amx::ANET_SEND scmd;
8689
            scmd.port = bt->getChannelPort();
8690
            scmd.channel = bt->getChannelNumber();
8691
            scmd.ID = scmd.channel;
8692
            scmd.msg = bt->getText(0);
8693
            scmd.MC = 0x008b;       // string value
8694
 
8695
            if (gAmxNet)
8696
                gAmxNet->sendCommand(scmd);
8697
            else
8698
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
8699
 
8700
        }
8701
    }
8702
}
8703
 
8704
/**
8705
 * Set the sound played when a button is pressed. If the sound name is blank
8706
 * the sound is then cleared. If the sound name is not matched, the button
8707
 * sound is not changed.
8708
 */
8709
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
8710
{
8711
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
8712
 
8713
    if (pars.size() < 2)
8714
    {
8715
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8716
        return;
8717
    }
8718
 
8719
    if (!gPrjResources)
8720
        return;
8721
 
8722
    TError::clear();
8723
    int btState = atoi(pars[0].c_str());
8724
    string sound = pars[1];
8725
 
8726
    if (!soundExist(sound))
8727
        return;
8728
 
193 andreas 8729
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8730
 
8731
    if (TError::isError() || map.empty())
8732
        return;
8733
 
8734
    vector<Button::TButton *> buttons = collectButtons(map);
8735
 
8736
    if (buttons.size() > 0)
8737
    {
8738
        vector<Button::TButton *>::iterator mapIter;
8739
 
8740
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8741
        {
8742
            Button::TButton *bt = *mapIter;
8743
 
8744
            if (btState == 0)
8745
            {
8746
                int bst = bt->getNumberInstances();
8747
 
8748
                for (int i = 0; i < bst; i++)
8749
                    bt->setSound(sound, i);
8750
            }
8751
            else
8752
                bt->setSound(sound, btState-1);
8753
        }
8754
    }
8755
}
8756
 
8757
/**
16 andreas 8758
 * Set the button word wrap feature to those buttons with a defined address
8759
 * range. By default, word-wrap is Off.
8760
 */
8761
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
8762
{
8763
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
8764
 
8765
    if (pars.size() < 1)
8766
    {
8767
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8768
        return;
8769
    }
8770
 
8771
    TError::clear();
8772
    int btState = atoi(pars[0].c_str());
8773
 
193 andreas 8774
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8775
 
8776
    if (TError::isError() || map.empty())
8777
        return;
8778
 
8779
    vector<Button::TButton *> buttons = collectButtons(map);
8780
 
83 andreas 8781
    if (buttons.size() > 0)
16 andreas 8782
    {
83 andreas 8783
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8784
 
83 andreas 8785
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8786
        {
83 andreas 8787
            Button::TButton *bt = *mapIter;
252 andreas 8788
//            setButtonCallbacks(bt);
16 andreas 8789
 
83 andreas 8790
            if (btState == 0)       // All instances?
8791
            {
8792
                int bst = bt->getNumberInstances();
8793
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
8794
 
8795
                for (int i = 0; i < bst; i++)
110 andreas 8796
                    bt->setTextWordWrap(true, i);
83 andreas 8797
            }
8798
            else
110 andreas 8799
                bt->setTextWordWrap(true, btState - 1);
16 andreas 8800
        }
8801
    }
8802
}
8803
 
108 andreas 8804
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
8805
{
8806
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
8807
 
8808
    if (pars.size() < 1)
8809
    {
8810
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8811
        return;
8812
    }
8813
 
8814
    TError::clear();
8815
    int btState = atoi(pars[0].c_str());
8816
 
193 andreas 8817
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8818
 
8819
    if (TError::isError() || map.empty())
8820
        return;
8821
 
8822
    vector<Button::TButton *> buttons = collectButtons(map);
8823
 
8824
    if (buttons.size() > 0)
8825
    {
110 andreas 8826
        Button::TButton *bt = buttons[0];
108 andreas 8827
 
110 andreas 8828
        if (btState == 0)       // All instances?
108 andreas 8829
        {
110 andreas 8830
            int bst = bt->getNumberInstances();
108 andreas 8831
 
110 andreas 8832
            for (int i = 0; i < bst; i++)
8833
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8834
        }
110 andreas 8835
        else
8836
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8837
    }
8838
}
8839
 
16 andreas 8840
/**
8841
 * Clear all page flips from a button.
8842
 */
22 andreas 8843
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 8844
{
8845
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
8846
 
8847
    TError::clear();
193 andreas 8848
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8849
 
8850
    if (TError::isError() || map.empty())
8851
        return;
8852
 
8853
    vector<Button::TButton *> buttons = collectButtons(map);
8854
 
83 andreas 8855
    if (buttons.size() > 0)
16 andreas 8856
    {
83 andreas 8857
        vector<Button::TButton *>::iterator mapIter;
8858
 
8859
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8860
        {
8861
            Button::TButton *bt = *mapIter;
252 andreas 8862
//            setButtonCallbacks(bt);
83 andreas 8863
            bt->clearPushFunctions();
8864
        }
16 andreas 8865
    }
8866
}
8867
 
8868
/**
8869
 * Delete page flips from button if it already exists.
8870
 */
8871
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
8872
{
8873
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
8874
 
8875
    if (pars.size() < 1)
8876
    {
8877
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8878
        return;
8879
    }
8880
 
8881
    TError::clear();
8882
    string action = pars[0];
8883
    string pname;
8884
 
8885
    if (pars.size() >= 2)
8886
    {
8887
        pname = pars[1];
8888
        vector<Button::TButton *> list;
8889
        // First we search for a subpage because this is more likely
8890
        TSubPage *spg = getSubPage(pname);
8891
 
8892
        if (spg)
8893
            list = spg->getButtons(port, channels[0]);
8894
        else    // Then for a page
8895
        {
8896
            TPage *pg = getPage(pname);
8897
 
8898
            if (pg)
8899
                list = pg->getButtons(port, channels[0]);
8900
            else
8901
            {
8902
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
8903
                return;
8904
            }
8905
        }
8906
 
8907
        if (list.empty())
8908
            return;
8909
 
8910
        vector<Button::TButton *>::iterator it;
8911
 
8912
        for (it = list.begin(); it != list.end(); it++)
8913
        {
8914
            Button::TButton *bt = *it;
252 andreas 8915
//            setButtonCallbacks(bt);
16 andreas 8916
            bt->clearPushFunction(action);
8917
        }
8918
 
8919
        return;
8920
    }
8921
 
8922
    // Here we don't have a page name
193 andreas 8923
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8924
 
8925
    if (TError::isError() || map.empty())
8926
        return;
8927
 
8928
    vector<Button::TButton *> buttons = collectButtons(map);
8929
 
83 andreas 8930
    if (buttons.size() > 0)
16 andreas 8931
    {
83 andreas 8932
        vector<Button::TButton *>::iterator mapIter;
8933
 
8934
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8935
        {
8936
            Button::TButton *bt = *mapIter;
252 andreas 8937
//            setButtonCallbacks(bt);
83 andreas 8938
            bt->clearPushFunction(action);
8939
        }
16 andreas 8940
    }
8941
}
8942
 
8943
/**
8944
 * Enable or disable buttons with a set variable text range.
8945
 */
8946
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
8947
{
8948
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
8949
 
8950
    if (pars.empty())
8951
    {
8952
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
341 andreas 8953
#if TESTMODE == 1
8954
        setAllDone();
8955
#endif
16 andreas 8956
        return;
8957
    }
8958
 
8959
    TError::clear();
8960
    int cvalue = atoi(pars[0].c_str());
8961
 
193 andreas 8962
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8963
 
8964
    if (TError::isError() || map.empty())
341 andreas 8965
    {
8966
#if TESTMODE == 1
8967
        setAllDone();
8968
#endif
16 andreas 8969
        return;
341 andreas 8970
    }
16 andreas 8971
 
8972
    vector<Button::TButton *> buttons = collectButtons(map);
8973
 
83 andreas 8974
    if (buttons.size() > 0)
16 andreas 8975
    {
83 andreas 8976
        vector<Button::TButton *>::iterator mapIter;
8977
 
8978
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8979
        {
8980
            Button::TButton *bt = *mapIter;
8981
            bt->setEnable(((cvalue)?true:false));
341 andreas 8982
#if TESTMODE == 1
8983
            __success = true;
8984
 
8985
            if (_gTestMode)
8986
                _gTestMode->setResult(intToString(cvalue));
8987
#endif
83 andreas 8988
        }
16 andreas 8989
    }
341 andreas 8990
#if TESTMODE == 1
8991
    setAllDone();
8992
#endif
16 andreas 8993
}
8994
 
8995
/**
8996
 * Set a font to a specific Font ID value for those buttons with a defined
8997
 * address range. Font ID numbers are generated by the TPDesign4 programmers
8998
 * report.
8999
 */
9000
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
9001
{
9002
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
9003
 
9004
    if (pars.size() < 2)
9005
    {
9006
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
342 andreas 9007
#if TESTMODE == 1
9008
        setAllDone();
9009
#endif
16 andreas 9010
        return;
9011
    }
9012
 
9013
    TError::clear();
342 andreas 9014
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 9015
    int fvalue = atoi(pars[1].c_str());
9016
 
193 andreas 9017
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9018
 
9019
    if (TError::isError() || map.empty())
9020
        return;
9021
 
9022
    vector<Button::TButton *> buttons = collectButtons(map);
9023
 
83 andreas 9024
    if (buttons.size() > 0)
16 andreas 9025
    {
83 andreas 9026
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9027
 
83 andreas 9028
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9029
        {
83 andreas 9030
            Button::TButton *bt = *mapIter;
342 andreas 9031
            bt->setFont(fvalue, btState);
9032
#if TESTMODE == 1
9033
            if (_gTestMode)
9034
                _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9035
#endif
16 andreas 9036
        }
9037
    }
342 andreas 9038
#if TESTMODE == 1
9039
    setDone();
9040
#endif
16 andreas 9041
}
9042
 
108 andreas 9043
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
9044
{
9045
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
9046
 
9047
    if (pars.size() < 1)
9048
    {
9049
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
342 andreas 9050
#if TESTMODE == 1
9051
        setAllDone();
9052
#endif
108 andreas 9053
        return;
9054
    }
9055
 
9056
    TError::clear();
9057
    int btState = atoi(pars[0].c_str());
9058
 
193 andreas 9059
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9060
 
9061
    if (TError::isError() || map.empty())
342 andreas 9062
    {
9063
#if TESTMODE == 1
9064
        setAllDone();
9065
#endif
108 andreas 9066
        return;
342 andreas 9067
    }
108 andreas 9068
 
9069
    vector<Button::TButton *> buttons = collectButtons(map);
9070
 
9071
    if (buttons.size() > 0)
9072
    {
110 andreas 9073
        Button::TButton *bt = buttons[0];
108 andreas 9074
 
110 andreas 9075
        if (btState == 0)       // All instances?
108 andreas 9076
        {
110 andreas 9077
            int bst = bt->getNumberInstances();
108 andreas 9078
 
110 andreas 9079
            for (int i = 0; i < bst; i++)
9080
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9081
        }
110 andreas 9082
        else
9083
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
342 andreas 9084
#if TESTMODE == 1
9085
        if (_gTestMode)
9086
            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9087
#endif
108 andreas 9088
    }
342 andreas 9089
#if TESTMODE == 1
9090
    __success = true;
9091
    setAllDone();
9092
#endif
108 andreas 9093
}
9094
 
16 andreas 9095
/**
60 andreas 9096
 * Change the bargraph upper limit.
9097
 */
9098
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
9099
{
9100
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
9101
 
9102
    if (pars.size() < 1)
9103
    {
9104
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9105
        return;
9106
    }
9107
 
9108
    TError::clear();
9109
    int limit = atoi(pars[0].c_str());
9110
 
9111
    if (limit < 1)
9112
    {
9113
        MSG_ERROR("Invalid upper limit " << limit << "!");
9114
        return;
9115
    }
9116
 
193 andreas 9117
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9118
 
9119
    if (TError::isError() || map.empty())
9120
        return;
9121
 
9122
    vector<Button::TButton *> buttons = collectButtons(map);
9123
 
83 andreas 9124
    if (buttons.size() > 0)
60 andreas 9125
    {
83 andreas 9126
        vector<Button::TButton *>::iterator mapIter;
9127
 
9128
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9129
        {
9130
            Button::TButton *bt = *mapIter;
252 andreas 9131
//            setButtonCallbacks(bt);
83 andreas 9132
            bt->setBargraphUpperLimit(limit);
9133
        }
60 andreas 9134
    }
9135
}
9136
 
9137
/**
9138
 * Change the bargraph lower limit.
9139
 */
9140
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
9141
{
9142
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
9143
 
9144
    if (pars.size() < 1)
9145
    {
9146
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9147
        return;
9148
    }
9149
 
9150
    TError::clear();
9151
    int limit = atoi(pars[0].c_str());
9152
 
9153
    if (limit < 1)
9154
    {
9155
        MSG_ERROR("Invalid lower limit " << limit << "!");
9156
        return;
9157
    }
9158
 
193 andreas 9159
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9160
 
9161
    if (TError::isError() || map.empty())
9162
        return;
9163
 
9164
    vector<Button::TButton *> buttons = collectButtons(map);
9165
 
83 andreas 9166
    if (buttons.size() > 0)
60 andreas 9167
    {
83 andreas 9168
        vector<Button::TButton *>::iterator mapIter;
9169
 
9170
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9171
        {
9172
            Button::TButton *bt = *mapIter;
252 andreas 9173
//            setButtonCallbacks(bt);
83 andreas 9174
            bt->setBargraphLowerLimit(limit);
9175
        }
60 andreas 9176
    }
9177
}
9178
 
108 andreas 9179
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
9180
{
9181
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
9182
 
9183
    if (pars.size() < 1)
9184
    {
9185
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9186
        return;
9187
    }
9188
 
9189
    TError::clear();
9190
    string color = pars[0];
193 andreas 9191
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9192
 
9193
    if (TError::isError() || map.empty())
9194
        return;
9195
 
9196
    vector<Button::TButton *> buttons = collectButtons(map);
9197
 
9198
    if (buttons.size() > 0)
9199
    {
9200
        vector<Button::TButton *>::iterator mapIter;
9201
 
9202
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9203
        {
9204
            Button::TButton *bt = *mapIter;
9205
            bt->setBargraphSliderColor(color);
9206
        }
9207
    }
9208
}
9209
 
361 andreas 9210
/*
9211
 * Change the bargraph slider name or joystick cursor name.
9212
 */
9213
void TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)
9214
{
9215
    DECL_TRACER("TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)");
9216
 
9217
    if (pars.size() < 1)
9218
    {
9219
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9220
        return;
9221
    }
9222
 
9223
    TError::clear();
9224
    string name = pars[0];
9225
    vector<TMap::MAP_T> map = findButtons(port, channels);
9226
 
9227
    if (TError::isError() || map.empty())
9228
        return;
9229
 
9230
    vector<Button::TButton *> buttons = collectButtons(map);
9231
 
9232
    if (buttons.size() > 0)
9233
    {
9234
        vector<Button::TButton *>::iterator mapIter;
9235
 
9236
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9237
        {
9238
            Button::TButton *bt = *mapIter;
9239
            bt->setBargraphSliderName(name);
9240
        }
9241
    }
9242
}
9243
 
60 andreas 9244
/**
14 andreas 9245
 * Set the icon to a button.
9246
 */
9247
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
9248
{
9249
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
9250
 
9251
    if (pars.size() < 2)
9252
    {
9253
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9254
        return;
9255
    }
9256
 
16 andreas 9257
    TError::clear();
14 andreas 9258
    int btState = atoi(pars[0].c_str());
9259
    int iconIdx = atoi(pars[1].c_str());
9260
 
193 andreas 9261
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9262
 
9263
    if (TError::isError() || map.empty())
9264
        return;
9265
 
9266
    vector<Button::TButton *> buttons = collectButtons(map);
9267
 
83 andreas 9268
    if (buttons.size() > 0)
14 andreas 9269
    {
83 andreas 9270
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9271
 
83 andreas 9272
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 9273
        {
83 andreas 9274
            Button::TButton *bt = *mapIter;
14 andreas 9275
 
83 andreas 9276
            if (btState == 0)       // All instances?
14 andreas 9277
            {
316 andreas 9278
                if (iconIdx > 0)
9279
                    bt->setIcon(iconIdx, -1);
9280
                else
9281
                    bt->revokeIcon(-1);
14 andreas 9282
            }
83 andreas 9283
            else if (iconIdx > 0)
9284
                bt->setIcon(iconIdx, btState - 1);
9285
            else
9286
                bt->revokeIcon(btState - 1);
14 andreas 9287
        }
9288
    }
9289
}
9290
 
108 andreas 9291
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
9292
{
9293
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
9294
 
9295
    if (pars.size() < 1)
9296
    {
9297
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9298
        return;
9299
    }
9300
 
9301
    TError::clear();
9302
    int btState = atoi(pars[0].c_str());
9303
 
193 andreas 9304
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9305
 
9306
    if (TError::isError() || map.empty())
9307
        return;
9308
 
9309
    vector<Button::TButton *> buttons = collectButtons(map);
9310
 
9311
    if (buttons.size() > 0)
9312
    {
110 andreas 9313
        Button::TButton *bt = buttons[0];
108 andreas 9314
 
110 andreas 9315
        if (btState == 0)       // All instances?
108 andreas 9316
        {
110 andreas 9317
            int bst = bt->getNumberInstances();
108 andreas 9318
 
110 andreas 9319
            for (int i = 0; i < bst; i++)
9320
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9321
        }
110 andreas 9322
        else
9323
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9324
    }
9325
}
9326
 
14 andreas 9327
/**
108 andreas 9328
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
9329
 * with a defined address range. The alignment of 0 is followed by
9330
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
9331
 * corner of the button.
9332
 */
9333
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
9334
{
9335
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9336
 
9337
    if (pars.size() < 2)
9338
    {
9339
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9340
        return;
9341
    }
9342
 
9343
    TError::clear();
9344
    int btState = atoi(pars[0].c_str());
9345
    int align = atoi(pars[1].c_str());
9346
    int x = 0, y = 0;
9347
 
9348
    if (!align && pars.size() >= 3)
9349
    {
9350
        x = atoi(pars[2].c_str());
9351
 
9352
        if (pars.size() >= 4)
9353
            y = atoi(pars[3].c_str());
9354
    }
9355
 
193 andreas 9356
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9357
 
9358
    if (TError::isError() || map.empty())
9359
        return;
9360
 
9361
    vector<Button::TButton *> buttons = collectButtons(map);
9362
 
9363
    if (buttons.size() > 0)
9364
    {
9365
        vector<Button::TButton *>::iterator mapIter;
9366
 
9367
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9368
        {
9369
            Button::TButton *bt = *mapIter;
9370
 
9371
            if (btState == 0)
9372
                bt->setBitmapJustification(align, x, y, -1);
9373
            else
9374
                bt->setBitmapJustification(align, x, y, btState-1);
9375
        }
9376
    }
9377
}
9378
 
9379
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
9380
{
9381
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9382
 
9383
    if (pars.size() < 1)
9384
    {
9385
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9386
        return;
9387
    }
9388
 
9389
    TError::clear();
9390
    int btState = atoi(pars[0].c_str());
9391
    int j, x, y;
9392
 
193 andreas 9393
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9394
 
9395
    if (TError::isError() || map.empty())
9396
        return;
9397
 
9398
    vector<Button::TButton *> buttons = collectButtons(map);
9399
 
9400
    if (buttons.size() > 0)
9401
    {
110 andreas 9402
        Button::TButton *bt = buttons[0];
108 andreas 9403
 
110 andreas 9404
        if (btState == 0)       // All instances?
108 andreas 9405
        {
110 andreas 9406
            int bst = bt->getNumberInstances();
108 andreas 9407
 
110 andreas 9408
            for (int i = 0; i < bst; i++)
108 andreas 9409
            {
110 andreas 9410
                j = bt->getBitmapJustification(&x, &y, i);
9411
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9412
            }
9413
        }
110 andreas 9414
        else
9415
        {
9416
            j = bt->getBitmapJustification(&x, &y, btState-1);
9417
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
9418
        }
108 andreas 9419
    }
9420
}
9421
 
9422
/**
9423
 * Set icon alignment using a numeric keypad layout for those buttons with a
9424
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
9425
 * The left and top coordinates are relative to the upper left corner of the
9426
 * button.
9427
 */
9428
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
9429
{
9430
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9431
 
9432
    if (pars.size() < 2)
9433
    {
9434
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9435
        return;
9436
    }
9437
 
9438
    TError::clear();
9439
    int btState = atoi(pars[0].c_str());
9440
    int align = atoi(pars[1].c_str());
9441
    int x = 0, y = 0;
9442
 
9443
    if (!align && pars.size() >= 3)
9444
    {
9445
        x = atoi(pars[2].c_str());
9446
 
9447
        if (pars.size() >= 4)
9448
            y = atoi(pars[3].c_str());
9449
    }
9450
 
193 andreas 9451
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9452
 
9453
    if (TError::isError() || map.empty())
9454
        return;
9455
 
9456
    vector<Button::TButton *> buttons = collectButtons(map);
9457
 
9458
    if (buttons.size() > 0)
9459
    {
9460
        vector<Button::TButton *>::iterator mapIter;
9461
 
9462
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9463
        {
9464
            Button::TButton *bt = *mapIter;
9465
 
9466
            if (btState == 0)
9467
                bt->setIconJustification(align, x, y, -1);
9468
            else
9469
                bt->setIconJustification(align, x, y, btState-1);
9470
        }
9471
    }
9472
}
9473
 
9474
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
9475
{
9476
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9477
 
9478
    if (pars.size() < 1)
9479
    {
9480
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9481
        return;
9482
    }
9483
 
9484
    TError::clear();
9485
    int btState = atoi(pars[0].c_str());
9486
    int j, x, y;
9487
 
193 andreas 9488
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9489
 
9490
    if (TError::isError() || map.empty())
9491
        return;
9492
 
9493
    vector<Button::TButton *> buttons = collectButtons(map);
9494
 
9495
    if (buttons.size() > 0)
9496
    {
110 andreas 9497
        Button::TButton *bt = buttons[0];
108 andreas 9498
 
110 andreas 9499
        if (btState == 0)       // All instances?
108 andreas 9500
        {
110 andreas 9501
            int bst = bt->getNumberInstances();
108 andreas 9502
 
110 andreas 9503
            for (int i = 0; i < bst; i++)
108 andreas 9504
            {
110 andreas 9505
                j = bt->getIconJustification(&x, &y, i);
9506
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9507
            }
9508
        }
110 andreas 9509
        else
9510
        {
9511
            j = bt->getIconJustification(&x, &y, btState-1);
9512
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
9513
        }
108 andreas 9514
    }
9515
}
9516
 
9517
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
9518
{
9519
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9520
 
9521
    if (pars.size() < 2)
9522
    {
9523
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9524
        return;
9525
    }
9526
 
9527
    TError::clear();
9528
    int btState = atoi(pars[0].c_str());
9529
    int align = atoi(pars[1].c_str());
9530
    int x = 0, y = 0;
9531
 
9532
    if (!align && pars.size() >= 3)
9533
    {
9534
        x = atoi(pars[2].c_str());
9535
 
9536
        if (pars.size() >= 4)
9537
            y = atoi(pars[3].c_str());
9538
    }
9539
 
193 andreas 9540
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9541
 
9542
    if (TError::isError() || map.empty())
9543
        return;
9544
 
9545
    vector<Button::TButton *> buttons = collectButtons(map);
9546
 
9547
    if (buttons.size() > 0)
9548
    {
9549
        vector<Button::TButton *>::iterator mapIter;
9550
 
9551
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9552
        {
9553
            Button::TButton *bt = *mapIter;
9554
 
9555
            if (btState == 0)
9556
                bt->setTextJustification(align, x, y, -1);
9557
            else
9558
                bt->setTextJustification(align, x, y, btState-1);
9559
        }
9560
    }
9561
}
9562
 
9563
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
9564
{
9565
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9566
 
9567
    if (pars.size() < 1)
9568
    {
9569
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9570
        return;
9571
    }
9572
 
9573
    TError::clear();
9574
    int btState = atoi(pars[0].c_str());
9575
    int j, x, y;
9576
 
193 andreas 9577
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9578
 
9579
    if (TError::isError() || map.empty())
9580
        return;
9581
 
9582
    vector<Button::TButton *> buttons = collectButtons(map);
9583
 
9584
    if (buttons.size() > 0)
9585
    {
110 andreas 9586
        Button::TButton *bt = buttons[0];
108 andreas 9587
 
110 andreas 9588
        if (btState == 0)       // All instances?
108 andreas 9589
        {
110 andreas 9590
            int bst = bt->getNumberInstances();
108 andreas 9591
 
110 andreas 9592
            for (int i = 0; i < bst; i++)
108 andreas 9593
            {
110 andreas 9594
                j = bt->getTextJustification(&x, &y, i);
9595
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9596
            }
9597
        }
110 andreas 9598
        else
9599
        {
9600
            j = bt->getTextJustification(&x, &y, btState-1);
9601
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
9602
        }
108 andreas 9603
    }
9604
}
9605
 
9606
/**
16 andreas 9607
 * Show or hide a button with a set variable text range.
9608
 */
9609
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
9610
{
9611
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
9612
 
9613
    if (pars.empty())
9614
    {
9615
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
9616
        return;
9617
    }
9618
 
9619
    TError::clear();
9620
    int cvalue = atoi(pars[0].c_str());
9621
 
193 andreas 9622
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9623
 
9624
    if (TError::isError() || map.empty())
9625
        return;
9626
 
9627
    vector<Button::TButton *> buttons = collectButtons(map);
9628
 
83 andreas 9629
    if (buttons.size() > 0)
16 andreas 9630
    {
83 andreas 9631
        vector<Button::TButton *>::iterator mapIter;
9632
 
9633
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9634
        {
9635
            Button::TButton *bt = *mapIter;
318 andreas 9636
 
100 andreas 9637
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
9638
            bool pVisible = false;
9639
 
9640
            if (pgID < 500)
9641
            {
9642
                TPage *pg = getPage(pgID);
9643
 
9644
                if (pg && pg->isVisilble())
9645
                    pVisible = true;
9646
            }
9647
            else
9648
            {
9649
                TSubPage *pg = getSubPage(pgID);
9650
 
9651
                if (pg && pg->isVisible())
9652
                    pVisible = true;
9653
            }
9654
 
151 andreas 9655
            bool oldV = bt->isVisible();
9656
            bool visible = cvalue ? true : false;
9657
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 9658
 
151 andreas 9659
            if (visible != oldV)
100 andreas 9660
            {
151 andreas 9661
                bt->setVisible(visible);
100 andreas 9662
 
151 andreas 9663
                if (pVisible)
9664
                {
9665
                    setButtonCallbacks(bt);
9666
 
9667
                    if (_setVisible)
9668
                        _setVisible(bt->getHandle(), visible);
9669
                    else
9670
                        bt->refresh();
9671
                }
100 andreas 9672
            }
83 andreas 9673
        }
16 andreas 9674
    }
9675
}
9676
 
108 andreas 9677
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
9678
{
9679
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
9680
 
9681
    if (pars.size() < 2)
9682
    {
9683
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9684
        return;
9685
    }
9686
 
9687
    TError::clear();
9688
    int btState = atoi(pars[0].c_str());
9689
    string color = pars[1];
9690
 
193 andreas 9691
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9692
 
9693
    if (TError::isError() || map.empty())
9694
        return;
9695
 
9696
    vector<Button::TButton *> buttons = collectButtons(map);
9697
 
9698
    if (buttons.size() > 0)
9699
    {
9700
        vector<Button::TButton *>::iterator mapIter;
9701
 
9702
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9703
        {
9704
            Button::TButton *bt = *mapIter;
9705
 
9706
            if (btState == 0)
9707
                bt->setTextEffectColor(color);
9708
            else
9709
                bt->setTextEffectColor(color, btState-1);
9710
        }
9711
    }
9712
}
9713
 
9714
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
9715
{
9716
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
9717
 
9718
    if (pars.size() < 1)
9719
    {
9720
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9721
        return;
9722
    }
9723
 
9724
    TError::clear();
9725
    int btState = atoi(pars[0].c_str());
9726
 
193 andreas 9727
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9728
 
9729
    if (TError::isError() || map.empty())
9730
        return;
9731
 
9732
    vector<Button::TButton *> buttons = collectButtons(map);
9733
 
9734
    if (buttons.size() > 0)
9735
    {
110 andreas 9736
        Button::TButton *bt = buttons[0];
9737
 
9738
        if (btState == 0)       // All instances?
9739
        {
9740
            int bst = bt->getNumberInstances();
9741
 
9742
            for (int i = 0; i < bst; i++)
9743
            {
9744
                string c = bt->getTextEffectColor(i);
300 andreas 9745
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9746
            }
9747
        }
9748
        else
9749
        {
9750
            string c = bt->getTextEffectColor(btState-1);
300 andreas 9751
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9752
        }
9753
    }
9754
}
9755
 
9756
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
9757
{
9758
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
9759
 
9760
    if (pars.size() < 2)
9761
    {
9762
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9763
        return;
9764
    }
9765
 
9766
    TError::clear();
9767
    int btState = atoi(pars[0].c_str());
9768
    string tef = pars[1];
9769
 
193 andreas 9770
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9771
 
9772
    if (TError::isError() || map.empty())
9773
        return;
9774
 
9775
    vector<Button::TButton *> buttons = collectButtons(map);
9776
 
9777
    if (buttons.size() > 0)
9778
    {
108 andreas 9779
        vector<Button::TButton *>::iterator mapIter;
9780
 
9781
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9782
        {
9783
            Button::TButton *bt = *mapIter;
9784
 
110 andreas 9785
            if (btState == 0)
9786
                bt->setTextEffectName(tef);
9787
            else
9788
                bt->setTextEffectName(tef, btState-1);
9789
        }
9790
    }
9791
}
108 andreas 9792
 
110 andreas 9793
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
9794
{
9795
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 9796
 
110 andreas 9797
    if (pars.size() < 1)
9798
    {
9799
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9800
        return;
9801
    }
108 andreas 9802
 
110 andreas 9803
    TError::clear();
9804
    int btState = atoi(pars[0].c_str());
9805
 
193 andreas 9806
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9807
 
9808
    if (TError::isError() || map.empty())
9809
        return;
9810
 
9811
    vector<Button::TButton *> buttons = collectButtons(map);
9812
 
9813
    if (buttons.size() > 0)
9814
    {
9815
        Button::TButton *bt = buttons[0];
9816
 
9817
        if (btState == 0)       // All instances?
9818
        {
9819
            int bst = bt->getNumberInstances();
9820
 
9821
            for (int i = 0; i < bst; i++)
108 andreas 9822
            {
110 andreas 9823
                string c = bt->getTextEffectName(i);
300 andreas 9824
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9825
            }
9826
        }
110 andreas 9827
        else
9828
        {
9829
            string c = bt->getTextEffectName(btState-1);
300 andreas 9830
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9831
        }
108 andreas 9832
    }
9833
}
9834
 
16 andreas 9835
/**
14 andreas 9836
 * Assign a text string to those buttons with a defined address range.
9837
 * Sets Non-Unicode text.
9838
 */
9839
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
9840
{
9841
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
9842
 
9843
    if (pars.size() < 1)
9844
    {
9845
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 9846
#if TESTMODE == 1
334 andreas 9847
        setAllDone();
331 andreas 9848
#endif
14 andreas 9849
        return;
9850
    }
9851
 
16 andreas 9852
    TError::clear();
333 andreas 9853
    int btState = atoi(pars[0].c_str()) - 1;
14 andreas 9854
    string text;
9855
 
333 andreas 9856
    // Every comma (,) in the text produces a new parameter. Therefor we must
9857
    // concatenate this parameters together and insert the comma.
14 andreas 9858
    if (pars.size() > 1)
150 andreas 9859
    {
9860
        for (size_t i = 1; i < pars.size(); ++i)
9861
        {
9862
            if (i > 1)
9863
                text += ",";
14 andreas 9864
 
150 andreas 9865
            text += pars[i];
9866
        }
9867
    }
9868
 
193 andreas 9869
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9870
 
9871
    if (TError::isError() || map.empty())
331 andreas 9872
    {
9873
#if TESTMODE == 1
334 andreas 9874
        setAllDone();
331 andreas 9875
#endif
14 andreas 9876
        return;
331 andreas 9877
    }
14 andreas 9878
 
9879
    vector<Button::TButton *> buttons = collectButtons(map);
9880
 
83 andreas 9881
    if (buttons.size() > 0)
14 andreas 9882
    {
83 andreas 9883
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9884
 
333 andreas 9885
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
14 andreas 9886
        {
83 andreas 9887
            Button::TButton *bt = *mapIter;
14 andreas 9888
 
252 andreas 9889
            if (!bt)
333 andreas 9890
                continue;
252 andreas 9891
 
333 andreas 9892
            bt->setText(text, btState);
331 andreas 9893
#if TESTMODE == 1
333 andreas 9894
            if (_gTestMode)
9895
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 9896
 
333 andreas 9897
            __success = true;
331 andreas 9898
#endif
14 andreas 9899
        }
9900
    }
331 andreas 9901
#if TESTMODE == 1
334 andreas 9902
    setDone();
331 andreas 9903
#endif
14 andreas 9904
}
21 andreas 9905
 
110 andreas 9906
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
9907
{
9908
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
9909
 
9910
    if (pars.size() < 1)
9911
    {
9912
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9913
        return;
9914
    }
9915
 
9916
    TError::clear();
9917
    int btState = atoi(pars[0].c_str());
9918
 
193 andreas 9919
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9920
 
9921
    if (TError::isError() || map.empty())
9922
        return;
9923
 
9924
    vector<Button::TButton *> buttons = collectButtons(map);
9925
 
9926
    if (buttons.size() > 0)
9927
    {
9928
        Button::TButton *bt = buttons[0];
9929
 
9930
        if (btState == 0)       // All instances?
9931
        {
9932
            int bst = bt->getNumberInstances();
9933
 
9934
            for (int i = 0; i < bst; i++)
9935
            {
9936
                string c = bt->getText(i);
300 andreas 9937
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 9938
#if TESTMODE == 1
9939
                if (_gTestMode)
9940
                    _gTestMode->setResult(c);
9941
#endif
110 andreas 9942
            }
9943
        }
9944
        else
9945
        {
9946
            string c = bt->getText(btState-1);
300 andreas 9947
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 9948
#if TESTMODE == 1
9949
            if (_gTestMode)
9950
                _gTestMode->setResult(c);
9951
#endif
110 andreas 9952
        }
9953
    }
334 andreas 9954
#if TESTMODE == 1
9955
    setAllDone();
9956
#endif
110 andreas 9957
}
9958
 
97 andreas 9959
/*
104 andreas 9960
 * Set button state legacy unicode text command.
9961
 *
9962
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
9963
 * text is sent as ASCII-HEX nibbles.
9964
 */
9965
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
9966
{
9967
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
9968
 
9969
    if (pars.size() < 1)
9970
    {
9971
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 9972
#if TESTMODE == 1
334 andreas 9973
        setAllDone();
331 andreas 9974
#endif
104 andreas 9975
        return;
9976
    }
9977
 
9978
    TError::clear();
333 andreas 9979
    int btState = atoi(pars[0].c_str()) - 1;
104 andreas 9980
    string text;
9981
 
361 andreas 9982
    // Unicode is the stadard character set used by Windows internally. It
9983
    // consists of 16 bit unsiged numbers. This can't be transported into a
9984
    // standard character string because a NULL byte means end of string.
9985
    // Therefor we must convert it to UFT-8.
104 andreas 9986
    if (pars.size() > 1)
9987
    {
9988
        string byte;
361 andreas 9989
        std::wstring uni;
104 andreas 9990
        size_t pos = 0;
9991
 
9992
        while (pos < pars[1].length())
9993
        {
361 andreas 9994
            byte = pars[1].substr(pos, 4);
9995
            wchar_t ch = (char)strtol(byte.c_str(), NULL, 16);
9996
            uni += ch;
9997
            pos += 4;
104 andreas 9998
        }
361 andreas 9999
 
10000
        text = UnicodeToUTF8(uni);
104 andreas 10001
    }
10002
 
193 andreas 10003
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10004
 
10005
    if (TError::isError() || map.empty())
331 andreas 10006
    {
10007
#if TESTMODE == 1
334 andreas 10008
        setAllDone();
331 andreas 10009
#endif
104 andreas 10010
        return;
331 andreas 10011
    }
104 andreas 10012
 
10013
    vector<Button::TButton *> buttons = collectButtons(map);
10014
 
10015
    if (buttons.size() > 0)
10016
    {
10017
        vector<Button::TButton *>::iterator mapIter;
10018
 
10019
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10020
        {
10021
            Button::TButton *bt = *mapIter;
10022
 
331 andreas 10023
#if TESTMODE == 1
333 andreas 10024
            bool res = bt->setText(text, btState);
104 andreas 10025
 
333 andreas 10026
            if (_gTestMode)
10027
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10028
 
333 andreas 10029
            __success = res;
10030
#else
10031
            bt->setText(text, btState);
331 andreas 10032
#endif
104 andreas 10033
        }
10034
    }
334 andreas 10035
#if TESTMODE == 1
10036
    setDone();
10037
#endif
104 andreas 10038
}
10039
 
10040
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
10041
{
10042
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10043
 
10044
    if (pars.size() < 1)
10045
    {
10046
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
10047
        return;
10048
    }
10049
 
10050
    TError::clear();
10051
    int btState = atoi(pars[0].c_str());
10052
    string text;
10053
 
10054
    if (pars.size() > 1)
150 andreas 10055
    {
10056
        for (size_t i = 1; i < pars.size(); ++i)
10057
        {
10058
            if (i > 1)
10059
                text += ",";
104 andreas 10060
 
150 andreas 10061
            text += pars[i];
10062
        }
10063
    }
10064
 
193 andreas 10065
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10066
 
10067
    if (TError::isError() || map.empty())
10068
        return;
10069
 
10070
    vector<Button::TButton *> buttons = collectButtons(map);
10071
 
10072
    if (buttons.size() > 0)
10073
    {
10074
        vector<Button::TButton *>::iterator mapIter;
10075
 
10076
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10077
        {
10078
            Button::TButton *bt = *mapIter;
10079
 
10080
            if (btState == 0)       // All instances?
10081
            {
10082
                int bst = bt->getNumberInstances();
10083
 
10084
                for (int i = 0; i < bst; i++)
10085
                    bt->setText(text, i);
10086
            }
10087
            else
10088
                bt->setText(text, btState - 1);
10089
        }
10090
    }
10091
}
111 andreas 10092
 
361 andreas 10093
/**
10094
 * Simulates a touch/release/pulse at the given coordinate. If the push event
10095
 * is less then 0 or grater than 2 the command is ignored. It is also ignored
10096
 * if the x and y coordinate is out of range. The range must be between 0 and
10097
 * the maximum with and height.
10098
 */
148 andreas 10099
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
10100
{
10101
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
10102
 
10103
    if (pars.size() < 3)
10104
    {
10105
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
10106
        return;
10107
    }
10108
 
10109
    int pushType = atoi(pars[0].c_str());
10110
    int x = atoi(pars[1].c_str());
10111
    int y = atoi(pars[2].c_str());
10112
 
10113
    if (pushType < 0 || pushType > 2)
10114
    {
10115
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
10116
        return;
10117
    }
10118
 
217 andreas 10119
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 10120
    {
10121
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
10122
        return;
10123
    }
10124
 
10125
    if (pushType == 0 || pushType == 2)
10126
        mouseEvent(x, y, true);
10127
 
10128
    if (pushType == 1 || pushType == 2)
10129
        mouseEvent(x, y, false);
10130
}
10131
 
111 andreas 10132
/**
10133
 * Set the keyboard passthru.
10134
 */
10135
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
10136
{
10137
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
10138
 
10139
    if (pars.size() < 1)
10140
    {
10141
        MSG_ERROR("Got no parameter. Ignoring command!");
10142
        return;
10143
    }
10144
 
10145
    int state = atoi(pars[0].c_str());
10146
 
10147
    if (state == 0)
10148
        mPassThrough = false;
10149
    else if (state == 5)
10150
        mPassThrough = true;
10151
}
10152
 
10153
void TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)
10154
{
10155
    DECL_TRACER("TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)");
10156
 
10157
    if (pars.size() < 1)
10158
    {
10159
        MSG_ERROR("Got no parameter. Ignoring command!");
10160
        return;
10161
    }
10162
 
10163
    if (_sendVirtualKeys)
10164
        _sendVirtualKeys(pars[0]);
10165
}
10166
 
104 andreas 10167
/*
97 andreas 10168
 * Set the bitmap of a button to use a particular resource.
10169
 * Syntax:
10170
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
10171
 * Variable:
10172
 *    variable text address range = 1 - 4000.
10173
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
10174
 *    resource name = 1 - 50 ASCII characters.
10175
 * Example:
10176
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
10177
 *    Sets the resource name of the button to ’Sports_Image’.
10178
 */
21 andreas 10179
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
10180
{
10181
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
10182
 
10183
    if (pars.size() < 2)
10184
    {
10185
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10186
        return;
10187
    }
10188
 
10189
    TError::clear();
10190
    int btState = atoi(pars[0].c_str());
10191
    string resName = pars[1];
10192
 
193 andreas 10193
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 10194
 
10195
    if (TError::isError() || map.empty())
10196
        return;
10197
 
10198
    vector<Button::TButton *> buttons = collectButtons(map);
10199
 
83 andreas 10200
    if (buttons.size() > 0)
21 andreas 10201
    {
83 andreas 10202
        vector<Button::TButton *>::iterator mapIter;
21 andreas 10203
 
83 andreas 10204
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 10205
        {
83 andreas 10206
            Button::TButton *bt = *mapIter;
252 andreas 10207
//            setButtonCallbacks(bt);
21 andreas 10208
 
83 andreas 10209
            if (btState == 0)       // All instances?
10210
            {
10211
                int bst = bt->getNumberInstances();
10212
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
10213
 
10214
                for (int i = 0; i < bst; i++)
10215
                    bt->setResourceName(resName, i);
10216
            }
10217
            else
10218
                bt->setResourceName(resName, btState - 1);
97 andreas 10219
 
10220
            if (bt->isVisible())
10221
                bt->refresh();
99 andreas 10222
            else if (_setVisible)
10223
                _setVisible(bt->getHandle(), false);
21 andreas 10224
        }
10225
    }
10226
}
10227
 
97 andreas 10228
/*
10229
 * Add new resources
10230
 * Adds any and all resource parameters by sending embedded codes and data.
10231
 * Since the embedded codes are preceded by a '%' character, any '%' character
10232
 * contained in* the URL must be escaped with a second '%' character (see
10233
 * example).
10234
 * The file name field (indicated by a %F embedded code) may contain special
10235
 * escape sequences as shown in the ^RAF, ^RMF.
10236
 * Syntax:
10237
 *    "'^RAF-<resource name>,<data>'"
10238
 * Variables:
10239
 *    resource name = 1 - 50 ASCII characters.
10240
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
10241
 * Example:
10242
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
10243
 *    Adds a new resource.
10244
 *    The resource name is ’New Image’
10245
 *    %P (protocol) is an HTTP
10246
 *    %H (host name) is AMX.COM
10247
 *    %A (file path) is Lab/Test_f ile
10248
 *    %F (file name) is test.jpg.
10249
 *    Note that the %%5F in the file path is actually encoded as %5F.
10250
 */
10251
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
10252
{
10253
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
10254
 
10255
    if (pars.size() < 2)
10256
    {
10257
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10258
        return;
10259
    }
10260
 
10261
    string name = pars[0];
10262
    string data = pars[1];
10263
 
10264
    vector<string> parts = StrSplit(data, "%");
10265
    RESOURCE_T res;
10266
 
10267
    if (parts.size() > 0)
10268
    {
10269
        vector<string>::iterator sIter;
10270
 
10271
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
10272
        {
10273
            const char *s = sIter->c_str();
10274
            string ss = *sIter;
10275
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
10276
 
10277
            switch(*s)
10278
            {
10279
                case 'P':
10280
                    if (*(s+1) == '0')
10281
                        res.protocol = "HTTP";
10282
                    else
10283
                        res.protocol = "FTP";
10284
                    break;
10285
 
10286
                case 'U': res.user = sIter->substr(1); break;
10287
                case 'S': res.password = sIter->substr(1); break;
10288
                case 'H': res.host = sIter->substr(1); break;
10289
                case 'F': res.file = sIter->substr(1); break;
10290
                case 'A': res.path = sIter->substr(1); break;
10291
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10292
 
10293
                default:
10294
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10295
            }
10296
        }
10297
 
10298
        if (gPrjResources)
10299
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
10300
    }
10301
}
10302
 
111 andreas 10303
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 10304
{
10305
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
10306
 
10307
    if (pars.size() < 1)
10308
    {
10309
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10310
        return;
10311
    }
10312
 
10313
    string name = pars[0];
193 andreas 10314
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 10315
 
10316
    if (TError::isError() || map.empty())
10317
        return;
10318
 
10319
    vector<Button::TButton *> buttons = collectButtons(map);
10320
 
10321
    if (buttons.size() > 0)
10322
    {
10323
        vector<Button::TButton *>::iterator mapIter;
10324
 
10325
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10326
        {
10327
            Button::TButton *bt = *mapIter;
10328
 
10329
            if (bt->isVisible())
10330
            {
252 andreas 10331
//                setButtonCallbacks(bt);
97 andreas 10332
                bt->refresh();
10333
            }
10334
        }
10335
    }
10336
}
10337
 
10338
/*
10339
 * Modify an existing resource
10340
 *
10341
 * Modifies any and all resource parameters by sending embedded codes and data.
10342
 * Since the embedded codes are preceded by a '%' character, any '%' character
10343
 * contained in the URL must be escaped with a second '%' character (see
10344
 * example).
10345
 * The file name field (indicated by a %F embedded code) may contain special
10346
 * escape sequences as shown in the ^RAF.
10347
 *
10348
 * Syntax:
10349
 * "'^RMF-<resource name>,<data>'"
10350
 * Variables:
10351
 *   • resource name = 1 - 50 ASCII characters
10352
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
10353
 * Example:
10354
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
10355
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
10356
 * ’Lab_Test/Images’.
10357
 * Note that the %%5F in the file path is actually encoded as %5F.
10358
 */
22 andreas 10359
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 10360
{
10361
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
10362
 
10363
    if (pars.size() < 2)
10364
    {
10365
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10366
        return;
10367
    }
10368
 
10369
    string name = pars[0];
10370
    string data = pars[1];
10371
 
10372
    vector<string> parts = StrSplit(data, "%");
10373
    RESOURCE_T res;
10374
 
83 andreas 10375
    if (parts.size() > 0)
21 andreas 10376
    {
83 andreas 10377
        vector<string>::iterator sIter;
21 andreas 10378
 
83 andreas 10379
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 10380
        {
83 andreas 10381
            const char *s = sIter->c_str();
10382
            string ss = *sIter;
10383
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 10384
 
83 andreas 10385
            switch(*s)
10386
            {
10387
                case 'P':
10388
                    if (*(s+1) == '0')
10389
                        res.protocol = "HTTP";
10390
                    else
10391
                        res.protocol = "FTP";
10392
                break;
21 andreas 10393
 
83 andreas 10394
                case 'U': res.user = sIter->substr(1); break;
10395
                case 'S': res.password = sIter->substr(1); break;
10396
                case 'H': res.host = sIter->substr(1); break;
10397
                case 'F': res.file = sIter->substr(1); break;
10398
                case 'A': res.path = sIter->substr(1); break;
10399
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10400
 
10401
                default:
10402
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10403
            }
21 andreas 10404
        }
83 andreas 10405
 
10406
        if (gPrjResources)
10407
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 10408
    }
10409
}
62 andreas 10410
 
10411
/**
111 andreas 10412
 * Change the refresh rate for a given resource.
10413
 */
10414
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
10415
{
10416
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
10417
 
10418
    if (pars.size() < 2)
10419
    {
10420
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10421
        return;
10422
    }
10423
 
10424
    string resName = pars[0];
10425
    int resRefresh = atoi(pars[1].c_str());
10426
 
10427
    if (!gPrjResources)
10428
    {
10429
        MSG_ERROR("Missing the resource module. Ignoring command!");
10430
        return;
10431
    }
10432
 
10433
    RESOURCE_T res = gPrjResources->findResource(resName);
10434
 
10435
    if (res.name.empty() || res.refresh == resRefresh)
10436
        return;
10437
 
10438
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
10439
}
10440
 
10441
/**
62 andreas 10442
 * @brief TPageManager::doAKB - Pop up the keyboard icon
10443
 * Pop up the keyboard icon and initialize the text string to that specified.
10444
 * Keyboard string is set to null on power up and is stored until power is lost.
10445
 * The Prompt Text is optional.
10446
 */
10447
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
10448
{
10449
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
10450
 
10451
    if (pars.size() < 1)
10452
    {
10453
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10454
        return;
10455
    }
10456
 
10457
    string initText = pars[0];
10458
    string promptText;
10459
 
10460
    if (pars.size() > 1)
10461
        promptText = pars[1];
10462
 
63 andreas 10463
    if (initText.empty())
10464
        initText = mAkbText;
10465
    else
10466
        mAkbText = initText;
62 andreas 10467
 
10468
    if (_callKeyboard)
63 andreas 10469
        _callKeyboard(initText, promptText, false);
62 andreas 10470
}
10471
 
63 andreas 10472
/**
10473
 * Pop up the keyboard icon and initialize the text string to that
10474
 * specified.
10475
 */
62 andreas 10476
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
10477
{
10478
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
10479
 
10480
    doAKB(port, channels, pars);
10481
}
10482
 
63 andreas 10483
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10484
{
10485
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10486
 
10487
    doAKP(port, channels, pars);
10488
}
10489
 
62 andreas 10490
/**
63 andreas 10491
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10492
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10493
 */
10494
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
10495
{
10496
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
10497
 
10498
    if (_callResetKeyboard)
10499
        _callResetKeyboard();
10500
}
10501
 
10502
/**
62 andreas 10503
 * @brief TPageManager::doAKP - Pop up the keypad icon
10504
 * Pop up the keypad icon and initialize the text string to that specified.
10505
 * Keypad string is set to null on power up and is stored until power is lost.
10506
 * The Prompt Text is optional.
10507
 */
10508
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
10509
{
10510
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
10511
 
10512
    if (pars.size() < 1)
10513
    {
10514
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10515
        return;
10516
    }
10517
 
10518
    string initText = pars[0];
10519
    string promptText;
10520
 
10521
    if (pars.size() > 1)
10522
        promptText = pars[1];
10523
 
63 andreas 10524
    if (initText.empty())
10525
        initText = mAkpText;
10526
    else
10527
        mAkpText = initText;
62 andreas 10528
 
10529
    if (_callKeypad)
63 andreas 10530
        _callKeypad(initText, promptText, false);
62 andreas 10531
}
10532
 
63 andreas 10533
/**
10534
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10535
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10536
 */
10537
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 10538
{
63 andreas 10539
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 10540
 
63 andreas 10541
    doAKEYR(port, channels, pars);
62 andreas 10542
}
10543
 
108 andreas 10544
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
10545
{
10546
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10547
 
10548
    if (!_playSound)
334 andreas 10549
    {
10550
#if TESTMODE == 1
10551
        setAllDone();
10552
#endif
108 andreas 10553
        return;
334 andreas 10554
    }
108 andreas 10555
 
10556
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10557
    TValidateFile vf;
10558
 
326 andreas 10559
    if (vf.isValidFile(snd))
108 andreas 10560
        _playSound(snd);
326 andreas 10561
#if TESTMODE == 1
10562
    else
10563
    {
10564
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10565
        setAllDone();
326 andreas 10566
    }
10567
#endif
108 andreas 10568
}
10569
 
10570
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
10571
{
10572
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10573
 
10574
    if (!_playSound)
10575
        return;
10576
 
10577
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10578
    TValidateFile vf;
10579
 
326 andreas 10580
    if (vf.isValidFile(snd))
108 andreas 10581
        _playSound(snd);
326 andreas 10582
#if TESTMODE == 1
10583
    else
10584
    {
10585
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10586
        setAllDone();
326 andreas 10587
    }
10588
#endif
108 andreas 10589
}
10590
 
71 andreas 10591
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
10592
{
10593
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10594
 
10595
    if (!_playSound)
326 andreas 10596
    {
10597
#if TESTMODE == 1
10598
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
334 andreas 10599
        setAllDone();
326 andreas 10600
#endif
71 andreas 10601
        return;
326 andreas 10602
    }
71 andreas 10603
 
10604
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10605
    TValidateFile vf;
108 andreas 10606
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 10607
 
326 andreas 10608
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 10609
        _playSound(snd);
326 andreas 10610
#if TESTMODE == 1
10611
    else
10612
    {
10613
        if (!sysSound.getSystemSoundState())
10614
        {
10615
            MSG_PROTOCOL("Sound state disabled!")
10616
        }
10617
        else
10618
        {
10619
            MSG_PROTOCOL("Sound file invalid!");
10620
        }
10621
 
334 andreas 10622
        setAllDone();
326 andreas 10623
    }
10624
#endif
71 andreas 10625
}
10626
 
10627
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
10628
{
10629
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10630
 
10631
    if (!_playSound)
10632
        return;
10633
 
10634
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10635
    TValidateFile vf;
108 andreas 10636
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 10637
 
326 andreas 10638
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 10639
        _playSound(snd);
326 andreas 10640
#if TESTMODE == 1
10641
    else
10642
    {
10643
        if (!sysSound.getSystemSoundState())
10644
        {
10645
            MSG_PROTOCOL("Sound state disabled!")
10646
        }
10647
        else
10648
        {
10649
            MSG_PROTOCOL("Sound file invalid!");
10650
        }
10651
 
334 andreas 10652
        setAllDone();
326 andreas 10653
    }
10654
#endif
71 andreas 10655
}
10656
 
63 andreas 10657
/**
10658
 * @brief Pop up the keypad icon and initialize the text string to that specified.
10659
 * Keypad string is set to null on power up and is stored until power is lost.
10660
 * The Prompt Text is optional.
10661
 */
62 andreas 10662
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10663
{
10664
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10665
 
10666
    doAKP(port, channels, pars);
10667
}
63 andreas 10668
 
10669
/**
10670
 * @brief Present a private keyboard.
10671
 * Pops up the keyboard icon and initializes the text string to that specified.
10672
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
10673
 */
10674
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
10675
{
10676
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
10677
 
10678
    if (pars.size() < 1)
10679
    {
10680
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10681
        return;
10682
    }
10683
 
10684
    string initText = pars[0];
10685
    string promptText;
10686
 
10687
    if (pars.size() > 1)
10688
        promptText = pars[1];
10689
 
10690
    if (_callKeyboard)
10691
        _callKeyboard(initText, promptText, true);
10692
}
10693
 
10694
/**
10695
 * @brief Present a private keypad.
10696
 * Pops up the keypad icon and initializes the text string to that specified.
10697
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
10698
 */
10699
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
10700
{
10701
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
10702
 
10703
    if (pars.size() < 1)
10704
    {
10705
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10706
        return;
10707
    }
10708
 
10709
    string initText = pars[0];
10710
    string promptText;
10711
 
10712
    if (pars.size() > 1)
10713
        promptText = pars[1];
10714
 
10715
    if (_callKeypad)
10716
        _callKeypad(initText, promptText, true);
10717
}
10718
 
10719
/**
64 andreas 10720
 * Send panel to SETUP page.
10721
 */
10722
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
10723
{
10724
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
10725
 
10726
    if (_callShowSetup)
10727
        _callShowSetup();
10728
}
10729
 
10730
/**
10731
 * Shut down the App
10732
 */
10733
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
10734
{
10735
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
10736
 
97 andreas 10737
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 10738
#ifdef __ANDROID__
10739
    stopNetworkState();
10740
#endif
10741
    prg_stopped = true;
10742
    killed = true;
10743
 
10744
    if (_shutdown)
10745
        _shutdown();
10746
}
10747
 
82 andreas 10748
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
10749
{
10750
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
10751
 
10752
    if (pars.size() < 1)
10753
    {
10754
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
10755
        return;
10756
    }
10757
 
10758
    if (!_playSound)
10759
    {
10760
        MSG_ERROR("@SOU: Missing sound module!");
10761
        return;
10762
    }
10763
 
165 andreas 10764
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
10765
        return;
10766
 
82 andreas 10767
    _playSound(pars[0]);
10768
}
10769
 
326 andreas 10770
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
10771
{
10772
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
10773
 
10774
    if (pars.size() < 1)
10775
    {
10776
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
10777
        return;
10778
    }
10779
 
10780
    bool mute = 0;
10781
 
10782
    if (pars[0] == "0")
10783
        mute = false;
10784
    else
10785
        mute = true;
10786
 
10787
    TConfig::setMuteState(mute);
10788
#if TESTMODE == 1
327 andreas 10789
    if (_gTestMode)
10790
    {
10791
        bool st = TConfig::getMuteState();
10792
        _gTestMode->setResult(st ? "1" : "0");
10793
    }
10794
 
326 andreas 10795
    __success = true;
334 andreas 10796
    setAllDone();
326 andreas 10797
#endif
10798
}
10799
 
64 andreas 10800
/**
63 andreas 10801
 * @brief Present a telephone keypad.
10802
 * Pops up the keypad icon and initializes the text string to that specified.
10803
 * The Prompt Text is optional.
10804
 */
10805
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
10806
{
10807
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
10808
 
10809
    // TODO: Implement a real telefone keypad.
10810
    doAKP(port, channels, pars);
10811
}
10812
 
10813
/**
10814
 * Popup the virtual keyboard
10815
 */
123 andreas 10816
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 10817
{
123 andreas 10818
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 10819
 
10820
    doAKP(port, channels, pars);
10821
}
129 andreas 10822
#ifndef _NOSIP_
123 andreas 10823
void TPageManager::sendPHN(vector<string>& cmds)
10824
{
10825
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
10826
 
10827
    vector<int> channels;
10828
    doPHN(-1, channels, cmds);
10829
}
10830
 
141 andreas 10831
void TPageManager::actPHN(vector<string>& cmds)
10832
{
10833
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
10834
 
10835
    vector<int> channels;
10836
    doPHN(1, channels, cmds);
10837
}
10838
 
140 andreas 10839
void TPageManager::phonePickup(int id)
10840
{
10841
    DECL_TRACER("TPageManager::phonePickup(int id)");
10842
 
10843
    if (id < 0 || id >= 4)
10844
        return;
10845
 
10846
    if (mSIPClient)
10847
        mSIPClient->pickup(id);
10848
}
10849
 
10850
void TPageManager::phoneHangup(int id)
10851
{
10852
    DECL_TRACER("TPageManager::phoneHangup(int id)");
10853
 
10854
    if (id < 0 || id >= 4)
10855
        return;
10856
 
10857
    if (mSIPClient)
10858
        mSIPClient->terminate(id);
10859
}
10860
 
123 andreas 10861
/**
10862
 * @brief Phone commands.
10863
 * The phone commands could come from the master or are send to the master.
10864
 * If the parameter \p port is less then 0 (zero) a command is send to the
10865
 * master. In any other case the command came from the mater.
125 andreas 10866
 *
10867
 * @param port  This is used to signal if the command was sent by the master
10868
 *              or generated from the panel. If ths is less then 0, then the
10869
 *              method was called because of an event happen in the panel.
10870
 *              If this is grater or equal 0, then the event is comming from
10871
 *              the master.
10872
 * @param pars  This are parameters. The first parameter defines the action
10873
 *              to be done. According to the command this parameter may have a
10874
 *              different number of arguments.
123 andreas 10875
 */
10876
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
10877
{
10878
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
10879
 
10880
    if (pars.size() < 1)
10881
    {
10882
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
10883
        return;
10884
    }
10885
 
10886
    string sCommand;
10887
    string cmd = toUpper(pars[0]);
10888
 
10889
    // Master to panel
10890
    if (port >= 0)
10891
    {
10892
        if (!mSIPClient)
10893
        {
10894
            MSG_ERROR("SIP client class was not initialized!")
10895
            return;
10896
        }
10897
 
10898
        if (cmd == "ANSWER")
10899
        {
10900
            if (pars.size() >= 2)
10901
            {
124 andreas 10902
                int id = atoi(pars[1].c_str());
10903
 
10904
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
10905
                    mSIPClient->resume(id);
10906
                else
135 andreas 10907
                    mSIPClient->pickup(id);
123 andreas 10908
            }
10909
        }
10910
        else if (cmd == "AUTOANSWER")
10911
        {
10912
            if (pars.size() >= 2)
10913
            {
10914
                if (pars[1].at(0) == '0')
10915
                    mPHNautoanswer = false;
10916
                else
10917
                    mPHNautoanswer = true;
127 andreas 10918
 
10919
                vector<string> cmds;
10920
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 10921
                sendPHN(cmds);
123 andreas 10922
            }
10923
        }
10924
        else if (cmd == "CALL")     // Initiate a call
10925
        {
10926
            if (pars.size() >= 2)
127 andreas 10927
                mSIPClient->call(pars[1]);
123 andreas 10928
        }
10929
        else if (cmd == "DTMF")     // Send tone modified codes
10930
        {
127 andreas 10931
            if (pars.size() >= 2)
10932
                mSIPClient->sendDTMF(pars[1]);
123 andreas 10933
        }
10934
        else if (cmd == "HANGUP")   // terminate a call
10935
        {
124 andreas 10936
            if (pars.size() >= 2)
10937
            {
10938
                int id = atoi(pars[1].c_str());
10939
                mSIPClient->terminate(id);
10940
            }
123 andreas 10941
        }
10942
        else if (cmd == "HOLD")     // Hold the line
10943
        {
124 andreas 10944
            if (pars.size() >= 2)
10945
            {
10946
                int id = atoi(pars[1].c_str());
10947
                mSIPClient->hold(id);
10948
            }
123 andreas 10949
        }
128 andreas 10950
        else if (cmd == "LINESTATE") // State of all line
127 andreas 10951
        {
128 andreas 10952
            mSIPClient->sendLinestate();
127 andreas 10953
        }
123 andreas 10954
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
10955
        {
128 andreas 10956
            if (pars.size() >= 2)
10957
            {
10958
                bool state = (pars[1].at(0) == '1' ? true : false);
10959
                mSIPClient->sendPrivate(state);
10960
            }
123 andreas 10961
        }
10962
        else if (cmd == "REDIAL")   // Redials the last number
10963
        {
128 andreas 10964
            mSIPClient->redial();
123 andreas 10965
        }
10966
        else if (cmd == "TRANSFER") // Transfer call to provided number
10967
        {
128 andreas 10968
            if (pars.size() >= 3)
10969
            {
10970
                int id = atoi(pars[1].c_str());
10971
                string num = pars[2];
10972
 
10973
                if (mSIPClient->transfer(id, num))
10974
                {
10975
                    vector<string> cmds;
10976
                    cmds.push_back("TRANSFERRED");
10977
                    sendPHN(cmds);
10978
                }
10979
            }
123 andreas 10980
        }
144 andreas 10981
        else if (cmd == "IM")
10982
        {
10983
            if (pars.size() < 3)
10984
                return;
10985
 
10986
            string to = pars[1];
10987
            string msg = pars[2];
10988
            string toUri;
10989
 
10990
            if (to.find("sip:") == string::npos)
10991
                toUri = "sip:";
10992
 
10993
            toUri += to;
10994
 
10995
            if (to.find("@") == string::npos)
10996
                toUri += "@" + TConfig::getSIPproxy();
10997
 
10998
            mSIPClient->sendIM(toUri, msg);
10999
        }
123 andreas 11000
        else if (cmd == "SETUP")    // Some temporary settings
11001
        {
11002
            if (pars.size() < 2)
11003
                return;
11004
 
11005
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
11006
                TConfig::setSIPdomain(pars[2]);
11007
            else if (pars[1] == "DTMFDURATION")
11008
            {
138 andreas 11009
                unsigned int ms = atoi(pars[2].c_str());
11010
                mSIPClient->setDTMFduration(ms);
123 andreas 11011
            }
11012
            else if (pars[1] == "ENABLE")   // (re)register user
11013
            {
11014
                TConfig::setSIPstatus(true);
127 andreas 11015
                mSIPClient->cleanUp();
135 andreas 11016
                mSIPClient->init();
123 andreas 11017
            }
127 andreas 11018
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
11019
                TConfig::setSIPdomain(pars[2]);
123 andreas 11020
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
11021
                TConfig::setSIPpassword(pars[2]);
11022
            else if (pars[1] == "PORT" && pars.size() != 3)
11023
                TConfig::setSIPport(atoi(pars[2].c_str()));
11024
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
11025
                TConfig::setSIPproxy(pars[2]);
11026
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
11027
                TConfig::setSIPstun(pars[2]);
11028
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
11029
                TConfig::setSIPuser(pars[2]);
11030
        }
11031
        else
11032
        {
11033
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
11034
        }
11035
    }
11036
    else   // Panel to master
11037
    {
11038
        vector<string>::iterator iter;
11039
 
11040
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11041
        {
11042
            if (!sCommand.empty())
11043
                sCommand += ",";
11044
 
11045
            sCommand += *iter;
11046
        }
11047
 
11048
        sendPHNcommand(sCommand);
11049
    }
11050
}
127 andreas 11051
 
11052
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
11053
{
11054
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
11055
 
11056
    if (pars.size() < 1)
11057
    {
11058
        MSG_ERROR("Invalid number of arguments!");
11059
        return;
11060
    }
11061
 
11062
    string cmd = pars[0];
11063
 
11064
    if (cmd == "AUTOANSWER")
11065
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
11066
    else if (cmd == "LINESTATE")
11067
    {
11068
        if (!mSIPClient)
11069
            return;
11070
 
138 andreas 11071
        mSIPClient->sendLinestate();
127 andreas 11072
    }
11073
    else if (cmd == "MSGWAITING")
11074
    {
144 andreas 11075
        size_t num = mSIPClient->getNumberMessages();
11076
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 11077
    }
11078
    else if (cmd == "PRIVACY")
11079
    {
138 andreas 11080
        if (mSIPClient->getPrivate())
11081
            sendPHNcommand(cmd + ",1");
11082
        else
11083
            sendPHNcommand(cmd + ",0");
127 andreas 11084
    }
144 andreas 11085
    else if (cmd == "REDIAL")
11086
    {
11087
        if (pars.size() < 2)
11088
            return;
11089
 
11090
        sendPHNcommand(cmd + "," + pars[1]);
11091
    }
127 andreas 11092
    else
11093
    {
11094
        MSG_WARNING("Unknown command " << cmd << " found!");
11095
    }
11096
}
129 andreas 11097
#endif  // _NOSIP_
134 andreas 11098
 
300 andreas 11099
/*
318 andreas 11100
 *  Hide all subpages in a subpage viewer button.
11101
 */
11102
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
11103
{
11104
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
11105
 
343 andreas 11106
    Q_UNUSED(pars);
318 andreas 11107
    vector<TMap::MAP_T> map = findButtons(port, channels);
11108
 
11109
    if (TError::isError() || map.empty())
11110
        return;
11111
 
11112
    vector<Button::TButton *> buttons = collectButtons(map);
11113
 
11114
    if (!buttons.empty())
11115
    {
11116
        vector<Button::TButton *>::iterator mapIter;
11117
 
11118
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11119
        {
11120
            Button::TButton *bt = *mapIter;
11121
 
11122
            if (_hideAllSubViewItems)
11123
                _hideAllSubViewItems(bt->getHandle());
11124
        }
11125
    }
11126
}
11127
 
11128
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
11129
{
11130
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
11131
 
11132
    if (pars.size() < 1)
11133
        return;
11134
 
11135
    string name = pars[0];
11136
 
11137
    vector<TMap::MAP_T> map = findButtons(port, channels);
11138
 
11139
    if (TError::isError() || map.empty())
11140
        return;
11141
 
11142
    vector<Button::TButton *> buttons = collectButtons(map);
11143
 
11144
    if (!buttons.empty())
11145
    {
11146
        vector<Button::TButton *>::iterator mapIter;
11147
 
11148
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11149
        {
11150
            Button::TButton *bt = *mapIter;
11151
 
11152
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11153
 
11154
            if (subviews.empty())
11155
                continue;
11156
 
11157
            vector<TSubPage *>::iterator itSub;
11158
 
11159
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11160
            {
11161
                TSubPage *sub = *itSub;
11162
 
11163
                if (sub && sub->getName() == name)
11164
                {
11165
                    if (_hideSubViewItem)
11166
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
11167
 
11168
                    break;
11169
                }
11170
            }
11171
        }
11172
    }
11173
}
11174
 
11175
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
11176
{
11177
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
11178
 
11179
    if (pars.size() < 1)
11180
        return;
11181
 
11182
    TError::clear();
11183
    int padding = atoi(pars[0].c_str());
11184
 
11185
    if (padding < 0 || padding > 100)
11186
        return;
11187
 
11188
    vector<TMap::MAP_T> map = findButtons(port, channels);
11189
 
11190
    if (TError::isError() || map.empty())
11191
        return;
11192
 
11193
    vector<Button::TButton *> buttons = collectButtons(map);
11194
 
11195
    if (!buttons.empty())
11196
    {
11197
        vector<Button::TButton *>::iterator mapIter;
11198
 
11199
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11200
        {
11201
            Button::TButton *bt = *mapIter;
11202
 
11203
            if (_setSubViewPadding)
11204
                _setSubViewPadding(bt->getHandle(), padding);
11205
        }
11206
    }
11207
}
11208
 
11209
/*
300 andreas 11210
 * This command will perform one of three different operations based on the following conditions:
11211
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
11212
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
11213
 * 3. If the named subpage is already present in the set and is not hidden then the viewer button will move it to the anchor
11214
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
11215
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
11216
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
11217
 */
11218
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
11219
{
11220
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
11221
 
11222
    if (pars.size() < 1)
11223
    {
11224
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11225
        return;
11226
    }
11227
 
11228
    TError::clear();
11229
    string name = pars[0];
11230
    int position = 0;   // optional
11231
    int time = 0;       // optional
11232
 
11233
    if (pars.size() > 1)
11234
        position = atoi(pars[1].c_str());
11235
 
11236
    if (pars.size() > 2)
11237
        time = atoi(pars[2].c_str());
11238
 
11239
    vector<TMap::MAP_T> map = findButtons(port, channels);
11240
 
11241
    if (TError::isError() || map.empty())
11242
        return;
11243
 
11244
    vector<Button::TButton *> buttons = collectButtons(map);
11245
 
11246
    if (!buttons.empty())
11247
    {
11248
        vector<Button::TButton *>::iterator mapIter;
11249
 
11250
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11251
        {
11252
            Button::TButton *bt = *mapIter;
11253
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11254
 
11255
            if (subviews.empty() || !bt)
11256
                continue;
11257
 
11258
            vector<TSubPage *>::iterator itSub;
11259
 
11260
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11261
            {
11262
                TSubPage *sub = *itSub;
11263
 
11264
                if (sub && sub->getName() == name)
11265
                {
11266
                    if (_showSubViewItem)
11267
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11268
 
11269
                    break;
11270
                }
11271
            }
11272
        }
11273
    }
11274
}
11275
 
318 andreas 11276
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
11277
{
11278
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
11279
 
11280
    if (pars.empty())
11281
    {
11282
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11283
        return;
11284
    }
11285
 
11286
    TError::clear();
11287
    string name = pars[0];
11288
    int position = 0;   // optional
11289
    int time = 0;       // optional
11290
 
11291
    if (pars.size() > 1)
11292
        position = atoi(pars[1].c_str());
11293
 
11294
    if (pars.size() > 2)
11295
        time = atoi(pars[2].c_str());
11296
 
11297
    vector<TMap::MAP_T> map = findButtons(port, channels);
11298
 
11299
    if (TError::isError() || map.empty())
11300
        return;
11301
 
11302
    vector<Button::TButton *> buttons = collectButtons(map);
11303
 
11304
    if (!buttons.empty())
11305
    {
11306
        vector<Button::TButton *>::iterator mapIter;
11307
 
11308
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11309
        {
11310
            Button::TButton *bt = *mapIter;
11311
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11312
 
11313
            if (subviews.empty() || !bt)
11314
                continue;
11315
 
11316
            vector<TSubPage *>::iterator itSub;
11317
 
11318
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11319
            {
11320
                TSubPage *sub = *itSub;
11321
 
11322
                if (sub && sub->getName() == name)
11323
                {
11324
                    if (_toggleSubViewItem)
11325
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11326
 
11327
                    break;
11328
                }
11329
            }
11330
        }
11331
    }
11332
}
11333
 
227 andreas 11334
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 11335
{
227 andreas 11336
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 11337
 
11338
    if (pars.size() < 1)
11339
    {
11340
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11341
        return;
11342
    }
11343
 
11344
    TError::clear();
11345
    string source = pars[0];
11346
    vector<string> configs;
11347
 
11348
    if (pars.size() > 1)
11349
    {
11350
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 11351
        {
11352
            string low = toLower(pars[i]);
11353
 
11354
            if (low.find_first_of("user=") != string::npos ||
11355
                low.find_first_of("pass=") != string::npos ||
11356
                low.find_first_of("csv=")  != string::npos ||
11357
                low.find_first_of("has_headers=") != string::npos)
11358
            {
11359
                configs.push_back(pars[i]);
11360
            }
11361
        }
225 andreas 11362
    }
11363
 
11364
    vector<TMap::MAP_T> map = findButtons(port, channels);
11365
 
11366
    if (TError::isError() || map.empty())
11367
        return;
11368
 
11369
    vector<Button::TButton *> buttons = collectButtons(map);
11370
 
11371
    if (buttons.size() > 0)
11372
    {
11373
        vector<Button::TButton *>::iterator mapIter;
11374
 
11375
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11376
        {
11377
            Button::TButton *bt = *mapIter;
11378
            bt->setListSource(source, configs);
11379
        }
11380
    }
11381
 
11382
}
11383
 
230 andreas 11384
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
11385
{
11386
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
11387
 
11388
    if (pars.size() < 1)
11389
    {
11390
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11391
        return;
11392
    }
11393
 
11394
    TError::clear();
11395
    int num = atoi(pars[0].c_str());
11396
 
11397
    vector<TMap::MAP_T> map = findButtons(port, channels);
11398
 
11399
    if (TError::isError() || map.empty())
11400
        return;
11401
 
11402
    vector<Button::TButton *> buttons = collectButtons(map);
11403
 
11404
    if (buttons.size() > 0)
11405
    {
11406
        vector<Button::TButton *>::iterator mapIter;
11407
 
11408
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11409
        {
11410
            Button::TButton *bt = *mapIter;
11411
            bt->setListViewEventNumber(num);
11412
        }
11413
    }
11414
 
11415
}
11416
 
227 andreas 11417
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
11418
{
11419
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
11420
 
11421
    if (pars.size() < 1)
11422
    {
11423
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11424
        return;
11425
    }
11426
 
11427
    TError::clear();
11428
    string filter;
11429
 
11430
    vector<string>::iterator iter;
11431
 
11432
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11433
    {
11434
        if (filter.length() > 0)
11435
            filter += ",";
11436
 
11437
        filter += *iter;
11438
    }
11439
 
11440
    vector<TMap::MAP_T> map = findButtons(port, channels);
11441
 
11442
    if (TError::isError() || map.empty())
11443
        return;
11444
 
11445
    vector<Button::TButton *> buttons = collectButtons(map);
11446
 
11447
    if (buttons.size() > 0)
11448
    {
11449
        vector<Button::TButton *>::iterator mapIter;
11450
 
11451
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11452
        {
11453
            Button::TButton *bt = *mapIter;
11454
            bt->setListSourceFilter(filter);
11455
        }
11456
    }
11457
}
11458
 
230 andreas 11459
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
11460
{
11461
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
11462
 
11463
    if (pars.size() < 1)
11464
    {
11465
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11466
        return;
11467
    }
11468
 
11469
    TError::clear();
233 andreas 11470
    bool hasColumns = false;
230 andreas 11471
    int columns = 0;
233 andreas 11472
    bool hasLayout = false;
230 andreas 11473
    int layout = 0;
233 andreas 11474
    bool hasComponent = false;
11475
    int component = 0;
11476
    bool hasCellHeight = false;
11477
    bool cellHeightPercent = false;
11478
    int cellheight = 0;
11479
    bool hasP1 = false;
11480
    int p1 = 0;
11481
    bool hasP2 = false;
11482
    int p2 = 0;
11483
    bool hasFilter = false;
11484
    bool filter = false;
11485
    bool hasFilterHeight = false;
11486
    bool filterHeightPercent = false;
11487
    int filterheight = 0;
11488
    bool hasAlphaScroll = false;
11489
    bool alphascroll = false;
230 andreas 11490
 
11491
    vector<string>::iterator iter;
11492
 
11493
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11494
    {
11495
        string low = toLower(*iter);
11496
 
11497
        if (low.find("columns=") != string::npos ||
11498
            low.find("nc=") != string::npos ||
11499
            low.find("numcol=") != string::npos)
11500
        {
11501
            size_t pos = low.find("=");
11502
            string sCols = low.substr(pos + 1);
11503
            columns = atoi(sCols.c_str());
233 andreas 11504
            hasColumns = true;
11505
        }
11506
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
11507
        {
11508
            size_t pos = low.find("=");
11509
            string sComp = low.substr(pos + 1);
11510
            component |= atoi(sComp.c_str());
11511
            hasComponent = true;
11512
        }
11513
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
11514
        {
11515
            size_t pos = low.find("=");
11516
            string sLay = low.substr(pos + 1);
11517
            layout = atoi(sLay.c_str());
11518
            hasLayout = true;
11519
        }
11520
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
11521
        {
11522
            size_t pos = low.find("=");
11523
            string sCh = low.substr(pos + 1);
11524
            cellheight = atoi(sCh.c_str());
230 andreas 11525
 
233 andreas 11526
            if (low.find("%") != string::npos)
11527
                cellHeightPercent = true;
11528
 
11529
            hasCellHeight = true;
230 andreas 11530
        }
233 andreas 11531
        else if (low.find("p1=") != string::npos)
11532
        {
11533
            size_t pos = low.find("=");
11534
            string sP1 = low.substr(pos + 1);
11535
            p1 = atoi(sP1.c_str());
11536
            hasP1 = true;
11537
        }
11538
        else if (low.find("p2=") != string::npos)
11539
        {
11540
            size_t pos = low.find("=");
11541
            string sP2 = low.substr(pos + 1);
11542
            p2 = atoi(sP2.c_str());
11543
            hasP2 = true;
11544
        }
11545
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
11546
        {
11547
            size_t pos = low.find("=");
11548
            string sFilter = low.substr(pos + 1);
11549
            filter = isTrue(sFilter);
11550
            hasFilter = true;
11551
        }
11552
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
11553
        {
11554
            size_t pos = low.find("=");
11555
            string sFilter = low.substr(pos + 1);
11556
            filterheight = atoi(sFilter.c_str());
11557
 
11558
            if (low.find("%") != string::npos)
11559
                filterHeightPercent = true;
11560
 
11561
            hasFilterHeight = true;
11562
        }
11563
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
11564
        {
11565
            size_t pos = low.find("=");
11566
            string sAlpha = low.substr(pos + 1);
11567
            alphascroll = isTrue(sAlpha);
11568
            hasAlphaScroll = true;
11569
        }
230 andreas 11570
    }
11571
 
11572
    vector<TMap::MAP_T> map = findButtons(port, channels);
11573
 
11574
    if (TError::isError() || map.empty())
11575
        return;
11576
 
11577
    vector<Button::TButton *> buttons = collectButtons(map);
11578
 
11579
    if (buttons.size() > 0)
11580
    {
11581
        vector<Button::TButton *>::iterator mapIter;
11582
 
11583
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11584
        {
11585
            Button::TButton *bt = *mapIter;
233 andreas 11586
 
11587
            if (hasColumns)         bt->setListViewColumns(columns);
11588
            if (hasComponent)       bt->setListViewComponent(component);
11589
            if (hasLayout)          bt->setListViewLayout(layout);
11590
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
11591
            if (hasP1)              bt->setListViewP1(p1);
11592
            if (hasP2)              bt->setListViewP2(p2);
11593
            if (hasFilter)          bt->setListViewColumnFilter(filter);
11594
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
11595
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 11596
        }
11597
    }
11598
}
11599
 
233 andreas 11600
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
11601
{
11602
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
11603
 
11604
    if (pars.size() < 1)
11605
    {
11606
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11607
        return;
11608
    }
11609
 
11610
    TError::clear();
11611
    map<string,string> mapField;
11612
 
11613
    vector<string>::iterator iter;
11614
 
11615
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11616
    {
11617
        string left, right;
11618
        size_t pos = 0;
11619
 
11620
        if ((pos = iter->find("=")) != string::npos)
11621
        {
11622
            string left = iter->substr(0, pos);
11623
            left = toLower(left);
11624
            string right = iter->substr(pos + 1);
11625
 
11626
            if (left == "t1" || left == "t2" || left == "i1")
11627
                mapField.insert(pair<string,string>(left, right));
11628
        }
11629
    }
11630
 
11631
    vector<TMap::MAP_T> map = findButtons(port, channels);
11632
 
11633
    if (TError::isError() || map.empty())
11634
        return;
11635
 
11636
    vector<Button::TButton *> buttons = collectButtons(map);
11637
 
11638
    if (buttons.size() > 0)
11639
    {
11640
        vector<Button::TButton *>::iterator mapIter;
11641
 
11642
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11643
        {
11644
            Button::TButton *bt = *mapIter;
11645
            bt->setListViewFieldMap(mapField);
11646
        }
11647
    }
11648
}
11649
 
11650
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
11651
{
11652
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
11653
 
11654
    if (pars.size() < 1)
11655
    {
11656
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11657
        return;
11658
    }
11659
 
11660
    TError::clear();
11661
    string command = pars[0];
11662
    bool select = false;
11663
 
11664
    if (pars.size() > 1)
11665
    {
11666
        if (isTrue(pars[1]))
11667
            select = true;
11668
    }
11669
 
11670
    vector<TMap::MAP_T> map = findButtons(port, channels);
11671
 
11672
    if (TError::isError() || map.empty())
11673
        return;
11674
 
11675
    vector<Button::TButton *> buttons = collectButtons(map);
11676
 
11677
    if (buttons.size() > 0)
11678
    {
11679
        vector<Button::TButton *>::iterator mapIter;
11680
 
11681
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11682
        {
11683
            Button::TButton *bt = *mapIter;
11684
            bt->listViewNavigate(command, select);
11685
        }
11686
    }
11687
}
11688
 
11689
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
11690
{
11691
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
11692
 
11693
    TError::clear();
11694
    int interval = -1;
11695
    bool force = false;
11696
 
11697
    if (pars.size() > 0)
11698
        interval = atoi(pars[0].c_str());
11699
 
11700
    if (pars.size() > 1)
11701
        force = isTrue(pars[1]);
11702
 
11703
    vector<TMap::MAP_T> map = findButtons(port, channels);
11704
 
11705
    if (TError::isError() || map.empty())
11706
        return;
11707
 
11708
    vector<Button::TButton *> buttons = collectButtons(map);
11709
 
11710
    if (buttons.size() > 0)
11711
    {
11712
        vector<Button::TButton *>::iterator mapIter;
11713
 
11714
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11715
        {
11716
            Button::TButton *bt = *mapIter;
11717
            bt->listViewRefresh(interval, force);
11718
        }
11719
    }
11720
}
11721
 
11722
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
11723
{
11724
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
11725
 
11726
    TError::clear();
11727
    vector<string> sortColumns;
11728
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
11729
    string override;
11730
 
11731
    if (pars.size() > 0)
11732
    {
11733
        vector<string>::iterator iter;
11734
 
11735
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11736
        {
11737
            if (iter->find(";") == string::npos)
11738
                sortColumns.push_back(*iter);
11739
            else
11740
            {
11741
                vector<string> parts = StrSplit(*iter, ";");
11742
                sortColumns.push_back(parts[0]);
11743
 
11744
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
11745
                    sort = Button::LIST_SORT_ASC;
11746
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
11747
                    sort = Button::LIST_SORT_DESC;
11748
                else if (parts[1].find("*") != string::npos)
11749
                {
11750
                    if (parts.size() > 2 && !parts[2].empty())
11751
                    {
11752
                        override = parts[2];
11753
                        sort = Button::LIST_SORT_OVERRIDE;
11754
                    }
11755
                }
11756
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
11757
                    sort = Button::LIST_SORT_NONE;
11758
            }
11759
        }
11760
    }
11761
 
11762
    vector<TMap::MAP_T> map = findButtons(port, channels);
11763
 
11764
    if (TError::isError() || map.empty())
11765
        return;
11766
 
11767
    vector<Button::TButton *> buttons = collectButtons(map);
11768
 
11769
    if (buttons.size() > 0)
11770
    {
11771
        vector<Button::TButton *>::iterator mapIter;
11772
 
11773
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11774
        {
11775
            Button::TButton *bt = *mapIter;
11776
            bt->listViewSortData(sortColumns, sort, override);
11777
        }
11778
    }
11779
}
11780
 
134 andreas 11781
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
11782
{
11783
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
11784
 
11785
    if (pars.size() < 1)
11786
    {
11787
        MSG_ERROR("Too few arguments for TPCCMD!");
11788
        return;
11789
    }
11790
 
11791
    string cmd = pars[0];
11792
 
11793
    if (strCaseCompare(cmd, "LocalHost") == 0)
11794
    {
11795
        if (pars.size() < 2 || pars[1].empty())
11796
        {
11797
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
11798
            return;
11799
        }
11800
 
11801
        TConfig::saveController(pars[1]);
11802
    }
11803
    else if (strCaseCompare(cmd, "LocalPort") == 0)
11804
    {
11805
        if (pars.size() < 2 || pars[1].empty())
11806
        {
11807
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
11808
            return;
11809
        }
11810
 
11811
        int port = atoi(pars[1].c_str());
11812
 
11813
        if (port > 0 && port < 65536)
11814
            TConfig::savePort(port);
11815
        else
11816
        {
11817
            MSG_ERROR("Invalid network port " << port);
11818
        }
11819
    }
11820
    else if (strCaseCompare(cmd, "DeviceID") == 0)
11821
    {
11822
        if (pars.size() < 2 || pars[1].empty())
11823
        {
11824
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
11825
            return;
11826
        }
11827
 
11828
        int id = atoi(pars[1].c_str());
11829
 
11830
        if (id >= 10000 && id < 30000)
11831
            TConfig::setSystemChannel(id);
11832
    }
11833
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
11834
    {
11835
        // We restart the network connection only
11836
        if (gAmxNet)
11837
            gAmxNet->reconnect();
11838
    }
11839
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
11840
    {
11841
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
11842
        info += ";HOSTNAME,";
11843
        char hostname[HOST_NAME_MAX];
11844
 
11845
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
11846
        {
11847
            MSG_ERROR("Can't get host name: " << strerror(errno));
11848
            return;
11849
        }
11850
 
11851
        info.append(hostname);
11852
        info += ";UUID," + TConfig::getUUID();
11853
        sendGlobalString(info);
11854
    }
11855
    else if (strCaseCompare(cmd, "LockRotation") == 0)
11856
    {
11857
        if (pars.size() < 2 || pars[1].empty())
11858
        {
11859
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
11860
            return;
11861
        }
11862
 
11863
        if (strCaseCompare(pars[1], "true") == 0)
11864
            TConfig::setRotationFixed(true);
11865
        else
11866
            TConfig::setRotationFixed(false);
11867
    }
11868
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
11869
    {
11870
        if (pars.size() < 2 || pars[1].empty())
11871
        {
11872
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
11873
            return;
11874
        }
11875
 
11876
        if (strCaseCompare(pars[1], "true") == 0)
11877
            TConfig::saveSystemSoundState(true);
11878
        else
11879
            TConfig::saveSystemSoundState(false);
11880
    }
11881
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
11882
    {
11883
        if (_resetSurface)
11884
            _resetSurface();
11885
    }
11886
}
11887
 
11888
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
11889
{
11890
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
11891
 
11892
    if (pars.size() < 1)
11893
    {
11894
        MSG_ERROR("Too few arguments for TPCACC!");
11895
        return;
11896
    }
11897
 
11898
    string cmd = pars[0];
11899
 
11900
    if (strCaseCompare(cmd, "ENABLE") == 0)
11901
    {
11902
        mInformOrientation = true;
11903
        sendOrientation();
11904
    }
11905
    else if (strCaseCompare(cmd, "DISABLE") == 0)
11906
    {
11907
        mInformOrientation = false;
11908
    }
11909
    else if (strCaseCompare(cmd, "QUERY") == 0)
11910
    {
11911
        sendOrientation();
11912
    }
11913
}
153 andreas 11914
 
279 andreas 11915
#ifndef _NOSIP_
153 andreas 11916
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
11917
{
11918
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
11919
 
11920
    if (pars.empty())
11921
        return;
11922
 
11923
    string cmd = toUpper(pars[0]);
11924
 
11925
    if (cmd == "SHOW" && _showPhoneDialog)
11926
        _showPhoneDialog(true);
11927
    else if (!_showPhoneDialog)
11928
    {
11929
        MSG_ERROR("There is no phone dialog registered!");
11930
    }
11931
}
279 andreas 11932
#endif