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