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);
4079
}
4080
 
4081
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4082
{
4083
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4084
 
16 andreas 4085
    TError::clear();
11 andreas 4086
    int realX = x - mFirstLeftPixel;
4087
    int realY = y - mFirstTopPixel;
263 andreas 4088
 
31 andreas 4089
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4090
#ifdef _SCALE_SKIA_
100 andreas 4091
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4092
    {
4093
        realX = (int)((double)realX / mScaleFactor);
4094
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4095
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4096
    }
43 andreas 4097
#endif
70 andreas 4098
 
154 andreas 4099
    TSubPage *subPage = nullptr;
11 andreas 4100
 
154 andreas 4101
    if (pressed)
4102
        subPage = getCoordMatch(realX, realY);
318 andreas 4103
    else if (mLastPagePush)
154 andreas 4104
        subPage = getSubPage(mLastPagePush);
4105
    else
4106
        subPage = getCoordMatch(realX, realY);
4107
 
11 andreas 4108
    if (!subPage)
14 andreas 4109
    {
146 andreas 4110
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4111
 
4112
        if (bt)
4113
        {
4114
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4115
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4116
        }
4117
 
11 andreas 4118
        return;
14 andreas 4119
    }
11 andreas 4120
 
154 andreas 4121
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4122
 
4123
    if (pressed)
4124
        mLastPagePush = subPage->getNumber();
4125
    else
4126
        mLastPagePush = 0;
4127
 
11 andreas 4128
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4129
}
11 andreas 4130
 
289 andreas 4131
void TPageManager::mouseEvent(ulong handle, bool pressed)
4132
{
4133
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4134
 
320 andreas 4135
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4136
        return;
4137
 
299 andreas 4138
    TLOCKER(click_mutex);
293 andreas 4139
 
299 andreas 4140
    _CLICK_QUEUE_t cq;
4141
    cq.handle = handle;
4142
    cq.pressed = pressed;
4143
    mClickQueue.push_back(cq);
4144
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4145
}
4146
 
4147
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4148
{
4149
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4150
 
293 andreas 4151
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4152
 
289 andreas 4153
    if (!handle)
4154
        return;
4155
 
4156
    int pageID = (handle >> 16) & 0x0000ffff;
4157
    int buttonID = (handle & 0x0000ffff);
4158
 
318 andreas 4159
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4160
        return;
4161
 
4162
    TSubPage *subPage = getSubPage(pageID);
4163
 
4164
    if (subPage)
4165
    {
4166
        Button::TButton *bt = subPage->getButton(buttonID);
4167
 
4168
        if (bt)
4169
        {
318 andreas 4170
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4171
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4172
        }
4173
    }
4174
}
4175
 
192 andreas 4176
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4177
{
4178
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4179
 
4180
    Button::TButton *bt = findButton(handle);
4181
 
4182
    if (!bt)
4183
    {
271 andreas 4184
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4185
        return;
4186
    }
4187
 
4188
    bt->setTextOnly(content, -1);
4189
}
4190
 
309 andreas 4191
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4192
{
4193
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4194
 
4195
    Button::TButton *bt = findButton(handle);
4196
 
4197
    if (!bt)
4198
    {
4199
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4200
        return;
4201
    }
4202
 
310 andreas 4203
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4204
 
4205
    if (pageID < REGULAR_SUBPAGE_START)
4206
    {
4207
        TPage *pg = getPage(pageID);
4208
 
4209
        if (!pg)
4210
            return;
4211
 
4212
        pg->setCursorPosition(handle, oldPos, newPos);
4213
    }
4214
    else
4215
    {
4216
        TSubPage *pg = getSubPage(pageID);
4217
 
4218
        if (!pg)
4219
            return;
4220
 
4221
        pg->setCursorPosition(handle, oldPos, newPos);
4222
    }
4223
}
4224
 
4225
void TPageManager::inputFocusChanged(ulong handle, bool in)
4226
{
4227
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4228
 
4229
    Button::TButton *bt = findButton(handle);
4230
 
4231
    if (!bt)
4232
    {
4233
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4234
        return;
4235
    }
4236
 
310 andreas 4237
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4238
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4239
 
4240
    if (pageID < REGULAR_SUBPAGE_START)
4241
    {
4242
        TPage *pg = getPage(pageID);
4243
 
4244
        if (!pg)
4245
            return;
4246
 
4247
        pg->setInputFocus(handle, in);
4248
    }
4249
    else
4250
    {
4251
        TSubPage *pg = getSubPage(pageID);
4252
 
4253
        if (!pg)
4254
            return;
4255
 
4256
        pg->setInputFocus(handle, in);
4257
    }
4258
}
4259
 
208 andreas 4260
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4261
{
208 andreas 4262
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4263
 
4264
    // First we search for the button the handle points to
4265
    Button::TButton *button = findButton(handle);
4266
 
4267
    if (!button)
4268
    {
271 andreas 4269
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4270
        return;
4271
    }
4272
 
4273
    // Now we search for all buttons with the same channel and port number
4274
    vector<int> channels;
4275
    channels.push_back(button->getAddressChannel());
193 andreas 4276
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4277
 
4278
    if (TError::isError() || map.empty())
4279
        return;
4280
 
4281
    // Here we load all buttons found.
4282
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4283
 
4284
    if (buttons.size() > 0)
51 andreas 4285
    {
83 andreas 4286
        vector<Button::TButton *>::iterator mapIter;
4287
        // Finaly we iterate through all found buttons and set the text
118 andreas 4288
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4289
        {
4290
            Button::TButton *bt = *mapIter;
51 andreas 4291
 
208 andreas 4292
            if (redraw)
4293
                bt->setText(txt, -1);
4294
            else
4295
                bt->setTextOnly(txt, -1);
83 andreas 4296
        }
51 andreas 4297
    }
4298
}
4299
 
193 andreas 4300
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4301
{
193 andreas 4302
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4303
 
4304
    vector<Button::TButton *> buttons;
83 andreas 4305
 
4306
    if (map.size() == 0)
4307
        return buttons;
4308
 
193 andreas 4309
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4310
 
118 andreas 4311
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4312
    {
209 andreas 4313
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4314
        {
4315
            TPage *page;
4316
 
4317
            if ((page = getPage(iter->pg)) == nullptr)
4318
            {
4319
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4320
 
4321
                if (!readPage(iter->pg))
4322
                    return buttons;
4323
 
4324
                page = getPage(iter->pg);
4325
            }
4326
 
4327
            Button::TButton *bt = page->getButton(iter->bt);
4328
 
4329
            if (bt)
4330
                buttons.push_back(bt);
4331
        }
4332
        else
4333
        {
4334
            TSubPage *subpage;
4335
 
4336
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4337
            {
4338
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4339
 
4340
                if (!readSubPage(iter->pg))
4341
                    return buttons;
4342
 
4343
                subpage = getSubPage(iter->pg);
4344
                TPage *page = getActualPage();
4345
 
4346
                if (!page)
4347
                {
4348
                    MSG_ERROR("No actual page loaded!");
4349
                    return buttons;
4350
                }
4351
            }
4352
 
4353
            Button::TButton *bt = subpage->getButton(iter->bt);
4354
 
4355
            if (bt)
4356
                buttons.push_back(bt);
4357
        }
4358
    }
4359
 
4360
    return buttons;
4361
}
4362
 
11 andreas 4363
/****************************************************************************
36 andreas 4364
 * Calls from a Java activity. This is only available for Android OS.
4365
 ****************************************************************************/
182 andreas 4366
#ifdef Q_OS_ANDROID
36 andreas 4367
void TPageManager::initNetworkState()
4368
{
4369
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4370
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4371
    QAndroidJniObject activity = QtAndroid::androidActivity();
4372
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4373
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4374
#else
4375
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4376
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4377
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4378
#endif
36 andreas 4379
}
4380
 
4381
void TPageManager::stopNetworkState()
4382
{
4383
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4384
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4385
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4386
#else
4387
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4388
#endif
36 andreas 4389
}
38 andreas 4390
 
4391
void TPageManager::initBatteryState()
4392
{
4393
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4394
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4395
    QAndroidJniObject activity = QtAndroid::androidActivity();
4396
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4397
#else
4398
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4399
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4400
#endif
38 andreas 4401
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4402
}
4403
 
61 andreas 4404
void TPageManager::initPhoneState()
4405
{
4406
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4407
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4408
    QAndroidJniObject activity = QtAndroid::androidActivity();
4409
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4410
#else
4411
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4412
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4413
#endif
61 andreas 4414
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4415
}
4416
 
38 andreas 4417
void TPageManager::stopBatteryState()
4418
{
4419
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4420
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4421
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4422
#else
4423
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4424
#endif
38 andreas 4425
}
4426
 
36 andreas 4427
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4428
{
250 andreas 4429
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4430
 
4431
    int l = 0;
4432
    string sType;
4433
 
4434
    switch (type)
4435
    {
4436
        case 1: sType = "Wifi"; break;
4437
        case 2: sType = "Mobile"; break;
4438
 
4439
        default:
4440
            sType = "Unknown"; break;
4441
    }
4442
 
4443
    if (conn)
4444
        l = level;
4445
 
93 andreas 4446
    if (mNetState && mNetState != type)     // Has the connection type changed?
4447
    {
4448
        if (gAmxNet)
4449
            gAmxNet->reconnect();
4450
    }
4451
 
4452
    mNetState = type;
4453
 
36 andreas 4454
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4455
 
83 andreas 4456
    if (mNetCalls.size() > 0)
36 andreas 4457
    {
83 andreas 4458
        std::map<int, std::function<void (int level)> >::iterator iter;
4459
 
4460
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4461
            iter->second(l);
36 andreas 4462
    }
4463
}
38 andreas 4464
 
4465
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4466
{
4467
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4468
 
59 andreas 4469
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4470
 
83 andreas 4471
    if (mBatteryCalls.size() > 0)
38 andreas 4472
    {
83 andreas 4473
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4474
 
4475
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4476
            iter->second(level, charging, chargeType);
38 andreas 4477
    }
4478
}
61 andreas 4479
 
4480
void TPageManager::informPhoneState(bool call, const string &pnumber)
4481
{
4482
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4483
 
4484
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4485
 
4486
    if (!gAmxNet)
4487
    {
4488
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4489
        return;
4490
    }
4491
}
130 andreas 4492
 
4493
void TPageManager::initOrientation()
4494
{
4495
    DECL_TRACER("TPageManager::initOrientation()");
4496
 
131 andreas 4497
    int rotate = getSettings()->getRotate();
264 andreas 4498
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4499
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4500
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4501
#else
4502
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4503
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4504
#endif
130 andreas 4505
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4506
}
255 andreas 4507
 
4508
void TPageManager::enterSetup()
4509
{
260 andreas 4510
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4511
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4512
    QAndroidJniObject activity = QtAndroid::androidActivity();
4513
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4514
#else
4515
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4516
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4517
#endif
4518
}
59 andreas 4519
#endif  // __ANDROID__
247 andreas 4520
#ifdef Q_OS_IOS
4521
void TPageManager::informBatteryStatus(int level, int state)
4522
{
4523
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4524
 
247 andreas 4525
    MSG_INFO("Battery status: level: " << level << ", " << state);
4526
 
4527
    if (mBatteryCalls.size() > 0)
4528
    {
4529
        std::map<int, std::function<void (int, int)> >::iterator iter;
4530
 
4531
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4532
            iter->second(level, state);
4533
    }
4534
}
250 andreas 4535
 
4536
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4537
{
4538
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4539
 
4540
    int l = 0;
4541
    string sType;
4542
 
4543
    switch (type)
4544
    {
4545
        case 1: sType = "Ethernet"; break;
4546
        case 2: sType = "Mobile"; break;
4547
        case 3: sType = "WiFi"; break;
4548
        case 4: sType = "Bluetooth"; break;
4549
 
4550
        default:
4551
            sType = "Unknown"; break;
4552
    }
4553
 
4554
    if (conn)
4555
        l = level;
4556
 
4557
    if (mNetState && mNetState != type)     // Has the connection type changed?
4558
    {
4559
        if (gAmxNet)
4560
            gAmxNet->reconnect();
4561
    }
4562
 
4563
    mNetState = type;
4564
 
4565
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4566
 
4567
    if (mNetCalls.size() > 0)
4568
    {
4569
        std::map<int, std::function<void (int level)> >::iterator iter;
4570
 
4571
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4572
            iter->second(l);
4573
    }
4574
}
4575
 
247 andreas 4576
#endif
4577
 
60 andreas 4578
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4579
{
227 andreas 4580
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4581
 
162 andreas 4582
    if (!bt)
4583
        return;
4584
 
60 andreas 4585
    bt->registerCallback(_displayButton);
4586
    bt->regCallPlayVideo(_callPlayVideo);
4587
    bt->setFonts(mFonts);
4588
    bt->setPalette(mPalette);
4589
}
4590
 
4591
void TPageManager::externalButton(extButtons_t bt, bool checked)
4592
{
4593
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4594
 
4595
    if (!mExternal)
4596
        return;
4597
 
4598
    EXTBUTTON_t button = mExternal->getButton(bt);
4599
 
4600
    if (button.type == EXT_NOBUTTON)
4601
        return;
4602
 
4603
    if (button.cp && button.ch)
4604
    {
4605
        amx::ANET_SEND scmd;
4606
 
4607
        scmd.device = TConfig::getChannel();
4608
        scmd.port = button.cp;
4609
        scmd.channel = button.ch;
4610
 
4611
        if (checked)
4612
            scmd.MC = 0x0084;   // push button
134 andreas 4613
        else
4614
            scmd.MC = 0x0085;   // release button
60 andreas 4615
 
134 andreas 4616
        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 4617
 
134 andreas 4618
        if (gAmxNet)
4619
            gAmxNet->sendCommand(scmd);
4620
        else
4621
        {
4622
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
4623
        }
60 andreas 4624
    }
4625
}
4626
 
62 andreas 4627
void TPageManager::sendKeyboard(const std::string& text)
4628
{
4629
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
4630
 
4631
    amx::ANET_SEND scmd;
4632
    scmd.port = 1;
4633
    scmd.channel = 0;
4634
    scmd.msg = UTF8ToCp1250(text);
4635
    scmd.MC = 0x008b;
4636
 
4637
    if (gAmxNet)
4638
        gAmxNet->sendCommand(scmd);
4639
    else
4640
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4641
}
4642
 
4643
void TPageManager::sendKeypad(const std::string& text)
4644
{
4645
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
4646
 
269 andreas 4647
    sendKeyboard(text);
62 andreas 4648
}
4649
 
4650
void TPageManager::sendString(uint handle, const std::string& text)
4651
{
4652
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
4653
 
4654
    Button::TButton *bt = findButton(handle);
4655
 
4656
    if (!bt)
4657
    {
271 andreas 4658
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 4659
        return;
4660
    }
4661
 
4662
    amx::ANET_SEND scmd;
4663
    scmd.port = bt->getAddressPort();
4664
    scmd.channel = bt->getAddressChannel();
4665
    scmd.msg = UTF8ToCp1250(text);
4666
    scmd.MC = 0x008b;
4667
 
4668
    if (gAmxNet)
4669
        gAmxNet->sendCommand(scmd);
4670
    else
4671
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4672
}
4673
 
134 andreas 4674
void TPageManager::sendGlobalString(const string& text)
4675
{
4676
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4677
 
4678
    if (text.empty() || text.find("-") == string::npos)
4679
        return;
4680
 
4681
    amx::ANET_SEND scmd;
4682
    scmd.port = 1;
4683
    scmd.channel = 0;
4684
    scmd.msg = text;
4685
    scmd.MC = 0x008b;
4686
 
4687
    if (gAmxNet)
4688
        gAmxNet->sendCommand(scmd);
4689
    else
4690
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4691
}
4692
 
147 andreas 4693
void TPageManager::sendCommandString(int port, const string& cmd)
4694
{
4695
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4696
 
4697
    if (cmd.empty())
4698
        return;
4699
 
4700
    amx::ANET_SEND scmd;
4701
    scmd.port = port;
4702
    scmd.channel = 0;
4703
    scmd.msg = cmd;
4704
    scmd.MC = 0x008c;
4705
 
4706
    if (gAmxNet)
4707
        gAmxNet->sendCommand(scmd);
4708
    else
4709
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4710
}
4711
 
123 andreas 4712
void TPageManager::sendPHNcommand(const std::string& cmd)
4713
{
4714
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
4715
 
4716
    amx::ANET_SEND scmd;
144 andreas 4717
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 4718
    scmd.channel = TConfig::getChannel();
4719
    scmd.msg = "^PHN-" + cmd;
127 andreas 4720
    scmd.MC = 0x008c;
4721
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 4722
 
4723
    if (gAmxNet)
4724
        gAmxNet->sendCommand(scmd);
4725
    else
4726
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
4727
}
4728
 
111 andreas 4729
void TPageManager::sendKeyStroke(char key)
4730
{
4731
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
4732
 
4733
    if (!key)
4734
        return;
4735
 
4736
    char msg[2];
4737
    msg[0] = key;
4738
    msg[1] = 0;
4739
 
4740
    amx::ANET_SEND scmd;
4741
    scmd.port = 1;
4742
    scmd.channel = 0;
4743
    scmd.msg.assign(msg);
127 andreas 4744
    scmd.MC = 0x008c;
111 andreas 4745
 
4746
    if (gAmxNet)
4747
        gAmxNet->sendCommand(scmd);
4748
    else
4749
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4750
}
4751
 
110 andreas 4752
/**
4753
 * Sending a custom event is identical in all cases. Because of this I
4754
 * implemented this method to send a custom event. This is called in all cases
4755
 * where a ?XXX command is received.
4756
 *
4757
 * @param value1    The instance of the button.
4758
 * @param value2    The value of a numeric request or the length of the string.
4759
 * @param value3    Always 0
4760
 * @param msg       In case of a string this contains the string.
4761
 * @param evType    This is the event type, a number between 1001 and 1099.
4762
 * @param cp        Channel port of button.
4763
 * @param cn        Channel number. of button.
4764
 *
4765
 * @return If all parameters are valid it returns TRUE.
4766
 */
4767
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
4768
{
4769
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
4770
 
4771
    if (value1 < 1)
4772
        return false;
4773
 
4774
    amx::ANET_SEND scmd;
4775
    scmd.port = cp;
4776
    scmd.channel = cn;
4777
    scmd.ID = scmd.channel;
4778
    scmd.flag = 0;
4779
    scmd.type = evType;
4780
    scmd.value1 = value1;   // instance
4781
    scmd.value2 = value2;
4782
    scmd.value3 = value3;
4783
    scmd.msg = msg;
4784
 
4785
    if (!msg.empty())
4786
        scmd.dtype = 0x0001;// Char array
4787
 
4788
    scmd.MC = 0x008d;       // custom event
4789
 
4790
    if (gAmxNet)
4791
        gAmxNet->sendCommand(scmd);
4792
    else
4793
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4794
 
4795
    return true;
4796
}
129 andreas 4797
#ifndef _NOSIP_
127 andreas 4798
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
4799
{
4800
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
4801
 
4802
    switch(s)
4803
    {
4804
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
4805
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
4806
        case TSIPClient::SIP_HOLD:          return "HOLD";
4807
        case TSIPClient::SIP_RINGING:       return "RINGING";
4808
        case TSIPClient::SIP_TRYING:        return "TRYING";
4809
 
4810
        default:
4811
            return "IDLE";
4812
    }
4813
 
4814
    return "IDLE";
4815
}
129 andreas 4816
#endif
134 andreas 4817
void TPageManager::sendOrientation()
4818
{
4819
    string ori;
4820
 
4821
    switch(mOrientation)
4822
    {
4823
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
4824
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
4825
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
4826
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
4827
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
4828
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
4829
        default:
4830
            return;
4831
    }
4832
 
4833
    sendGlobalString("TPCACC-" + ori);
4834
}
4835
 
153 andreas 4836
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
4837
{
4838
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
4839
 
4840
    // Swipes are defined in "external".
4841
    if (!mExternal)
4842
        return;
4843
 
4844
    extButtons_t eBt;
4845
    string dbg;
4846
 
4847
    switch(sw)
4848
    {
4849
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
4850
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
4851
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
4852
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
4853
 
4854
        default:
4855
            return;
4856
    }
4857
 
4858
    int pgNum = getActualPageNumber();
4859
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
4860
 
4861
    if (bt.bi == 0)
4862
        return;
4863
 
4864
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
4865
 
4866
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
4867
    {                                           // Yes, then feed it into command queue.
4868
        MSG_DEBUG("Button has a self feed command");
4869
 
4870
        int channel = TConfig::getChannel();
4871
        int system = TConfig::getSystem();
4872
 
4873
        amx::ANET_COMMAND cmd;
4874
        cmd.MC = 0x000c;
4875
        cmd.device1 = channel;
4876
        cmd.port1 = bt.ap;
4877
        cmd.system = system;
4878
        cmd.data.message_string.device = channel;
4879
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
4880
        cmd.data.message_string.system = system;
4881
        cmd.data.message_string.type = 1;   // 8 bit char string
4882
 
4883
        vector<string>::iterator iter;
4884
 
4885
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
4886
        {
4887
            cmd.data.message_string.length = iter->length();
4888
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
4889
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
4890
            doCommand(cmd);
4891
        }
4892
    }
4893
    else if (!bt.cm.empty())
4894
    {
4895
        MSG_DEBUG("Button sends a command on port " << bt.co);
4896
 
4897
        vector<string>::iterator iter;
4898
 
4899
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
4900
            sendCommandString(bt.co, *iter);
4901
    }
4902
}
4903
 
36 andreas 4904
/****************************************************************************
11 andreas 4905
 * The following functions implements one of the commands the panel accepts.
4906
 ****************************************************************************/
43 andreas 4907
 
4908
/**
4909
 * This is a special function handling the progress bars when the files of the
4910
 * panel are updated. Instead of simply displaying a ready page, it fakes one
4911
 * with the actual dimensions of the main page. This is possible, because we've
4912
 * always a main page even if the panel is started for the first time.
4913
 */
4914
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 4915
{
43 andreas 4916
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 4917
 
23 andreas 4918
    if (pars.empty())
4919
    {
4920
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
4921
        return;
4922
    }
4923
 
96 andreas 4924
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 4925
    {
96 andreas 4926
        for (size_t i = 0; i < pars.size(); i++)
4927
        {
4928
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
4929
        }
23 andreas 4930
    }
43 andreas 4931
 
4932
    if (pars.at(0).compare("START") == 0)
4933
    {
4934
        // Here we have to drop all pages and subpages first and then display
4935
        // the faked page with the progress bars.
4936
        MSG_DEBUG("Starting file transfer ...");
4937
        doPPX(port, channels, pars);
4938
        TPage *pg = getPage("_progress");
4939
 
4940
        if (!pg)
4941
        {
4942
            if (!readPage("_progress"))
4943
            {
4944
                MSG_ERROR("Error creating the system page _progress!");
4945
                return;
4946
            }
4947
 
4948
            pg = getPage("_progress");
4949
 
4950
            if (!pg)
4951
            {
4952
                MSG_ERROR("Error getting system page _progress!");
4953
                return;
4954
            }
4955
        }
4956
 
4957
        pg->setFonts(mFonts);
4958
        pg->registerCallback(_setBackground);
4959
        pg->regCallPlayVideo(_callPlayVideo);
4960
 
4961
        if (!pg || !_setPage || !mTSettings)
4962
            return;
4963
 
4964
        int width, height;
217 andreas 4965
        width = mTSettings->getWidth();
43 andreas 4966
        height = mTSettings->getHeight();
4967
#ifdef _SCALE_SKIA_
4968
        if (mScaleFactor != 1.0)
4969
        {
4970
            width = (int)((double)width * mScaleFactor);
4971
            height = (int)((double)height * mScaleFactor);
4972
        }
4973
#endif
4974
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
4975
        pg->show();
4976
        MSG_DEBUG("Page _progress on screen");
4977
    }
4978
    else if (pars.at(0).compare("SYNC") == 0)
4979
    {
4980
        TPage *pg = getPage("_progress");
4981
 
4982
        if (!pg)
4983
        {
4984
            MSG_ERROR("Page _progress not found!");
4985
            return;
4986
        }
4987
 
4988
        Button::TButton *bt = pg->getButton(1);   // Line 1
4989
 
4990
        if (!bt)
4991
        {
4992
            MSG_ERROR("Button 160 of page _progress not found!");
4993
            return;
4994
        }
4995
 
4996
        bt->setText(pars.at(2), 0);
4997
        bt->show();
4998
    }
4999
    else if (pars.at(0).compare("FTRSTART") == 0)
5000
    {
5001
        TPage *pg = getPage("_progress");
5002
 
5003
        if (!pg)
5004
        {
5005
            MSG_ERROR("Page _progress not found!");
5006
            return;
5007
        }
5008
 
5009
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5010
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5011
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5012
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5013
 
5014
        if (!bt1 || !bt2 || !bt3 || !bt4)
5015
        {
5016
            MSG_ERROR("Buttons of page _progress not found!");
5017
            return;
5018
        }
5019
 
5020
        bt1->setText("Transfering files ...", 0);
5021
        bt1->show();
5022
        bt2->setText(pars.at(3), 0);
5023
        bt2->show();
5024
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5025
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5026
    }
5027
    else if (pars.at(0).compare("FTRPART") == 0)
5028
    {
5029
        TPage *pg = getPage("_progress");
5030
 
5031
        if (!pg)
5032
        {
5033
            MSG_ERROR("Page _progress not found!");
5034
            return;
5035
        }
5036
 
5037
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5038
 
5039
        if (!bt)
5040
        {
5041
            MSG_ERROR("Buttons of page _progress not found!");
5042
            return;
5043
        }
5044
 
5045
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5046
    }
5047
    else if (pars.at(0).compare("END") == 0)
5048
    {
5049
        MSG_TRACE("End of file transfer reached.");
44 andreas 5050
 
155 andreas 5051
        // To make sure the new surface will not be deleted and replaced by the
5052
        // default build in surface, we must delete the "virgin" marker first.
5053
        // This is a file called <project path>/.system.
5054
        string virgin = TConfig::getProjectPath() + "/.system";
5055
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5056
 
44 andreas 5057
        if (_resetSurface)
5058
            _resetSurface();
5059
        else
5060
        {
5061
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5062
        }
43 andreas 5063
    }
23 andreas 5064
}
5065
 
318 andreas 5066
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5067
{
5068
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5069
 
5070
    mLevelSend = true;
5071
}
5072
 
5073
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5074
{
5075
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5076
 
5077
    mLevelSend = false;
5078
}
5079
 
5080
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5081
{
5082
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5083
 
5084
    mRxOn = true;
5085
}
5086
 
5087
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5088
{
5089
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5090
 
5091
    mRxOn = false;
5092
}
5093
 
22 andreas 5094
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5095
{
5096
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5097
 
5098
    if (pars.empty())
5099
    {
5100
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
5101
        return;
5102
    }
5103
 
16 andreas 5104
    TError::clear();
14 andreas 5105
    int c = atoi(pars[0].c_str());
5106
 
5107
    if (c <= 0)
5108
    {
5109
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
5110
        return;
5111
    }
5112
 
5113
    vector<int> chans = { c };
193 andreas 5114
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5115
 
5116
    if (TError::isError() || map.empty())
5117
        return;
5118
 
5119
    vector<Button::TButton *> buttons = collectButtons(map);
5120
 
83 andreas 5121
    if (buttons.size() > 0)
14 andreas 5122
    {
83 andreas 5123
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5124
 
118 andreas 5125
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5126
        {
5127
            Button::TButton *bt = *mapIter;
5128
 
195 andreas 5129
            if (bt->getButtonType() == GENERAL)
83 andreas 5130
                bt->setActive(1);
5131
        }
14 andreas 5132
    }
5133
}
5134
 
22 andreas 5135
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5136
{
5137
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5138
 
5139
    if (pars.empty())
5140
    {
5141
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
5142
        return;
5143
    }
5144
 
16 andreas 5145
    TError::clear();
14 andreas 5146
    int c = atoi(pars[0].c_str());
5147
 
5148
    if (c <= 0)
5149
    {
5150
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
5151
        return;
5152
    }
5153
 
5154
    vector<int> chans = { c };
193 andreas 5155
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5156
 
5157
    if (TError::isError() || map.empty())
5158
        return;
5159
 
5160
    vector<Button::TButton *> buttons = collectButtons(map);
5161
 
83 andreas 5162
    if (buttons.size() > 0)
14 andreas 5163
    {
83 andreas 5164
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5165
 
118 andreas 5166
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5167
        {
5168
            Button::TButton *bt = *mapIter;
5169
 
195 andreas 5170
            if (bt->getButtonType() == GENERAL)
83 andreas 5171
                bt->setActive(0);
5172
        }
14 andreas 5173
    }
5174
}
5175
 
22 andreas 5176
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5177
{
5178
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5179
 
5180
    if (pars.size() < 2)
5181
    {
5182
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
5183
        return;
5184
    }
5185
 
16 andreas 5186
    TError::clear();
15 andreas 5187
    int c = atoi(pars[0].c_str());
5188
    int level = atoi(pars[1].c_str());
5189
 
5190
    if (c <= 0)
5191
    {
5192
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
5193
        return;
5194
    }
5195
 
5196
    vector<int> chans = { c };
193 andreas 5197
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5198
 
5199
    if (TError::isError() || map.empty())
5200
    {
5201
        MSG_WARNING("No bargraphs found!");
5202
        return;
5203
    }
5204
 
5205
    vector<Button::TButton *> buttons = collectButtons(map);
5206
 
83 andreas 5207
    if (buttons.size() > 0)
15 andreas 5208
    {
83 andreas 5209
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5210
 
118 andreas 5211
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5212
        {
83 andreas 5213
            Button::TButton *bt = *mapIter;
5214
 
195 andreas 5215
            if (bt->getButtonType() == BARGRAPH)
83 andreas 5216
                bt->drawBargraph(bt->getActiveInstance(), level);
195 andreas 5217
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH)
83 andreas 5218
            {
5219
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5220
                bt->setActive(state);
5221
            }
15 andreas 5222
        }
5223
    }
5224
}
5225
 
22 andreas 5226
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5227
{
5228
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5229
 
5230
    if (pars.size() < 4)
5231
    {
5232
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
5233
        return;
5234
    }
5235
 
16 andreas 5236
    TError::clear();
15 andreas 5237
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5238
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5239
 
5240
    if (TError::isError() || map.empty())
5241
    {
5242
        MSG_WARNING("No system buttons found.");
5243
        return;
5244
    }
5245
 
5246
    vector<Button::TButton *> buttons = collectButtons(map);
5247
    vector<Button::TButton *>::iterator mapIter;
5248
 
5249
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5250
    {
5251
        Button::TButton *bt = *mapIter;
5252
        bt->setActive(0);
5253
    }
5254
}
5255
 
162 andreas 5256
/**
5257
 * Send the version of the panel to the NetLinx. This is the real application
5258
 * version.
5259
 */
127 andreas 5260
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5261
{
5262
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5263
 
5264
    amx::ANET_SEND scmd;
5265
    scmd.port = 1;
5266
    scmd.channel = 0;
5267
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5268
    scmd.MC = 0x008c;
5269
 
5270
    if (gAmxNet)
5271
        gAmxNet->sendCommand(scmd);
5272
    else
5273
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5274
}
5275
 
162 andreas 5276
/**
5277
 * Returns the user name used to connect to a SIP server. An empty string is
5278
 * returned if there is no user defined.
5279
 */
279 andreas 5280
#ifndef _NOSIP_
127 andreas 5281
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5282
{
5283
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5284
 
5285
    if (!TConfig::getSIPstatus())
5286
        return;
5287
 
5288
    amx::ANET_SEND scmd;
5289
    scmd.port = 1;
5290
    scmd.channel = 0;
5291
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5292
    scmd.MC = 0x008c;
5293
 
5294
    if (gAmxNet)
5295
        gAmxNet->sendCommand(scmd);
5296
    else
5297
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5298
}
279 andreas 5299
#endif
14 andreas 5300
/**
147 andreas 5301
 * Flip to specified page using the named animation.
5302
 * FIXME: Implement animation for pages.
5303
 */
5304
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
5305
{
5306
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
5307
 
5308
    if (pars.size() < 4)
5309
    {
5310
        MSG_ERROR("Less than 4 parameters!");
5311
        return;
5312
    }
5313
 
5314
    TError::clear();
5315
    string pname = pars[0];
5316
//    string ani = pars[1];
5317
//    int origin = atoi(pars[2].c_str());
5318
//    int duration = atoi(pars[3].c_str());
5319
 
5320
    // FIXME: Animation of pages is currently not implemented.
5321
 
5322
    if (!pname.empty())
5323
        setPage(pname);
5324
    else if (mPreviousPage)
5325
        setPage(mPreviousPage);
5326
}
5327
 
5328
/**
14 andreas 5329
 * Add a specific popup page to a specified popup group if it does not already
5330
 * exist. If the new popup is added to a group which has a popup displayed on
5331
 * the current page along with the new pop-up, the displayed popup will be
5332
 * hidden and the new popup will be displayed.
5333
 */
22 andreas 5334
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5335
{
5336
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5337
 
5338
    if (pars.size() < 2)
5339
    {
5340
        MSG_ERROR("Less than 2 parameters!");
5341
        return;
5342
    }
5343
 
16 andreas 5344
    TError::clear();
11 andreas 5345
    closeGroup(pars[1]);
14 andreas 5346
 
96 andreas 5347
    TPage *page = nullptr;
5348
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 5349
 
11 andreas 5350
    if (!subPage)
5351
    {
5352
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
5353
        return;
5354
    }
5355
 
162 andreas 5356
    if (!page)
5357
    {
5358
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
5359
        return;
5360
    }
5361
 
152 andreas 5362
    page->addSubPage(subPage);
11 andreas 5363
    subPage->setGroup(pars[1]);
14 andreas 5364
    subPage->setZOrder(page->getNextZOrder());
152 andreas 5365
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 5366
    subPage->show();
5367
}
5368
 
14 andreas 5369
/**
5370
 * Clear all popup pages from specified popup group.
5371
 */
22 andreas 5372
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5373
{
5374
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5375
 
5376
    if (pars.size() < 1)
5377
    {
5378
        MSG_ERROR("Expecting 1 parameter but got only 1!");
5379
        return;
5380
    }
5381
 
16 andreas 5382
    TError::clear();
11 andreas 5383
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
5384
 
83 andreas 5385
    if (pageList.size() > 0)
11 andreas 5386
    {
83 andreas 5387
        vector<SUBPAGELIST_T>::iterator pgIter;
5388
 
5389
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 5390
        {
83 andreas 5391
            if (pgIter->group.compare(pars[0]) == 0)
5392
            {
5393
                pgIter->group.clear();
5394
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 5395
 
83 andreas 5396
                if (pg)
5397
                    pg->setGroup(pgIter->group);
5398
            }
11 andreas 5399
        }
5400
    }
5401
}
5402
 
14 andreas 5403
/**
5404
 * Delete a specific popup page from specified popup group if it exists.
5405
 */
22 andreas 5406
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5407
{
5408
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5409
 
5410
    if (pars.size() < 2)
5411
    {
5412
        MSG_ERROR("Less than 2 parameters!");
5413
        return;
5414
    }
5415
 
16 andreas 5416
    TError::clear();
11 andreas 5417
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
5418
 
5419
    if (!listPg.isValid)
5420
        return;
5421
 
5422
    if (listPg.group.compare(pars[1]) == 0)
5423
    {
5424
        listPg.group.clear();
5425
        TSubPage *pg = getSubPage(listPg.pageID);
5426
 
5427
        if (pg)
5428
            pg->setGroup(listPg.group);
5429
    }
5430
}
5431
 
14 andreas 5432
/**
15 andreas 5433
 * Set the hide effect for the specified popup page to the named hide effect.
5434
 */
22 andreas 5435
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 5436
{
5437
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
5438
 
5439
    if (pars.size() < 2)
5440
    {
5441
        MSG_ERROR("Less than 2 parameters!");
5442
        return;
5443
    }
5444
 
16 andreas 5445
    TError::clear();
96 andreas 5446
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5447
 
5448
    if (!pg)
96 andreas 5449
        return;
15 andreas 5450
 
162 andreas 5451
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5452
        pg->setHideEffect(SE_FADE);
162 andreas 5453
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5454
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 5455
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5456
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 5457
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5458
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 5459
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5460
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 5461
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5462
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5463
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5464
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5465
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5466
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 5467
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5468
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
5469
    else
5470
        pg->setHideEffect(SE_NONE);
5471
}
5472
 
5473
/**
5474
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
5475
 * however, the command will specify both. This command sets the location at
5476
 * which the effect will end at.
5477
 */
22 andreas 5478
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 5479
{
5480
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
5481
 
5482
    if (pars.size() < 2)
5483
    {
5484
        MSG_ERROR("Less than 2 parameters!");
5485
        return;
5486
    }
5487
 
16 andreas 5488
    TError::clear();
15 andreas 5489
    size_t pos = pars[1].find(",");
5490
    int x, y;
5491
 
5492
    if (pos == string::npos)
5493
    {
5494
        x = atoi(pars[1].c_str());
5495
        y = 0;
5496
    }
5497
    else
5498
    {
5499
        x = atoi(pars[1].substr(0, pos).c_str());
5500
        y = atoi(pars[1].substr(pos+1).c_str());
5501
    }
5502
 
96 andreas 5503
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5504
 
5505
    if (!pg)
96 andreas 5506
        return;
15 andreas 5507
 
5508
    pg->setHideEndPosition(x, y);
5509
}
5510
 
5511
/**
5512
 * Set the hide effect time for the specified popup page.
5513
 */
22 andreas 5514
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 5515
{
5516
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
5517
 
5518
    if (pars.size() < 2)
5519
    {
5520
        MSG_ERROR("Less than 2 parameters!");
5521
        return;
5522
    }
5523
 
16 andreas 5524
    TError::clear();
96 andreas 5525
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5526
 
5527
    if (!pg)
96 andreas 5528
        return;
15 andreas 5529
 
5530
    pg->setHideTime(atoi(pars[1].c_str()));
5531
}
5532
 
5533
/**
14 andreas 5534
 * Close all popups on a specified page. If the page name is empty, the current
5535
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
5536
 */
22 andreas 5537
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5538
{
5539
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5540
 
16 andreas 5541
    TError::clear();
11 andreas 5542
    TPage *pg;
5543
 
5544
    if (pars.size() == 0)
5545
        pg = getPage(mActualPage);
5546
    else
5547
        pg = getPage(pars[0]);
5548
 
5549
    if (!pg)
5550
        return;
5551
 
12 andreas 5552
    pg->drop();
14 andreas 5553
    pg->resetZOrder();
11 andreas 5554
}
5555
 
14 andreas 5556
/**
5557
 * Deactivate a specific popup page on either a specified page or the current
5558
 * page. If the page name is empty, the current page is used. If the popup page
5559
 * is part of a group, the whole group is deactivated. This command works in
5560
 * the same way as the ’Hide Popup’ command in TPDesign4.
5561
 */
22 andreas 5562
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5563
{
5564
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5565
 
5566
    if (pars.size() < 1)
5567
    {
5568
        MSG_ERROR("At least 1 parameter is expected!");
5569
        return;
5570
    }
5571
 
16 andreas 5572
    TError::clear();
14 andreas 5573
    hideSubPage(pars[0]);
12 andreas 5574
}
5575
 
14 andreas 5576
/**
5577
 * Toggle a specific popup page on either a specified page or the current page.
5578
 * If the page name is empty, the current page is used. Toggling refers to the
5579
 * activating/deactivating (On/Off) of a popup page. This command works in the
5580
 * same way as the ’Toggle Popup’ command in TPDesign4.
5581
 */
22 andreas 5582
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5583
{
5584
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5585
 
12 andreas 5586
    if (pars.size() < 1)
5587
    {
5588
        MSG_ERROR("At least 1 parameter is expected!");
5589
        return;
5590
    }
5591
 
16 andreas 5592
    TError::clear();
14 andreas 5593
    TPage *page = getPage(mActualPage);
5594
 
5595
    if (!page)
5596
    {
5597
        MSG_ERROR("No active page found! Internal error.");
5598
        return;
5599
    }
5600
 
12 andreas 5601
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 5602
 
12 andreas 5603
    if (!pg)
5604
        return;
14 andreas 5605
 
12 andreas 5606
    if (pg->isVisible())
5607
    {
5608
        pg->drop();
162 andreas 5609
        page->decZOrder();
12 andreas 5610
        return;
5611
    }
5612
 
5613
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 5614
 
12 andreas 5615
    while(sub)
5616
    {
5617
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
5618
            sub->drop();
14 andreas 5619
 
12 andreas 5620
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
5621
    }
5622
 
152 andreas 5623
    pg->setZOrder(page->getNextZOrder());
5624
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 5625
    pg->show();
5626
}
5627
 
14 andreas 5628
/**
5629
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
5630
 * the pop-up page is part of a group, the whole group is deactivated. This
5631
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
5632
 */
22 andreas 5633
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5634
{
5635
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5636
 
12 andreas 5637
    if (pars.size() < 1)
5638
    {
5639
        MSG_ERROR("At least 1 parameter is expected!");
5640
        return;
5641
    }
5642
 
16 andreas 5643
    TError::clear();
14 andreas 5644
    TPage *page = getPage(mActualPage);
5645
 
5646
    if (!page)
5647
    {
5648
        MSG_ERROR("No active page found! Internal error.");
5649
        return;
5650
    }
5651
 
12 andreas 5652
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 5653
 
12 andreas 5654
    if (pg)
14 andreas 5655
    {
5656
        pg->drop();
162 andreas 5657
        page->decZOrder();
14 andreas 5658
    }
12 andreas 5659
}
5660
 
14 andreas 5661
/**
5662
 * Set the modality of a specific popup page to Modal or NonModal.
5663
 * A Modal popup page, when active, only allows you to use the buttons and
5664
 * features on that popup page. All other buttons on the panel page are
5665
 * inactivated.
5666
 */
22 andreas 5667
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5668
{
5669
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5670
 
12 andreas 5671
    if (pars.size() < 2)
5672
    {
5673
        MSG_ERROR("Expecting 2 parameters!");
5674
        return;
5675
    }
14 andreas 5676
 
16 andreas 5677
    TError::clear();
12 andreas 5678
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 5679
 
12 andreas 5680
    if (pg)
5681
    {
162 andreas 5682
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 5683
            pg->setModal(1);
5684
        else
5685
            pg->setModal(0);
5686
    }
5687
}
5688
 
14 andreas 5689
/**
5690
 * Activate a specific popup page to launch on either a specified page or the
5691
 * current page. If the page name is empty, the current page is used. If the
5692
 * popup page is already on, do not re-draw it. This command works in the same
5693
 * way as the ’Show Popup’ command in TPDesign4.
5694
 */
22 andreas 5695
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5696
{
5697
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5698
 
5699
    if (pars.size() < 1)
5700
    {
5701
        MSG_ERROR("At least 1 parameter is expected!");
5702
        return;
5703
    }
5704
 
16 andreas 5705
    TError::clear();
14 andreas 5706
    showSubPage(pars[0]);
12 andreas 5707
}
5708
 
14 andreas 5709
/**
15 andreas 5710
 * Set a specific popup page to timeout within a specified time. If timeout is
5711
 * empty, popup page will clear the timeout.
5712
 */
22 andreas 5713
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 5714
{
5715
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
5716
 
5717
    if (pars.size() < 2)
5718
    {
5719
        MSG_ERROR("Expecting 2 parameters!");
5720
        return;
5721
    }
5722
 
16 andreas 5723
    TError::clear();
96 andreas 5724
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5725
 
5726
    if (!pg)
96 andreas 5727
        return;
15 andreas 5728
 
5729
    pg->setTimeout(atoi(pars[1].c_str()));
5730
}
5731
 
5732
/**
14 andreas 5733
 * Close all popups on all pages. This command works in the same way as the
5734
 * 'Clear All' command in TPDesign 4.
5735
 */
22 andreas 5736
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 5737
{
5738
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5739
 
16 andreas 5740
    TError::clear();
12 andreas 5741
    PCHAIN_T *chain = mPchain;
14 andreas 5742
 
12 andreas 5743
    while(chain)
5744
    {
5745
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 5746
 
12 andreas 5747
        while (sub)
5748
        {
14 andreas 5749
            MSG_DEBUG("Dopping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 5750
            sub->drop();
5751
            sub = chain->page->getNextSubPage();
5752
        }
14 andreas 5753
 
12 andreas 5754
        chain = chain->next;
5755
    }
14 andreas 5756
 
5757
    TPage *page = getPage(mActualPage);
5758
 
5759
    if (!page)
5760
    {
5761
        MSG_ERROR("No active page found! Internal error.");
5762
        return;
5763
    }
5764
 
5765
    page->resetZOrder();
12 andreas 5766
}
5767
 
14 andreas 5768
/**
15 andreas 5769
 * Set the show effect for the specified popup page to the named show effect.
5770
 */
22 andreas 5771
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 5772
{
5773
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
5774
 
5775
    if (pars.size() < 2)
5776
    {
5777
        MSG_ERROR("Less than 2 parameters!");
5778
        return;
5779
    }
5780
 
16 andreas 5781
    TError::clear();
96 andreas 5782
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5783
 
5784
    if (!pg)
96 andreas 5785
        return;
15 andreas 5786
 
162 andreas 5787
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5788
        pg->setShowEffect(SE_FADE);
162 andreas 5789
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5790
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 5791
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5792
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 5793
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5794
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 5795
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5796
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 5797
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5798
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5799
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5800
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5801
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5802
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 5803
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5804
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
5805
    else
5806
        pg->setShowEffect(SE_NONE);
5807
}
5808
 
162 andreas 5809
/**
5810
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
5811
 * however, the command will specify both. This command sets the location at
5812
 * which the effect will begin.
5813
 */
22 andreas 5814
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 5815
{
5816
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
5817
 
5818
    if (pars.size() < 2)
5819
    {
5820
        MSG_ERROR("Less than 2 parameters!");
5821
        return;
5822
    }
5823
 
16 andreas 5824
    TError::clear();
15 andreas 5825
    size_t pos = pars[1].find(",");
5826
    int x, y;
5827
 
5828
    if (pos == string::npos)
5829
    {
5830
        x = atoi(pars[1].c_str());
5831
        y = 0;
5832
    }
5833
    else
5834
    {
5835
        x = atoi(pars[1].substr(0, pos).c_str());
5836
        y = atoi(pars[1].substr(pos+1).c_str());
5837
    }
5838
 
96 andreas 5839
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5840
 
5841
    if (!pg)
96 andreas 5842
        return;
15 andreas 5843
 
5844
    pg->setShowEndPosition(x, y);
5845
}
5846
 
5847
/**
5848
 * Set the show effect time for the specified popup page.
5849
 */
22 andreas 5850
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 5851
{
5852
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
5853
 
5854
    if (pars.size() < 2)
5855
    {
5856
        MSG_ERROR("Less than 2 parameters!");
5857
        return;
5858
    }
5859
 
16 andreas 5860
    TError::clear();
96 andreas 5861
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5862
 
5863
    if (!pg)
96 andreas 5864
        return;
15 andreas 5865
 
5866
    pg->setShowTime(atoi(pars[1].c_str()));
5867
}
5868
 
5869
/**
14 andreas 5870
 * Flips to a page with a specified page name. If the page is currently active,
5871
 * it will not redraw the page.
5872
 */
22 andreas 5873
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5874
{
5875
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5876
 
15 andreas 5877
    if (pars.empty())
5878
    {
5879
        MSG_WARNING("Got no page parameter!");
5880
        return;
5881
    }
14 andreas 5882
 
16 andreas 5883
    TError::clear();
15 andreas 5884
    setPage(pars[0]);
5885
}
5886
 
5887
/**
38 andreas 5888
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
5889
 * Syntax:
5890
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
5891
 * Variable:
5892
 *      variable text address range = 1 - 4000.
5893
 *      start state = Beginning of button state (0= current state).
5894
 *      end state = End of button state.
5895
 *      time = In 1/10 second intervals.
5896
 * Example:
5897
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
5898
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
5899
 *
5900
 * @param port      The port number
5901
 * @param channels  The channels of the buttons
5902
 * @param pars      The parameters
5903
 */
5904
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
5905
{
5906
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
5907
 
5908
    if (pars.size() < 3)
5909
    {
5910
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
5911
        return;
5912
    }
5913
 
5914
    TError::clear();
5915
    int stateStart = atoi(pars[0].c_str());
5916
    int endState = atoi(pars[1].c_str());
5917
    int runTime = atoi(pars[2].c_str());
5918
 
193 andreas 5919
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 5920
 
5921
    if (TError::isError() || map.empty())
5922
        return;
5923
 
5924
    vector<Button::TButton *> buttons = collectButtons(map);
5925
 
83 andreas 5926
    if (buttons.size() > 0)
38 andreas 5927
    {
83 andreas 5928
        vector<Button::TButton *>::iterator mapIter;
5929
 
5930
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5931
        {
5932
            Button::TButton *bt = *mapIter;
5933
            bt->startAnimation(stateStart, endState, runTime);
5934
        }
38 andreas 5935
    }
5936
}
5937
 
5938
/**
15 andreas 5939
 * Add page flip action to a button if it does not already exist.
5940
 */
5941
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
5942
{
5943
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
5944
 
5945
    if (pars.size() < 2)
5946
    {
5947
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
14 andreas 5948
        return;
15 andreas 5949
    }
14 andreas 5950
 
16 andreas 5951
    TError::clear();
15 andreas 5952
    string action = pars[0];
5953
    string pname = pars[1];
14 andreas 5954
 
193 andreas 5955
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 5956
 
15 andreas 5957
    if (TError::isError() || map.empty())
5958
        return;
5959
 
5960
    vector<Button::TButton *> buttons = collectButtons(map);
5961
 
83 andreas 5962
    if (buttons.size() > 0)
12 andreas 5963
    {
83 andreas 5964
        vector<Button::TButton *>::iterator mapIter;
5965
 
5966
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5967
        {
5968
            Button::TButton *bt = *mapIter;
252 andreas 5969
//            setButtonCallbacks(bt);
83 andreas 5970
            bt->addPushFunction(action, pname);
5971
        }
15 andreas 5972
    }
5973
}
12 andreas 5974
 
15 andreas 5975
/**
43 andreas 5976
 * Append non-unicode text.
5977
 */
5978
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
5979
{
5980
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
5981
 
5982
    if (pars.size() < 1)
5983
    {
5984
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 5985
#if TESTMODE == 1
5986
        __done = true;
5987
#endif
43 andreas 5988
        return;
5989
    }
5990
 
5991
    TError::clear();
5992
    int btState = atoi(pars[0].c_str());
5993
    string text;
5994
 
5995
    if (pars.size() > 1)
5996
        text = pars[1];
5997
 
193 andreas 5998
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 5999
 
6000
    if (TError::isError() || map.empty())
330 andreas 6001
    {
6002
#if TESTMODE == 1
6003
        __done = true;
6004
#endif
43 andreas 6005
        return;
330 andreas 6006
    }
43 andreas 6007
 
6008
    vector<Button::TButton *> buttons = collectButtons(map);
6009
 
162 andreas 6010
    if (buttons.empty())
330 andreas 6011
    {
6012
#if TESTMODE == 1
6013
        __done = true;
6014
#endif
162 andreas 6015
        return;
330 andreas 6016
    }
162 andreas 6017
 
6018
    vector<Button::TButton *>::iterator mapIter;
6019
 
6020
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6021
    {
162 andreas 6022
        Button::TButton *bt = *mapIter;
43 andreas 6023
 
162 andreas 6024
        if (btState == 0)       // All instances?
43 andreas 6025
        {
162 andreas 6026
            int bst = bt->getNumberInstances();
43 andreas 6027
 
162 andreas 6028
            for (int i = 0; i < bst; i++)
330 andreas 6029
            {
162 andreas 6030
                bt->appendText(text, i);
330 andreas 6031
#if TESTMODE == 1
6032
                if (_gTestMode)
6033
                    _gTestMode->setResult(bt->getText(i));
6034
 
6035
                __success = true;
6036
#endif
6037
            }
43 andreas 6038
        }
162 andreas 6039
        else
330 andreas 6040
        {
162 andreas 6041
            bt->appendText(text, btState - 1);
330 andreas 6042
#if TESTMODE == 1
6043
            if (_gTestMode)
6044
                _gTestMode->setResult(bt->getText(btState - 1));
6045
 
6046
            __success = true;
6047
#endif
6048
        }
43 andreas 6049
    }
330 andreas 6050
#if TESTMODE == 1
6051
    __done = true;
6052
#endif
43 andreas 6053
}
6054
 
6055
/**
60 andreas 6056
 * @brief Append unicode text. Same format as ^UNI.
6057
 * This command allows to set up to 50 characters of ASCII code. The unicode
6058
 * characters must be set as hex numbers.
6059
 */
6060
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6061
{
6062
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
6063
 
6064
    if (pars.size() < 1)
6065
    {
6066
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6067
#if TESTMODE == 1
6068
        __done = true;
6069
#endif
60 andreas 6070
        return;
6071
    }
6072
 
6073
    TError::clear();
6074
    int btState = atoi(pars[0].c_str());
6075
    string text;
6076
    char ch[3];
6077
 
162 andreas 6078
    if (pars.size() > 1 && (pars.size() % 2) == 0)
60 andreas 6079
    {
162 andreas 6080
        try
60 andreas 6081
        {
162 andreas 6082
            text = pars[1];
6083
            // Because the unicode characters are hex numbers, we scan the text
6084
            // and convert the hex numbers into real numbers.
6085
            size_t len = text.length();
6086
            bool inHex = false;
6087
            int lastChar = 0;
6088
            std::wstring uniText;
6089
            int uniPos = 0;
60 andreas 6090
 
162 andreas 6091
            for (size_t i = 0; i < len; i++)
60 andreas 6092
            {
162 andreas 6093
                int c = text.at(i);
60 andreas 6094
 
162 andreas 6095
                if (!inHex && isHex(c))
6096
                {
6097
                    inHex = true;
6098
                    lastChar = c;
6099
                    continue;
6100
                }
6101
 
6102
                if (inHex && !isHex(c))
6103
                    break;
6104
 
6105
                if (inHex && isHex(c))
6106
                {
6107
                    ch[0] = lastChar;
6108
                    ch[1] = c;
6109
                    ch[2] = 0;
6110
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
6111
                    uniText += num;
6112
                    uniPos++;
6113
                    inHex = false;
6114
 
6115
                    if (uniPos >= 50)
6116
                        break;
6117
 
6118
                    continue;
6119
                }
60 andreas 6120
            }
6121
 
162 andreas 6122
            text = CharConvert::UtfConv<std::string>(uniText);
60 andreas 6123
        }
162 andreas 6124
        catch (std::exception const & e)
6125
        {
6126
            MSG_ERROR("Character conversion error: " << e.what());
330 andreas 6127
#if TESTMODE == 1
6128
            __done = true;
6129
#endif
162 andreas 6130
            return;
6131
        }
60 andreas 6132
    }
6133
 
193 andreas 6134
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6135
 
6136
    if (TError::isError() || map.empty())
6137
        return;
6138
 
6139
    vector<Button::TButton *> buttons = collectButtons(map);
6140
 
83 andreas 6141
    if (buttons.size() > 0)
60 andreas 6142
    {
83 andreas 6143
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6144
 
83 andreas 6145
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6146
        {
83 andreas 6147
            Button::TButton *bt = *mapIter;
60 andreas 6148
 
83 andreas 6149
            if (btState == 0)       // All instances?
6150
            {
6151
                int bst = bt->getNumberInstances();
6152
 
6153
                for (int i = 0; i < bst; i++)
330 andreas 6154
                {
83 andreas 6155
                    bt->appendText(text, i);
330 andreas 6156
#if TESTMODE == 1
6157
                    if (_gTestMode)
6158
                        _gTestMode->setResult(bt->getText(i));
6159
 
6160
                    __success = true;
6161
#endif
6162
                }
83 andreas 6163
            }
6164
            else
330 andreas 6165
            {
83 andreas 6166
                bt->appendText(text, btState - 1);
330 andreas 6167
#if TESTMODE == 1
6168
                if (_gTestMode)
6169
                    _gTestMode->setResult(bt->getText(btState - 1));
6170
 
6171
                __success = true;
6172
#endif
6173
            }
60 andreas 6174
        }
6175
    }
330 andreas 6176
#if TESTMODE == 1
6177
    __done = true;
6178
#endif
60 andreas 6179
}
6180
 
6181
/**
43 andreas 6182
 * @brief TPageManager::doBCB Set the border color.
6183
 * Set the border color to the specified color. Only if the specified border
6184
 * color is not the same as the current color.
6185
 * Note: Color can be assigned by color name (without spaces), number or
6186
 * R,G,B value (RRGGBB or RRGGBBAA).
6187
 */
6188
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
6189
{
6190
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
6191
 
6192
    if (pars.size() < 1)
6193
    {
6194
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6195
        return;
6196
    }
6197
 
6198
    TError::clear();
6199
    int btState = atoi(pars[0].c_str());
6200
    string color;
6201
 
6202
    if (pars.size() > 1)
6203
        color = pars[1];
6204
 
193 andreas 6205
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6206
 
6207
    if (TError::isError() || map.empty())
6208
        return;
6209
 
6210
    vector<Button::TButton *> buttons = collectButtons(map);
6211
 
83 andreas 6212
    if (buttons.size() > 0)
43 andreas 6213
    {
83 andreas 6214
        vector<Button::TButton *>::iterator mapIter;
43 andreas 6215
 
83 andreas 6216
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6217
        {
83 andreas 6218
            Button::TButton *bt = *mapIter;
252 andreas 6219
//            setButtonCallbacks(bt);
43 andreas 6220
 
83 andreas 6221
            if (btState == 0)       // All instances?
6222
            {
6223
                int bst = bt->getNumberInstances();
6224
 
6225
                for (int i = 0; i < bst; i++)
6226
                    bt->setBorderColor(color, i);
6227
            }
6228
            else
6229
                bt->setBorderColor(color, btState - 1);
43 andreas 6230
        }
6231
    }
6232
}
60 andreas 6233
 
82 andreas 6234
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
6235
{
6236
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
6237
 
6238
    if (pars.size() < 1)
6239
    {
6240
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6241
        return;
6242
    }
6243
 
6244
    TError::clear();
6245
    int btState = atoi(pars[0].c_str());
6246
    string color;
6247
 
193 andreas 6248
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6249
 
6250
    if (TError::isError() || map.empty())
6251
        return;
6252
 
6253
    vector<Button::TButton *> buttons = collectButtons(map);
6254
 
83 andreas 6255
    if (buttons.size() > 0)
82 andreas 6256
    {
110 andreas 6257
        Button::TButton *bt = buttons[0];
82 andreas 6258
 
110 andreas 6259
        if (btState == 0)       // All instances?
82 andreas 6260
        {
110 andreas 6261
            int bst = bt->getNumberInstances();
82 andreas 6262
 
110 andreas 6263
            for (int i = 0; i < bst; i++)
82 andreas 6264
            {
110 andreas 6265
                color = bt->getBorderColor(i);
82 andreas 6266
 
110 andreas 6267
                if (color.empty())
6268
                    continue;
83 andreas 6269
 
300 andreas 6270
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 6271
            }
110 andreas 6272
        }
6273
        else
6274
        {
6275
            color = bt->getBorderColor(btState - 1);
83 andreas 6276
 
110 andreas 6277
            if (color.empty())
6278
                return;
82 andreas 6279
 
300 andreas 6280
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
82 andreas 6281
        }
6282
    }
6283
}
6284
 
43 andreas 6285
/**
60 andreas 6286
 * @brief Set the fill color to the specified color.
6287
 * Only if the specified fill color is not the same as the current color.
6288
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 6289
 */
60 andreas 6290
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 6291
{
60 andreas 6292
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 6293
 
60 andreas 6294
    if (pars.size() < 1)
15 andreas 6295
    {
60 andreas 6296
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
12 andreas 6297
        return;
6298
    }
14 andreas 6299
 
16 andreas 6300
    TError::clear();
15 andreas 6301
    int btState = atoi(pars[0].c_str());
60 andreas 6302
    string color;
14 andreas 6303
 
60 andreas 6304
    if (pars.size() > 1)
6305
        color = pars[1];
6306
 
193 andreas 6307
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 6308
 
6309
    if (TError::isError() || map.empty())
6310
        return;
6311
 
6312
    vector<Button::TButton *> buttons = collectButtons(map);
6313
 
83 andreas 6314
    if (buttons.size() > 0)
15 andreas 6315
    {
83 andreas 6316
        vector<Button::TButton *>::iterator mapIter;
15 andreas 6317
 
83 andreas 6318
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 6319
        {
83 andreas 6320
            Button::TButton *bt = *mapIter;
252 andreas 6321
//            setButtonCallbacks(bt);
15 andreas 6322
 
83 andreas 6323
            if (btState == 0)       // All instances?
6324
            {
6325
                int bst = bt->getNumberInstances();
6326
 
6327
                for (int i = 0; i < bst; i++)
6328
                    bt->setFillColor(color, i);
6329
            }
6330
            else
6331
                bt->setFillColor(color, btState - 1);
15 andreas 6332
        }
6333
    }
12 andreas 6334
}
6335
 
82 andreas 6336
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
6337
{
6338
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
6339
 
6340
    if (pars.size() < 1)
6341
    {
6342
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6343
        return;
6344
    }
6345
 
6346
    TError::clear();
6347
    int btState = atoi(pars[0].c_str());
6348
    string color;
6349
 
193 andreas 6350
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6351
 
6352
    if (TError::isError() || map.empty())
6353
        return;
6354
 
6355
    vector<Button::TButton *> buttons = collectButtons(map);
6356
 
83 andreas 6357
    if (buttons.size() > 0)
82 andreas 6358
    {
110 andreas 6359
        Button::TButton *bt = buttons[0];
82 andreas 6360
 
110 andreas 6361
        if (btState == 0)       // All instances?
82 andreas 6362
        {
110 andreas 6363
            int bst = bt->getNumberInstances();
82 andreas 6364
 
110 andreas 6365
            for (int i = 0; i < bst; i++)
82 andreas 6366
            {
110 andreas 6367
                color = bt->getFillColor(i);
82 andreas 6368
 
110 andreas 6369
                if (color.empty())
6370
                    continue;
82 andreas 6371
 
300 andreas 6372
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 6373
            }
82 andreas 6374
        }
110 andreas 6375
        else
6376
        {
6377
            color = bt->getFillColor(btState-1);
300 andreas 6378
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 6379
        }
82 andreas 6380
    }
6381
}
6382
 
60 andreas 6383
/**
6384
 * @brief Set the text color to the specified color.
6385
 * Only if the specified text color is not the same as the current color.
6386
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
6387
 */
6388
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 6389
{
60 andreas 6390
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
6391
 
6392
    if (pars.size() < 1)
6393
    {
6394
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6395
        return;
6396
    }
6397
 
6398
    TError::clear();
6399
    int btState = atoi(pars[0].c_str());
6400
    string color;
6401
 
6402
    if (pars.size() > 1)
6403
        color = pars[1];
6404
 
193 andreas 6405
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6406
 
6407
    if (TError::isError() || map.empty())
6408
        return;
6409
 
6410
    vector<Button::TButton *> buttons = collectButtons(map);
6411
 
83 andreas 6412
    if (buttons.size() > 0)
60 andreas 6413
    {
83 andreas 6414
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6415
 
83 andreas 6416
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6417
        {
83 andreas 6418
            Button::TButton *bt = *mapIter;
252 andreas 6419
//            setButtonCallbacks(bt);
60 andreas 6420
 
83 andreas 6421
            if (btState == 0)       // All instances?
6422
            {
6423
                int bst = bt->getNumberInstances();
6424
 
6425
                for (int i = 0; i < bst; i++)
6426
                    bt->setTextColor(color, i);
6427
            }
6428
            else
6429
                bt->setTextColor(color, btState - 1);
60 andreas 6430
        }
6431
    }
18 andreas 6432
}
6433
 
82 andreas 6434
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
6435
{
6436
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
6437
 
6438
    if (pars.size() < 1)
6439
    {
6440
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6441
        return;
6442
    }
6443
 
6444
    TError::clear();
6445
    int btState = atoi(pars[0].c_str());
6446
    string color;
6447
 
193 andreas 6448
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6449
 
6450
    if (TError::isError() || map.empty())
6451
        return;
6452
 
6453
    vector<Button::TButton *> buttons = collectButtons(map);
6454
 
83 andreas 6455
    if (buttons.size() > 0)
82 andreas 6456
    {
110 andreas 6457
        Button::TButton *bt = buttons[0];
82 andreas 6458
 
110 andreas 6459
        if (btState == 0)       // All instances?
82 andreas 6460
        {
110 andreas 6461
            int bst = bt->getNumberInstances();
82 andreas 6462
 
110 andreas 6463
            for (int i = 0; i < bst; i++)
82 andreas 6464
            {
110 andreas 6465
                color = bt->getTextColor(i);
82 andreas 6466
 
110 andreas 6467
                if (color.empty())
6468
                    continue;
82 andreas 6469
 
300 andreas 6470
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 6471
            }
82 andreas 6472
        }
110 andreas 6473
        else
6474
        {
6475
            color = bt->getTextColor(btState - 1);
300 andreas 6476
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 6477
        }
82 andreas 6478
    }
6479
}
6480
 
60 andreas 6481
/**
6482
 * Set the button draw order
6483
 * Determines what order each layer of the button is drawn.
6484
 */
6485
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 6486
{
60 andreas 6487
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 6488
 
60 andreas 6489
    if (pars.size() < 1)
6490
    {
6491
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
32 andreas 6492
        return;
60 andreas 6493
    }
32 andreas 6494
 
60 andreas 6495
    TError::clear();
6496
    int btState = atoi(pars[0].c_str());
6497
    string order;
32 andreas 6498
 
60 andreas 6499
    if (pars.size() > 1)
6500
    {
6501
        string ord = pars[1];
6502
        // Convert the numbers into the expected draw order
6503
        for (size_t i = 0; i < ord.length(); i++)
6504
        {
6505
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
6506
            {
6507
                char hv0[32];
6508
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
6509
                order.append(hv0);
6510
            }
6511
            else
6512
            {
6513
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
6514
                return;
6515
            }
6516
        }
6517
 
6518
        if (order.length() != 10)
6519
        {
6520
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
6521
            return;
6522
        }
6523
    }
6524
 
193 andreas 6525
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6526
 
6527
    if (TError::isError() || map.empty())
32 andreas 6528
        return;
6529
 
60 andreas 6530
    vector<Button::TButton *> buttons = collectButtons(map);
6531
 
83 andreas 6532
    if (buttons.size() > 0)
32 andreas 6533
    {
83 andreas 6534
        vector<Button::TButton *>::iterator mapIter;
32 andreas 6535
 
83 andreas 6536
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6537
        {
83 andreas 6538
            Button::TButton *bt = *mapIter;
252 andreas 6539
//            setButtonCallbacks(bt);
32 andreas 6540
 
83 andreas 6541
            if (btState == 0)       // All instances?
6542
            {
6543
                int bst = bt->getNumberInstances();
6544
 
6545
                for (int i = 0; i < bst; i++)
6546
                    bt->setDrawOrder(order, i);
6547
            }
6548
            else
6549
                bt->setDrawOrder(order, btState - 1);
60 andreas 6550
        }
6551
    }
6552
}
32 andreas 6553
 
60 andreas 6554
/**
6555
 * Set the feedback type of the button.
6556
 * ONLY works on General-type buttons.
6557
 */
6558
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
6559
{
6560
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 6561
 
60 andreas 6562
    if (pars.size() < 1)
6563
    {
6564
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6565
        return;
6566
    }
6567
 
6568
    TError::clear();
6569
    Button::FEEDBACK type = Button::FB_NONE;
6570
    string stype = pars[0];
6571
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
6572
    vector<string>::iterator iter;
6573
    int i = 0;
6574
 
6575
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
6576
    {
6577
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 6578
        {
60 andreas 6579
            type = (Button::FEEDBACK)i;
6580
            break;
32 andreas 6581
        }
60 andreas 6582
 
6583
        i++;
32 andreas 6584
    }
6585
 
193 andreas 6586
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6587
 
6588
    if (TError::isError() || map.empty())
6589
        return;
6590
 
6591
    vector<Button::TButton *> buttons = collectButtons(map);
6592
 
83 andreas 6593
    if (buttons.size() > 0)
60 andreas 6594
    {
83 andreas 6595
        vector<Button::TButton *>::iterator mapIter;
6596
 
6597
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6598
        {
6599
            Button::TButton *bt = *mapIter;
252 andreas 6600
//            setButtonCallbacks(bt);
83 andreas 6601
            bt->setFeedback(type);
6602
        }
60 andreas 6603
    }
32 andreas 6604
}
6605
 
224 andreas 6606
/*
6607
 * Set the input mask for the specified address.
6608
 */
6609
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
6610
{
6611
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
6612
 
6613
    if (pars.size() < 1)
6614
    {
6615
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6616
        return;
6617
    }
6618
 
6619
    TError::clear();
6620
    string mask = pars[0];
6621
    vector<TMap::MAP_T> map = findButtons(port, channels);
6622
 
6623
    if (TError::isError() || map.empty())
6624
        return;
6625
 
6626
    vector<Button::TButton *> buttons = collectButtons(map);
6627
 
6628
    if (buttons.size() > 0)
6629
    {
6630
        vector<Button::TButton *>::iterator mapIter;
6631
 
6632
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6633
        {
6634
            Button::TButton *bt = *mapIter;
6635
            bt->setInputMask(mask);
6636
        }
6637
    }
6638
}
6639
 
106 andreas 6640
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
6641
{
6642
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
6643
 
6644
    if (pars.size() < 5)
6645
    {
6646
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
6647
        return;
6648
    }
6649
 
6650
    TError::clear();
6651
    int btState = atoi(pars[0].c_str());
6652
    int src_port = atoi(pars[1].c_str());
6653
    int src_addr = atoi(pars[2].c_str());
6654
    int src_state = atoi(pars[3].c_str());
6655
    string src_codes = pars[4];
6656
    vector<int> src_channel;
6657
    src_channel.push_back(src_addr);
6658
 
193 andreas 6659
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 6660
 
6661
    if (src_map.size() == 0)
6662
    {
6663
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
6664
        return;
6665
    }
6666
 
6667
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
6668
 
6669
    if (src_buttons.size() == 0)
6670
    {
6671
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
6672
        return;
6673
    }
6674
 
6675
    if (src_buttons[0]->getNumberInstances() < src_state)
6676
    {
6677
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
6678
        return;
6679
    }
6680
 
6681
    if (src_state < 1)
6682
    {
6683
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
6684
        return;
6685
    }
6686
 
6687
    src_state--;
6688
 
6689
    if (btState > 0)
6690
        btState--;
6691
 
193 andreas 6692
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 6693
    vector<Button::TButton *> buttons = collectButtons(map);
6694
    //                        0     1     2     3     4     5     6     7
6695
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
6696
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
6697
                            "VI", "WW" };   // 16, 17
6698
 
6699
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
6700
    {
6701
        vector<string>::iterator iter;
6702
        int idx = 0;
6703
 
6704
        for (iter = codes.begin(); iter != codes.end(); ++iter)
6705
        {
6706
            if (src_codes.find(*iter) != string::npos)
6707
            {
6708
                int j, x, y;
6709
 
6710
                switch(idx)
6711
                {
6712
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
6713
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
6714
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
6715
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
6716
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
6717
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
6718
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
6719
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 6720
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 6721
 
6722
                    case 9:
6723
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
6724
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
6725
                    break;
6726
 
6727
                    case 10:
6728
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
6729
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
6730
                    break;
6731
 
6732
                    case 11:
6733
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
6734
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
6735
                    break;
6736
 
6737
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
6738
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
6739
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
6740
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
6741
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
6742
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
6743
                }
6744
            }
6745
 
6746
            idx++;
6747
        }
6748
    }
6749
}
6750
 
149 andreas 6751
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
6752
{
6753
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
6754
 
6755
    if (pars.size() < 2)
6756
        return;
6757
 
6758
    TError::clear();
6759
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 6760
    string commands;
149 andreas 6761
 
150 andreas 6762
    for (size_t i = 1; i < pars.size(); ++i)
6763
    {
6764
        if (i > 1)
6765
            commands += ",";
6766
 
6767
        commands += pars[i];
6768
    }
6769
 
193 andreas 6770
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 6771
 
6772
    if (TError::isError() || map.empty())
6773
        return;
6774
 
6775
    // Start of parsing the command line
162 andreas 6776
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 6777
    vector<string> parts = StrSplit(commands, "%");
6778
 
162 andreas 6779
    if (parts.empty())
6780
        return;
6781
 
149 andreas 6782
    // Search for all buttons who need to be updated
6783
    vector<Button::TButton *> buttons = collectButtons(map);
6784
 
6785
    if (buttons.size() > 0)
6786
    {
6787
        vector<Button::TButton *>::iterator mapIter;
6788
 
6789
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6790
        {
6791
            Button::TButton *bt = *mapIter;
162 andreas 6792
 
6793
            if (!bt)
6794
            {
6795
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
6796
                continue;
6797
            }
6798
 
149 andreas 6799
            // Iterate through commands and apply them to button
6800
            vector<string>::iterator iter;
6801
 
6802
            for (iter = parts.begin(); iter != parts.end(); ++iter)
6803
            {
6804
                char cmd = iter->at(0);
6805
                char cmd2;
6806
                string content;
6807
 
6808
                switch(cmd)
6809
                {
6810
                    case 'B':   // Border style
6811
                        content = iter->substr(1);
6812
                        bt->setBorderStyle(content, btState);
6813
                    break;
6814
 
6815
                    case 'C':   // Colors
6816
                        cmd2 = iter->at(1);
6817
                        content = iter->substr(2);
6818
 
6819
                        switch(cmd2)
6820
                        {
6821
                            case 'B':   // Border color
6822
                                bt->setBorderColor(content, btState);
6823
                            break;
6824
 
6825
                            case 'F':   // Fill color
6826
                                bt->setFillColor(content, btState);
6827
                            break;
6828
 
6829
                            case 'T':   // Text color
6830
                                bt->setTextColor(content, btState);
6831
                            break;
6832
                        }
6833
                    break;
6834
 
150 andreas 6835
                    case 'D':   // Draw order
6836
                        cmd2 = iter->at(1);
6837
                        content = iter->substr(2);
6838
 
6839
                        if (cmd2 == 'O')
6840
                            bt->setDrawOrder(content, btState);
6841
                    break;
6842
 
149 andreas 6843
                    case 'E':   // Text effect
6844
                        cmd2 = iter->at(1);
6845
                        content = iter->substr(2);
6846
 
6847
                        switch(cmd2)
6848
                        {
6849
                            case 'C':   // Text effect color
6850
                                bt->setTextEffectColor(content, btState);
6851
                            break;
6852
 
6853
                            case 'F':   // Text effect name
6854
                                bt->setTextEffectName(content, btState);
6855
                            break;
6856
 
6857
                            case 'N':   // Enable/disable button
6858
                                bt->setEnable((content[0] == '1' ? true : false));
6859
                            break;
6860
                        }
6861
                    break;
6862
 
6863
                    case 'F':   // Set font file name
6864
                        content = iter->substr(1);
150 andreas 6865
 
6866
                        if (!isdigit(content[0]))
6867
                            bt->setFontFileName(content, -1, btState);
6868
                        else
6869
                            bt->setFontIndex(atoi(content.c_str()), btState);
149 andreas 6870
                    break;
6871
 
6872
                    case 'G':   // Bargraphs
6873
                        cmd2 = iter->at(1);
6874
                        content = iter->substr(2);
6875
 
6876
                        switch(cmd2)
6877
                        {
6878
                            case 'C':   // Bargraph slider color
6879
                                bt->setBargraphSliderColor(content);
6880
                            break;
6881
 
6882
                            case 'D':   // Ramp down time
6883
                                // FIXME: Add function to set ramp time
6884
                            break;
6885
 
6886
                            case 'G':   // Drag increment
6887
                                // FIXME: Add function to set drag increment
6888
                            break;
6889
 
6890
                            case 'H':   // Upper limit
6891
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
6892
                            break;
6893
 
6894
                            case 'I':   // Invert/noninvert
6895
                                // FIXME: Add function to set inverting
6896
                            break;
6897
 
6898
                            case 'L':   // Lower limit
6899
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
6900
                            break;
6901
 
6902
                            case 'N':   // Slider name
6903
                                // FIXME: Add function to set slider name
6904
                            break;
6905
 
6906
                            case 'R':   // Repeat interval
6907
                                // FIXME: Add function to set repeat interval
6908
                            break;
6909
 
6910
                            case 'U':   // Ramp up time
6911
                                // FIXME: Add function to set ramp up time
6912
                            break;
6913
 
6914
                            case 'V':   // Bargraph value
6915
                                // FIXME: Add function to set level value
6916
                            break;
6917
                        }
6918
                    break;
6919
 
152 andreas 6920
                    case 'I':   // Set the icon
6921
                        content = iter->substr(1);
6922
                        bt->setIcon(atoi(content.c_str()), btState);
6923
                    break;
6924
 
149 andreas 6925
                    case 'J':   // Set text justification
150 andreas 6926
                        cmd2 = iter->at(1);
6927
 
6928
                        if (cmd2 != 'T' && cmd2 != 'B' && cmd2 != 'I')
6929
                        {
6930
                            content = iter->substr(1);
152 andreas 6931
                            int just = atoi(content.c_str());
6932
                            int x = 0, y = 0;
6933
 
6934
                            if (just == 0)
6935
                            {
6936
                                vector<string> coords = StrSplit(content, ",");
6937
 
6938
                                if (coords.size() >= 3)
6939
                                {
6940
                                    x = atoi(coords[1].c_str());
6941
                                    y = atoi(coords[2].c_str());
6942
                                }
6943
                            }
6944
 
6945
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
150 andreas 6946
                        }
6947
                        else
6948
                        {
6949
                            content = iter->substr(2);
152 andreas 6950
                            int x = 0, y = 0;
6951
                            int just = atoi(content.c_str());
150 andreas 6952
 
152 andreas 6953
                            if (just == 0)
6954
                            {
6955
                                vector<string> coords = StrSplit(content, ",");
6956
 
6957
                                if (coords.size() >= 3)
6958
                                {
6959
                                    x = atoi(coords[1].c_str());
6960
                                    y = atoi(coords[2].c_str());
6961
                                }
6962
                            }
6963
 
150 andreas 6964
                            switch(cmd2)
6965
                            {
6966
                                case 'B':   // Alignment of bitmap
152 andreas 6967
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
150 andreas 6968
                                break;
6969
 
6970
                                case 'I':   // Alignment of icon
152 andreas 6971
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
150 andreas 6972
                                break;
6973
 
6974
                                case 'T':   // Alignment of text
152 andreas 6975
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
150 andreas 6976
                                break;
6977
                            }
6978
                        }
6979
                    break;
6980
 
6981
                    case 'M':   // Text area
6982
                        cmd2 = iter->at(1);
6983
                        content = iter->substr(2);
6984
 
6985
                        switch(cmd2)
6986
                        {
152 andreas 6987
                            case 'I':   // Set mask image
6988
                                // FIXME: Add code for image mask
6989
                            break;
6990
 
150 andreas 6991
                            case 'K':   // Input mask of text area
6992
                                // FIXME: Add input mask
6993
                            break;
6994
 
6995
                            case 'L':   // Maximum length of text area
6996
                                // FIXME: Add code to set maximum length
6997
                            break;
6998
                        }
6999
                    break;
7000
 
7001
                    case 'O':   // Set feedback typ, opacity
7002
                        cmd2 = iter->at(1);
7003
 
7004
                        switch(cmd2)
7005
                        {
7006
                            case 'P':   // Set opacity
7007
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
7008
                            break;
7009
 
7010
                            case 'T':   // Set feedback type
7011
                                content = iter->substr(2);
7012
                                content = toUpper(content);
7013
 
7014
                                if (content == "NONE")
7015
                                    bt->setFeedback(Button::FB_NONE);
7016
                                else if (content == "CHANNEL")
7017
                                    bt->setFeedback(Button::FB_CHANNEL);
7018
                                else if (content == "INVERT")
7019
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
7020
                                else if (content == "ON")
7021
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
7022
                                else if (content == "MOMENTARY")
7023
                                    bt->setFeedback(Button::FB_MOMENTARY);
7024
                                else if (content == "BLINK")
7025
                                    bt->setFeedback(Button::FB_BLINK);
7026
                                else
7027
                                {
7028
                                    MSG_WARNING("Unknown feedback type " << content);
7029
                                }
7030
                            break;
7031
 
7032
                            default:
7033
                                content = iter->substr(1);
7034
                                // FIXME: Add code to set the feedback type
7035
                        }
7036
                    break;
7037
 
152 andreas 7038
                    case 'P':   // Set picture/bitmap file name
7039
                        content = iter->substr(1);
165 andreas 7040
 
7041
                        if (content.find(".") == string::npos)  // If the image has no extension ...
7042
                        {                                       // we must find the image in the map
7043
                            string iname = findImage(content);
7044
 
7045
                            if (!iname.empty())
7046
                                content = iname;
7047
                        }
7048
 
152 andreas 7049
                        bt->setBitmap(content, btState);
7050
                    break;
7051
 
7052
                    case 'R':   // Set rectangle
7053
                    {
7054
                        content = iter->substr(1);
7055
                        vector<string> corners = StrSplit(content, ",");
7056
 
7057
                        if (corners.size() > 0)
7058
                        {
7059
                            vector<string>::iterator itcorn;
7060
                            int pos = 0;
7061
                            int left, top, right, bottom;
7062
                            left = top = right = bottom = 0;
7063
 
7064
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
7065
                            {
7066
                                switch(pos)
7067
                                {
7068
                                    case 0: left   = atoi(itcorn->c_str()); break;
7069
                                    case 1: top    = atoi(itcorn->c_str()); break;
7070
                                    case 2: right  = atoi(itcorn->c_str()); break;
7071
                                    case 3: bottom = atoi(itcorn->c_str()); break;
7072
                                }
7073
 
7074
                                pos++;
7075
                            }
7076
 
7077
                            if (pos >= 4)
7078
                                bt->setRectangle(left, top, right, bottom);
7079
                        }
7080
                    }
7081
                    break;
7082
 
150 andreas 7083
                    case 'S':   // show/hide, style, sound
7084
                        cmd2 = iter->at(1);
7085
                        content = iter->substr(2);
7086
 
7087
                        switch(cmd2)
7088
                        {
7089
                            case 'F':   // Set focus of text area button
7090
                                // FIXME: Add code to set the focus of text area button
7091
                            break;
7092
 
7093
                            case 'M':   // Submit text
169 andreas 7094
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
7095
                                {
7096
                                    size_t pos = 0;
7097
 
7098
                                    while ((pos = content.find("|")) != string::npos)
7099
                                        content = content.replace(pos, 1, "\n");
7100
                                }
7101
 
150 andreas 7102
                                bt->setText(content, btState);
7103
                            break;
7104
 
7105
                            case 'O':   // Sound
7106
                                bt->setSound(content, btState);
7107
                            break;
7108
 
7109
                            case 'T':   // Button style
7110
                                // FIXME: Add code to set the button style
7111
                            break;
7112
 
7113
                            case 'W':   // Show / hide button
7114
                                if (content[0] == '0')
7115
                                    bt->hide();
7116
                                else
7117
                                    bt->show();
7118
                            break;
7119
                        }
7120
                    break;
7121
 
152 andreas 7122
                    case 'T':   // Set text
7123
                        content = iter->substr(1);
169 andreas 7124
 
7125
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
7126
                        {
7127
                            size_t pos = 0;
7128
 
7129
                            while ((pos = content.find("|")) != string::npos)
7130
                                content = content.replace(pos, 1, "\n");
7131
                        }
7132
 
152 andreas 7133
                        bt->setText(content, btState);
7134
                    break;
7135
 
150 andreas 7136
                    case 'U':   // Set the unicode text
7137
                        if (iter->at(1) == 'N')
7138
                        {
7139
                            content = iter->substr(2);
152 andreas 7140
                            string byte, text;
7141
                            size_t pos = 0;
7142
 
7143
                            while (pos < content.length())
7144
                            {
7145
                                byte = content.substr(pos, 2);
7146
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
7147
                                text += ch;
7148
                                pos += 2;
7149
                            }
7150
 
169 andreas 7151
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
7152
                            {
7153
                                size_t pos = 0;
7154
 
7155
                                while ((pos = text.find("|")) != string::npos)
7156
                                    text = text.replace(pos, 1, "\n");
7157
                            }
7158
 
152 andreas 7159
                            bt->setText(text, btState);
150 andreas 7160
                        }
7161
                    break;
7162
 
7163
                    case 'V':   // Video on / off
7164
                        cmd2 = iter->at(1);
7165
                        // Controlling a computer remotely is not supported.
7166
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
7167
                        {
7168
                            content = iter->substr(2);
7169
                            // FIXME: Add code to switch video on or off
7170
                        }
7171
                    break;
7172
 
7173
                    case 'W':   // Word wrap
152 andreas 7174
                        if (iter->at(1) == 'W')
7175
                        {
7176
                            content = iter->substr(2);
7177
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
7178
                        }
149 andreas 7179
                    break;
7180
                }
7181
            }
7182
        }
7183
    }
7184
}
7185
 
14 andreas 7186
/**
110 andreas 7187
 * Set the maximum length of the text area button. If this value is set to
7188
 * zero (0), the text area has no max length. The maximum length available is
7189
 * 2000. This is only for a Text area input button and not for a Text area input
7190
 * masking button.
7191
 */
7192
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
7193
{
7194
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
7195
 
7196
    if (pars.size() < 1)
7197
    {
7198
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
7199
        return;
7200
    }
7201
 
7202
    TError::clear();
7203
    int maxLen = atoi(pars[0].c_str());
7204
 
7205
    if (maxLen < 0 || maxLen > 2000)
7206
    {
7207
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
7208
        return;
7209
    }
7210
 
193 andreas 7211
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 7212
 
7213
    if (TError::isError() || map.empty())
7214
        return;
7215
 
7216
    vector<Button::TButton *> buttons = collectButtons(map);
7217
 
7218
    if (buttons.size() > 0)
7219
    {
7220
        vector<Button::TButton *>::iterator mapIter;
7221
 
7222
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7223
        {
7224
            Button::TButton *bt = *mapIter;
7225
            bt->setTextMaxChars(maxLen);
7226
        }
7227
    }
7228
}
7229
 
7230
/**
60 andreas 7231
 * Assign a picture to those buttons with a defined address range.
7232
 */
7233
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
7234
{
7235
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
7236
 
7237
    if (pars.size() < 2)
7238
    {
7239
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
7240
        return;
7241
    }
7242
 
7243
    TError::clear();
7244
    int btState = atoi(pars[0].c_str());
7245
    string bitmap = pars[1];
104 andreas 7246
    // If this is a G5 command, we may have up to 2 additional parameters.
7247
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 7248
 
104 andreas 7249
    if (pars.size() > 2)
7250
    {
7251
        slot = atoi(pars[2].c_str());
7252
 
7253
        if (pars.size() >= 4)
7254
        {
7255
            justify = atoi(pars[4].c_str());
7256
 
7257
            if (justify == 0)
7258
            {
7259
                if (pars.size() >= 5)
7260
                    jx = atoi(pars[5].c_str());
7261
 
7262
                if (pars.size() >= 6)
7263
                    jy = atoi(pars[6].c_str());
7264
            }
7265
        }
7266
    }
7267
 
193 andreas 7268
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7269
 
7270
    if (TError::isError() || map.empty())
7271
        return;
7272
 
7273
    vector<Button::TButton *> buttons = collectButtons(map);
7274
 
83 andreas 7275
    if (buttons.size() > 0)
60 andreas 7276
    {
83 andreas 7277
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7278
 
83 andreas 7279
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7280
        {
83 andreas 7281
            Button::TButton *bt = *mapIter;
252 andreas 7282
//            setButtonCallbacks(bt);
60 andreas 7283
 
83 andreas 7284
            if (btState == 0)       // All instances?
7285
            {
7286
                int bst = bt->getNumberInstances();
96 andreas 7287
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 7288
 
7289
                for (int i = 0; i < bst; i++)
104 andreas 7290
                {
7291
                    if (justify >= 0)
7292
                    {
7293
                        if (slot == 2)
7294
                            bt->setIconJustification(justify, jx, jy, i);
7295
                        else
106 andreas 7296
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 7297
                    }
7298
 
7299
                    if (slot >= 0)
7300
                    {
7301
                        switch(slot)
7302
                        {
7303
                            case 0: bt->setCameleon(bitmap, i); break;
7304
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
7305
                            default:
7306
                                bt->setBitmap(bitmap, i);
7307
                        }
7308
                    }
7309
                    else
7310
                        bt->setBitmap(bitmap, i);
7311
                }
83 andreas 7312
            }
7313
            else
104 andreas 7314
            {
7315
                if (justify >= 0)
7316
                {
7317
                    if (slot == 2)
7318
                        bt->setIconJustification(justify, jx, jy, btState);
7319
                    else
106 andreas 7320
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 7321
                }
7322
 
7323
                if (slot >= 0)
7324
                {
7325
                    switch(slot)
7326
                    {
7327
                        case 0: bt->setCameleon(bitmap, btState); break;
7328
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
7329
                        default:
7330
                            bt->setBitmap(bitmap, btState);
7331
                    }
7332
                }
7333
                else
7334
                    bt->setBitmap(bitmap, btState);
7335
            }
60 andreas 7336
        }
7337
    }
7338
}
7339
 
82 andreas 7340
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
7341
{
7342
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
7343
 
7344
    if (pars.size() < 1)
7345
    {
7346
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
7347
        return;
7348
    }
7349
 
7350
    TError::clear();
7351
    int btState = atoi(pars[0].c_str());
7352
    string bmp;
7353
 
193 andreas 7354
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7355
 
7356
    if (TError::isError() || map.empty())
7357
        return;
7358
 
7359
    vector<Button::TButton *> buttons = collectButtons(map);
7360
 
83 andreas 7361
    if (buttons.size() > 0)
82 andreas 7362
    {
110 andreas 7363
        Button::TButton *bt = buttons[0];
82 andreas 7364
 
110 andreas 7365
        if (btState == 0)       // All instances?
82 andreas 7366
        {
110 andreas 7367
            int bst = bt->getNumberInstances();
82 andreas 7368
 
110 andreas 7369
            for (int i = 0; i < bst; i++)
82 andreas 7370
            {
110 andreas 7371
                bmp = bt->getBitmapName(i);
82 andreas 7372
 
110 andreas 7373
                if (bmp.empty())
7374
                    continue;
82 andreas 7375
 
300 andreas 7376
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 7377
            }
82 andreas 7378
        }
110 andreas 7379
        else
7380
        {
7381
            bmp = bt->getTextColor(btState-1);
300 andreas 7382
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 7383
        }
82 andreas 7384
    }
7385
}
7386
 
60 andreas 7387
/**
16 andreas 7388
 * Set the button opacity. The button opacity can be specified as a decimal
7389
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
7390
 * HEX code, as used in the color commands by preceding the HEX code with
7391
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
7392
 * If the opacity is set to zero (0), this does not make the button inactive,
7393
 * only invisible.
7394
 */
7395
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
7396
{
7397
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
7398
 
7399
    if (pars.size() < 2)
7400
    {
7401
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
7402
        return;
7403
    }
7404
 
7405
    TError::clear();
7406
    int btState = atoi(pars[0].c_str());
7407
    int btOpacity = 0;
7408
 
7409
    if (pars[1].at(0) == '#')
7410
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
7411
    else
7412
        btOpacity = atoi(pars[1].c_str());
7413
 
193 andreas 7414
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 7415
 
7416
    if (TError::isError() || map.empty())
7417
        return;
7418
 
7419
    vector<Button::TButton *> buttons = collectButtons(map);
7420
 
83 andreas 7421
    if (buttons.size() > 0)
16 andreas 7422
    {
83 andreas 7423
        vector<Button::TButton *>::iterator mapIter;
16 andreas 7424
 
83 andreas 7425
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 7426
        {
83 andreas 7427
            Button::TButton *bt = *mapIter;
252 andreas 7428
//            setButtonCallbacks(bt);
16 andreas 7429
 
83 andreas 7430
            if (btState == 0)       // All instances?
7431
            {
7432
                int bst = bt->getNumberInstances();
7433
                MSG_DEBUG("Setting opacity " << btOpacity << " on all " << bst << " instances...");
7434
 
7435
                for (int i = 0; i < bst; i++)
7436
                    bt->setOpacity(btOpacity, i);
7437
            }
7438
            else
7439
                bt->setOpacity(btOpacity, btState);
16 andreas 7440
        }
7441
    }
7442
}
7443
 
106 andreas 7444
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
7445
{
7446
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
7447
 
7448
    if (pars.size() < 1)
7449
    {
7450
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
7451
        return;
7452
    }
7453
 
7454
    TError::clear();
7455
    int btState = atoi(pars[0].c_str());
7456
 
193 andreas 7457
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7458
 
7459
    if (TError::isError() || map.empty())
7460
        return;
7461
 
7462
    vector<Button::TButton *> buttons = collectButtons(map);
7463
 
7464
    if (buttons.size() > 0)
7465
    {
110 andreas 7466
        Button::TButton *bt = buttons[0];
106 andreas 7467
 
110 andreas 7468
        if (btState == 0)       // All instances?
106 andreas 7469
        {
110 andreas 7470
            int bst = bt->getNumberInstances();
106 andreas 7471
 
110 andreas 7472
            for (int i = 0; i < bst; i++)
106 andreas 7473
            {
110 andreas 7474
                int oo = bt->getOpacity(i);
7475
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 7476
            }
7477
        }
110 andreas 7478
        else
7479
        {
7480
            int oo = bt->getOpacity(btState-1);
7481
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
7482
        }
106 andreas 7483
    }
7484
}
7485
 
60 andreas 7486
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
7487
{
7488
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
7489
 
7490
    if (pars.size() < 1)
7491
    {
7492
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
7493
        return;
7494
    }
7495
 
7496
    TError::clear();
7497
    // Numbers of styles from 0 to 41
7498
    vector<string> styles = { "No border", "No border", "Single line", "Double line", "Quad line",
7499
                              "Circle 15", "Circle 25", "Single line", "Double line",
7500
                              "Quad line", "Picture frame", "Picture frame", "Double line",
7501
                              "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A",
7502
                              "Bevel-S", "Bevel-M", "Circle 15", "Circle 25", "Neon inactive-S",
7503
                              "Neon inactive-M", "Neon inactive-L", "Neon inactive-L",
7504
                              "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A",
7505
                              "Diamond 55", "Diamond 56" };
7506
    string bor = pars[0];
7507
    string border = "None";
7508
    int ibor = -1;
7509
 
7510
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
7511
        ibor = atoi(bor.c_str());
7512
    else
7513
    {
7514
        vector<string>::iterator iter;
7515
        int i = 0;
7516
 
7517
        for (iter = styles.begin(); iter != styles.end(); ++iter)
7518
        {
7519
            if (strCaseCompare(*iter, bor) == 0)
7520
            {
7521
                ibor = i;
7522
                break;
7523
            }
7524
 
7525
            i++;
7526
        }
7527
    }
7528
 
7529
    if (ibor < 0 || ibor > 41)
7530
    {
7531
        MSG_ERROR("Invalid border type " << bor << "!");
7532
        return;
7533
    }
7534
 
7535
    switch (ibor)
7536
    {
7537
        case 20: border = "Bevel Raised -S"; break;
7538
        case 21: border = "Bevel Raised -M"; break;
7539
        case 24: border = "AMX Elite Raised -S"; break;
7540
        case 25: border = "AMX Elite Inset -S"; break;
7541
        case 26: border = "AMX Elite Raised -M"; break;
7542
        case 27: border = "AMX Elite Inset -M"; break;
7543
        case 28: border = "AMX Elite Raised -L"; break;
7544
        case 29: border = "AMX Elite Inset -L"; break;
7545
        case 30: border = "Circle 35"; break;
7546
        case 31: border = "Circle 45"; break;
7547
        case 32: border = "Circle 55"; break;
7548
        case 33: border = "Circle 65"; break;
7549
        case 34: border = "Circle 75"; break;
7550
        case 35: border = "Circle 85"; break;
7551
        case 36: border = "Circle 95"; break;
7552
        case 37: border = "Circle 105"; break;
7553
        case 38: border = "Circle 115"; break;
7554
        case 39: border = "Circle 125"; break;
7555
        default:
7556
            border = styles[ibor];
7557
    }
7558
 
193 andreas 7559
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7560
 
7561
    if (TError::isError() || map.empty())
7562
        return;
7563
 
7564
    vector<Button::TButton *> buttons = collectButtons(map);
7565
 
83 andreas 7566
    if (buttons.size() > 0)
60 andreas 7567
    {
83 andreas 7568
        vector<Button::TButton *>::iterator mapIter;
7569
 
7570
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7571
        {
7572
            Button::TButton *bt = *mapIter;
252 andreas 7573
//            setButtonCallbacks(bt);
83 andreas 7574
            bt->setBorderStyle(border);
7575
        }
60 andreas 7576
    }
7577
}
7578
 
107 andreas 7579
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
7580
{
7581
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
7582
 
7583
    if (pars.size() < 2)
7584
    {
7585
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
7586
        return;
7587
    }
7588
 
7589
    TError::clear();
7590
    int btState = atoi(pars[0].c_str());
7591
    int videoState = atoi(pars[1].c_str());
7592
 
193 andreas 7593
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 7594
 
7595
    if (TError::isError() || map.empty())
7596
        return;
7597
 
7598
    vector<Button::TButton *> buttons = collectButtons(map);
7599
 
7600
    if (buttons.size() > 0)
7601
    {
7602
        vector<Button::TButton *>::iterator mapIter;
7603
 
7604
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7605
        {
7606
            Button::TButton *bt = *mapIter;
7607
 
7608
            if (btState == 0)       // All instances?
7609
                bt->setDynamic(videoState);
7610
            else
7611
                bt->setDynamic(videoState, btState-1);
7612
        }
7613
    }
7614
}
7615
 
16 andreas 7616
/**
60 andreas 7617
 * Set the border of a button state/states.
7618
 * The border names are available through the TPDesign4 border-name drop-down
7619
 * list.
7620
 */
7621
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
7622
{
7623
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
7624
 
7625
    if (pars.size() < 1)
7626
    {
7627
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
7628
        return;
7629
    }
7630
 
7631
    TError::clear();
7632
    int btState = atoi(pars[0].c_str());
7633
    string border = "None";
7634
 
7635
    if (pars.size() > 1)
7636
        border = pars[1];
7637
 
193 andreas 7638
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7639
 
7640
    if (TError::isError() || map.empty())
7641
        return;
7642
 
7643
    vector<Button::TButton *> buttons = collectButtons(map);
7644
 
83 andreas 7645
    if (buttons.size() > 0)
60 andreas 7646
    {
83 andreas 7647
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7648
 
83 andreas 7649
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7650
        {
83 andreas 7651
            Button::TButton *bt = *mapIter;
252 andreas 7652
//            setButtonCallbacks(bt);
60 andreas 7653
 
83 andreas 7654
            if (btState == 0)       // All instances?
7655
            {
7656
                int bst = bt->getNumberInstances();
7657
 
7658
                for (int i = 0; i < bst; i++)
106 andreas 7659
                    bt->setBorderStyle(border, i+1);
83 andreas 7660
            }
7661
            else
106 andreas 7662
                bt->setBorderStyle(border, btState);
60 andreas 7663
        }
7664
    }
7665
}
7666
 
107 andreas 7667
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
7668
{
7669
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
7670
 
7671
    if (pars.size() < 1)
7672
    {
7673
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
7674
        return;
7675
    }
7676
 
7677
    TError::clear();
7678
    int btState = atoi(pars[0].c_str());
7679
 
193 andreas 7680
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 7681
 
7682
    if (TError::isError() || map.empty())
7683
        return;
7684
 
7685
    vector<Button::TButton *> buttons = collectButtons(map);
7686
 
7687
    if (buttons.size() > 0)
7688
    {
110 andreas 7689
        Button::TButton *bt = buttons[0];
107 andreas 7690
 
110 andreas 7691
        if (btState == 0)       // All instances?
107 andreas 7692
        {
110 andreas 7693
            int bst = bt->getNumberInstances();
107 andreas 7694
 
110 andreas 7695
            for (int i = 0; i < bst; i++)
107 andreas 7696
            {
110 andreas 7697
                string bname = bt->getBorderStyle(i);
300 andreas 7698
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 7699
            }
7700
        }
110 andreas 7701
        else
7702
        {
7703
            string bname = bt->getBorderStyle(btState-1);
300 andreas 7704
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 7705
        }
107 andreas 7706
    }
7707
}
7708
 
60 andreas 7709
/**
16 andreas 7710
 * Set the button size and its position on the page.
7711
 */
7712
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
7713
{
7714
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
7715
 
7716
    if (pars.size() < 1)
7717
    {
7718
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
7719
        return;
7720
    }
7721
 
7722
    TError::clear();
7723
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
7724
    int x, y;
7725
 
83 andreas 7726
    if (pars.size() > 0)
16 andreas 7727
    {
83 andreas 7728
        vector<string>::iterator iter;
7729
 
7730
        for (iter = pars.begin(); iter != pars.end(); iter++)
7731
        {
7732
            if (iter->compare("left") == 0)
7733
                bLeft = true;
7734
            else if (iter->compare("top") == 0)
7735
                bTop = true;
7736
            else if (iter->compare("right") == 0)
7737
                bRight = true;
7738
            else if (iter->compare("bottom") == 0)
7739
                bBottom = true;
7740
        }
16 andreas 7741
    }
7742
 
193 andreas 7743
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 7744
 
7745
    if (TError::isError() || map.empty())
7746
        return;
7747
 
7748
    vector<Button::TButton *> buttons = collectButtons(map);
7749
 
83 andreas 7750
    if (buttons.size() > 0)
16 andreas 7751
    {
83 andreas 7752
        vector<Button::TButton *>::iterator mapIter;
16 andreas 7753
 
83 andreas 7754
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7755
        {
7756
            Button::TButton *bt = *mapIter;
7757
            setButtonCallbacks(bt);
16 andreas 7758
 
83 andreas 7759
            if (bLeft)
7760
                x = 0;
16 andreas 7761
 
83 andreas 7762
            if (bTop)
7763
                y = 0;
16 andreas 7764
 
83 andreas 7765
            if (bRight)
16 andreas 7766
            {
83 andreas 7767
                ulong handle = bt->getHandle();
7768
                int parentID = (handle >> 16) & 0x0000ffff;
7769
                int pwidth = 0;
16 andreas 7770
 
83 andreas 7771
                if (parentID < 500)
16 andreas 7772
                {
83 andreas 7773
                    TPage *pg = getPage(parentID);
7774
 
7775
                    if (!pg)
7776
                    {
7777
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
7778
                        return;
7779
                    }
7780
 
7781
                    pwidth = pg->getWidth();
16 andreas 7782
                }
83 andreas 7783
                else
7784
                {
7785
                    TSubPage *spg = getSubPage(parentID);
16 andreas 7786
 
83 andreas 7787
                    if (!spg)
7788
                    {
7789
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
7790
                        return;
7791
                    }
16 andreas 7792
 
83 andreas 7793
                    pwidth = spg->getWidth();
16 andreas 7794
                }
7795
 
83 andreas 7796
                x = pwidth - bt->getWidth();
16 andreas 7797
            }
7798
 
83 andreas 7799
            if (bBottom)
7800
            {
7801
                ulong handle = bt->getHandle();
7802
                int parentID = (handle >> 16) & 0x0000ffff;
7803
                int pheight = 0;
16 andreas 7804
 
83 andreas 7805
                if (parentID < 500)
7806
                {
7807
                    TPage *pg = getPage(parentID);
16 andreas 7808
 
83 andreas 7809
                    if (!pg)
7810
                    {
7811
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
7812
                        return;
7813
                    }
16 andreas 7814
 
83 andreas 7815
                    pheight = pg->getHeight();
7816
                }
7817
                else
16 andreas 7818
                {
83 andreas 7819
                    TSubPage *spg = getSubPage(parentID);
16 andreas 7820
 
83 andreas 7821
                    if (!spg)
7822
                    {
7823
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
7824
                        return;
7825
                    }
16 andreas 7826
 
83 andreas 7827
                    pheight = spg->getHeight();
16 andreas 7828
                }
7829
 
83 andreas 7830
                y = pheight - bt->getHeight();
16 andreas 7831
            }
7832
 
83 andreas 7833
            bt->setLeftTop(x, y);
16 andreas 7834
        }
7835
    }
7836
}
7837
 
7838
/**
107 andreas 7839
 * Submit text for text area buttons. This command causes the text areas to
7840
 * send their text as strings to the NetLinx Master.
7841
 */
7842
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
7843
{
7844
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
7845
 
7846
    TError::clear();
193 andreas 7847
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 7848
 
7849
    if (TError::isError() || map.empty())
7850
        return;
7851
 
7852
    vector<Button::TButton *> buttons = collectButtons(map);
7853
 
7854
    if (buttons.size() > 0)
7855
    {
7856
        vector<Button::TButton *>::iterator mapIter;
7857
 
7858
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7859
        {
7860
            Button::TButton *bt = *mapIter;
7861
 
195 andreas 7862
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
107 andreas 7863
                return;
7864
 
7865
            amx::ANET_SEND scmd;
7866
            scmd.port = bt->getChannelPort();
7867
            scmd.channel = bt->getChannelNumber();
7868
            scmd.ID = scmd.channel;
7869
            scmd.msg = bt->getText(0);
7870
            scmd.MC = 0x008b;       // string value
7871
 
7872
            if (gAmxNet)
7873
                gAmxNet->sendCommand(scmd);
7874
            else
7875
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
7876
 
7877
        }
7878
    }
7879
}
7880
 
7881
/**
7882
 * Set the sound played when a button is pressed. If the sound name is blank
7883
 * the sound is then cleared. If the sound name is not matched, the button
7884
 * sound is not changed.
7885
 */
7886
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
7887
{
7888
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
7889
 
7890
    if (pars.size() < 2)
7891
    {
7892
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
7893
        return;
7894
    }
7895
 
7896
    if (!gPrjResources)
7897
        return;
7898
 
7899
    TError::clear();
7900
    int btState = atoi(pars[0].c_str());
7901
    string sound = pars[1];
7902
 
7903
    if (!soundExist(sound))
7904
        return;
7905
 
193 andreas 7906
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 7907
 
7908
    if (TError::isError() || map.empty())
7909
        return;
7910
 
7911
    vector<Button::TButton *> buttons = collectButtons(map);
7912
 
7913
    if (buttons.size() > 0)
7914
    {
7915
        vector<Button::TButton *>::iterator mapIter;
7916
 
7917
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7918
        {
7919
            Button::TButton *bt = *mapIter;
7920
 
7921
            if (btState == 0)
7922
            {
7923
                int bst = bt->getNumberInstances();
7924
 
7925
                for (int i = 0; i < bst; i++)
7926
                    bt->setSound(sound, i);
7927
            }
7928
            else
7929
                bt->setSound(sound, btState-1);
7930
        }
7931
    }
7932
}
7933
 
7934
/**
16 andreas 7935
 * Set the button word wrap feature to those buttons with a defined address
7936
 * range. By default, word-wrap is Off.
7937
 */
7938
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
7939
{
7940
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
7941
 
7942
    if (pars.size() < 1)
7943
    {
7944
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
7945
        return;
7946
    }
7947
 
7948
    TError::clear();
7949
    int btState = atoi(pars[0].c_str());
7950
 
193 andreas 7951
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 7952
 
7953
    if (TError::isError() || map.empty())
7954
        return;
7955
 
7956
    vector<Button::TButton *> buttons = collectButtons(map);
7957
 
83 andreas 7958
    if (buttons.size() > 0)
16 andreas 7959
    {
83 andreas 7960
        vector<Button::TButton *>::iterator mapIter;
16 andreas 7961
 
83 andreas 7962
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 7963
        {
83 andreas 7964
            Button::TButton *bt = *mapIter;
252 andreas 7965
//            setButtonCallbacks(bt);
16 andreas 7966
 
83 andreas 7967
            if (btState == 0)       // All instances?
7968
            {
7969
                int bst = bt->getNumberInstances();
7970
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
7971
 
7972
                for (int i = 0; i < bst; i++)
110 andreas 7973
                    bt->setTextWordWrap(true, i);
83 andreas 7974
            }
7975
            else
110 andreas 7976
                bt->setTextWordWrap(true, btState - 1);
16 andreas 7977
        }
7978
    }
7979
}
7980
 
108 andreas 7981
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
7982
{
7983
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
7984
 
7985
    if (pars.size() < 1)
7986
    {
7987
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
7988
        return;
7989
    }
7990
 
7991
    TError::clear();
7992
    int btState = atoi(pars[0].c_str());
7993
 
193 andreas 7994
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 7995
 
7996
    if (TError::isError() || map.empty())
7997
        return;
7998
 
7999
    vector<Button::TButton *> buttons = collectButtons(map);
8000
 
8001
    if (buttons.size() > 0)
8002
    {
110 andreas 8003
        Button::TButton *bt = buttons[0];
108 andreas 8004
 
110 andreas 8005
        if (btState == 0)       // All instances?
108 andreas 8006
        {
110 andreas 8007
            int bst = bt->getNumberInstances();
108 andreas 8008
 
110 andreas 8009
            for (int i = 0; i < bst; i++)
8010
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8011
        }
110 andreas 8012
        else
8013
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8014
    }
8015
}
8016
 
16 andreas 8017
/**
8018
 * Clear all page flips from a button.
8019
 */
22 andreas 8020
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 8021
{
8022
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
8023
 
8024
    TError::clear();
193 andreas 8025
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8026
 
8027
    if (TError::isError() || map.empty())
8028
        return;
8029
 
8030
    vector<Button::TButton *> buttons = collectButtons(map);
8031
 
83 andreas 8032
    if (buttons.size() > 0)
16 andreas 8033
    {
83 andreas 8034
        vector<Button::TButton *>::iterator mapIter;
8035
 
8036
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8037
        {
8038
            Button::TButton *bt = *mapIter;
252 andreas 8039
//            setButtonCallbacks(bt);
83 andreas 8040
            bt->clearPushFunctions();
8041
        }
16 andreas 8042
    }
8043
}
8044
 
8045
/**
8046
 * Delete page flips from button if it already exists.
8047
 */
8048
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
8049
{
8050
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
8051
 
8052
    if (pars.size() < 1)
8053
    {
8054
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8055
        return;
8056
    }
8057
 
8058
    TError::clear();
8059
    string action = pars[0];
8060
    string pname;
8061
 
8062
    if (pars.size() >= 2)
8063
    {
8064
        pname = pars[1];
8065
        vector<Button::TButton *> list;
8066
        // First we search for a subpage because this is more likely
8067
        TSubPage *spg = getSubPage(pname);
8068
 
8069
        if (spg)
8070
            list = spg->getButtons(port, channels[0]);
8071
        else    // Then for a page
8072
        {
8073
            TPage *pg = getPage(pname);
8074
 
8075
            if (pg)
8076
                list = pg->getButtons(port, channels[0]);
8077
            else
8078
            {
8079
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
8080
                return;
8081
            }
8082
        }
8083
 
8084
        if (list.empty())
8085
            return;
8086
 
8087
        vector<Button::TButton *>::iterator it;
8088
 
8089
        for (it = list.begin(); it != list.end(); it++)
8090
        {
8091
            Button::TButton *bt = *it;
252 andreas 8092
//            setButtonCallbacks(bt);
16 andreas 8093
            bt->clearPushFunction(action);
8094
        }
8095
 
8096
        return;
8097
    }
8098
 
8099
    // Here we don't have a page name
193 andreas 8100
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8101
 
8102
    if (TError::isError() || map.empty())
8103
        return;
8104
 
8105
    vector<Button::TButton *> buttons = collectButtons(map);
8106
 
83 andreas 8107
    if (buttons.size() > 0)
16 andreas 8108
    {
83 andreas 8109
        vector<Button::TButton *>::iterator mapIter;
8110
 
8111
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8112
        {
8113
            Button::TButton *bt = *mapIter;
252 andreas 8114
//            setButtonCallbacks(bt);
83 andreas 8115
            bt->clearPushFunction(action);
8116
        }
16 andreas 8117
    }
8118
}
8119
 
8120
/**
8121
 * Enable or disable buttons with a set variable text range.
8122
 */
8123
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
8124
{
8125
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
8126
 
8127
    if (pars.empty())
8128
    {
8129
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
8130
        return;
8131
    }
8132
 
8133
    TError::clear();
8134
    int cvalue = atoi(pars[0].c_str());
8135
 
193 andreas 8136
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8137
 
8138
    if (TError::isError() || map.empty())
8139
        return;
8140
 
8141
    vector<Button::TButton *> buttons = collectButtons(map);
8142
 
83 andreas 8143
    if (buttons.size() > 0)
16 andreas 8144
    {
83 andreas 8145
        vector<Button::TButton *>::iterator mapIter;
8146
 
8147
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8148
        {
8149
            Button::TButton *bt = *mapIter;
252 andreas 8150
//            setButtonCallbacks(bt);
83 andreas 8151
            bt->setEnable(((cvalue)?true:false));
8152
        }
16 andreas 8153
    }
8154
}
8155
 
8156
/**
8157
 * Set a font to a specific Font ID value for those buttons with a defined
8158
 * address range. Font ID numbers are generated by the TPDesign4 programmers
8159
 * report.
8160
 */
8161
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
8162
{
8163
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
8164
 
8165
    if (pars.size() < 2)
8166
    {
8167
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8168
        return;
8169
    }
8170
 
8171
    TError::clear();
8172
    int btState = atoi(pars[0].c_str());
8173
    int fvalue = atoi(pars[1].c_str());
8174
 
193 andreas 8175
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8176
 
8177
    if (TError::isError() || map.empty())
8178
        return;
8179
 
8180
    vector<Button::TButton *> buttons = collectButtons(map);
8181
 
83 andreas 8182
    if (buttons.size() > 0)
16 andreas 8183
    {
83 andreas 8184
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8185
 
83 andreas 8186
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8187
        {
83 andreas 8188
            Button::TButton *bt = *mapIter;
252 andreas 8189
//            setButtonCallbacks(bt);
16 andreas 8190
 
83 andreas 8191
            if (btState == 0)       // All instances?
8192
            {
8193
                int bst = bt->getNumberInstances();
8194
                MSG_DEBUG("Setting font " << fvalue << " on all " << bst << " instances...");
8195
 
8196
                for (int i = 0; i < bst; i++)
8197
                    bt->setFont(fvalue, i);
8198
            }
8199
            else
8200
                bt->setFont(fvalue, btState - 1);
16 andreas 8201
        }
8202
    }
8203
}
8204
 
108 andreas 8205
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
8206
{
8207
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
8208
 
8209
    if (pars.size() < 1)
8210
    {
8211
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8212
        return;
8213
    }
8214
 
8215
    TError::clear();
8216
    int btState = atoi(pars[0].c_str());
8217
 
193 andreas 8218
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8219
 
8220
    if (TError::isError() || map.empty())
8221
        return;
8222
 
8223
    vector<Button::TButton *> buttons = collectButtons(map);
8224
 
8225
    if (buttons.size() > 0)
8226
    {
110 andreas 8227
        Button::TButton *bt = buttons[0];
108 andreas 8228
 
110 andreas 8229
        if (btState == 0)       // All instances?
108 andreas 8230
        {
110 andreas 8231
            int bst = bt->getNumberInstances();
108 andreas 8232
 
110 andreas 8233
            for (int i = 0; i < bst; i++)
8234
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8235
        }
110 andreas 8236
        else
8237
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8238
    }
8239
}
8240
 
16 andreas 8241
/**
60 andreas 8242
 * Change the bargraph upper limit.
8243
 */
8244
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
8245
{
8246
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
8247
 
8248
    if (pars.size() < 1)
8249
    {
8250
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8251
        return;
8252
    }
8253
 
8254
    TError::clear();
8255
    int limit = atoi(pars[0].c_str());
8256
 
8257
    if (limit < 1)
8258
    {
8259
        MSG_ERROR("Invalid upper limit " << limit << "!");
8260
        return;
8261
    }
8262
 
193 andreas 8263
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8264
 
8265
    if (TError::isError() || map.empty())
8266
        return;
8267
 
8268
    vector<Button::TButton *> buttons = collectButtons(map);
8269
 
83 andreas 8270
    if (buttons.size() > 0)
60 andreas 8271
    {
83 andreas 8272
        vector<Button::TButton *>::iterator mapIter;
8273
 
8274
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8275
        {
8276
            Button::TButton *bt = *mapIter;
252 andreas 8277
//            setButtonCallbacks(bt);
83 andreas 8278
            bt->setBargraphUpperLimit(limit);
8279
        }
60 andreas 8280
    }
8281
}
8282
 
8283
/**
8284
 * Change the bargraph lower limit.
8285
 */
8286
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
8287
{
8288
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
8289
 
8290
    if (pars.size() < 1)
8291
    {
8292
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8293
        return;
8294
    }
8295
 
8296
    TError::clear();
8297
    int limit = atoi(pars[0].c_str());
8298
 
8299
    if (limit < 1)
8300
    {
8301
        MSG_ERROR("Invalid lower limit " << limit << "!");
8302
        return;
8303
    }
8304
 
193 andreas 8305
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8306
 
8307
    if (TError::isError() || map.empty())
8308
        return;
8309
 
8310
    vector<Button::TButton *> buttons = collectButtons(map);
8311
 
83 andreas 8312
    if (buttons.size() > 0)
60 andreas 8313
    {
83 andreas 8314
        vector<Button::TButton *>::iterator mapIter;
8315
 
8316
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8317
        {
8318
            Button::TButton *bt = *mapIter;
252 andreas 8319
//            setButtonCallbacks(bt);
83 andreas 8320
            bt->setBargraphLowerLimit(limit);
8321
        }
60 andreas 8322
    }
8323
}
8324
 
108 andreas 8325
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
8326
{
8327
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
8328
 
8329
    if (pars.size() < 1)
8330
    {
8331
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8332
        return;
8333
    }
8334
 
8335
    TError::clear();
8336
    string color = pars[0];
193 andreas 8337
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8338
 
8339
    if (TError::isError() || map.empty())
8340
        return;
8341
 
8342
    vector<Button::TButton *> buttons = collectButtons(map);
8343
 
8344
    if (buttons.size() > 0)
8345
    {
8346
        vector<Button::TButton *>::iterator mapIter;
8347
 
8348
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8349
        {
8350
            Button::TButton *bt = *mapIter;
252 andreas 8351
//            setButtonCallbacks(bt);
108 andreas 8352
            bt->setBargraphSliderColor(color);
8353
        }
8354
    }
8355
}
8356
 
60 andreas 8357
/**
14 andreas 8358
 * Set the icon to a button.
8359
 */
8360
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
8361
{
8362
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
8363
 
8364
    if (pars.size() < 2)
8365
    {
8366
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8367
        return;
8368
    }
8369
 
16 andreas 8370
    TError::clear();
14 andreas 8371
    int btState = atoi(pars[0].c_str());
8372
    int iconIdx = atoi(pars[1].c_str());
8373
 
193 andreas 8374
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 8375
 
8376
    if (TError::isError() || map.empty())
8377
        return;
8378
 
8379
    vector<Button::TButton *> buttons = collectButtons(map);
8380
 
83 andreas 8381
    if (buttons.size() > 0)
14 andreas 8382
    {
83 andreas 8383
        vector<Button::TButton *>::iterator mapIter;
14 andreas 8384
 
83 andreas 8385
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 8386
        {
83 andreas 8387
            Button::TButton *bt = *mapIter;
14 andreas 8388
 
83 andreas 8389
            if (btState == 0)       // All instances?
14 andreas 8390
            {
316 andreas 8391
                if (iconIdx > 0)
8392
                    bt->setIcon(iconIdx, -1);
8393
                else
8394
                    bt->revokeIcon(-1);
14 andreas 8395
            }
83 andreas 8396
            else if (iconIdx > 0)
8397
                bt->setIcon(iconIdx, btState - 1);
8398
            else
8399
                bt->revokeIcon(btState - 1);
14 andreas 8400
        }
8401
    }
8402
}
8403
 
108 andreas 8404
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
8405
{
8406
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
8407
 
8408
    if (pars.size() < 1)
8409
    {
8410
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8411
        return;
8412
    }
8413
 
8414
    TError::clear();
8415
    int btState = atoi(pars[0].c_str());
8416
 
193 andreas 8417
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8418
 
8419
    if (TError::isError() || map.empty())
8420
        return;
8421
 
8422
    vector<Button::TButton *> buttons = collectButtons(map);
8423
 
8424
    if (buttons.size() > 0)
8425
    {
110 andreas 8426
        Button::TButton *bt = buttons[0];
108 andreas 8427
 
110 andreas 8428
        if (btState == 0)       // All instances?
108 andreas 8429
        {
110 andreas 8430
            int bst = bt->getNumberInstances();
108 andreas 8431
 
110 andreas 8432
            for (int i = 0; i < bst; i++)
8433
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8434
        }
110 andreas 8435
        else
8436
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8437
    }
8438
}
8439
 
14 andreas 8440
/**
108 andreas 8441
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
8442
 * with a defined address range. The alignment of 0 is followed by
8443
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
8444
 * corner of the button.
8445
 */
8446
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
8447
{
8448
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
8449
 
8450
    if (pars.size() < 2)
8451
    {
8452
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
8453
        return;
8454
    }
8455
 
8456
    TError::clear();
8457
    int btState = atoi(pars[0].c_str());
8458
    int align = atoi(pars[1].c_str());
8459
    int x = 0, y = 0;
8460
 
8461
    if (!align && pars.size() >= 3)
8462
    {
8463
        x = atoi(pars[2].c_str());
8464
 
8465
        if (pars.size() >= 4)
8466
            y = atoi(pars[3].c_str());
8467
    }
8468
 
193 andreas 8469
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8470
 
8471
    if (TError::isError() || map.empty())
8472
        return;
8473
 
8474
    vector<Button::TButton *> buttons = collectButtons(map);
8475
 
8476
    if (buttons.size() > 0)
8477
    {
8478
        vector<Button::TButton *>::iterator mapIter;
8479
 
8480
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8481
        {
8482
            Button::TButton *bt = *mapIter;
8483
 
8484
            if (btState == 0)
8485
                bt->setBitmapJustification(align, x, y, -1);
8486
            else
8487
                bt->setBitmapJustification(align, x, y, btState-1);
8488
        }
8489
    }
8490
}
8491
 
8492
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
8493
{
8494
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
8495
 
8496
    if (pars.size() < 1)
8497
    {
8498
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8499
        return;
8500
    }
8501
 
8502
    TError::clear();
8503
    int btState = atoi(pars[0].c_str());
8504
    int j, x, y;
8505
 
193 andreas 8506
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8507
 
8508
    if (TError::isError() || map.empty())
8509
        return;
8510
 
8511
    vector<Button::TButton *> buttons = collectButtons(map);
8512
 
8513
    if (buttons.size() > 0)
8514
    {
110 andreas 8515
        Button::TButton *bt = buttons[0];
108 andreas 8516
 
110 andreas 8517
        if (btState == 0)       // All instances?
108 andreas 8518
        {
110 andreas 8519
            int bst = bt->getNumberInstances();
108 andreas 8520
 
110 andreas 8521
            for (int i = 0; i < bst; i++)
108 andreas 8522
            {
110 andreas 8523
                j = bt->getBitmapJustification(&x, &y, i);
8524
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8525
            }
8526
        }
110 andreas 8527
        else
8528
        {
8529
            j = bt->getBitmapJustification(&x, &y, btState-1);
8530
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
8531
        }
108 andreas 8532
    }
8533
}
8534
 
8535
/**
8536
 * Set icon alignment using a numeric keypad layout for those buttons with a
8537
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
8538
 * The left and top coordinates are relative to the upper left corner of the
8539
 * button.
8540
 */
8541
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
8542
{
8543
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
8544
 
8545
    if (pars.size() < 2)
8546
    {
8547
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
8548
        return;
8549
    }
8550
 
8551
    TError::clear();
8552
    int btState = atoi(pars[0].c_str());
8553
    int align = atoi(pars[1].c_str());
8554
    int x = 0, y = 0;
8555
 
8556
    if (!align && pars.size() >= 3)
8557
    {
8558
        x = atoi(pars[2].c_str());
8559
 
8560
        if (pars.size() >= 4)
8561
            y = atoi(pars[3].c_str());
8562
    }
8563
 
193 andreas 8564
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8565
 
8566
    if (TError::isError() || map.empty())
8567
        return;
8568
 
8569
    vector<Button::TButton *> buttons = collectButtons(map);
8570
 
8571
    if (buttons.size() > 0)
8572
    {
8573
        vector<Button::TButton *>::iterator mapIter;
8574
 
8575
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8576
        {
8577
            Button::TButton *bt = *mapIter;
8578
 
8579
            if (btState == 0)
8580
                bt->setIconJustification(align, x, y, -1);
8581
            else
8582
                bt->setIconJustification(align, x, y, btState-1);
8583
        }
8584
    }
8585
}
8586
 
8587
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
8588
{
8589
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
8590
 
8591
    if (pars.size() < 1)
8592
    {
8593
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8594
        return;
8595
    }
8596
 
8597
    TError::clear();
8598
    int btState = atoi(pars[0].c_str());
8599
    int j, x, y;
8600
 
193 andreas 8601
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8602
 
8603
    if (TError::isError() || map.empty())
8604
        return;
8605
 
8606
    vector<Button::TButton *> buttons = collectButtons(map);
8607
 
8608
    if (buttons.size() > 0)
8609
    {
110 andreas 8610
        Button::TButton *bt = buttons[0];
108 andreas 8611
 
110 andreas 8612
        if (btState == 0)       // All instances?
108 andreas 8613
        {
110 andreas 8614
            int bst = bt->getNumberInstances();
108 andreas 8615
 
110 andreas 8616
            for (int i = 0; i < bst; i++)
108 andreas 8617
            {
110 andreas 8618
                j = bt->getIconJustification(&x, &y, i);
8619
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8620
            }
8621
        }
110 andreas 8622
        else
8623
        {
8624
            j = bt->getIconJustification(&x, &y, btState-1);
8625
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
8626
        }
108 andreas 8627
    }
8628
}
8629
 
8630
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
8631
{
8632
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
8633
 
8634
    if (pars.size() < 2)
8635
    {
8636
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
8637
        return;
8638
    }
8639
 
8640
    TError::clear();
8641
    int btState = atoi(pars[0].c_str());
8642
    int align = atoi(pars[1].c_str());
8643
    int x = 0, y = 0;
8644
 
8645
    if (!align && pars.size() >= 3)
8646
    {
8647
        x = atoi(pars[2].c_str());
8648
 
8649
        if (pars.size() >= 4)
8650
            y = atoi(pars[3].c_str());
8651
    }
8652
 
193 andreas 8653
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8654
 
8655
    if (TError::isError() || map.empty())
8656
        return;
8657
 
8658
    vector<Button::TButton *> buttons = collectButtons(map);
8659
 
8660
    if (buttons.size() > 0)
8661
    {
8662
        vector<Button::TButton *>::iterator mapIter;
8663
 
8664
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8665
        {
8666
            Button::TButton *bt = *mapIter;
8667
 
8668
            if (btState == 0)
8669
                bt->setTextJustification(align, x, y, -1);
8670
            else
8671
                bt->setTextJustification(align, x, y, btState-1);
8672
        }
8673
    }
8674
}
8675
 
8676
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
8677
{
8678
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
8679
 
8680
    if (pars.size() < 1)
8681
    {
8682
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8683
        return;
8684
    }
8685
 
8686
    TError::clear();
8687
    int btState = atoi(pars[0].c_str());
8688
    int j, x, y;
8689
 
193 andreas 8690
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8691
 
8692
    if (TError::isError() || map.empty())
8693
        return;
8694
 
8695
    vector<Button::TButton *> buttons = collectButtons(map);
8696
 
8697
    if (buttons.size() > 0)
8698
    {
110 andreas 8699
        Button::TButton *bt = buttons[0];
108 andreas 8700
 
110 andreas 8701
        if (btState == 0)       // All instances?
108 andreas 8702
        {
110 andreas 8703
            int bst = bt->getNumberInstances();
108 andreas 8704
 
110 andreas 8705
            for (int i = 0; i < bst; i++)
108 andreas 8706
            {
110 andreas 8707
                j = bt->getTextJustification(&x, &y, i);
8708
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8709
            }
8710
        }
110 andreas 8711
        else
8712
        {
8713
            j = bt->getTextJustification(&x, &y, btState-1);
8714
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
8715
        }
108 andreas 8716
    }
8717
}
8718
 
8719
/**
16 andreas 8720
 * Show or hide a button with a set variable text range.
8721
 */
8722
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
8723
{
8724
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
8725
 
8726
    if (pars.empty())
8727
    {
8728
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
8729
        return;
8730
    }
8731
 
8732
    TError::clear();
8733
    int cvalue = atoi(pars[0].c_str());
8734
 
193 andreas 8735
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8736
 
8737
    if (TError::isError() || map.empty())
8738
        return;
8739
 
8740
    vector<Button::TButton *> buttons = collectButtons(map);
8741
 
83 andreas 8742
    if (buttons.size() > 0)
16 andreas 8743
    {
83 andreas 8744
        vector<Button::TButton *>::iterator mapIter;
8745
 
8746
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8747
        {
8748
            Button::TButton *bt = *mapIter;
318 andreas 8749
 
100 andreas 8750
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
8751
            bool pVisible = false;
8752
 
8753
            if (pgID < 500)
8754
            {
8755
                TPage *pg = getPage(pgID);
8756
 
8757
                if (pg && pg->isVisilble())
8758
                    pVisible = true;
8759
            }
8760
            else
8761
            {
8762
                TSubPage *pg = getSubPage(pgID);
8763
 
8764
                if (pg && pg->isVisible())
8765
                    pVisible = true;
8766
            }
8767
 
151 andreas 8768
            bool oldV = bt->isVisible();
8769
            bool visible = cvalue ? true : false;
8770
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 8771
 
151 andreas 8772
            if (visible != oldV)
100 andreas 8773
            {
151 andreas 8774
                bt->setVisible(visible);
100 andreas 8775
 
151 andreas 8776
                if (pVisible)
8777
                {
8778
                    setButtonCallbacks(bt);
8779
 
8780
                    if (_setVisible)
8781
                        _setVisible(bt->getHandle(), visible);
8782
                    else
8783
                        bt->refresh();
8784
                }
100 andreas 8785
            }
83 andreas 8786
        }
16 andreas 8787
    }
8788
}
8789
 
108 andreas 8790
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
8791
{
8792
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
8793
 
8794
    if (pars.size() < 2)
8795
    {
8796
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
8797
        return;
8798
    }
8799
 
8800
    TError::clear();
8801
    int btState = atoi(pars[0].c_str());
8802
    string color = pars[1];
8803
 
193 andreas 8804
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8805
 
8806
    if (TError::isError() || map.empty())
8807
        return;
8808
 
8809
    vector<Button::TButton *> buttons = collectButtons(map);
8810
 
8811
    if (buttons.size() > 0)
8812
    {
8813
        vector<Button::TButton *>::iterator mapIter;
8814
 
8815
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8816
        {
8817
            Button::TButton *bt = *mapIter;
8818
 
8819
            if (btState == 0)
8820
                bt->setTextEffectColor(color);
8821
            else
8822
                bt->setTextEffectColor(color, btState-1);
8823
        }
8824
    }
8825
}
8826
 
8827
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
8828
{
8829
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
8830
 
8831
    if (pars.size() < 1)
8832
    {
8833
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8834
        return;
8835
    }
8836
 
8837
    TError::clear();
8838
    int btState = atoi(pars[0].c_str());
8839
 
193 andreas 8840
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8841
 
8842
    if (TError::isError() || map.empty())
8843
        return;
8844
 
8845
    vector<Button::TButton *> buttons = collectButtons(map);
8846
 
8847
    if (buttons.size() > 0)
8848
    {
110 andreas 8849
        Button::TButton *bt = buttons[0];
8850
 
8851
        if (btState == 0)       // All instances?
8852
        {
8853
            int bst = bt->getNumberInstances();
8854
 
8855
            for (int i = 0; i < bst; i++)
8856
            {
8857
                string c = bt->getTextEffectColor(i);
300 andreas 8858
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8859
            }
8860
        }
8861
        else
8862
        {
8863
            string c = bt->getTextEffectColor(btState-1);
300 andreas 8864
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8865
        }
8866
    }
8867
}
8868
 
8869
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
8870
{
8871
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
8872
 
8873
    if (pars.size() < 2)
8874
    {
8875
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
8876
        return;
8877
    }
8878
 
8879
    TError::clear();
8880
    int btState = atoi(pars[0].c_str());
8881
    string tef = pars[1];
8882
 
193 andreas 8883
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8884
 
8885
    if (TError::isError() || map.empty())
8886
        return;
8887
 
8888
    vector<Button::TButton *> buttons = collectButtons(map);
8889
 
8890
    if (buttons.size() > 0)
8891
    {
108 andreas 8892
        vector<Button::TButton *>::iterator mapIter;
8893
 
8894
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8895
        {
8896
            Button::TButton *bt = *mapIter;
8897
 
110 andreas 8898
            if (btState == 0)
8899
                bt->setTextEffectName(tef);
8900
            else
8901
                bt->setTextEffectName(tef, btState-1);
8902
        }
8903
    }
8904
}
108 andreas 8905
 
110 andreas 8906
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
8907
{
8908
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 8909
 
110 andreas 8910
    if (pars.size() < 1)
8911
    {
8912
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8913
        return;
8914
    }
108 andreas 8915
 
110 andreas 8916
    TError::clear();
8917
    int btState = atoi(pars[0].c_str());
8918
 
193 andreas 8919
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8920
 
8921
    if (TError::isError() || map.empty())
8922
        return;
8923
 
8924
    vector<Button::TButton *> buttons = collectButtons(map);
8925
 
8926
    if (buttons.size() > 0)
8927
    {
8928
        Button::TButton *bt = buttons[0];
8929
 
8930
        if (btState == 0)       // All instances?
8931
        {
8932
            int bst = bt->getNumberInstances();
8933
 
8934
            for (int i = 0; i < bst; i++)
108 andreas 8935
            {
110 andreas 8936
                string c = bt->getTextEffectName(i);
300 andreas 8937
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8938
            }
8939
        }
110 andreas 8940
        else
8941
        {
8942
            string c = bt->getTextEffectName(btState-1);
300 andreas 8943
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8944
        }
108 andreas 8945
    }
8946
}
8947
 
16 andreas 8948
/**
14 andreas 8949
 * Assign a text string to those buttons with a defined address range.
8950
 * Sets Non-Unicode text.
8951
 */
8952
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
8953
{
8954
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
8955
 
8956
    if (pars.size() < 1)
8957
    {
8958
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8959
        return;
8960
    }
8961
 
16 andreas 8962
    TError::clear();
14 andreas 8963
    int btState = atoi(pars[0].c_str());
8964
    string text;
8965
 
8966
    if (pars.size() > 1)
150 andreas 8967
    {
8968
        for (size_t i = 1; i < pars.size(); ++i)
8969
        {
8970
            if (i > 1)
8971
                text += ",";
14 andreas 8972
 
150 andreas 8973
            text += pars[i];
8974
        }
8975
    }
8976
 
193 andreas 8977
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 8978
 
8979
    if (TError::isError() || map.empty())
8980
        return;
8981
 
8982
    vector<Button::TButton *> buttons = collectButtons(map);
8983
 
83 andreas 8984
    if (buttons.size() > 0)
14 andreas 8985
    {
83 andreas 8986
        vector<Button::TButton *>::iterator mapIter;
14 andreas 8987
 
83 andreas 8988
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 8989
        {
83 andreas 8990
            Button::TButton *bt = *mapIter;
14 andreas 8991
 
252 andreas 8992
            if (!bt)
8993
                break;
8994
 
83 andreas 8995
            if (btState == 0)       // All instances?
316 andreas 8996
                bt->setText(text, -1);
83 andreas 8997
            else
8998
                bt->setText(text, btState - 1);
14 andreas 8999
        }
9000
    }
9001
}
21 andreas 9002
 
110 andreas 9003
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
9004
{
9005
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
9006
 
9007
    if (pars.size() < 1)
9008
    {
9009
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9010
        return;
9011
    }
9012
 
9013
    TError::clear();
9014
    int btState = atoi(pars[0].c_str());
9015
 
193 andreas 9016
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9017
 
9018
    if (TError::isError() || map.empty())
9019
        return;
9020
 
9021
    vector<Button::TButton *> buttons = collectButtons(map);
9022
 
9023
    if (buttons.size() > 0)
9024
    {
9025
        Button::TButton *bt = buttons[0];
9026
 
9027
        if (btState == 0)       // All instances?
9028
        {
9029
            int bst = bt->getNumberInstances();
9030
 
9031
            for (int i = 0; i < bst; i++)
9032
            {
9033
                string c = bt->getText(i);
300 andreas 9034
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9035
            }
9036
        }
9037
        else
9038
        {
9039
            string c = bt->getText(btState-1);
300 andreas 9040
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9041
        }
9042
    }
9043
}
9044
 
97 andreas 9045
/*
104 andreas 9046
 * Set button state legacy unicode text command.
9047
 *
9048
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
9049
 * text is sent as ASCII-HEX nibbles.
9050
 */
9051
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
9052
{
9053
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
9054
 
9055
    if (pars.size() < 1)
9056
    {
9057
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
9058
        return;
9059
    }
9060
 
9061
    TError::clear();
9062
    int btState = atoi(pars[0].c_str());
9063
    string text;
9064
 
9065
    // Because UTF8 is not supported out of the box from Windows and NetLinx
9066
    // Studio has no native support for it, any UTF8 text must be encoded in
9067
    // bytes. Because of this we must decode the bytes into real bytes here.
9068
    if (pars.size() > 1)
9069
    {
9070
        string byte;
9071
        size_t pos = 0;
9072
 
9073
        while (pos < pars[1].length())
9074
        {
9075
            byte = pars[1].substr(pos, 2);
9076
            char ch = (char)strtol(byte.c_str(), NULL, 16);
9077
            text += ch;
9078
            pos += 2;
9079
        }
9080
    }
9081
 
193 andreas 9082
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 9083
 
9084
    if (TError::isError() || map.empty())
9085
        return;
9086
 
9087
    vector<Button::TButton *> buttons = collectButtons(map);
9088
 
9089
    if (buttons.size() > 0)
9090
    {
9091
        vector<Button::TButton *>::iterator mapIter;
9092
 
9093
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9094
        {
9095
            Button::TButton *bt = *mapIter;
252 andreas 9096
//            setButtonCallbacks(bt);
104 andreas 9097
 
9098
            if (btState == 0)       // All instances?
9099
            {
9100
                int bst = bt->getNumberInstances();
9101
                MSG_DEBUG("Setting UNI on all " << bst << " instances...");
9102
 
9103
                for (int i = 0; i < bst; i++)
9104
                    bt->setText(text, i);
9105
            }
9106
            else
9107
                bt->setText(text, btState - 1);
9108
        }
9109
    }
9110
}
9111
 
9112
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
9113
{
9114
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
9115
 
9116
    if (pars.size() < 1)
9117
    {
9118
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
9119
        return;
9120
    }
9121
 
9122
    TError::clear();
9123
    int btState = atoi(pars[0].c_str());
9124
    string text;
9125
 
9126
    if (pars.size() > 1)
150 andreas 9127
    {
9128
        for (size_t i = 1; i < pars.size(); ++i)
9129
        {
9130
            if (i > 1)
9131
                text += ",";
104 andreas 9132
 
150 andreas 9133
            text += pars[i];
9134
        }
9135
    }
9136
 
193 andreas 9137
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 9138
 
9139
    if (TError::isError() || map.empty())
9140
        return;
9141
 
9142
    vector<Button::TButton *> buttons = collectButtons(map);
9143
 
9144
    if (buttons.size() > 0)
9145
    {
9146
        vector<Button::TButton *>::iterator mapIter;
9147
 
9148
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9149
        {
9150
            Button::TButton *bt = *mapIter;
252 andreas 9151
//            setButtonCallbacks(bt);
104 andreas 9152
 
9153
            if (btState == 0)       // All instances?
9154
            {
9155
                int bst = bt->getNumberInstances();
9156
                MSG_DEBUG("Setting TXT on all " << bst << " instances...");
9157
 
9158
                for (int i = 0; i < bst; i++)
9159
                    bt->setText(text, i);
9160
            }
9161
            else
9162
                bt->setText(text, btState - 1);
9163
        }
9164
    }
9165
}
111 andreas 9166
 
148 andreas 9167
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
9168
{
9169
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
9170
 
9171
    if (pars.size() < 3)
9172
    {
9173
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
9174
        return;
9175
    }
9176
 
9177
    int pushType = atoi(pars[0].c_str());
9178
    int x = atoi(pars[1].c_str());
9179
    int y = atoi(pars[2].c_str());
9180
 
9181
    if (pushType < 0 || pushType > 2)
9182
    {
9183
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
9184
        return;
9185
    }
9186
 
217 andreas 9187
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 9188
    {
9189
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
9190
        return;
9191
    }
9192
 
9193
    if (pushType == 0 || pushType == 2)
9194
        mouseEvent(x, y, true);
9195
 
9196
    if (pushType == 1 || pushType == 2)
9197
        mouseEvent(x, y, false);
9198
}
9199
 
111 andreas 9200
/**
9201
 * Set the keyboard passthru.
9202
 */
9203
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
9204
{
9205
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
9206
 
9207
    if (pars.size() < 1)
9208
    {
9209
        MSG_ERROR("Got no parameter. Ignoring command!");
9210
        return;
9211
    }
9212
 
9213
    int state = atoi(pars[0].c_str());
9214
 
9215
    if (state == 0)
9216
        mPassThrough = false;
9217
    else if (state == 5)
9218
        mPassThrough = true;
9219
}
9220
 
9221
void TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)
9222
{
9223
    DECL_TRACER("TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)");
9224
 
9225
    if (pars.size() < 1)
9226
    {
9227
        MSG_ERROR("Got no parameter. Ignoring command!");
9228
        return;
9229
    }
9230
 
9231
    if (_sendVirtualKeys)
9232
        _sendVirtualKeys(pars[0]);
9233
}
9234
 
104 andreas 9235
/*
97 andreas 9236
 * Set the bitmap of a button to use a particular resource.
9237
 * Syntax:
9238
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
9239
 * Variable:
9240
 *    variable text address range = 1 - 4000.
9241
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
9242
 *    resource name = 1 - 50 ASCII characters.
9243
 * Example:
9244
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
9245
 *    Sets the resource name of the button to ’Sports_Image’.
9246
 */
21 andreas 9247
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
9248
{
9249
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
9250
 
9251
    if (pars.size() < 2)
9252
    {
9253
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
9254
        return;
9255
    }
9256
 
9257
    TError::clear();
9258
    int btState = atoi(pars[0].c_str());
9259
    string resName = pars[1];
9260
 
193 andreas 9261
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 9262
 
9263
    if (TError::isError() || map.empty())
9264
        return;
9265
 
9266
    vector<Button::TButton *> buttons = collectButtons(map);
9267
 
83 andreas 9268
    if (buttons.size() > 0)
21 andreas 9269
    {
83 andreas 9270
        vector<Button::TButton *>::iterator mapIter;
21 andreas 9271
 
83 andreas 9272
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 9273
        {
83 andreas 9274
            Button::TButton *bt = *mapIter;
252 andreas 9275
//            setButtonCallbacks(bt);
21 andreas 9276
 
83 andreas 9277
            if (btState == 0)       // All instances?
9278
            {
9279
                int bst = bt->getNumberInstances();
9280
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
9281
 
9282
                for (int i = 0; i < bst; i++)
9283
                    bt->setResourceName(resName, i);
9284
            }
9285
            else
9286
                bt->setResourceName(resName, btState - 1);
97 andreas 9287
 
9288
            if (bt->isVisible())
9289
                bt->refresh();
99 andreas 9290
            else if (_setVisible)
9291
                _setVisible(bt->getHandle(), false);
21 andreas 9292
        }
9293
    }
9294
}
9295
 
97 andreas 9296
/*
9297
 * Add new resources
9298
 * Adds any and all resource parameters by sending embedded codes and data.
9299
 * Since the embedded codes are preceded by a '%' character, any '%' character
9300
 * contained in* the URL must be escaped with a second '%' character (see
9301
 * example).
9302
 * The file name field (indicated by a %F embedded code) may contain special
9303
 * escape sequences as shown in the ^RAF, ^RMF.
9304
 * Syntax:
9305
 *    "'^RAF-<resource name>,<data>'"
9306
 * Variables:
9307
 *    resource name = 1 - 50 ASCII characters.
9308
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
9309
 * Example:
9310
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
9311
 *    Adds a new resource.
9312
 *    The resource name is ’New Image’
9313
 *    %P (protocol) is an HTTP
9314
 *    %H (host name) is AMX.COM
9315
 *    %A (file path) is Lab/Test_f ile
9316
 *    %F (file name) is test.jpg.
9317
 *    Note that the %%5F in the file path is actually encoded as %5F.
9318
 */
9319
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
9320
{
9321
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
9322
 
9323
    if (pars.size() < 2)
9324
    {
9325
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
9326
        return;
9327
    }
9328
 
9329
    string name = pars[0];
9330
    string data = pars[1];
9331
 
9332
    vector<string> parts = StrSplit(data, "%");
9333
    RESOURCE_T res;
9334
 
9335
    if (parts.size() > 0)
9336
    {
9337
        vector<string>::iterator sIter;
9338
 
9339
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
9340
        {
9341
            const char *s = sIter->c_str();
9342
            string ss = *sIter;
9343
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
9344
 
9345
            switch(*s)
9346
            {
9347
                case 'P':
9348
                    if (*(s+1) == '0')
9349
                        res.protocol = "HTTP";
9350
                    else
9351
                        res.protocol = "FTP";
9352
                    break;
9353
 
9354
                case 'U': res.user = sIter->substr(1); break;
9355
                case 'S': res.password = sIter->substr(1); break;
9356
                case 'H': res.host = sIter->substr(1); break;
9357
                case 'F': res.file = sIter->substr(1); break;
9358
                case 'A': res.path = sIter->substr(1); break;
9359
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
9360
 
9361
                default:
9362
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
9363
            }
9364
        }
9365
 
9366
        if (gPrjResources)
9367
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
9368
    }
9369
}
9370
 
111 andreas 9371
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 9372
{
9373
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
9374
 
9375
    if (pars.size() < 1)
9376
    {
9377
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
9378
        return;
9379
    }
9380
 
9381
    string name = pars[0];
193 andreas 9382
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 9383
 
9384
    if (TError::isError() || map.empty())
9385
        return;
9386
 
9387
    vector<Button::TButton *> buttons = collectButtons(map);
9388
 
9389
    if (buttons.size() > 0)
9390
    {
9391
        vector<Button::TButton *>::iterator mapIter;
9392
 
9393
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9394
        {
9395
            Button::TButton *bt = *mapIter;
9396
 
9397
            if (bt->isVisible())
9398
            {
252 andreas 9399
//                setButtonCallbacks(bt);
97 andreas 9400
                bt->refresh();
9401
            }
9402
        }
9403
    }
9404
}
9405
 
9406
/*
9407
 * Modify an existing resource
9408
 *
9409
 * Modifies any and all resource parameters by sending embedded codes and data.
9410
 * Since the embedded codes are preceded by a '%' character, any '%' character
9411
 * contained in the URL must be escaped with a second '%' character (see
9412
 * example).
9413
 * The file name field (indicated by a %F embedded code) may contain special
9414
 * escape sequences as shown in the ^RAF.
9415
 *
9416
 * Syntax:
9417
 * "'^RMF-<resource name>,<data>'"
9418
 * Variables:
9419
 *   • resource name = 1 - 50 ASCII characters
9420
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
9421
 * Example:
9422
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
9423
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
9424
 * ’Lab_Test/Images’.
9425
 * Note that the %%5F in the file path is actually encoded as %5F.
9426
 */
22 andreas 9427
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 9428
{
9429
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
9430
 
9431
    if (pars.size() < 2)
9432
    {
9433
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
9434
        return;
9435
    }
9436
 
9437
    string name = pars[0];
9438
    string data = pars[1];
9439
 
9440
    vector<string> parts = StrSplit(data, "%");
9441
    RESOURCE_T res;
9442
 
83 andreas 9443
    if (parts.size() > 0)
21 andreas 9444
    {
83 andreas 9445
        vector<string>::iterator sIter;
21 andreas 9446
 
83 andreas 9447
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 9448
        {
83 andreas 9449
            const char *s = sIter->c_str();
9450
            string ss = *sIter;
9451
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 9452
 
83 andreas 9453
            switch(*s)
9454
            {
9455
                case 'P':
9456
                    if (*(s+1) == '0')
9457
                        res.protocol = "HTTP";
9458
                    else
9459
                        res.protocol = "FTP";
9460
                break;
21 andreas 9461
 
83 andreas 9462
                case 'U': res.user = sIter->substr(1); break;
9463
                case 'S': res.password = sIter->substr(1); break;
9464
                case 'H': res.host = sIter->substr(1); break;
9465
                case 'F': res.file = sIter->substr(1); break;
9466
                case 'A': res.path = sIter->substr(1); break;
9467
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
9468
 
9469
                default:
9470
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
9471
            }
21 andreas 9472
        }
83 andreas 9473
 
9474
        if (gPrjResources)
9475
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 9476
    }
9477
}
62 andreas 9478
 
9479
/**
111 andreas 9480
 * Change the refresh rate for a given resource.
9481
 */
9482
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
9483
{
9484
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
9485
 
9486
    if (pars.size() < 2)
9487
    {
9488
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
9489
        return;
9490
    }
9491
 
9492
    string resName = pars[0];
9493
    int resRefresh = atoi(pars[1].c_str());
9494
 
9495
    if (!gPrjResources)
9496
    {
9497
        MSG_ERROR("Missing the resource module. Ignoring command!");
9498
        return;
9499
    }
9500
 
9501
    RESOURCE_T res = gPrjResources->findResource(resName);
9502
 
9503
    if (res.name.empty() || res.refresh == resRefresh)
9504
        return;
9505
 
9506
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
9507
}
9508
 
9509
/**
62 andreas 9510
 * @brief TPageManager::doAKB - Pop up the keyboard icon
9511
 * Pop up the keyboard icon and initialize the text string to that specified.
9512
 * Keyboard string is set to null on power up and is stored until power is lost.
9513
 * The Prompt Text is optional.
9514
 */
9515
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
9516
{
9517
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
9518
 
9519
    if (pars.size() < 1)
9520
    {
9521
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
9522
        return;
9523
    }
9524
 
9525
    string initText = pars[0];
9526
    string promptText;
9527
 
9528
    if (pars.size() > 1)
9529
        promptText = pars[1];
9530
 
63 andreas 9531
    if (initText.empty())
9532
        initText = mAkbText;
9533
    else
9534
        mAkbText = initText;
62 andreas 9535
 
9536
    if (_callKeyboard)
63 andreas 9537
        _callKeyboard(initText, promptText, false);
62 andreas 9538
}
9539
 
63 andreas 9540
/**
9541
 * Pop up the keyboard icon and initialize the text string to that
9542
 * specified.
9543
 */
62 andreas 9544
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
9545
{
9546
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
9547
 
9548
    doAKB(port, channels, pars);
9549
}
9550
 
63 andreas 9551
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
9552
{
9553
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
9554
 
9555
    doAKP(port, channels, pars);
9556
}
9557
 
62 andreas 9558
/**
63 andreas 9559
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
9560
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
9561
 */
9562
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
9563
{
9564
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
9565
 
9566
    if (_callResetKeyboard)
9567
        _callResetKeyboard();
9568
}
9569
 
9570
/**
62 andreas 9571
 * @brief TPageManager::doAKP - Pop up the keypad icon
9572
 * Pop up the keypad icon and initialize the text string to that specified.
9573
 * Keypad string is set to null on power up and is stored until power is lost.
9574
 * The Prompt Text is optional.
9575
 */
9576
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
9577
{
9578
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
9579
 
9580
    if (pars.size() < 1)
9581
    {
9582
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
9583
        return;
9584
    }
9585
 
9586
    string initText = pars[0];
9587
    string promptText;
9588
 
9589
    if (pars.size() > 1)
9590
        promptText = pars[1];
9591
 
63 andreas 9592
    if (initText.empty())
9593
        initText = mAkpText;
9594
    else
9595
        mAkpText = initText;
62 andreas 9596
 
9597
    if (_callKeypad)
63 andreas 9598
        _callKeypad(initText, promptText, false);
62 andreas 9599
}
9600
 
63 andreas 9601
/**
9602
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
9603
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
9604
 */
9605
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 9606
{
63 andreas 9607
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 9608
 
63 andreas 9609
    doAKEYR(port, channels, pars);
62 andreas 9610
}
9611
 
108 andreas 9612
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
9613
{
9614
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
9615
 
9616
    if (!_playSound)
9617
        return;
9618
 
9619
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
9620
    TValidateFile vf;
9621
 
326 andreas 9622
    if (vf.isValidFile(snd))
108 andreas 9623
        _playSound(snd);
326 andreas 9624
#if TESTMODE == 1
9625
    else
9626
    {
9627
        MSG_PROTOCOL("Sound file invalid!");
9628
        __done = true;
9629
    }
9630
#endif
108 andreas 9631
}
9632
 
9633
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
9634
{
9635
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
9636
 
9637
    if (!_playSound)
9638
        return;
9639
 
9640
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
9641
    TValidateFile vf;
9642
 
326 andreas 9643
    if (vf.isValidFile(snd))
108 andreas 9644
        _playSound(snd);
326 andreas 9645
#if TESTMODE == 1
9646
    else
9647
    {
9648
        MSG_PROTOCOL("Sound file invalid!");
9649
        __done = true;
9650
    }
9651
#endif
108 andreas 9652
}
9653
 
71 andreas 9654
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
9655
{
9656
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
9657
 
9658
    if (!_playSound)
326 andreas 9659
    {
9660
#if TESTMODE == 1
9661
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
9662
        __done = true;
9663
#endif
71 andreas 9664
        return;
326 andreas 9665
    }
71 andreas 9666
 
9667
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
9668
    TValidateFile vf;
108 andreas 9669
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 9670
 
326 andreas 9671
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 9672
        _playSound(snd);
326 andreas 9673
#if TESTMODE == 1
9674
    else
9675
    {
9676
        if (!sysSound.getSystemSoundState())
9677
        {
9678
            MSG_PROTOCOL("Sound state disabled!")
9679
        }
9680
        else
9681
        {
9682
            MSG_PROTOCOL("Sound file invalid!");
9683
        }
9684
 
9685
        __done = true;
9686
    }
9687
#endif
71 andreas 9688
}
9689
 
9690
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
9691
{
9692
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
9693
 
9694
    if (!_playSound)
9695
        return;
9696
 
9697
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
9698
    TValidateFile vf;
108 andreas 9699
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 9700
 
326 andreas 9701
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 9702
        _playSound(snd);
326 andreas 9703
#if TESTMODE == 1
9704
    else
9705
    {
9706
        if (!sysSound.getSystemSoundState())
9707
        {
9708
            MSG_PROTOCOL("Sound state disabled!")
9709
        }
9710
        else
9711
        {
9712
            MSG_PROTOCOL("Sound file invalid!");
9713
        }
9714
 
9715
        __done = true;
9716
    }
9717
#endif
71 andreas 9718
}
9719
 
63 andreas 9720
/**
9721
 * @brief Pop up the keypad icon and initialize the text string to that specified.
9722
 * Keypad string is set to null on power up and is stored until power is lost.
9723
 * The Prompt Text is optional.
9724
 */
62 andreas 9725
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
9726
{
9727
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
9728
 
9729
    doAKP(port, channels, pars);
9730
}
63 andreas 9731
 
9732
/**
9733
 * @brief Present a private keyboard.
9734
 * Pops up the keyboard icon and initializes the text string to that specified.
9735
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
9736
 */
9737
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
9738
{
9739
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
9740
 
9741
    if (pars.size() < 1)
9742
    {
9743
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
9744
        return;
9745
    }
9746
 
9747
    string initText = pars[0];
9748
    string promptText;
9749
 
9750
    if (pars.size() > 1)
9751
        promptText = pars[1];
9752
 
9753
    if (_callKeyboard)
9754
        _callKeyboard(initText, promptText, true);
9755
}
9756
 
9757
/**
9758
 * @brief Present a private keypad.
9759
 * Pops up the keypad icon and initializes the text string to that specified.
9760
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
9761
 */
9762
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
9763
{
9764
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
9765
 
9766
    if (pars.size() < 1)
9767
    {
9768
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
9769
        return;
9770
    }
9771
 
9772
    string initText = pars[0];
9773
    string promptText;
9774
 
9775
    if (pars.size() > 1)
9776
        promptText = pars[1];
9777
 
9778
    if (_callKeypad)
9779
        _callKeypad(initText, promptText, true);
9780
}
9781
 
9782
/**
64 andreas 9783
 * Send panel to SETUP page.
9784
 */
9785
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
9786
{
9787
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
9788
 
9789
    if (_callShowSetup)
9790
        _callShowSetup();
9791
}
9792
 
9793
/**
9794
 * Shut down the App
9795
 */
9796
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
9797
{
9798
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
9799
 
97 andreas 9800
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 9801
#ifdef __ANDROID__
9802
    stopNetworkState();
9803
#endif
9804
    prg_stopped = true;
9805
    killed = true;
9806
 
9807
    if (_shutdown)
9808
        _shutdown();
9809
}
9810
 
82 andreas 9811
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
9812
{
9813
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
9814
 
9815
    if (pars.size() < 1)
9816
    {
9817
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
9818
        return;
9819
    }
9820
 
9821
    if (!_playSound)
9822
    {
9823
        MSG_ERROR("@SOU: Missing sound module!");
9824
        return;
9825
    }
9826
 
165 andreas 9827
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
9828
        return;
9829
 
82 andreas 9830
    _playSound(pars[0]);
9831
}
9832
 
326 andreas 9833
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
9834
{
9835
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
9836
 
9837
    if (pars.size() < 1)
9838
    {
9839
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
9840
        return;
9841
    }
9842
 
9843
    bool mute = 0;
9844
 
9845
    if (pars[0] == "0")
9846
        mute = false;
9847
    else
9848
        mute = true;
9849
 
9850
    TConfig::setMuteState(mute);
9851
#if TESTMODE == 1
327 andreas 9852
    if (_gTestMode)
9853
    {
9854
        bool st = TConfig::getMuteState();
9855
        _gTestMode->setResult(st ? "1" : "0");
9856
    }
9857
 
326 andreas 9858
    __success = true;
9859
    __done = true;
9860
#endif
9861
}
9862
 
64 andreas 9863
/**
63 andreas 9864
 * @brief Present a telephone keypad.
9865
 * Pops up the keypad icon and initializes the text string to that specified.
9866
 * The Prompt Text is optional.
9867
 */
9868
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
9869
{
9870
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
9871
 
9872
    // TODO: Implement a real telefone keypad.
9873
    doAKP(port, channels, pars);
9874
}
9875
 
9876
/**
9877
 * Popup the virtual keyboard
9878
 */
123 andreas 9879
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 9880
{
123 andreas 9881
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 9882
 
9883
    doAKP(port, channels, pars);
9884
}
129 andreas 9885
#ifndef _NOSIP_
123 andreas 9886
void TPageManager::sendPHN(vector<string>& cmds)
9887
{
9888
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
9889
 
9890
    vector<int> channels;
9891
    doPHN(-1, channels, cmds);
9892
}
9893
 
141 andreas 9894
void TPageManager::actPHN(vector<string>& cmds)
9895
{
9896
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
9897
 
9898
    vector<int> channels;
9899
    doPHN(1, channels, cmds);
9900
}
9901
 
140 andreas 9902
void TPageManager::phonePickup(int id)
9903
{
9904
    DECL_TRACER("TPageManager::phonePickup(int id)");
9905
 
9906
    if (id < 0 || id >= 4)
9907
        return;
9908
 
9909
    if (mSIPClient)
9910
        mSIPClient->pickup(id);
9911
}
9912
 
9913
void TPageManager::phoneHangup(int id)
9914
{
9915
    DECL_TRACER("TPageManager::phoneHangup(int id)");
9916
 
9917
    if (id < 0 || id >= 4)
9918
        return;
9919
 
9920
    if (mSIPClient)
9921
        mSIPClient->terminate(id);
9922
}
9923
 
123 andreas 9924
/**
9925
 * @brief Phone commands.
9926
 * The phone commands could come from the master or are send to the master.
9927
 * If the parameter \p port is less then 0 (zero) a command is send to the
9928
 * master. In any other case the command came from the mater.
125 andreas 9929
 *
9930
 * @param port  This is used to signal if the command was sent by the master
9931
 *              or generated from the panel. If ths is less then 0, then the
9932
 *              method was called because of an event happen in the panel.
9933
 *              If this is grater or equal 0, then the event is comming from
9934
 *              the master.
9935
 * @param pars  This are parameters. The first parameter defines the action
9936
 *              to be done. According to the command this parameter may have a
9937
 *              different number of arguments.
123 andreas 9938
 */
9939
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
9940
{
9941
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
9942
 
9943
    if (pars.size() < 1)
9944
    {
9945
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
9946
        return;
9947
    }
9948
 
9949
    string sCommand;
9950
    string cmd = toUpper(pars[0]);
9951
 
9952
    // Master to panel
9953
    if (port >= 0)
9954
    {
9955
        if (!mSIPClient)
9956
        {
9957
            MSG_ERROR("SIP client class was not initialized!")
9958
            return;
9959
        }
9960
 
9961
        if (cmd == "ANSWER")
9962
        {
9963
            if (pars.size() >= 2)
9964
            {
124 andreas 9965
                int id = atoi(pars[1].c_str());
9966
 
9967
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
9968
                    mSIPClient->resume(id);
9969
                else
135 andreas 9970
                    mSIPClient->pickup(id);
123 andreas 9971
            }
9972
        }
9973
        else if (cmd == "AUTOANSWER")
9974
        {
9975
            if (pars.size() >= 2)
9976
            {
9977
                if (pars[1].at(0) == '0')
9978
                    mPHNautoanswer = false;
9979
                else
9980
                    mPHNautoanswer = true;
127 andreas 9981
 
9982
                vector<string> cmds;
9983
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 9984
                sendPHN(cmds);
123 andreas 9985
            }
9986
        }
9987
        else if (cmd == "CALL")     // Initiate a call
9988
        {
9989
            if (pars.size() >= 2)
127 andreas 9990
                mSIPClient->call(pars[1]);
123 andreas 9991
        }
9992
        else if (cmd == "DTMF")     // Send tone modified codes
9993
        {
127 andreas 9994
            if (pars.size() >= 2)
9995
                mSIPClient->sendDTMF(pars[1]);
123 andreas 9996
        }
9997
        else if (cmd == "HANGUP")   // terminate a call
9998
        {
124 andreas 9999
            if (pars.size() >= 2)
10000
            {
10001
                int id = atoi(pars[1].c_str());
10002
                mSIPClient->terminate(id);
10003
            }
123 andreas 10004
        }
10005
        else if (cmd == "HOLD")     // Hold the line
10006
        {
124 andreas 10007
            if (pars.size() >= 2)
10008
            {
10009
                int id = atoi(pars[1].c_str());
10010
                mSIPClient->hold(id);
10011
            }
123 andreas 10012
        }
128 andreas 10013
        else if (cmd == "LINESTATE") // State of all line
127 andreas 10014
        {
128 andreas 10015
            mSIPClient->sendLinestate();
127 andreas 10016
        }
123 andreas 10017
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
10018
        {
128 andreas 10019
            if (pars.size() >= 2)
10020
            {
10021
                bool state = (pars[1].at(0) == '1' ? true : false);
10022
                mSIPClient->sendPrivate(state);
10023
            }
123 andreas 10024
        }
10025
        else if (cmd == "REDIAL")   // Redials the last number
10026
        {
128 andreas 10027
            mSIPClient->redial();
123 andreas 10028
        }
10029
        else if (cmd == "TRANSFER") // Transfer call to provided number
10030
        {
128 andreas 10031
            if (pars.size() >= 3)
10032
            {
10033
                int id = atoi(pars[1].c_str());
10034
                string num = pars[2];
10035
 
10036
                if (mSIPClient->transfer(id, num))
10037
                {
10038
                    vector<string> cmds;
10039
                    cmds.push_back("TRANSFERRED");
10040
                    sendPHN(cmds);
10041
                }
10042
            }
123 andreas 10043
        }
144 andreas 10044
        else if (cmd == "IM")
10045
        {
10046
            if (pars.size() < 3)
10047
                return;
10048
 
10049
            string to = pars[1];
10050
            string msg = pars[2];
10051
            string toUri;
10052
 
10053
            if (to.find("sip:") == string::npos)
10054
                toUri = "sip:";
10055
 
10056
            toUri += to;
10057
 
10058
            if (to.find("@") == string::npos)
10059
                toUri += "@" + TConfig::getSIPproxy();
10060
 
10061
            mSIPClient->sendIM(toUri, msg);
10062
        }
123 andreas 10063
        else if (cmd == "SETUP")    // Some temporary settings
10064
        {
10065
            if (pars.size() < 2)
10066
                return;
10067
 
10068
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
10069
                TConfig::setSIPdomain(pars[2]);
10070
            else if (pars[1] == "DTMFDURATION")
10071
            {
138 andreas 10072
                unsigned int ms = atoi(pars[2].c_str());
10073
                mSIPClient->setDTMFduration(ms);
123 andreas 10074
            }
10075
            else if (pars[1] == "ENABLE")   // (re)register user
10076
            {
10077
                TConfig::setSIPstatus(true);
127 andreas 10078
                mSIPClient->cleanUp();
135 andreas 10079
                mSIPClient->init();
123 andreas 10080
            }
127 andreas 10081
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
10082
                TConfig::setSIPdomain(pars[2]);
123 andreas 10083
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
10084
                TConfig::setSIPpassword(pars[2]);
10085
            else if (pars[1] == "PORT" && pars.size() != 3)
10086
                TConfig::setSIPport(atoi(pars[2].c_str()));
10087
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
10088
                TConfig::setSIPproxy(pars[2]);
10089
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
10090
                TConfig::setSIPstun(pars[2]);
10091
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
10092
                TConfig::setSIPuser(pars[2]);
10093
        }
10094
        else
10095
        {
10096
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
10097
        }
10098
    }
10099
    else   // Panel to master
10100
    {
10101
        vector<string>::iterator iter;
10102
 
10103
        for (iter = pars.begin(); iter != pars.end(); ++iter)
10104
        {
10105
            if (!sCommand.empty())
10106
                sCommand += ",";
10107
 
10108
            sCommand += *iter;
10109
        }
10110
 
10111
        sendPHNcommand(sCommand);
10112
    }
10113
}
127 andreas 10114
 
10115
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
10116
{
10117
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
10118
 
10119
    if (pars.size() < 1)
10120
    {
10121
        MSG_ERROR("Invalid number of arguments!");
10122
        return;
10123
    }
10124
 
10125
    string cmd = pars[0];
10126
 
10127
    if (cmd == "AUTOANSWER")
10128
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
10129
    else if (cmd == "LINESTATE")
10130
    {
10131
        if (!mSIPClient)
10132
            return;
10133
 
138 andreas 10134
        mSIPClient->sendLinestate();
127 andreas 10135
    }
10136
    else if (cmd == "MSGWAITING")
10137
    {
144 andreas 10138
        size_t num = mSIPClient->getNumberMessages();
10139
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 10140
    }
10141
    else if (cmd == "PRIVACY")
10142
    {
138 andreas 10143
        if (mSIPClient->getPrivate())
10144
            sendPHNcommand(cmd + ",1");
10145
        else
10146
            sendPHNcommand(cmd + ",0");
127 andreas 10147
    }
144 andreas 10148
    else if (cmd == "REDIAL")
10149
    {
10150
        if (pars.size() < 2)
10151
            return;
10152
 
10153
        sendPHNcommand(cmd + "," + pars[1]);
10154
    }
127 andreas 10155
    else
10156
    {
10157
        MSG_WARNING("Unknown command " << cmd << " found!");
10158
    }
10159
}
129 andreas 10160
#endif  // _NOSIP_
134 andreas 10161
 
300 andreas 10162
/*
318 andreas 10163
 *  Hide all subpages in a subpage viewer button.
10164
 */
10165
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
10166
{
10167
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
10168
 
10169
    vector<TMap::MAP_T> map = findButtons(port, channels);
10170
 
10171
    if (TError::isError() || map.empty())
10172
        return;
10173
 
10174
    vector<Button::TButton *> buttons = collectButtons(map);
10175
 
10176
    if (!buttons.empty())
10177
    {
10178
        vector<Button::TButton *>::iterator mapIter;
10179
 
10180
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10181
        {
10182
            Button::TButton *bt = *mapIter;
10183
 
10184
            if (_hideAllSubViewItems)
10185
                _hideAllSubViewItems(bt->getHandle());
10186
        }
10187
    }
10188
}
10189
 
10190
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
10191
{
10192
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
10193
 
10194
    if (pars.size() < 1)
10195
        return;
10196
 
10197
    string name = pars[0];
10198
 
10199
    vector<TMap::MAP_T> map = findButtons(port, channels);
10200
 
10201
    if (TError::isError() || map.empty())
10202
        return;
10203
 
10204
    vector<Button::TButton *> buttons = collectButtons(map);
10205
 
10206
    if (!buttons.empty())
10207
    {
10208
        vector<Button::TButton *>::iterator mapIter;
10209
 
10210
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10211
        {
10212
            Button::TButton *bt = *mapIter;
10213
 
10214
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
10215
 
10216
            if (subviews.empty())
10217
                continue;
10218
 
10219
            vector<TSubPage *>::iterator itSub;
10220
 
10221
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
10222
            {
10223
                TSubPage *sub = *itSub;
10224
 
10225
                if (sub && sub->getName() == name)
10226
                {
10227
                    if (_hideSubViewItem)
10228
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
10229
 
10230
                    break;
10231
                }
10232
            }
10233
        }
10234
    }
10235
}
10236
 
10237
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
10238
{
10239
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
10240
 
10241
    if (pars.size() < 1)
10242
        return;
10243
 
10244
    TError::clear();
10245
    int padding = atoi(pars[0].c_str());
10246
 
10247
    if (padding < 0 || padding > 100)
10248
        return;
10249
 
10250
    vector<TMap::MAP_T> map = findButtons(port, channels);
10251
 
10252
    if (TError::isError() || map.empty())
10253
        return;
10254
 
10255
    vector<Button::TButton *> buttons = collectButtons(map);
10256
 
10257
    if (!buttons.empty())
10258
    {
10259
        vector<Button::TButton *>::iterator mapIter;
10260
 
10261
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10262
        {
10263
            Button::TButton *bt = *mapIter;
10264
 
10265
            if (_setSubViewPadding)
10266
                _setSubViewPadding(bt->getHandle(), padding);
10267
        }
10268
    }
10269
}
10270
 
10271
/*
300 andreas 10272
 * This command will perform one of three different operations based on the following conditions:
10273
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
10274
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
10275
 * 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
10276
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
10277
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
10278
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
10279
 */
10280
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
10281
{
10282
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
10283
 
10284
    if (pars.size() < 1)
10285
    {
10286
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10287
        return;
10288
    }
10289
 
10290
    TError::clear();
10291
    string name = pars[0];
10292
    int position = 0;   // optional
10293
    int time = 0;       // optional
10294
 
10295
    if (pars.size() > 1)
10296
        position = atoi(pars[1].c_str());
10297
 
10298
    if (pars.size() > 2)
10299
        time = atoi(pars[2].c_str());
10300
 
10301
    vector<TMap::MAP_T> map = findButtons(port, channels);
10302
 
10303
    if (TError::isError() || map.empty())
10304
        return;
10305
 
10306
    vector<Button::TButton *> buttons = collectButtons(map);
10307
 
10308
    if (!buttons.empty())
10309
    {
10310
        vector<Button::TButton *>::iterator mapIter;
10311
 
10312
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10313
        {
10314
            Button::TButton *bt = *mapIter;
10315
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
10316
 
10317
            if (subviews.empty() || !bt)
10318
                continue;
10319
 
10320
            vector<TSubPage *>::iterator itSub;
10321
 
10322
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
10323
            {
10324
                TSubPage *sub = *itSub;
10325
 
10326
                if (sub && sub->getName() == name)
10327
                {
10328
                    if (_showSubViewItem)
10329
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
10330
 
10331
                    break;
10332
                }
10333
            }
10334
        }
10335
    }
10336
}
10337
 
318 andreas 10338
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
10339
{
10340
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
10341
 
10342
    if (pars.empty())
10343
    {
10344
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10345
        return;
10346
    }
10347
 
10348
    TError::clear();
10349
    string name = pars[0];
10350
    int position = 0;   // optional
10351
    int time = 0;       // optional
10352
 
10353
    if (pars.size() > 1)
10354
        position = atoi(pars[1].c_str());
10355
 
10356
    if (pars.size() > 2)
10357
        time = atoi(pars[2].c_str());
10358
 
10359
    vector<TMap::MAP_T> map = findButtons(port, channels);
10360
 
10361
    if (TError::isError() || map.empty())
10362
        return;
10363
 
10364
    vector<Button::TButton *> buttons = collectButtons(map);
10365
 
10366
    if (!buttons.empty())
10367
    {
10368
        vector<Button::TButton *>::iterator mapIter;
10369
 
10370
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10371
        {
10372
            Button::TButton *bt = *mapIter;
10373
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
10374
 
10375
            if (subviews.empty() || !bt)
10376
                continue;
10377
 
10378
            vector<TSubPage *>::iterator itSub;
10379
 
10380
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
10381
            {
10382
                TSubPage *sub = *itSub;
10383
 
10384
                if (sub && sub->getName() == name)
10385
                {
10386
                    if (_toggleSubViewItem)
10387
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
10388
 
10389
                    break;
10390
                }
10391
            }
10392
        }
10393
    }
10394
}
10395
 
227 andreas 10396
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 10397
{
227 andreas 10398
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 10399
 
10400
    if (pars.size() < 1)
10401
    {
10402
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10403
        return;
10404
    }
10405
 
10406
    TError::clear();
10407
    string source = pars[0];
10408
    vector<string> configs;
10409
 
10410
    if (pars.size() > 1)
10411
    {
10412
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 10413
        {
10414
            string low = toLower(pars[i]);
10415
 
10416
            if (low.find_first_of("user=") != string::npos ||
10417
                low.find_first_of("pass=") != string::npos ||
10418
                low.find_first_of("csv=")  != string::npos ||
10419
                low.find_first_of("has_headers=") != string::npos)
10420
            {
10421
                configs.push_back(pars[i]);
10422
            }
10423
        }
225 andreas 10424
    }
10425
 
10426
    vector<TMap::MAP_T> map = findButtons(port, channels);
10427
 
10428
    if (TError::isError() || map.empty())
10429
        return;
10430
 
10431
    vector<Button::TButton *> buttons = collectButtons(map);
10432
 
10433
    if (buttons.size() > 0)
10434
    {
10435
        vector<Button::TButton *>::iterator mapIter;
10436
 
10437
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10438
        {
10439
            Button::TButton *bt = *mapIter;
10440
            bt->setListSource(source, configs);
10441
        }
10442
    }
10443
 
10444
}
10445
 
230 andreas 10446
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
10447
{
10448
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
10449
 
10450
    if (pars.size() < 1)
10451
    {
10452
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10453
        return;
10454
    }
10455
 
10456
    TError::clear();
10457
    int num = atoi(pars[0].c_str());
10458
 
10459
    vector<TMap::MAP_T> map = findButtons(port, channels);
10460
 
10461
    if (TError::isError() || map.empty())
10462
        return;
10463
 
10464
    vector<Button::TButton *> buttons = collectButtons(map);
10465
 
10466
    if (buttons.size() > 0)
10467
    {
10468
        vector<Button::TButton *>::iterator mapIter;
10469
 
10470
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10471
        {
10472
            Button::TButton *bt = *mapIter;
10473
            bt->setListViewEventNumber(num);
10474
        }
10475
    }
10476
 
10477
}
10478
 
227 andreas 10479
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
10480
{
10481
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
10482
 
10483
    if (pars.size() < 1)
10484
    {
10485
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10486
        return;
10487
    }
10488
 
10489
    TError::clear();
10490
    string filter;
10491
 
10492
    vector<string>::iterator iter;
10493
 
10494
    for (iter = pars.begin(); iter != pars.end(); ++iter)
10495
    {
10496
        if (filter.length() > 0)
10497
            filter += ",";
10498
 
10499
        filter += *iter;
10500
    }
10501
 
10502
    vector<TMap::MAP_T> map = findButtons(port, channels);
10503
 
10504
    if (TError::isError() || map.empty())
10505
        return;
10506
 
10507
    vector<Button::TButton *> buttons = collectButtons(map);
10508
 
10509
    if (buttons.size() > 0)
10510
    {
10511
        vector<Button::TButton *>::iterator mapIter;
10512
 
10513
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10514
        {
10515
            Button::TButton *bt = *mapIter;
10516
            bt->setListSourceFilter(filter);
10517
        }
10518
    }
10519
}
10520
 
230 andreas 10521
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
10522
{
10523
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
10524
 
10525
    if (pars.size() < 1)
10526
    {
10527
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10528
        return;
10529
    }
10530
 
10531
    TError::clear();
233 andreas 10532
    bool hasColumns = false;
230 andreas 10533
    int columns = 0;
233 andreas 10534
    bool hasLayout = false;
230 andreas 10535
    int layout = 0;
233 andreas 10536
    bool hasComponent = false;
10537
    int component = 0;
10538
    bool hasCellHeight = false;
10539
    bool cellHeightPercent = false;
10540
    int cellheight = 0;
10541
    bool hasP1 = false;
10542
    int p1 = 0;
10543
    bool hasP2 = false;
10544
    int p2 = 0;
10545
    bool hasFilter = false;
10546
    bool filter = false;
10547
    bool hasFilterHeight = false;
10548
    bool filterHeightPercent = false;
10549
    int filterheight = 0;
10550
    bool hasAlphaScroll = false;
10551
    bool alphascroll = false;
230 andreas 10552
 
10553
    vector<string>::iterator iter;
10554
 
10555
    for (iter = pars.begin(); iter != pars.end(); ++iter)
10556
    {
10557
        string low = toLower(*iter);
10558
 
10559
        if (low.find("columns=") != string::npos ||
10560
            low.find("nc=") != string::npos ||
10561
            low.find("numcol=") != string::npos)
10562
        {
10563
            size_t pos = low.find("=");
10564
            string sCols = low.substr(pos + 1);
10565
            columns = atoi(sCols.c_str());
233 andreas 10566
            hasColumns = true;
10567
        }
10568
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
10569
        {
10570
            size_t pos = low.find("=");
10571
            string sComp = low.substr(pos + 1);
10572
            component |= atoi(sComp.c_str());
10573
            hasComponent = true;
10574
        }
10575
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
10576
        {
10577
            size_t pos = low.find("=");
10578
            string sLay = low.substr(pos + 1);
10579
            layout = atoi(sLay.c_str());
10580
            hasLayout = true;
10581
        }
10582
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
10583
        {
10584
            size_t pos = low.find("=");
10585
            string sCh = low.substr(pos + 1);
10586
            cellheight = atoi(sCh.c_str());
230 andreas 10587
 
233 andreas 10588
            if (low.find("%") != string::npos)
10589
                cellHeightPercent = true;
10590
 
10591
            hasCellHeight = true;
230 andreas 10592
        }
233 andreas 10593
        else if (low.find("p1=") != string::npos)
10594
        {
10595
            size_t pos = low.find("=");
10596
            string sP1 = low.substr(pos + 1);
10597
            p1 = atoi(sP1.c_str());
10598
            hasP1 = true;
10599
        }
10600
        else if (low.find("p2=") != string::npos)
10601
        {
10602
            size_t pos = low.find("=");
10603
            string sP2 = low.substr(pos + 1);
10604
            p2 = atoi(sP2.c_str());
10605
            hasP2 = true;
10606
        }
10607
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
10608
        {
10609
            size_t pos = low.find("=");
10610
            string sFilter = low.substr(pos + 1);
10611
            filter = isTrue(sFilter);
10612
            hasFilter = true;
10613
        }
10614
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
10615
        {
10616
            size_t pos = low.find("=");
10617
            string sFilter = low.substr(pos + 1);
10618
            filterheight = atoi(sFilter.c_str());
10619
 
10620
            if (low.find("%") != string::npos)
10621
                filterHeightPercent = true;
10622
 
10623
            hasFilterHeight = true;
10624
        }
10625
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
10626
        {
10627
            size_t pos = low.find("=");
10628
            string sAlpha = low.substr(pos + 1);
10629
            alphascroll = isTrue(sAlpha);
10630
            hasAlphaScroll = true;
10631
        }
230 andreas 10632
    }
10633
 
10634
    vector<TMap::MAP_T> map = findButtons(port, channels);
10635
 
10636
    if (TError::isError() || map.empty())
10637
        return;
10638
 
10639
    vector<Button::TButton *> buttons = collectButtons(map);
10640
 
10641
    if (buttons.size() > 0)
10642
    {
10643
        vector<Button::TButton *>::iterator mapIter;
10644
 
10645
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10646
        {
10647
            Button::TButton *bt = *mapIter;
233 andreas 10648
 
10649
            if (hasColumns)         bt->setListViewColumns(columns);
10650
            if (hasComponent)       bt->setListViewComponent(component);
10651
            if (hasLayout)          bt->setListViewLayout(layout);
10652
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
10653
            if (hasP1)              bt->setListViewP1(p1);
10654
            if (hasP2)              bt->setListViewP2(p2);
10655
            if (hasFilter)          bt->setListViewColumnFilter(filter);
10656
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
10657
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 10658
        }
10659
    }
10660
}
10661
 
233 andreas 10662
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
10663
{
10664
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
10665
 
10666
    if (pars.size() < 1)
10667
    {
10668
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10669
        return;
10670
    }
10671
 
10672
    TError::clear();
10673
    map<string,string> mapField;
10674
 
10675
    vector<string>::iterator iter;
10676
 
10677
    for (iter = pars.begin(); iter != pars.end(); ++iter)
10678
    {
10679
        string left, right;
10680
        size_t pos = 0;
10681
 
10682
        if ((pos = iter->find("=")) != string::npos)
10683
        {
10684
            string left = iter->substr(0, pos);
10685
            left = toLower(left);
10686
            string right = iter->substr(pos + 1);
10687
 
10688
            if (left == "t1" || left == "t2" || left == "i1")
10689
                mapField.insert(pair<string,string>(left, right));
10690
        }
10691
    }
10692
 
10693
    vector<TMap::MAP_T> map = findButtons(port, channels);
10694
 
10695
    if (TError::isError() || map.empty())
10696
        return;
10697
 
10698
    vector<Button::TButton *> buttons = collectButtons(map);
10699
 
10700
    if (buttons.size() > 0)
10701
    {
10702
        vector<Button::TButton *>::iterator mapIter;
10703
 
10704
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10705
        {
10706
            Button::TButton *bt = *mapIter;
10707
            bt->setListViewFieldMap(mapField);
10708
        }
10709
    }
10710
}
10711
 
10712
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
10713
{
10714
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
10715
 
10716
    if (pars.size() < 1)
10717
    {
10718
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
10719
        return;
10720
    }
10721
 
10722
    TError::clear();
10723
    string command = pars[0];
10724
    bool select = false;
10725
 
10726
    if (pars.size() > 1)
10727
    {
10728
        if (isTrue(pars[1]))
10729
            select = true;
10730
    }
10731
 
10732
    vector<TMap::MAP_T> map = findButtons(port, channels);
10733
 
10734
    if (TError::isError() || map.empty())
10735
        return;
10736
 
10737
    vector<Button::TButton *> buttons = collectButtons(map);
10738
 
10739
    if (buttons.size() > 0)
10740
    {
10741
        vector<Button::TButton *>::iterator mapIter;
10742
 
10743
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10744
        {
10745
            Button::TButton *bt = *mapIter;
10746
            bt->listViewNavigate(command, select);
10747
        }
10748
    }
10749
}
10750
 
10751
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
10752
{
10753
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
10754
 
10755
    TError::clear();
10756
    int interval = -1;
10757
    bool force = false;
10758
 
10759
    if (pars.size() > 0)
10760
        interval = atoi(pars[0].c_str());
10761
 
10762
    if (pars.size() > 1)
10763
        force = isTrue(pars[1]);
10764
 
10765
    vector<TMap::MAP_T> map = findButtons(port, channels);
10766
 
10767
    if (TError::isError() || map.empty())
10768
        return;
10769
 
10770
    vector<Button::TButton *> buttons = collectButtons(map);
10771
 
10772
    if (buttons.size() > 0)
10773
    {
10774
        vector<Button::TButton *>::iterator mapIter;
10775
 
10776
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10777
        {
10778
            Button::TButton *bt = *mapIter;
10779
            bt->listViewRefresh(interval, force);
10780
        }
10781
    }
10782
}
10783
 
10784
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
10785
{
10786
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
10787
 
10788
    TError::clear();
10789
    vector<string> sortColumns;
10790
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
10791
    string override;
10792
 
10793
    if (pars.size() > 0)
10794
    {
10795
        vector<string>::iterator iter;
10796
 
10797
        for (iter = pars.begin(); iter != pars.end(); ++iter)
10798
        {
10799
            if (iter->find(";") == string::npos)
10800
                sortColumns.push_back(*iter);
10801
            else
10802
            {
10803
                vector<string> parts = StrSplit(*iter, ";");
10804
                sortColumns.push_back(parts[0]);
10805
 
10806
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
10807
                    sort = Button::LIST_SORT_ASC;
10808
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
10809
                    sort = Button::LIST_SORT_DESC;
10810
                else if (parts[1].find("*") != string::npos)
10811
                {
10812
                    if (parts.size() > 2 && !parts[2].empty())
10813
                    {
10814
                        override = parts[2];
10815
                        sort = Button::LIST_SORT_OVERRIDE;
10816
                    }
10817
                }
10818
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
10819
                    sort = Button::LIST_SORT_NONE;
10820
            }
10821
        }
10822
    }
10823
 
10824
    vector<TMap::MAP_T> map = findButtons(port, channels);
10825
 
10826
    if (TError::isError() || map.empty())
10827
        return;
10828
 
10829
    vector<Button::TButton *> buttons = collectButtons(map);
10830
 
10831
    if (buttons.size() > 0)
10832
    {
10833
        vector<Button::TButton *>::iterator mapIter;
10834
 
10835
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10836
        {
10837
            Button::TButton *bt = *mapIter;
10838
            bt->listViewSortData(sortColumns, sort, override);
10839
        }
10840
    }
10841
}
10842
 
134 andreas 10843
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
10844
{
10845
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
10846
 
10847
    if (pars.size() < 1)
10848
    {
10849
        MSG_ERROR("Too few arguments for TPCCMD!");
10850
        return;
10851
    }
10852
 
10853
    string cmd = pars[0];
10854
 
10855
    if (strCaseCompare(cmd, "LocalHost") == 0)
10856
    {
10857
        if (pars.size() < 2 || pars[1].empty())
10858
        {
10859
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
10860
            return;
10861
        }
10862
 
10863
        TConfig::saveController(pars[1]);
10864
    }
10865
    else if (strCaseCompare(cmd, "LocalPort") == 0)
10866
    {
10867
        if (pars.size() < 2 || pars[1].empty())
10868
        {
10869
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
10870
            return;
10871
        }
10872
 
10873
        int port = atoi(pars[1].c_str());
10874
 
10875
        if (port > 0 && port < 65536)
10876
            TConfig::savePort(port);
10877
        else
10878
        {
10879
            MSG_ERROR("Invalid network port " << port);
10880
        }
10881
    }
10882
    else if (strCaseCompare(cmd, "DeviceID") == 0)
10883
    {
10884
        if (pars.size() < 2 || pars[1].empty())
10885
        {
10886
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
10887
            return;
10888
        }
10889
 
10890
        int id = atoi(pars[1].c_str());
10891
 
10892
        if (id >= 10000 && id < 30000)
10893
            TConfig::setSystemChannel(id);
10894
    }
10895
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
10896
    {
10897
        // We restart the network connection only
10898
        if (gAmxNet)
10899
            gAmxNet->reconnect();
10900
    }
10901
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
10902
    {
10903
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
10904
        info += ";HOSTNAME,";
10905
        char hostname[HOST_NAME_MAX];
10906
 
10907
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
10908
        {
10909
            MSG_ERROR("Can't get host name: " << strerror(errno));
10910
            return;
10911
        }
10912
 
10913
        info.append(hostname);
10914
        info += ";UUID," + TConfig::getUUID();
10915
        sendGlobalString(info);
10916
    }
10917
    else if (strCaseCompare(cmd, "LockRotation") == 0)
10918
    {
10919
        if (pars.size() < 2 || pars[1].empty())
10920
        {
10921
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
10922
            return;
10923
        }
10924
 
10925
        if (strCaseCompare(pars[1], "true") == 0)
10926
            TConfig::setRotationFixed(true);
10927
        else
10928
            TConfig::setRotationFixed(false);
10929
    }
10930
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
10931
    {
10932
        if (pars.size() < 2 || pars[1].empty())
10933
        {
10934
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
10935
            return;
10936
        }
10937
 
10938
        if (strCaseCompare(pars[1], "true") == 0)
10939
            TConfig::saveSystemSoundState(true);
10940
        else
10941
            TConfig::saveSystemSoundState(false);
10942
    }
10943
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
10944
    {
10945
        if (_resetSurface)
10946
            _resetSurface();
10947
    }
10948
}
10949
 
10950
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
10951
{
10952
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
10953
 
10954
    if (pars.size() < 1)
10955
    {
10956
        MSG_ERROR("Too few arguments for TPCACC!");
10957
        return;
10958
    }
10959
 
10960
    string cmd = pars[0];
10961
 
10962
    if (strCaseCompare(cmd, "ENABLE") == 0)
10963
    {
10964
        mInformOrientation = true;
10965
        sendOrientation();
10966
    }
10967
    else if (strCaseCompare(cmd, "DISABLE") == 0)
10968
    {
10969
        mInformOrientation = false;
10970
    }
10971
    else if (strCaseCompare(cmd, "QUERY") == 0)
10972
    {
10973
        sendOrientation();
10974
    }
10975
}
153 andreas 10976
 
279 andreas 10977
#ifndef _NOSIP_
153 andreas 10978
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
10979
{
10980
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
10981
 
10982
    if (pars.empty())
10983
        return;
10984
 
10985
    string cmd = toUpper(pars[0]);
10986
 
10987
    if (cmd == "SHOW" && _showPhoneDialog)
10988
        _showPhoneDialog(true);
10989
    else if (!_showPhoneDialog)
10990
    {
10991
        MSG_ERROR("There is no phone dialog registered!");
10992
    }
10993
}
279 andreas 10994
#endif