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