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