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