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