window_QT.cpp

Harald Schmidt, 2012-08-24 07:15 pm

Download (137.3 kB)

 
1
//IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
2
3
// By downloading, copying, installing or using the software you agree to this license.
4
// If you do not agree to this license, do not download, install,
5
// copy or use the software.
6
7
8
//                          License Agreement
9
//               For Open Source Computer Vision Library
10
11
//Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
12
//Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved.
13
//Third party copyrights are property of their respective owners.
14
15
//Redistribution and use in source and binary forms, with or without modification,
16
//are permitted provided that the following conditions are met:
17
18
//  * Redistribution's of source code must retain the above copyright notice,
19
//  this list of conditions and the following disclaimer.
20
21
//  * Redistribution's in binary form must reproduce the above copyright notice,
22
//  this list of conditions and the following disclaimer in the documentation
23
//  and/or other materials provided with the distribution.
24
25
//  * The name of the copyright holders may not be used to endorse or promote products
26
//  derived from this software without specific prior written permission.
27
28
//This software is provided by the copyright holders and contributors "as is" and
29
//any express or implied warranties, including, but not limited to, the implied
30
//warranties of merchantability and fitness for a particular purpose are disclaimed.
31
//In no event shall the Intel Corporation or contributors be liable for any direct,
32
//indirect, incidental, special, exemplary, or consequential damages
33
//(including, but not limited to, procurement of substitute goods or services;
34
//loss of use, data, or profits; or business interruption) however caused
35
//and on any theory of liability, whether in contract, strict liability,
36
//or tort (including negligence or otherwise) arising in any way out of
37
//the use of this software, even if advised of the possibility of such damage.
38
39
//--------------------Google Code 2010 -- Yannick Verdie--------------------//
40
41
//--------------------------------------------------------------------------//
42
// following interface functions added by H.Schmidt :
43
// 
44
// CVAPI(int)  cvGetCommand(const const char* WndName, char* cmd );
45
// CVAPI(int)  cvGetButtonBarContent(const char * WndName, int idx, char * txt );
46
// CVAPI(int)  cvSetButtonBarContent(const char * WndName, int etype, int idx, char * txt );
47
// CVAPI(void) cvDispInfoBox_Qt( const char* WndName, char* caption, const char * csTxt ); 
48
// CVAPI(void) cvAdjustWindowPos_Qt( const char * name, int xp, int xwp, int yp, int yhp );
49
//
50
// 
51
// This functions interact with a *.cfg file named by *.exe of your application.
52
// If your executable is named test.exe and you have test.cfg in the same directory
53
// opencv_highgui*.dll will read in the config file and compose a new ButtonBar for
54
// each window defined in test.cfg
55
// If this specific *.cfg is missing we try to read ButtonNames.cfg instead
56
// ButtonNames.cfg ist of type "general purpose" so "source" is the window name.
57
// Panning and Zoom Functions are yet available across right mouse key (shortcut menue),
58
// if no ButtonBar is configured. Add $Zoom, $Panning $PropWnd in *.cfg to reactivate icons
59
//
60
// Harald Schmidt, 21.8.2012 
61
62
#if defined(HAVE_QT)
63
64
#include <memory>
65
66
#include <window_QT.h>
67
68
#include <math.h>
69
#include <string>                  // HS, 10.6.2012
70
#include <QDesktopWidget>        // to get screen resolution
71
72
#ifdef _WIN32
73
#include <windows.h>
74
#else
75
#include <unistd.h>
76
#endif
77
78
#ifdef HAVE_QT_OPENGL
79
    #ifdef Q_WS_X11
80
        #include <GL/glx.h>
81
    #endif
82
#endif
83
84
85
//Static and global first
86
static GuiReceiver *guiMainThread = NULL;
87
static int parameterSystemC = 1;
88
static char* parameterSystemV[] = {(char*)""};
89
static bool multiThreads = false;
90
static int last_key = -1;
91
QWaitCondition key_pressed;
92
QMutex mutexKey;
93
static const unsigned int threshold_zoom_img_region = 30;
94
//the minimum zoom value to start displaying the values in the grid
95
//that is also the number of pixel per grid
96
97
static CvWinProperties* global_control_panel = NULL;
98
//end static and global
99
100
101
CV_IMPL CvFont cvFontQt(const char* nameFont, int pointSize,CvScalar color,int weight,int style, int spacing)
102
{
103
    /*
104
    //nameFont   <- only Qt
105
    //CvScalar color   <- only Qt (blue_component, green_component, red\_component[, alpha_component])
106
    int         font_face;//<- style in Qt
107
    const int*  ascii;
108
    const int*  greek;
109
    const int*  cyrillic;
110
    float       hscale, vscale;
111
    float       shear;
112
    int         thickness;//<- weight in Qt
113
    float       dx;//spacing letter in Qt (0 default) in pixel
114
    int         line_type;//<- pointSize in Qt
115
    */
116
    CvFont f = {nameFont,color,style,NULL,NULL,NULL,0,0,0,weight,spacing,pointSize};
117
    return f;
118
}
119
120
121
CV_IMPL void cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont* font)
122
{
123
    if (!guiMainThread)
124
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
125
126
    QMetaObject::invokeMethod(guiMainThread,
127
        "putText",
128
        Qt::AutoConnection,
129
        Q_ARG(void*, (void*) img),
130
        Q_ARG(QString,QString(text)),
131
        Q_ARG(QPoint, QPoint(org.x,org.y)),
132
        Q_ARG(void*,(void*) font));
133
}
134
135
136
double cvGetRatioWindow_QT(const char* name)
137
{
138
    if (!guiMainThread)
139
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
140
141
    double result = -1;
142
    QMetaObject::invokeMethod(guiMainThread,
143
        "getRatioWindow",
144
        //Qt::DirectConnection,
145
        Qt::AutoConnection,
146
        Q_RETURN_ARG(double, result),
147
        Q_ARG(QString, QString(name)));
148
149
    return result;
150
}
151
152
153
void cvSetRatioWindow_QT(const char* name,double prop_value)
154
{
155
156
    if (!guiMainThread)
157
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
158
159
    QMetaObject::invokeMethod(guiMainThread,
160
        "setRatioWindow",
161
        Qt::AutoConnection,
162
        Q_ARG(QString, QString(name)),
163
        Q_ARG(double, prop_value));
164
}
165
166
167
double cvGetPropWindow_QT(const char* name)
168
{
169
    if (!guiMainThread)
170
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
171
172
    double result = -1;
173
    QMetaObject::invokeMethod(guiMainThread,
174
        "getPropWindow",
175
        //Qt::DirectConnection,
176
        Qt::AutoConnection,
177
        Q_RETURN_ARG(double, result),
178
        Q_ARG(QString, QString(name)));
179
180
    return result;
181
}
182
183
184
void cvSetPropWindow_QT(const char* name,double prop_value)
185
{
186
    if (!guiMainThread)
187
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
188
189
    QMetaObject::invokeMethod(guiMainThread,
190
        "setPropWindow",
191
        Qt::AutoConnection,
192
        Q_ARG(QString, QString(name)),
193
        Q_ARG(double, prop_value));
194
}
195
196
197
void cvSetModeWindow_QT(const char* name, double prop_value)
198
{
199
    if (!guiMainThread)
200
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
201
202
    QMetaObject::invokeMethod(guiMainThread,
203
        "toggleFullScreen",
204
        Qt::AutoConnection,
205
        Q_ARG(QString, QString(name)),
206
        Q_ARG(double, prop_value));
207
}
208
209
210
double cvGetModeWindow_QT(const char* name)
211
{
212
    if (!guiMainThread)
213
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
214
215
    double result = -1;
216
217
    QMetaObject::invokeMethod(guiMainThread,
218
        "isFullScreen",
219
        Qt::AutoConnection,
220
        Q_RETURN_ARG(double, result),
221
        Q_ARG(QString, QString(name)));
222
223
    return result;
224
}
225
226
CV_IMPL void cvAdjustWindowPos_Qt( const char * name, int xp, int xwp, int yp, int yhp )
227
{
228
        int cx,cy;
229
        QDesktopWidget* pDeskWid = QApplication::desktop() ;
230
        QRect ScreenGeo = pDeskWid->screenGeometry();  // braucht  #include <QDesktopWidget>
231
        cx = ScreenGeo.width();
232
        cy = ScreenGeo.height();
233
        int    x = 0.01 * ( xp * cx );
234
        int    y = 0.01 * ( yp * cy );
235
        int neww = 0.01 * (xwp * cx );
236
        int newh = 0.01 * (yhp * cy );
237
        cvMoveWindow( name, x, y );
238
        cvResizeWindow( name, neww, newh );   
239
}
240
241
CV_IMPL void cvDisplayOverlay(const char* name, const char* text, int delayms)
242
{
243
    if (!guiMainThread)
244
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
245
246
    QMetaObject::invokeMethod(guiMainThread,
247
        "displayInfo",
248
        Qt::AutoConnection,
249
        //Qt::DirectConnection,
250
        Q_ARG(QString, QString(name)),
251
        Q_ARG(QString, QString(text)),
252
        Q_ARG(int, delayms));
253
}
254
255
CV_IMPL void cvSaveWindowParameters(const char* name)
256
{
257
    if (!guiMainThread)
258
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
259
260
    QMetaObject::invokeMethod(guiMainThread,
261
        "saveWindowParameters",
262
        Qt::AutoConnection,
263
        Q_ARG(QString, QString(name)));
264
}
265
266
267
CV_IMPL void cvLoadWindowParameters(const char* name)
268
{
269
    if (!guiMainThread)
270
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
271
272
    QMetaObject::invokeMethod(guiMainThread,
273
        "loadWindowParameters",
274
        Qt::AutoConnection,
275
        Q_ARG(QString, QString(name)));
276
}
277
278
279
CV_IMPL void cvDisplayStatusBar(const char* name, const char* text, int delayms)
280
{
281
    if (!guiMainThread)
282
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
283
284
    QMetaObject::invokeMethod(guiMainThread,
285
        "displayStatusBar",
286
        Qt::AutoConnection,
287
        //Qt::DirectConnection,
288
        Q_ARG(QString, QString(name)),
289
        Q_ARG(QString, QString(text)),
290
        Q_ARG(int, delayms));
291
}
292
293
294
CV_IMPL int cvWaitKey(int delay)
295
{
296
    int result = -1;
297
298
    if (!guiMainThread)
299
        return result;
300
301
    unsigned long delayms = delay <= 0 ? ULONG_MAX : delay; //in milliseconds
302
303
    if (multiThreads)
304
    {
305
        mutexKey.lock();
306
        if (key_pressed.wait(&mutexKey, delayms)) //false if timeout
307
        {
308
            result = last_key;
309
        }
310
        last_key = -1;
311
        mutexKey.unlock();
312
    }
313
    else
314
    {
315
        //cannot use wait here because events will not be distributed before processEvents (the main eventLoop is broken)
316
        //so I create a Thread for the QTimer
317
318
        if (delay > 0)
319
            guiMainThread->timer->start(delay);
320
321
        //QMutex dummy;
322
323
        while (!guiMainThread->bTimeOut)
324
        {
325
            qApp->processEvents(QEventLoop::AllEvents);
326
327
            if (!guiMainThread)//when all the windows are deleted
328
                return result;
329
330
            mutexKey.lock();
331
            if (last_key != -1)
332
            {
333
                result = last_key;
334
                last_key = -1;
335
                guiMainThread->timer->stop();
336
                //printf("keypressed\n");
337
            }
338
            mutexKey.unlock();
339
340
            if (result!=-1)
341
            {
342
                break;
343
            }
344
            else
345
            {
346
                /*
347
    * //will not work, I broke the event loop !!!!
348
    dummy.lock();
349
    QWaitCondition waitCondition;
350
    waitCondition.wait(&dummy, 2);
351
    */
352
353
                //to decrease CPU usage
354
                //sleep 1 millisecond
355
#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
356
                Sleep(1);
357
#else
358
                usleep(1000);
359
#endif
360
            }
361
        }
362
363
        guiMainThread->bTimeOut = false;
364
    }
365
366
    return result;
367
}
368
369
370
//Yannick Verdie
371
//This function is experimental and some functions (such as cvSet/getWindowProperty will not work)
372
//We recommend not using this function for now
373
CV_IMPL int cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[])
374
{
375
    multiThreads = true;
376
    QFuture<int> future = QtConcurrent::run(pt2Func, argc, argv);
377
    return guiMainThread->start();
378
}
379
380
381
CV_IMPL void cvStopLoop()
382
{
383
    qApp->exit();
384
}
385
386
387
static CvWindow* icvFindWindowByName(QString name)
388
{
389
    CvWindow* window = 0;
390
391
    //This is not a very clean way to do the stuff. Indeed, QAction automatically generate toolTil (QLabel)
392
    //that can be grabbed here and crash the code at 'w->param_name==name'.
393
    foreach (QWidget* widget, QApplication::topLevelWidgets())
394
    {
395
        if (widget->isWindow() && !widget->parentWidget())//is a window without parent
396
        {
397
            CvWinModel* temp = (CvWinModel*) widget;
398
399
            if (temp->type == type_CvWindow)
400
            {
401
                CvWindow* w = (CvWindow*) temp;
402
                if (w->windowTitle() == name)
403
                {
404
                    window = w;
405
                    break;
406
                }
407
            }
408
        }
409
    }
410
411
    return window;
412
}
413
414
415
static CvBar* icvFindBarByName(QBoxLayout* layout, QString name_bar, typeBar type)
416
{
417
    if (!layout)
418
        return NULL;
419
420
    int stop_index = layout->layout()->count();
421
422
    for (int i = 0; i < stop_index; ++i)
423
    {
424
        CvBar* t = (CvBar*) layout->layout()->itemAt(i);
425
426
        if (t->type == type && t->name_bar == name_bar)
427
            return t;
428
    }
429
430
    return NULL;
431
}
432
433
434
static CvTrackbar* icvFindTrackBarByName(const char* name_trackbar, const char* name_window, QBoxLayout* layout = NULL)
435
{
436
    QString nameQt(name_trackbar);
437
438
    if (!name_window && global_control_panel) //window name is null and we have a control panel
439
        layout = global_control_panel->myLayout;
440
441
    if (!layout)
442
    {
443
        QPointer<CvWindow> w = icvFindWindowByName(QLatin1String(name_window));
444
445
        if (!w)
446
            CV_Error(CV_StsNullPtr, "NULL window handler");
447
448
        if (w->param_gui_mode == CV_GUI_NORMAL)
449
            return (CvTrackbar*) icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar);
450
451
        if (w->param_gui_mode == CV_GUI_EXPANDED)
452
        {
453
            CvBar* result = icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar);
454
455
            if (result)
456
                return (CvTrackbar*) result;
457
458
            return (CvTrackbar*) icvFindBarByName(global_control_panel->myLayout, nameQt, type_CvTrackbar);
459
        }
460
461
        return NULL;
462
    }
463
    else
464
    {
465
        //layout was specified
466
        return (CvTrackbar*) icvFindBarByName(layout, nameQt, type_CvTrackbar);
467
    }
468
}
469
470
/*
471
static CvButtonbar* icvFindButtonBarByName(const char* button_name, QBoxLayout* layout)
472
{
473
    QString nameQt(button_name);
474
    return (CvButtonbar*) icvFindBarByName(layout, nameQt, type_CvButtonbar);
475
}
476
*/
477
478
static int icvInitSystem(int* c, char** v)
479
{
480
    //"For any GUI application using Qt, there is precisely one QApplication object"
481
    if (!QApplication::instance())
482
    {
483
        new QApplication(*c, v);
484
485
        qDebug() << "init done";
486
487
#ifdef HAVE_QT_OPENGL
488
        qDebug() << "opengl support available";
489
#endif
490
    }
491
492
    return 0;
493
}
494
495
496
CV_IMPL int cvInitSystem(int, char**)
497
{
498
    icvInitSystem(&parameterSystemC, parameterSystemV);
499
    return 0;
500
}
501
502
503
CV_IMPL int cvNamedWindow(const char* name, int flags)
504
{
505
    if (!guiMainThread)
506
        guiMainThread = new GuiReceiver;
507
508
    if (multiThreads)
509
        QMetaObject::invokeMethod(guiMainThread,
510
        "createWindow",
511
        Qt::BlockingQueuedConnection,
512
        Q_ARG(QString, QString(name)),
513
        Q_ARG(int, flags));
514
    else
515
        guiMainThread->createWindow(QString(name), flags);
516
517
    return 1; //Dummy value
518
}
519
520
521
CV_IMPL void cvDestroyWindow(const char* name)
522
{
523
    if (!guiMainThread)
524
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
525
526
    QMetaObject::invokeMethod(guiMainThread,
527
        "destroyWindow",
528
        //Qt::BlockingQueuedConnection,
529
        Qt::AutoConnection,
530
        Q_ARG(QString, QString(name)));
531
}
532
533
534
CV_IMPL void cvDestroyAllWindows()
535
{
536
    if (!guiMainThread)
537
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
538
539
    QMetaObject::invokeMethod(guiMainThread,
540
        "destroyAllWindow",
541
        //Qt::BlockingQueuedConnection,
542
        Qt::AutoConnection);
543
}
544
545
546
CV_IMPL void* cvGetWindowHandle(const char* name)
547
{
548
    if (!name)
549
        CV_Error( CV_StsNullPtr, "NULL name string" );
550
551
    return (void*) icvFindWindowByName(QLatin1String(name));
552
}
553
554
555
CV_IMPL const char* cvGetWindowName(void* window_handle)
556
{
557
    if( !window_handle )
558
        CV_Error( CV_StsNullPtr, "NULL window handler" );
559
560
    return ((CvWindow*)window_handle)->windowTitle().toLatin1().data();
561
}
562
563
564
CV_IMPL void cvMoveWindow(const char* name, int x, int y)
565
{
566
    if (!guiMainThread)
567
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
568
569
    QMetaObject::invokeMethod(guiMainThread,
570
        "moveWindow",
571
        //Qt::BlockingQueuedConnection,
572
        Qt::AutoConnection,
573
        Q_ARG(QString, QString(name)),
574
        Q_ARG(int, x),
575
        Q_ARG(int, y));
576
}
577
578
579
CV_IMPL void cvResizeWindow(const char* name, int width, int height)
580
{
581
    if (!guiMainThread)
582
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
583
584
    QMetaObject::invokeMethod(guiMainThread,
585
        "resizeWindow",
586
        //Qt::BlockingQueuedConnection,
587
        Qt::AutoConnection,
588
        Q_ARG(QString, QString(name)),
589
        Q_ARG(int, width),
590
        Q_ARG(int, height));
591
}
592
593
594
CV_IMPL int cvCreateTrackbar2(const char* name_bar, const char* window_name, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata)
595
{
596
    if (!guiMainThread)
597
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
598
599
    QMetaObject::invokeMethod(guiMainThread,
600
        "addSlider2",
601
        Qt::AutoConnection,
602
        Q_ARG(QString, QString(name_bar)),
603
        Q_ARG(QString, QString(window_name)),
604
        Q_ARG(void*, (void*)val),
605
        Q_ARG(int, count),
606
        Q_ARG(void*, (void*)on_notify),
607
        Q_ARG(void*, (void*)userdata));
608
609
    return 1; //dummy value
610
}
611
612
613
CV_IMPL int cvStartWindowThread()
614
{
615
    return 0;
616
}
617
618
619
CV_IMPL int cvCreateTrackbar(const char* name_bar, const char* window_name, int* value, int count, CvTrackbarCallback on_change)
620
{
621
    if (!guiMainThread)
622
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
623
624
    QMetaObject::invokeMethod(guiMainThread,
625
        "addSlider",
626
        Qt::AutoConnection,
627
        Q_ARG(QString, QString(name_bar)),
628
        Q_ARG(QString, QString(window_name)),
629
        Q_ARG(void*, (void*)value),
630
        Q_ARG(int, count),
631
        Q_ARG(void*, (void*)on_change));
632
633
    return 1; //dummy value
634
}
635
636
637
CV_IMPL int cvCreateButton(const char* button_name, CvButtonCallback on_change, void* userdata, int button_type, int initial_button_state)
638
{
639
    if (!guiMainThread)
640
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
641
642
    if (initial_button_state < 0 || initial_button_state > 1)
643
        return 0;
644
645
    QMetaObject::invokeMethod(guiMainThread,
646
        "addButton",
647
        Qt::AutoConnection,
648
        Q_ARG(QString, QString(button_name)),
649
        Q_ARG(int,  button_type),
650
        Q_ARG(int, initial_button_state),
651
        Q_ARG(void*, (void*)on_change),
652
        Q_ARG(void*, userdata));
653
654
    return 1;//dummy value
655
}
656
657
658
CV_IMPL int cvGetTrackbarPos(const char* name_bar, const char* window_name)
659
{
660
    int result = -1;
661
662
    QPointer<CvTrackbar> t = icvFindTrackBarByName(name_bar, window_name);
663
664
    if (t)
665
        result = t->slider->value();
666
667
    return result;
668
}
669
670
671
CV_IMPL void cvSetTrackbarPos(const char* name_bar, const char* window_name, int pos)
672
{
673
    QPointer<CvTrackbar> t = icvFindTrackBarByName(name_bar, window_name);
674
675
    if (t)
676
        t->slider->setValue(pos);
677
}
678
679
680
/* assign callback for mouse events */
681
CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mouse, void* param)
682
{
683
    QPointer<CvWindow> w = icvFindWindowByName(QLatin1String(window_name));
684
685
    if (!w)
686
        CV_Error(CV_StsNullPtr, "NULL window handler");
687
688
    w->setMouseCallBack(on_mouse, param);
689
690
}
691
692
693
CV_IMPL void cvShowImage(const char* name, const CvArr* arr)
694
{
695
    if (!guiMainThread)
696
        guiMainThread = new GuiReceiver;
697
698
    QMetaObject::invokeMethod(guiMainThread,
699
        "showImage",
700
        //Qt::BlockingQueuedConnection,
701
        Qt::DirectConnection,
702
        Q_ARG(QString, QString(name)),
703
        Q_ARG(void*, (void*)arr));
704
}
705
706
CV_IMPL void cvDispInfoBox_Qt( const char* WndName, char* caption, const char * csTxt ) 
707
{
708
        if (!WndName)
709
                CV_Error( CV_StsNullPtr, "NULL name string" );
710
711
        QPointer<CvWindow> w = icvFindWindowByName(QLatin1String(WndName));
712
        if ( w == NULL ) 
713
        {
714
                printf("\ncvDispInfoBox_Qt: [%s] is unknown as WndName ! ", WndName ); 
715
                return;
716
        }
717
        w->MsgBoxInfo( caption, std::string(csTxt) );
718
}
719
720
CV_IMPL int cvGetCommand( const char* WndName, char* cmd)
721
{
722
    if (!WndName)
723
        {
724
                CV_Error( CV_StsNullPtr, "NULL name string" );
725
                return 0;
726
        }
727
        QPointer<CvWindow> w = icvFindWindowByName(QLatin1String(WndName));
728
        if ( w == NULL ) 
729
        {
730
                printf("\ncvGetCommand: [%s] is unknown as WndName ! ", WndName ); 
731
                return 0;
732
        }
733
        if ( w->m_CmdVec.size() > 0 )
734
        {
735
                strcpy( cmd, qPrintable(w->m_CmdVec[0]) );
736
                w->m_CmdVec.clear();
737
        } else {
738
                cmd[0] = 0;
739
        }
740
        return 1;
741
}
742
743
CV_IMPL int cvGetButtonBarContent(const char * WndName, int idx, char * txt )
744
{
745
        if (!WndName)
746
        {
747
                CV_Error( CV_StsNullPtr, "NULL name string" );
748
                return 0;
749
        }
750
        QPointer<CvWindow> w = icvFindWindowByName(QLatin1String(WndName));
751
        if ( w == NULL ) 
752
        {
753
                printf("\ncvGetButtonBarCommand: [%s] is unknown as WndName ! ", WndName ); 
754
                return 0;
755
        }
756
        if ( idx < w->m_ContentVec.size() )
757
        {
758
                QString stng = w->m_ContentVec[idx];
759
                strcpy( txt, qPrintable(stng) );
760
                return 1;
761
        } 
762
        return 0;
763
}
764
765
CV_IMPL int cvSetButtonBarContent(const char * WndName, int etype, int idx, char * txt )
766
{
767
        if (!guiMainThread)
768
                CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
769
770
        QMetaObject::invokeMethod(guiMainThread,
771
                "ModifyContent",
772
                Qt::AutoConnection,
773
                Q_ARG(QString, QString(WndName)),
774
                Q_ARG(int, etype ),
775
                Q_ARG(int, idx),
776
                Q_ARG(QString, QString(txt)) );
777
        
778
        return 0;
779
}
780
781
/*
782
        // Example for usage from application:
783
        while (iKey != 27)
784
    {
785
                cv::getCommandVec("ColorImg", stringVec, csBuffer );
786
                if ( strlen(csBuffer) > 0  )
787
                {
788
                                printf("\n cvGetCommandVec(ColorImg)->[%s]\n ", csBuffer );
789
                                // print buttonbar content ......
790
                                for ( int j=0; j < stringVec.size() ; j++ )
791
                                {
792
                                        printf("<%s>", stringVec[j].c_str() );
793
                                }
794
                                // do something, depending on csBuffer.......
795
                }
796
                iKey = cv::waitKey(5);
797
        }
798
*/
799
800
801
802
#ifdef HAVE_QT_OPENGL
803
804
CV_IMPL void cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata)
805
{
806
    if (!guiMainThread)
807
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
808
809
    QMetaObject::invokeMethod(guiMainThread,
810
        "setOpenGlDrawCallback",
811
        Qt::AutoConnection,
812
        Q_ARG(QString, QString(window_name)),
813
        Q_ARG(void*, (void*)callback),
814
        Q_ARG(void*, userdata));
815
}
816
817
818
void icvSetOpenGlCleanCallback(const char* window_name, CvOpenGlCleanCallback callback, void* userdata)
819
{
820
    if (!guiMainThread)
821
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
822
823
    QMetaObject::invokeMethod(guiMainThread,
824
        "setOpenGlCleanCallback",
825
        Qt::AutoConnection,
826
        Q_ARG(QString, QString(window_name)),
827
        Q_ARG(void*, (void*)callback),
828
        Q_ARG(void*, userdata));
829
}
830
831
832
CV_IMPL void cvSetOpenGlContext(const char* window_name)
833
{
834
    if (!guiMainThread)
835
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
836
837
    QMetaObject::invokeMethod(guiMainThread,
838
        "setOpenGlContext",
839
        Qt::AutoConnection,
840
        Q_ARG(QString, QString(window_name)));
841
}
842
843
844
CV_IMPL void cvUpdateWindow(const char* window_name)
845
{
846
    if (!guiMainThread)
847
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
848
849
    QMetaObject::invokeMethod(guiMainThread,
850
        "updateWindow",
851
        Qt::AutoConnection,
852
        Q_ARG(QString, QString(window_name)));
853
}
854
855
#endif
856
857
858
double cvGetOpenGlProp_QT(const char* name)
859
{
860
    double result = -1;
861
862
    if (guiMainThread)
863
    {
864
        QMetaObject::invokeMethod(guiMainThread,
865
            "isOpenGl",
866
            Qt::AutoConnection,
867
            Q_RETURN_ARG(double, result),
868
            Q_ARG(QString, QString(name)));
869
    }
870
871
    return result;
872
}
873
874
875
//////////////////////////////////////////////////////
876
// GuiReceiver
877
878
879
GuiReceiver::GuiReceiver() : bTimeOut(false), nb_windows(0)
880
{
881
    doesExternalQAppExist = (QApplication::instance() != 0);
882
    icvInitSystem(&parameterSystemC, parameterSystemV);
883
884
    timer = new QTimer(this);
885
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timeOut()));
886
    timer->setSingleShot(true);
887
}
888
889
890
void GuiReceiver::isLastWindow()
891
{
892
    if (--nb_windows <= 0)
893
    {
894
        delete guiMainThread;//delete global_control_panel too
895
        guiMainThread = NULL;
896
897
        if (!doesExternalQAppExist)
898
        {
899
            qApp->quit();
900
        }
901
    }
902
}
903
904
905
GuiReceiver::~GuiReceiver()
906
{
907
    if (global_control_panel)
908
    {
909
        delete global_control_panel;
910
        global_control_panel = NULL;
911
    }
912
}
913
914
915
void GuiReceiver::putText(void* arr, QString text, QPoint org, void* arg2)
916
{
917
    CV_Assert(arr);
918
919
    CvMat* mat, stub;
920
    mat = cvGetMat(arr, &stub);
921
922
    int nbChannelOriginImage = cvGetElemType(mat);
923
    if (nbChannelOriginImage != CV_8UC3) return; //for now, font works only with 8UC3
924
925
    QImage qimg(mat->data.ptr, mat->cols, mat->rows, mat->step, QImage::Format_RGB888);
926
927
    CvFont* font = (CvFont*)arg2;
928
929
    QPainter qp(&qimg);
930
    if (font)
931
    {
932
        QFont f(font->nameFont, font->line_type/*PointSize*/, font->thickness/*weight*/);
933
        f.setStyle((QFont::Style) font->font_face/*style*/);
934
        f.setLetterSpacing(QFont::AbsoluteSpacing, font->dx/*spacing*/);
935
        //cvScalar(blue_component, green_component, red_component[, alpha_component])
936
        //Qt map non-transparent to 0xFF and transparent to 0
937
        //OpenCV scalar is the reverse, so 255-font->color.val[3]
938
        qp.setPen(QColor(font->color.val[2], font->color.val[1], font->color.val[0], 255 - font->color.val[3]));
939
        qp.setFont(f);
940
    }
941
    qp.drawText(org, text);
942
    qp.end();
943
}
944
945
946
void GuiReceiver::saveWindowParameters(QString name)
947
{
948
    QPointer<CvWindow> w = icvFindWindowByName(name);
949
950
    if (w)
951
        w->writeSettings();
952
}
953
954
955
void GuiReceiver::loadWindowParameters(QString name)
956
{
957
    QPointer<CvWindow> w = icvFindWindowByName(name);
958
959
    if (w)
960
        w->readSettings();
961
}
962
963
964
double GuiReceiver::getRatioWindow(QString name)
965
{
966
    QPointer<CvWindow> w = icvFindWindowByName(name);
967
968
    if (!w)
969
        return -1;
970
971
    return w->getRatio();
972
}
973
974
975
void GuiReceiver::setRatioWindow(QString name, double arg2)
976
{
977
    QPointer<CvWindow> w = icvFindWindowByName( name.toLatin1().data() );
978
979
    if (!w)
980
        return;
981
982
    int flags = (int) arg2;
983
984
    w->setRatio(flags);
985
}
986
987
988
double GuiReceiver::getPropWindow(QString name)
989
{
990
    QPointer<CvWindow> w = icvFindWindowByName(name);
991
992
    if (!w)
993
        return -1;
994
995
    return (double) w->getPropWindow();
996
}
997
998
999
void GuiReceiver::setPropWindow(QString name, double arg2)
1000
{
1001
    QPointer<CvWindow> w = icvFindWindowByName(name);
1002
1003
    if (!w)
1004
        return;
1005
1006
    int flags = (int) arg2;
1007
1008
    w->setPropWindow(flags);
1009
}
1010
1011
1012
double GuiReceiver::isFullScreen(QString name)
1013
{
1014
    QPointer<CvWindow> w = icvFindWindowByName(name);
1015
1016
    if (!w)
1017
        return -1;
1018
1019
    return w->isFullScreen() ? CV_WINDOW_FULLSCREEN : CV_WINDOW_NORMAL;
1020
}
1021
1022
1023
void GuiReceiver::toggleFullScreen(QString name, double arg2)
1024
{
1025
    QPointer<CvWindow> w = icvFindWindowByName(name);
1026
1027
    if (!w)
1028
        return;
1029
1030
    int flags = (int) arg2;
1031
1032
    w->toggleFullScreen(flags);
1033
}
1034
1035
1036
void GuiReceiver::createWindow(QString name, int flags)
1037
{
1038
    if (!qApp)
1039
        CV_Error(CV_StsNullPtr, "NULL session handler" );
1040
1041
    // Check the name in the storage
1042
    if (icvFindWindowByName(name.toLatin1().data()))
1043
    {
1044
        return;
1045
    }
1046
1047
    nb_windows++;
1048
    new CvWindow(name, flags);
1049
}
1050
1051
1052
void GuiReceiver::timeOut()
1053
{
1054
    bTimeOut = true;
1055
}
1056
1057
1058
void GuiReceiver::displayInfo(QString name, QString text, int delayms)
1059
{
1060
    QPointer<CvWindow> w = icvFindWindowByName(name);
1061
1062
    if (w)
1063
        w->displayInfo(text, delayms);
1064
}
1065
1066
1067
void GuiReceiver::displayStatusBar(QString name, QString text, int delayms)
1068
{
1069
    QPointer<CvWindow> w = icvFindWindowByName(name);
1070
1071
    if (w)
1072
        w->displayStatusBar(text, delayms);
1073
}
1074
1075
1076
void GuiReceiver::showImage(QString name, void* arr)
1077
{
1078
    QPointer<CvWindow> w = icvFindWindowByName(name);
1079
1080
    if (!w) //as observed in the previous implementation (W32, GTK or Carbon), create a new window is the pointer returned is null
1081
    {
1082
        cvNamedWindow(name.toLatin1().data());
1083
        w = icvFindWindowByName(name);
1084
    }
1085
1086
    if (!w || !arr)
1087
        return; // keep silence here.
1088
1089
    if (w->isOpenGl())
1090
    {
1091
        CvMat* mat, stub;
1092
1093
        mat = cvGetMat(arr, &stub);
1094
1095
        cv::Mat im(mat);
1096
        cv::imshow(name.toStdString(), im);
1097
    }
1098
    else
1099
    {
1100
        w->updateImage(arr);
1101
    }
1102
1103
    if (w->isHidden())
1104
        w->show();
1105
}
1106
1107
1108
void GuiReceiver::destroyWindow(QString name)
1109
{
1110
    QPointer<CvWindow> w = icvFindWindowByName(name);
1111
1112
    if (w)
1113
    {
1114
        w->close();
1115
1116
        //in not-multiThreads mode, looks like the window is hidden but not deleted
1117
        //so I do it manually
1118
        //otherwise QApplication do it for me if the exec command was executed (in multiThread mode)
1119
        if (!multiThreads)
1120
            delete w;
1121
    }
1122
}
1123
1124
1125
void GuiReceiver::destroyAllWindow()
1126
{
1127
    if (!qApp)
1128
        CV_Error(CV_StsNullPtr, "NULL session handler" );
1129
1130
    if (multiThreads)
1131
    {
1132
        // WARNING: this could even close windows from an external parent app
1133
        //#TODO check externalQAppExists and in case it does, close windows carefully,
1134
        //      i.e. apply the className-check from below...
1135
        qApp->closeAllWindows();
1136
    }
1137
    else
1138
    {
1139
        bool isWidgetDeleted = true;
1140
        while(isWidgetDeleted)
1141
        {
1142
            isWidgetDeleted = false;
1143
            QWidgetList list = QApplication::topLevelWidgets();
1144
            for (int i = 0; i < list.count(); i++)
1145
            {
1146
                QObject *obj = list.at(i);
1147
                if (obj->metaObject()->className() == QString("CvWindow"))
1148
                {
1149
                    delete obj;
1150
                    isWidgetDeleted = true;
1151
                    break;
1152
                }
1153
            }
1154
        }
1155
    }
1156
}
1157
1158
1159
void GuiReceiver::moveWindow(QString name, int x, int y)
1160
{
1161
    QPointer<CvWindow> w = icvFindWindowByName(name);
1162
1163
    if (w)
1164
        w->move(x, y);
1165
}
1166
1167
1168
void GuiReceiver::resizeWindow(QString name, int width, int height)
1169
{
1170
    QPointer<CvWindow> w = icvFindWindowByName(name);
1171
1172
    if (w)
1173
    {
1174
        w->showNormal();
1175
        w->setViewportSize(QSize(width, height));
1176
    }
1177
}
1178
1179
1180
void GuiReceiver::enablePropertiesButtonEachWindow()
1181
{
1182
    //For each window, enable window property button
1183
    foreach (QWidget* widget, QApplication::topLevelWidgets())
1184
    {
1185
        if (widget->isWindow() && !widget->parentWidget()) //is a window without parent
1186
        {
1187
            CvWinModel* temp = (CvWinModel*) widget;
1188
            if (temp->type == type_CvWindow)
1189
            {
1190
                CvWindow* w = (CvWindow*) widget;
1191
1192
                //active window properties button
1193
                w->enablePropertiesButton();
1194
            }
1195
        }
1196
    }
1197
}
1198
1199
void GuiReceiver::ModifyContent(QString WndName, int etype, int idx, QString text)
1200
{
1201
        QPointer<CvWindow> w = icvFindWindowByName(WndName);
1202
1203
        if (w)
1204
                w->modifyContent(WndName,etype,idx,text);
1205
        else 
1206
                printf("\nNo window found with name [%s] ", qPrintable(WndName) );
1207
}
1208
1209
void GuiReceiver::addButton(QString button_name, int button_type, int initial_button_state, void* on_change, void* userdata)
1210
{
1211
    if (!global_control_panel)
1212
        return;
1213
1214
    QPointer<CvButtonbar> b;
1215
1216
    if (global_control_panel->myLayout->count() == 0) //if that is the first button attach to the control panel, create a new button bar
1217
    {
1218
        b = CvWindow::createButtonBar(button_name); //the bar has the name of the first button attached to it
1219
        enablePropertiesButtonEachWindow();
1220
1221
    }
1222
    else
1223
    {
1224
        CvBar* lastbar = (CvBar*) global_control_panel->myLayout->itemAt(global_control_panel->myLayout->count() - 1);
1225
1226
        if (lastbar->type == type_CvTrackbar) //if last bar is a trackbar, create a new buttonbar, else, attach to the current bar
1227
            b = CvWindow::createButtonBar(button_name); //the bar has the name of the first button attached to it
1228
        else
1229
            b = (CvButtonbar*) lastbar;
1230
1231
    }
1232
1233
    b->addButton(button_name, (CvButtonCallback) on_change, userdata, button_type, initial_button_state);
1234
}
1235
1236
1237
void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, int count, void* on_change, void *userdata)
1238
{
1239
    QBoxLayout *layout = NULL;
1240
    QPointer<CvWindow> w;
1241
1242
    if (!window_name.isEmpty())
1243
    {
1244
        w = icvFindWindowByName(window_name);
1245
1246
        if (!w)
1247
            return;
1248
    }
1249
    else
1250
    {
1251
        if (global_control_panel)
1252
            layout = global_control_panel->myLayout;
1253
    }
1254
1255
    QPointer<CvTrackbar> t = icvFindTrackBarByName(bar_name.toLatin1().data(), window_name.toLatin1().data(), layout);
1256
1257
    if (t) //trackbar exists
1258
        return;
1259
1260
    if (!value)
1261
        CV_Error(CV_StsNullPtr, "NULL value pointer" );
1262
1263
    if (count <= 0) //count is the max value of the slider, so must be bigger than 0
1264
        CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" );
1265
1266
    CvWindow::addSlider2(w, bar_name, (int*)value, count, (CvTrackbarCallback2) on_change, userdata);
1267
}
1268
1269
1270
void GuiReceiver::addSlider(QString bar_name, QString window_name, void* value, int count, void* on_change)
1271
{
1272
    QBoxLayout *layout = NULL;
1273
    QPointer<CvWindow> w;
1274
1275
    if (!window_name.isEmpty())
1276
    {
1277
        w = icvFindWindowByName(window_name);
1278
1279
        if (!w)
1280
            return;
1281
    }
1282
    else
1283
    {
1284
        if (global_control_panel)
1285
            layout = global_control_panel->myLayout;
1286
    }
1287
1288
    QPointer<CvTrackbar> t = icvFindTrackBarByName(bar_name.toLatin1().data(), window_name.toLatin1().data(), layout);
1289
1290
    if (t) //trackbar exists
1291
        return;
1292
1293
    if (!value)
1294
        CV_Error(CV_StsNullPtr, "NULL value pointer" );
1295
1296
    if (count <= 0) //count is the max value of the slider, so must be bigger than 0
1297
        CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" );
1298
1299
    CvWindow::addSlider(w, bar_name, (int*)value, count, (CvTrackbarCallback) on_change);
1300
}
1301
1302
1303
int GuiReceiver::start()
1304
{
1305
    return qApp->exec();
1306
}
1307
1308
1309
void GuiReceiver::setOpenGlDrawCallback(QString name, void* callback, void* userdata)
1310
{
1311
    QPointer<CvWindow> w = icvFindWindowByName(name);
1312
1313
    if (w)
1314
        w->setOpenGlDrawCallback((CvOpenGlDrawCallback) callback, userdata);
1315
}
1316
1317
void GuiReceiver::setOpenGlCleanCallback(QString name, void* callback, void* userdata)
1318
{
1319
    QPointer<CvWindow> w = icvFindWindowByName(name);
1320
1321
    if (w)
1322
        w->setOpenGlCleanCallback((CvOpenGlCleanCallback) callback, userdata);
1323
}
1324
1325
void GuiReceiver::setOpenGlContext(QString name)
1326
{
1327
    QPointer<CvWindow> w = icvFindWindowByName(name);
1328
1329
    if (w)
1330
        w->makeCurrentOpenGlContext();
1331
}
1332
1333
void GuiReceiver::updateWindow(QString name)
1334
{
1335
    QPointer<CvWindow> w = icvFindWindowByName(name);
1336
1337
    if (w)
1338
        w->updateGl();
1339
}
1340
1341
double GuiReceiver::isOpenGl(QString name)
1342
{
1343
    double result = -1;
1344
1345
    QPointer<CvWindow> w = icvFindWindowByName(name);
1346
1347
    if (w)
1348
        result = (double) w->isOpenGl();
1349
1350
    return result;
1351
}
1352
1353
1354
//////////////////////////////////////////////////////
1355
// CvTrackbar
1356
1357
1358
CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int _count, CvTrackbarCallback2 on_change, void* data)
1359
{
1360
    callback = NULL;
1361
    callback2 = on_change;
1362
    userdata = data;
1363
1364
    create(arg, name, value, _count);
1365
}
1366
1367
1368
CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int _count, CvTrackbarCallback on_change)
1369
{
1370
    callback = on_change;
1371
    callback2 = NULL;
1372
    userdata = NULL;
1373
1374
    create(arg, name, value, _count);
1375
}
1376
1377
1378
void CvTrackbar::create(CvWindow* arg, QString name, int* value, int _count)
1379
{
1380
    type = type_CvTrackbar;
1381
    myparent = arg;
1382
    name_bar = name;
1383
    setObjectName(name_bar);
1384
    dataSlider = value;
1385
1386
    slider = new QSlider(Qt::Horizontal);
1387
    slider->setFocusPolicy(Qt::StrongFocus);
1388
    slider->setMinimum(0);
1389
    slider->setMaximum(_count);
1390
    slider->setPageStep(5);
1391
    slider->setValue(*value);
1392
    slider->setTickPosition(QSlider::TicksBelow);
1393
1394
1395
    //Change style of the Slider
1396
    //slider->setStyleSheet(str_Trackbar_css);
1397
1398
    QFile qss(":/stylesheet-trackbar");
1399
    if (qss.open(QFile::ReadOnly))
1400
    {
1401
        slider->setStyleSheet(QLatin1String(qss.readAll()));
1402
        qss.close();
1403
    }
1404
1405
1406
    //this next line does not work if we change the style with a stylesheet, why ? (bug in QT ?)
1407
    //slider->setTickPosition(QSlider::TicksBelow);
1408
    label = new QPushButton;
1409
    label->setFlat(true);
1410
    setLabel(slider->value());
1411
1412
1413
    QObject::connect(slider, SIGNAL(valueChanged(int)), this, SLOT(update(int)));
1414
1415
    QObject::connect(label, SIGNAL(clicked()), this, SLOT(createDialog()));
1416
1417
    //label->setStyleSheet("QPushButton:disabled {color: black}");
1418
1419
    addWidget(label, Qt::AlignLeft);//name + value
1420
    addWidget(slider, Qt::AlignCenter);//slider
1421
}
1422
1423
1424
void CvTrackbar::createDialog()
1425
{
1426
    bool ok = false;
1427
1428
    //crash if I access the values directly and give them to QInputDialog, so do a copy first.
1429
    int value = slider->value();
1430
    int step = slider->singleStep();
1431
    int min = slider->minimum();
1432
    int max = slider->maximum();
1433
1434
    int i =
1435
#if QT_VERSION >= 0x040500
1436
        QInputDialog::getInt
1437
#else
1438
        QInputDialog::getInteger
1439
#endif
1440
        (this->parentWidget(),
1441
        tr("Slider %1").arg(name_bar),
1442
        tr("New value:"),
1443
        value,
1444
        min,
1445
        max,
1446
        step,
1447
        &ok);
1448
1449
    if (ok)
1450
        slider->setValue(i);
1451
}
1452
1453
1454
void CvTrackbar::update(int myvalue)
1455
{
1456
    setLabel(myvalue);
1457
1458
    *dataSlider = myvalue;
1459
    if (callback)
1460
    {
1461
        callback(myvalue);
1462
        return;
1463
    }
1464
1465
    if (callback2)
1466
    {
1467
        callback2(myvalue, userdata);
1468
        return;
1469
    }
1470
}
1471
1472
1473
void CvTrackbar::setLabel(int myvalue)
1474
{
1475
    QString nameNormalized = name_bar.leftJustified( 10, ' ', true );
1476
    QString valueMaximum = QString("%1").arg(slider->maximum());
1477
    QString str = QString("%1 (%2/%3)").arg(nameNormalized).arg(myvalue,valueMaximum.length(),10,QChar('0')).arg(valueMaximum);
1478
    label->setText(str);
1479
}
1480
1481
1482
//////////////////////////////////////////////////////
1483
// CvButtonbar
1484
1485
1486
//here CvButtonbar class
1487
CvButtonbar::CvButtonbar(QWidget* arg,  QString arg2)
1488
{
1489
    type = type_CvButtonbar;
1490
    myparent = arg;
1491
    name_bar = arg2;
1492
    setObjectName(name_bar);
1493
1494
    group_button = new QButtonGroup(this);
1495
}
1496
1497
1498
void CvButtonbar::setLabel()
1499
{
1500
    QString nameNormalized = name_bar.leftJustified(10, ' ', true);
1501
    label->setText(nameNormalized);
1502
}
1503
1504
1505
void CvButtonbar::addButton(QString name, CvButtonCallback call, void* userdata,  int button_type, int initial_button_state)
1506
{
1507
    QString button_name = name;
1508
1509
    if (button_name == "")
1510
        button_name = tr("button %1").arg(this->count());
1511
1512
    QPointer<QAbstractButton> button;
1513
1514
    if (button_type == CV_PUSH_BUTTON)
1515
        button = (QAbstractButton*) new CvPushButton(this, button_name,call, userdata);
1516
1517
    if (button_type == CV_CHECKBOX)
1518
        button = (QAbstractButton*) new CvCheckBox(this, button_name,call, userdata, initial_button_state);
1519
1520
    if (button_type == CV_RADIOBOX)
1521
    {
1522
        button = (QAbstractButton*) new CvRadioButton(this, button_name,call, userdata, initial_button_state);
1523
        group_button->addButton(button);
1524
    }
1525
1526
    if (button)
1527
    {
1528
        if (button_type == CV_PUSH_BUTTON)
1529
            QObject::connect(button, SIGNAL(clicked(bool)), button, SLOT(callCallBack(bool)));
1530
        else
1531
            QObject::connect(button, SIGNAL(toggled(bool)), button, SLOT(callCallBack(bool)));
1532
1533
        addWidget(button, Qt::AlignCenter);
1534
    }
1535
}
1536
1537
1538
//////////////////////////////////////////////////////
1539
// Buttons
1540
1541
1542
//buttons here
1543
CvPushButton::CvPushButton(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4)
1544
{
1545
    myparent = arg1;
1546
    button_name = arg2;
1547
    callback = arg3;
1548
    userdata = arg4;
1549
1550
    setObjectName(button_name);
1551
    setText(button_name);
1552
1553
    if (isChecked())
1554
        callCallBack(true);
1555
}
1556
1557
1558
void CvPushButton::callCallBack(bool checked)
1559
{
1560
    if (callback)
1561
        callback(checked, userdata);
1562
}
1563
1564
1565
CvCheckBox::CvCheckBox(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4, int initial_button_state)
1566
{
1567
    myparent = arg1;
1568
    button_name = arg2;
1569
    callback = arg3;
1570
    userdata = arg4;
1571
1572
    setObjectName(button_name);
1573
    setCheckState((initial_button_state == 1 ? Qt::Checked : Qt::Unchecked));
1574
    setText(button_name);
1575
1576
    if (isChecked())
1577
        callCallBack(true);
1578
}
1579
1580
1581
void CvCheckBox::callCallBack(bool checked)
1582
{
1583
    if (callback)
1584
        callback(checked, userdata);
1585
}
1586
1587
1588
CvRadioButton::CvRadioButton(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4, int initial_button_state)
1589
{
1590
    myparent = arg1;
1591
    button_name = arg2;
1592
    callback = arg3;
1593
    userdata = arg4;
1594
1595
    setObjectName(button_name);
1596
    setChecked(initial_button_state);
1597
    setText(button_name);
1598
1599
    if (isChecked())
1600
        callCallBack(true);
1601
}
1602
1603
void CvRadioButton::callCallBack(bool checked)
1604
{
1605
    if (callback)
1606
        callback(checked, userdata);
1607
}
1608
1609
1610
//////////////////////////////////////////////////////
1611
// CvWinProperties
1612
1613
1614
//here CvWinProperties class
1615
CvWinProperties::CvWinProperties(QString name_paraWindow, QObject* /*parent*/)
1616
{
1617
    //setParent(parent);
1618
    type = type_CvWinProperties;
1619
    setWindowFlags(Qt::Tool);
1620
    setContentsMargins(0, 0, 0, 0);
1621
    setWindowTitle(name_paraWindow);
1622
    setObjectName(name_paraWindow);
1623
    resize(100, 50);
1624
1625
    myLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1626
    myLayout->setObjectName(QString::fromUtf8("boxLayout"));
1627
    myLayout->setContentsMargins(0, 0, 0, 0);
1628
    myLayout->setSpacing(0);
1629
    myLayout->setMargin(0);
1630
    myLayout->setSizeConstraint(QLayout::SetFixedSize);
1631
    setLayout(myLayout);
1632
1633
    hide();
1634
}
1635
1636
1637
void CvWinProperties::closeEvent(QCloseEvent* e)
1638
{
1639
    e->accept(); //intersept the close event (not sure I really need it)
1640
    //an hide event is also sent. I will intercept it and do some processing
1641
}
1642
1643
1644
void CvWinProperties::showEvent(QShowEvent* evnt)
1645
{
1646
    //why -1,-1 ?: do this trick because the first time the code is run,
1647
    //no value pos was saved so we let Qt move the window in the middle of its parent (event ignored).
1648
    //then hide will save the last position and thus, we want to retreive it (event accepted).
1649
    QPoint mypos(-1, -1);
1650
    QSettings settings("OpenCV2", windowTitle());
1651
    mypos = settings.value("pos", mypos).toPoint();
1652
1653
    if (mypos.x() >= 0)
1654
    {
1655
        move(mypos);
1656
        evnt->accept();
1657
    }
1658
    else
1659
    {
1660
        evnt->ignore();
1661
    }
1662
}
1663
1664
1665
void CvWinProperties::hideEvent(QHideEvent* evnt)
1666
{
1667
    QSettings settings("OpenCV2", windowTitle());
1668
    settings.setValue("pos", pos()); //there is an offset of 6 pixels (so the window's position is wrong -- why ?)
1669
    evnt->accept();
1670
}
1671
1672
1673
CvWinProperties::~CvWinProperties()
1674
{
1675
    //clear the setting pos
1676
    QSettings settings("OpenCV2", windowTitle());
1677
    settings.remove("pos");
1678
}
1679
1680
1681
//////////////////////////////////////////////////////
1682
// CvWindow
1683
1684
1685
CvWindow::CvWindow(QString name, int arg2)
1686
{
1687
1688
    type = type_CvWindow;
1689
    moveToThread(qApp->instance()->thread());
1690
1691
    param_flags = arg2 & 0x0000000F;
1692
    param_gui_mode = arg2 & 0x000000F0;
1693
    param_ratio_mode =  arg2 & 0x00000F00;
1694
    m_idxPropWnd = -1;
1695
    bVerbose = false;
1696
        
1697
    if ( bVerbose)
1698
    {
1699
        printf("\n\n CvWindow::CvWindow(%s,%d) => ratio=%d  gui=%d  flags=%d  bVerbose=%d \n", qPrintable(name), 
1700
                                        arg2,param_ratio_mode, param_gui_mode, param_flags, (int) bVerbose );
1701
    }
1702
1703
    //setAttribute(Qt::WA_DeleteOnClose); //in other case, does not release memory
1704
    setContentsMargins(0, 0, 0, 0);
1705
    setWindowTitle(name);
1706
    setObjectName(name);
1707
    m_WndName = name;
1708
1709
    setFocus( Qt::PopupFocusReason ); //#1695 arrow keys are not recieved without the explicit focus
1710
1711
    resize(400, 300);
1712
1713
    if ( param_flags == CV_WINDOW_NORMAL_Z ) 
1714
    {
1715
        printf(" CV_WINDOW_NORMAL_Z ");
1716
        resize(1024, 768);
1717
    } else {
1718
                if ( bVerbose )
1719
                {
1720
                        if ( param_flags == CV_WINDOW_NORMAL   )
1721
                        {
1722
                                        printf("\nCvWindow::CvWindow(%s,CV_WINDOW_NORMAL ", qPrintable(name) ); 
1723
                        }                 
1724
                        if ( param_flags == CV_WINDOW_AUTOSIZE ) 
1725
                        { 
1726
                                        printf("\nCvWindow::CvWindow(%s,CV_WINDOW_AUTOSIZE ", qPrintable(name) );         
1727
                        }
1728
                
1729
                        if ( param_gui_mode == CV_GUI_EXPANDED    ) printf("| CV_GUI_EXPANDED) ");
1730
                        if ( param_gui_mode == CV_GUI_NORMAL      ) printf("| CV_GUI_NORMAL)   ");
1731
                }
1732
                // resize(640, 480);
1733
    }
1734
    
1735
    setMinimumSize(1, 1);
1736
1737
    //1: create control panel
1738
    if (!global_control_panel)
1739
        global_control_panel = createParameterWindow();
1740
1741
    //2: Layouts
1742
    createBarLayout();
1743
    createGlobalLayout();
1744
1745
    //3: my view
1746
#ifndef HAVE_QT_OPENGL
1747
    if (arg2 & CV_WINDOW_OPENGL)
1748
        CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" );
1749
    mode_display = CV_MODE_NORMAL;
1750
#else
1751
    mode_display = arg2 & CV_WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL;
1752
    if (mode_display == CV_MODE_OPENGL)
1753
        param_gui_mode = CV_GUI_NORMAL;
1754
#endif
1755
    createView();
1756
1757
    //4: shortcuts and actions
1758
    //5: toolBar and statusbar
1759
    if (param_gui_mode == CV_GUI_EXPANDED)
1760
    {
1761
        createActions();
1762
        createShortcuts();
1763
1764
        createToolBar();
1765
        createStatusBar();
1766
    }
1767
1768
    //Now attach everything
1769
    if (myToolBar)
1770
        myGlobalLayout->addWidget(myToolBar, Qt::AlignCenter);
1771
1772
    myGlobalLayout->addWidget(myView->getWidget(), Qt::AlignCenter);
1773
1774
    myGlobalLayout->addLayout(myBarLayout, Qt::AlignCenter);
1775
1776
    if (myStatusBar)
1777
        myGlobalLayout->addWidget(myStatusBar, Qt::AlignCenter);
1778
1779
    setLayout(myGlobalLayout);
1780
    show();
1781
}
1782
1783
1784
CvWindow::~CvWindow()
1785
{
1786
    if (guiMainThread)
1787
        guiMainThread->isLastWindow();
1788
}
1789
1790
1791
void CvWindow::setMouseCallBack(CvMouseCallback callback, void* param)
1792
{
1793
    myView->setMouseCallBack(callback, param);
1794
}
1795
1796
1797
void CvWindow::writeSettings()
1798
{
1799
    //organisation and application's name
1800
    QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName());
1801
1802
    settings.setValue("pos", pos());
1803
    settings.setValue("size", size());
1804
    settings.setValue("mode_resize" ,param_flags);
1805
    settings.setValue("mode_gui", param_gui_mode);
1806
1807
    myView->writeSettings(settings);
1808
1809
    icvSaveTrackbars(&settings);
1810
1811
    if (global_control_panel)
1812
    {
1813
        icvSaveControlPanel();
1814
        settings.setValue("posPanel", global_control_panel->pos());
1815
    }
1816
}
1817
1818
1819
1820
//TODO: load CV_GUI flag (done) and act accordingly (create win property if needed and attach trackbars)
1821
void CvWindow::readSettings()
1822
{
1823
    //organisation and application's name
1824
    QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName());
1825
1826
    QPoint _pos = settings.value("pos", QPoint(200, 200)).toPoint();
1827
    QSize _size = settings.value("size", QSize(400, 400)).toSize();
1828
1829
    param_flags = settings.value("mode_resize", param_flags).toInt();
1830
    param_gui_mode = settings.value("mode_gui", param_gui_mode).toInt();
1831
1832
    param_flags = settings.value("mode_resize", param_flags).toInt();
1833
1834
    myView->readSettings(settings);
1835
1836
    //trackbar here
1837
    icvLoadTrackbars(&settings);
1838
1839
    resize(_size);
1840
    move(_pos);
1841
1842
    if (global_control_panel)
1843
    {
1844
        icvLoadControlPanel();
1845
        global_control_panel->move(settings.value("posPanel", global_control_panel->pos()).toPoint());
1846
    }
1847
}
1848
1849
1850
double CvWindow::getRatio()
1851
{
1852
    return myView->getRatio();
1853
}
1854
1855
1856
void CvWindow::setRatio(int flags)
1857
{
1858
    myView->setRatio(flags);
1859
}
1860
1861
1862
int CvWindow::getPropWindow()
1863
{
1864
    return param_flags;
1865
}
1866
1867
1868
void CvWindow::setPropWindow(int flags)
1869
{
1870
    if (param_flags == flags) //nothing to do
1871
        return;
1872
1873
    switch(flags)
1874
    {
1875
    case CV_WINDOW_NORMAL:
1876
        myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
1877
        param_flags = flags;
1878
1879
        break;
1880
1881
    case CV_WINDOW_AUTOSIZE:
1882
        myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize);
1883
        param_flags = flags;
1884
1885
        break;
1886
1887
    default:
1888
        ;
1889
    }
1890
}
1891
1892
1893
void CvWindow::toggleFullScreen(int flags)
1894
{
1895
    if (isFullScreen() && flags == CV_WINDOW_NORMAL)
1896
    {
1897
        showTools();
1898
        showNormal();
1899
        return;
1900
    }
1901
1902
    if (!isFullScreen() && flags == CV_WINDOW_FULLSCREEN)
1903
    {
1904
        hideTools();
1905
        showFullScreen();
1906
        return;
1907
    }
1908
}
1909
1910
1911
void CvWindow::updateImage(void* arr)
1912
{
1913
    myView->updateImage(arr);
1914
}
1915
1916
1917
void CvWindow::displayInfo(QString text, int delayms)
1918
{
1919
    myView->startDisplayInfo(text, delayms);
1920
}
1921
1922
1923
void CvWindow::displayStatusBar(QString text, int delayms)
1924
{
1925
    if (myStatusBar)
1926
        myStatusBar->showMessage(text, delayms);
1927
}
1928
1929
1930
void CvWindow::enablePropertiesButton()
1931
{
1932
    if (m_idxPropWnd >= 0)
1933
        vect_QActions[m_idxPropWnd]->setDisabled(false);
1934
}
1935
1936
1937
CvButtonbar* CvWindow::createButtonBar(QString name_bar)
1938
{
1939
    QPointer<CvButtonbar> t = new CvButtonbar(global_control_panel, name_bar);
1940
    t->setAlignment(Qt::AlignHCenter);
1941
1942
    QPointer<QBoxLayout> myLayout = global_control_panel->myLayout;
1943
1944
    myLayout->insertLayout(myLayout->count(), t);
1945
1946
    return t;
1947
}
1948
1949
1950
void CvWindow::addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change)
1951
{
1952
    QPointer<CvTrackbar> t = new CvTrackbar(w, name, value, count, on_change);
1953
    t->setAlignment(Qt::AlignHCenter);
1954
1955
    QPointer<QBoxLayout> myLayout;
1956
1957
    if (w)
1958
    {
1959
        myLayout = w->myBarLayout;
1960
    }
1961
    else
1962
    {
1963
        myLayout = global_control_panel->myLayout;
1964
1965
        //if first one, enable control panel
1966
        if (myLayout->count() == 0)
1967
            guiMainThread->enablePropertiesButtonEachWindow();
1968
    }
1969
1970
    myLayout->insertLayout(myLayout->count(), t);
1971
}
1972
1973
1974
void CvWindow::addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* userdata)
1975
{
1976
    QPointer<CvTrackbar> t = new CvTrackbar(w, name, value, count, on_change, userdata);
1977
    t->setAlignment(Qt::AlignHCenter);
1978
1979
    QPointer<QBoxLayout> myLayout;
1980
1981
    if (w)
1982
    {
1983
        myLayout = w->myBarLayout;
1984
    }
1985
    else
1986
    {
1987
        myLayout = global_control_panel->myLayout;
1988
1989
        //if first one, enable control panel
1990
        if (myLayout->count() == 0)
1991
            guiMainThread->enablePropertiesButtonEachWindow();
1992
    }
1993
1994
    myLayout->insertLayout(myLayout->count(), t);
1995
}
1996
1997
1998
void CvWindow::setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata)
1999
{
2000
    myView->setOpenGlDrawCallback(callback, userdata);
2001
}
2002
2003
2004
void CvWindow::setOpenGlCleanCallback(CvOpenGlCleanCallback callback, void* userdata)
2005
{
2006
    myView->setOpenGlCleanCallback(callback, userdata);
2007
}
2008
2009
2010
void CvWindow::makeCurrentOpenGlContext()
2011
{
2012
    myView->makeCurrentOpenGlContext();
2013
}
2014
2015
2016
void CvWindow::updateGl()
2017
{
2018
    myView->updateGl();
2019
}
2020
2021
2022
bool CvWindow::isOpenGl()
2023
{
2024
    return mode_display == CV_MODE_OPENGL;
2025
}
2026
2027
2028
void CvWindow::setViewportSize(QSize _size)
2029
{
2030
    QWidget* view = myView->getWidget();
2031
    int dx = _size.width();
2032
    int dy = _size.height();
2033
    view->parentWidget()->resize(dx-7, dy);
2034
    myView->setSize(_size);
2035
}
2036
2037
2038
void CvWindow::createBarLayout()
2039
{
2040
    myBarLayout = new QBoxLayout(QBoxLayout::TopToBottom);
2041
    myBarLayout->setObjectName(QString::fromUtf8("barLayout"));
2042
    myBarLayout->setContentsMargins(0, 0, 0, 0);
2043
    myBarLayout->setSpacing(0);
2044
    myBarLayout->setMargin(0);
2045
}
2046
2047
2048
void CvWindow::createGlobalLayout()
2049
{
2050
    myGlobalLayout = new QBoxLayout(QBoxLayout::TopToBottom);
2051
    myGlobalLayout->setObjectName(QString::fromUtf8("boxLayout"));
2052
    myGlobalLayout->setContentsMargins(0, 0, 0, 0);
2053
    myGlobalLayout->setSpacing(0);
2054
    myGlobalLayout->setMargin(0);
2055
    setMinimumSize(1, 1);
2056
2057
    if (param_flags == CV_WINDOW_AUTOSIZE)
2058
        myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize);
2059
    else if (param_flags == CV_WINDOW_NORMAL)
2060
        myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
2061
}
2062
2063
2064
void CvWindow::createView()
2065
{
2066
#ifdef HAVE_QT_OPENGL
2067
    if (isOpenGl())
2068
        myView = new OpenGlViewPort(this);
2069
    else
2070
#endif
2071
        myView = new DefaultViewPort(this, param_ratio_mode);
2072
}
2073
2074
2075
void CvWindow::createStandardActions()
2076
{
2077
    vect_QActions.resize(10);
2078
2079
    QWidget* view = myView->getWidget();
2080
2081
    //if the shortcuts are changed in window_QT.h, we need to update the tooltip manually
2082
    vect_QActions[0] = new QAction(QIcon(":/left-icon"), "Panning left (CTRL+arrowLEFT)", this);
2083
    vect_QActions[0]->setIconVisibleInMenu(true);
2084
    QObject::connect(vect_QActions[0], SIGNAL(triggered()), view, SLOT(siftWindowOnLeft()));
2085
2086
    vect_QActions[1] = new QAction(QIcon(":/right-icon"), "Panning right (CTRL+arrowRIGHT)", this);
2087
    vect_QActions[1]->setIconVisibleInMenu(true);
2088
    QObject::connect(vect_QActions[1], SIGNAL(triggered()), view, SLOT(siftWindowOnRight()));
2089
2090
    vect_QActions[2] = new QAction(QIcon(":/up-icon"), "Panning up (CTRL+arrowUP)", this);
2091
    vect_QActions[2]->setIconVisibleInMenu(true);
2092
    QObject::connect(vect_QActions[2], SIGNAL(triggered()), view, SLOT(siftWindowOnUp()));
2093
2094
    vect_QActions[3] = new QAction(QIcon(":/down-icon"), "Panning down (CTRL+arrowDOWN)", this);
2095
    vect_QActions[3]->setIconVisibleInMenu(true);
2096
    QObject::connect(vect_QActions[3], SIGNAL(triggered()), view, SLOT(siftWindowOnDown()) );
2097
2098
    vect_QActions[4] = new QAction(QIcon(":/zoom_x1-icon"), "Zoom x1 (CTRL+P)", this);
2099
    vect_QActions[4]->setIconVisibleInMenu(true);
2100
    QObject::connect(vect_QActions[4], SIGNAL(triggered()), view, SLOT(resetZoom()));
2101
2102
    vect_QActions[5] = new QAction(QIcon(":/imgRegion-icon"), tr("Zoom x%1 (see label) (CTRL+X)").arg(threshold_zoom_img_region), this);
2103
    vect_QActions[5]->setIconVisibleInMenu(true);
2104
    QObject::connect(vect_QActions[5], SIGNAL(triggered()), view, SLOT(imgRegion()));
2105
2106
    vect_QActions[6] = new QAction(QIcon(":/zoom_in-icon"), "Zoom in (CTRL++)", this);
2107
    vect_QActions[6]->setIconVisibleInMenu(true);
2108
    QObject::connect(vect_QActions[6], SIGNAL(triggered()), view, SLOT(ZoomIn()));
2109
2110
    vect_QActions[7] = new QAction(QIcon(":/zoom_out-icon"), "Zoom out (CTRL+-)", this);
2111
    vect_QActions[7]->setIconVisibleInMenu(true);
2112
    QObject::connect(vect_QActions[7], SIGNAL(triggered()), view, SLOT(ZoomOut()));
2113
2114
    vect_QActions[8] = new QAction(QIcon(":/save-icon"), "Save current image (CTRL+S)", this);
2115
    vect_QActions[8]->setIconVisibleInMenu(true);
2116
    QObject::connect(vect_QActions[8], SIGNAL(triggered()), view, SLOT(saveView()));
2117
2118
    m_idxPropWnd = 9;
2119
    vect_QActions[9] = new QAction(QIcon(":/properties-icon"), "Display properties window (CTRL+P)", this);
2120
    vect_QActions[9]->setIconVisibleInMenu(true);
2121
    QObject::connect(vect_QActions[9], SIGNAL(triggered()), this, SLOT(displayPropertiesWin()));
2122
2123
    if (global_control_panel->myLayout->count() == 0)
2124
        vect_QActions[9]->setDisabled(true);
2125
}
2126
2127
2128
void CvWindow::createActions()
2129
{
2130
        // Read in dynamic controls coming from *.cfg 
2131
        
2132
        QString CfgWndName = "";
2133
        m_bApplyLanguage = false;
2134
2135
        vecString.clear();
2136
        char csBuffer[255];
2137
        QString exe_name = QFileInfo(QApplication::applicationFilePath()).fileName();
2138
        char csCfgFile[512];
2139
        strcpy( csCfgFile, qPrintable(exe_name));
2140
        char * p = strrchr( csCfgFile,'.');
2141
2142
        if ( p != NULL )
2143
        {
2144
                *p = 0;
2145
                strcat( csCfgFile, ".cfg") ;
2146
        } else {
2147
                // linux
2148
                strcat( csCfgFile, ".cfg") ;
2149
        }
2150
        FILE * fp = fopen(csCfgFile,"rt");
2151
        if ( fp == NULL )
2152
        {
2153
                strcpy(csCfgFile, "ButtonNames.cfg" );
2154
                fp = fopen(csCfgFile,"rt");
2155
        }
2156
        //----------------------------------------------------------
2157
        vect_Adm.clear();
2158
    // int ElemIdx = 0;
2159
        if ( fp != NULL )
2160
        {        
2161
                while ( !feof(fp) )
2162
                { 
2163
                  fgets(csBuffer,250, fp);
2164
                  char *p = strrchr(csBuffer,10);
2165
                  if ( p != NULL ) *p =0;
2166
                  p = strrchr(csBuffer,13);
2167
                  if ( p != NULL ) *p =0;
2168
                          
2169
                  // todo: remove trailing blanks/tabs
2170
2171
                  if ( strlen(csBuffer) > 0 )
2172
                  {
2173
                          // recognize a new window definition 
2174
                          p = strstr(csBuffer,"-- [");
2175
                          if ( p != NULL )
2176
                          {
2177
                                  // 
2178
                                  char * q = strchr(csBuffer,']');
2179
                                  if ( q != NULL )
2180
                                  {   *q = 0;
2181
                                          CfgWndName = QString(p+4);
2182
                                          csBuffer[0] = 0;
2183
                                          if ( bVerbose )
2184
                                                  printf("\n[CfgWndName=%s]", qPrintable(CfgWndName) );
2185
                                  }
2186
                          }
2187
2188
                          p = strstr(csBuffer,"-- <");
2189
                          if ( p != NULL )
2190
                          {
2191
                                  char * q = strchr(csBuffer,'>');
2192
                                  if ( q != NULL )
2193
                                  {   *q = 0;
2194
                                          CfgWndName = "<" + QString(p+4) + ">";
2195
                                          csBuffer[0] = 0;
2196
                                          if ( bVerbose )
2197
                                                  printf("\n[CfgWndName=%s]", qPrintable(CfgWndName) );
2198
                                  }
2199
                          }
2200
2201
                  }
2202
                  
2203
                  if ( CfgWndName != "<LanguageTransTab>" ) 
2204
                  {
2205
                          if ( strstr(csBuffer,"$verbose") != NULL ) {
2206
                                  if ( csBuffer[0] != '#') 
2207
                                                  bVerbose = true;
2208
                          }
2209
                          
2210
                          if ( CfgWndName != m_WndName ) csBuffer[0] = 0;
2211
                  }
2212
2213
                  if ( strlen(csBuffer) > 0 )
2214
                  {
2215
                          // only if CfgWndName == m_WndName
2216
                          AdmElem CtrlElem;
2217
                          if ( (csBuffer[0] != '$') && (csBuffer[0] != '#')  ) {
2218
2219
                                  if ( CfgWndName == "<LanguageTransTab>" ) 
2220
                                  {
2221
                                          m_LanguageVec.push_back(csBuffer);
2222
                                  } else {
2223
                                          // simple text button internal later stored as QToolButton  
2224
                                          CtrlElem.elemtype = EMOD_TxtButton;
2225
                                          vect_Adm.push_back(CtrlElem);                        
2226
                                          vecString.push_back(QString(csBuffer));
2227
                                  }
2228
2229
                          } else {
2230
                                  if ( csBuffer[0] != '#' )
2231
                                  {
2232
                                    // some default action buttons with used icons
2233
            
2234
                                    if ( strstr(csBuffer,"$Panning") != NULL )
2235
                                    {
2236
                                            CtrlElem.elemtype = EMOD_Panning;
2237
                                            vect_Adm.push_back(CtrlElem);
2238
                                    }
2239
                                    if ( strstr(csBuffer,"$Zoom") != NULL )
2240
                                    {
2241
                                            CtrlElem.elemtype = EMOD_Zoom;
2242
                                            vect_Adm.push_back(CtrlElem);
2243
                                    }
2244
                                    if ( strstr(csBuffer,"$SaveImg") != NULL )
2245
                                    {
2246
                                            CtrlElem.elemtype = EMOD_SaveImg;
2247
                                            vect_Adm.push_back(CtrlElem);
2248
                                    }
2249
                                    if ( strstr(csBuffer,"$PropWnd") != NULL )
2250
                                    {
2251
                                            CtrlElem.elemtype = EMOD_PropWnd;
2252
                                            vect_Adm.push_back(CtrlElem);
2253
                                    }
2254
2255
                                    if ( strstr(csBuffer,"$applyLanguage") != NULL )
2256
                                            m_bApplyLanguage = true;
2257
                            
2258
                                    //----------------------------------------
2259
                                    // icons are not supported for user defined controls in *.cfg
2260
                                    if ( strstr(csBuffer,"$Label") != NULL )
2261
                                    {
2262
                                            QLabel * pLabel = new QLabel();
2263
                                            pLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
2264
                                            p = strchr(csBuffer,' ');
2265
                                            if ( p != NULL )
2266
                                            {
2267
                                                    pLabel->setText(QString(p+1));
2268
                                            }
2269
                                            CtrlElem.elemtype = EMOD_Label;
2270
                                            CtrlElem.start    = vect_QLabel.size();
2271
                                            vect_QLabel.push_back(pLabel);
2272
                                            vect_Adm.push_back(CtrlElem);
2273
                                    }
2274
2275
                                    //---------------------- split 
2276
                                    QString str   = "";
2277
                                    QString name  = "";
2278
                                    QString param = "";
2279
                                    QString tmp   = "";
2280
                                    bool bEmit = false;
2281
                                    p = strchr(csBuffer,' ');
2282
                                    if ( p != NULL )
2283
                                    {
2284
                                            str = QString(p+1);
2285
                                            int ipos = str.indexOf(QString(" "));
2286
                                            name  = str.left(ipos);                                                                        
2287
                                            if ( ipos > 0 ) param = str.mid(ipos+1);
2288
                                            ipos = param.indexOf(QString(" emit"));
2289
                                            if ( ipos > 0 )
2290
                                            {        
2291
                                                    bEmit = true;
2292
                                                    param = param.left(ipos);
2293
                                            }
2294
                                    }
2295
                                    
2296
                                    //printf("\n\n[%s]\n[name=%s][param=%s][bEmit=%d]\n", 
2297
                                    //        csBuffer, qPrintable(name), qPrintable(param), (int) bEmit ); 
2298
2299
                                    if ( strstr(csBuffer,"$CheckBox") != NULL )
2300
                                    {
2301
                                            // Example: $CheckBox Logging true                
2302
                                            if (param.length() > 0 )
2303
                                            {
2304
                                                    bool bChecked = false;
2305
                                                    int ipos = param.indexOf(QString("true"));
2306
                                                    if ( ipos>= 0) 
2307
                                                    {
2308
                                                            bChecked = true;
2309
                                                    }
2310
                                                    QCheckBox * pCheck = new  QCheckBox(name, this);
2311
                                                    if ( bChecked )        pCheck->setChecked(true);
2312
                                                    pCheck->setObjectName( name + "_EMOD_CheckBox" );
2313
                                                    CtrlElem.elemtype = EMOD_CheckBox;
2314
                                                    CtrlElem.start    = vect_QCheckBox.size();
2315
                                                    if ( CtrlElem.start == 0 ) 
2316
                                                            QObject::connect( pCheck, SIGNAL(clicked()), this, SLOT( slotCallCheck_0() ));
2317
                                                    if ( CtrlElem.start == 1 ) 
2318
                                                            QObject::connect( pCheck, SIGNAL(clicked()), this, SLOT( slotCallCheck_1() ));
2319
                                                    if ( CtrlElem.start == 2 ) 
2320
                                                            QObject::connect( pCheck, SIGNAL(clicked()), this, SLOT( slotCallCheck_2() ));                                
2321
                                                    vect_QCheckBox.push_back(pCheck);
2322
                                                    vect_Adm.push_back(CtrlElem);
2323
                                            }
2324
                                    }
2325
2326
                                    if ( strstr(csBuffer,"$CheckText") != NULL )
2327
                                    {
2328
                                            // Example1: $CheckText Histo2D false
2329
                                            //           => Histo2D_EMOD_CheckText
2330
                                            // Example2: $CheckText Apply
2331
                                            //           => Apply_EMOD_PushText
2332
                                            bool bCheck = false;
2333
                                            bool bChecked = false;
2334
                                            if (param.length() > 3 )
2335
                                            {
2336
                                                    bCheck = true;
2337
                                                    int ipos = param.indexOf(QString("true"));
2338
                                                    if ( ipos>= 0) 
2339
                                                    {
2340
                                                            bChecked = true;
2341
                                                    }
2342
                                            }
2343
                                            QPushButton * pBut = new QPushButton(name, this);
2344
                                            CtrlElem.start    = vect_QButton.size();
2345
                                            if ( bCheck )   
2346
                                            {
2347
                                                    pBut->setCheckable(true);
2348
                                                    if ( bChecked )        pBut->setChecked(true);
2349
                                                    CtrlElem.elemtype = EMOD_CheckText;
2350
                                                    pBut->setObjectName( name + "_EMOD_CheckText");
2351
                                            } else {
2352
                                                    CtrlElem.elemtype = EMOD_PushText;
2353
                                                    pBut->setObjectName( name + "_EMOD_PushText");
2354
                                            }
2355
                                            if ( CtrlElem.start == 0 ) QObject::connect( pBut, SIGNAL(clicked()), this, SLOT( slotCallPush_0() ));
2356
                                            if ( CtrlElem.start == 1 ) QObject::connect( pBut, SIGNAL(clicked()), this, SLOT( slotCallPush_1() ));
2357
                                            if ( CtrlElem.start == 2 ) QObject::connect( pBut, SIGNAL(clicked()), this, SLOT( slotCallPush_2() ));
2358
                                            if ( CtrlElem.start == 3 ) QObject::connect( pBut, SIGNAL(clicked()), this, SLOT( slotCallPush_3() ));
2359
                                            if ( CtrlElem.start == 4 ) QObject::connect( pBut, SIGNAL(clicked()), this, SLOT( slotCallPush_4() ));
2360
                                            vect_QButton.push_back(pBut);
2361
                                            vect_Adm.push_back(CtrlElem);
2362
                                    }
2363
2364
                                          
2365
                                    if ( strstr(csBuffer,"$Edit") != NULL )
2366
                                    {
2367
                                            // Example: $Edit jpgq 80; w30                                            
2368
                                            CtrlElem.elemtype = EMOD_Edit;
2369
                                            CtrlElem.start    = vect_QLineEdit.size();
2370
2371
                                            QLineEdit * pEdit = new QLineEdit();                                                        
2372
                                            if ( name.length() > 0 )
2373
                                            {
2374
                                                    int ipos = param.indexOf(QString(";"));
2375
                                                    if ( ipos>= 0) 
2376
                                                    {
2377
                                                            QString attr = param.mid(ipos+1);
2378
                                                            tmp = param.left(ipos);
2379
                                                            int ipos2 = attr.indexOf(QString("w"));
2380
                                                            if ( ipos2 >=0 ) {
2381
                                                                      QString Num = attr.mid(ipos2+1);  
2382
                                                                      int width = atoi(qPrintable(Num)); // max display width
2383
                                                                      if ( width > 5 ) pEdit->setMaximumWidth(width); 
2384
                                                            }
2385
                                                    } else {
2386
                                                            tmp = param;        
2387
                                                    }
2388
                                                    // pEdit->setObjectName(name+"_EMOD_Edit_");
2389
                                                    pEdit->setObjectName(QString(name + "_EMOD_Edit_%1").arg(CtrlElem.start) );
2390
                                                    pEdit->setText(tmp);                                                        
2391
                                            }
2392
                                            
2393
                                            vect_QLineEdit.push_back(pEdit);
2394
                                            vect_Adm.push_back(CtrlElem);
2395
                                    }
2396
2397
                                    if ( strstr(csBuffer,"$Combo") != NULL )
2398
                                    {
2399
                                            // example: $Combo ComboSrc WebCam,Video,Image emit
2400
                                            //          => 3 Elements in ComboBox; emit => connect() 
2401
                                            if ( name.length() > 0 )
2402
                                            {
2403
                                                            QStringList list = param.split(",");
2404
                                                            if ( list.size() > 0 )
2405
                                                            {
2406
                                                                    QComboBox * pCombo = new QComboBox();
2407
                                                                    pCombo->addItems( list );
2408
                                                                    CtrlElem.elemtype = EMOD_Combo;
2409
                                                                    CtrlElem.start    = vect_QCombo.size();
2410
                                                                    pCombo->setObjectName(name+"_EMOD_Combo");
2411
                                                                    vect_QCombo.push_back( pCombo );
2412
                                                                    vect_Adm.push_back(CtrlElem);
2413
                                                            
2414
                                                                    if (bEmit)
2415
                                                                    {
2416
                                                                            connect( pCombo, SIGNAL(currentIndexChanged(const QString &)),
2417
                                                                                              this, SLOT( slotCallString(const QString &) ) 
2418
                                                                            );
2419
                                                                    }        
2420
                                                            }
2421
                                            }        
2422
                                    }
2423
                                          
2424
                                          if ( strstr(csBuffer,"$Menu") != NULL )
2425
                                          {
2426
                                                  if ( name.length() > 0 )
2427
                                                  {
2428
                                                    QStringList list = param.split(",");
2429
                                                    if ( list.size() > 0 )
2430
                                                    {                                                        
2431
                                                        QToolButton * pTool = new QToolButton();
2432
                                                        p = strchr(csBuffer,' ');
2433
                                                        if ( p != NULL )
2434
                                                        {
2435
                                                                pTool->setText(name);
2436
                                                        }
2437
                                                        CtrlElem.elemtype = EMOD_Pulldown;
2438
                                                        CtrlElem.start    = vect_QToolButton.size();
2439
                                                        
2440
                                                        pTool->setObjectName( name + "_EMOD_Pulldown" );
2441
                                                        QMenu * pMenu;
2442
                                                        // QMenu * pM;
2443
                                                        pMenu = new QMenu(name);
2444
                                                        for ( int j=0; j < list.size() ; j++ )
2445
                                                        {                                                                
2446
                                                                QAction * pAct = new QAction( list[j], this);
2447
                                                                QString userData = name + "|" + list[j];
2448
                                                                pAct->setData( userData );
2449
                                                                pAct->setStatusTip(tr("Open an existing file"));
2450
                                                                int idx = vect_MenuAct.size();
2451
                                                                if ( idx == 0 ) connect(pAct, SIGNAL(triggered()), this, SLOT( slotMenuAct0() ));
2452
                                                                if ( idx == 1 ) connect(pAct, SIGNAL(triggered()), this, SLOT( slotMenuAct1() ));
2453
                                                                if ( idx == 2 ) connect(pAct, SIGNAL(triggered()), this, SLOT( slotMenuAct2() ));
2454
                                                                if ( idx == 3 ) connect(pAct, SIGNAL(triggered()), this, SLOT( slotMenuAct3() ));
2455
                                                                if ( idx == 4 ) connect(pAct, SIGNAL(triggered()), this, SLOT( slotMenuAct4() ));
2456
                                                                pMenu->addAction(pAct);
2457
                                                                vect_MenuAct.push_back(pAct);                                                                                                                                 
2458
                                                        }
2459
2460
                                                        // vect_QMenu.push_back(pMenu);
2461
                                                        pTool->setMenu(pMenu);
2462
                                                        pTool->setPopupMode( QToolButton::MenuButtonPopup );  // MenuButtonPopup
2463
                                                        
2464
                                                        vect_QToolButton.push_back(pTool);
2465
                                                        vect_Adm.push_back(CtrlElem);                
2466
                                                    }
2467
                                                  }
2468
                                          }
2469
2470
2471
                                          if ( strstr(csBuffer,"$Slider") != NULL )
2472
                                          {
2473
                                                  // example: $Slider MySlider -75,100,20 emit
2474
                                                  //                        => horz. slider with limits [-75 .. 100] default 20
2475
                                                  //                           SpinBox automatical generated+named+added
2476
                                                  if ( name.length() > 0 )
2477
                                                  {
2478
                                                          QStringList list = param.split(",");
2479
                                                          if ( list.size() > 2 )
2480
                                                          {
2481
                                                            int iMin  = list[0].toInt();
2482
                                                            int iMax  = list[1].toInt();
2483
                                                            int iVal  = list[2].toInt();
2484
                                                            // printf("\n Slider [%d .. %d] %d", iMin, iMax, iVal );
2485
                                                            QSlider * pSlider = new QSlider(Qt::Horizontal);
2486
                                                            pSlider->setTickInterval( 20 );
2487
                                                            pSlider->setTickPosition( QSlider::TicksBothSides );
2488
                                                            pSlider->setRange(iMin, iMax);
2489
                                                            pSlider->setValue(iVal);
2490
                                                            CtrlElem.elemtype = EMOD_Slider;
2491
                                                            CtrlElem.start    = vect_QSlider.size();                                                                                
2492
                                                            
2493
                                                            pSlider->setObjectName(name+"_EMOD_Slider_");
2494
                                                            
2495
                                                            vect_QSlider.push_back( pSlider );
2496
                                                            vect_Adm.push_back(CtrlElem);
2497
2498
                                                            // we need something to display the slider value....
2499
                                                            QSpinBox * pSpin = new QSpinBox();
2500
                                                            pSpin->setRange(iMin, iMax);
2501
                                                            pSpin->setValue(iVal);
2502
                                                            CtrlElem.elemtype = EMOD_Spin;
2503
                                                            CtrlElem.start    = vect_QSpinBox.size();
2504
                                                            pSpin->setObjectName(name+"_EMOD_Spin");
2505
                                                            vect_QSpinBox.push_back(pSpin);
2506
                                                            vect_Adm.push_back(CtrlElem);
2507
                                                            // cross connect of slider and spin
2508
                                                            connect( pSlider, SIGNAL(valueChanged(int)),
2509
                                                            pSpin, SLOT( setValue(int) )  );
2510
                                                                  connect( pSpin, SIGNAL(valueChanged(int)),
2511
                                                            pSlider, SLOT( setValue(int) )  );
2512
2513
                                                                  if (bEmit)
2514
                                                                  {
2515
                                                                    if ( CtrlElem.start == 0 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2516
                                                                                                                                    this, SLOT( slotCallSpin_0(int) )  );
2517
                                                                    }
2518
                                                                    if ( CtrlElem.start == 1 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2519
                                                                                                                                    this, SLOT( slotCallSpin_1(int) )  );
2520
                                                                    }
2521
                                                                    if ( CtrlElem.start == 2 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2522
                                                                                                                                    this, SLOT( slotCallSpin_2(int) )  );
2523
                                                                    }
2524
                                                                    if ( CtrlElem.start == 3 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2525
                                                                                                                                    this, SLOT( slotCallSpin_3(int) )  );
2526
                                                                    }
2527
                                                                    if ( CtrlElem.start == 4 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2528
                                                                                                                                    this, SLOT( slotCallSpin_4(int) )  );
2529
                                                                    }
2530
                                                                  }
2531
2532
                                                          }
2533
                                                  }
2534
                                          }
2535
                                          
2536
                                          if ( strstr(csBuffer,"Spin") != NULL )
2537
                                          {
2538
                                              // example: $Spin JPGQ 0,100,75
2539
                                              //          => 
2540
                                              if ( name.length() > 0 )
2541
                                              {
2542
                                                QStringList list = param.split(",");
2543
                                                if ( list.size() > 2 )
2544
                                                {
2545
                                                    int iMin  = list[0].toInt();
2546
                                                    int iMax  = list[1].toInt();
2547
                                                    int iVal  = list[2].toInt();
2548
                                                    QSpinBox * pSpin = new QSpinBox();
2549
                                                    pSpin->setRange(iMin, iMax);
2550
                                                    pSpin->setValue(iVal);
2551
                                                    pSpin->setObjectName(name + "_EMOD_Spin");
2552
                                                    CtrlElem.elemtype = EMOD_Spin;
2553
                                                    CtrlElem.start    = vect_QSpinBox.size();
2554
                                                    vect_QSpinBox.push_back(pSpin);
2555
                                                    vect_Adm.push_back(CtrlElem);
2556
                                                    if (bEmit)
2557
                                                    {
2558
                                                            if ( CtrlElem.start == 0 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2559
                                                                                                                            this, SLOT( slotCallSpin_0(int) )  );
2560
                                                            }
2561
                                                            if ( CtrlElem.start == 1 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2562
                                                                                                                            this, SLOT( slotCallSpin_1(int) )  );
2563
                                                            }
2564
                                                            if ( CtrlElem.start == 2 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2565
                                                                                                                            this, SLOT( slotCallSpin_2(int) )  );
2566
                                                            }
2567
                                                            if ( CtrlElem.start == 3 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2568
                                                                                                                            this, SLOT( slotCallSpin_3(int) )  );
2569
                                                            }
2570
                                                            if ( CtrlElem.start == 4 ) { connect( pSpin, SIGNAL(valueChanged(int)),
2571
                                                                                                                            this, SLOT( slotCallSpin_4(int) )  );
2572
                                                            }
2573
                                                    }
2574
                                                }
2575
                                              }
2576
                                          }
2577
                                          //-----------------------
2578
                                  }
2579
                          }
2580
                        }
2581
                }
2582
        } 
2583
2584
        if ( bVerbose )
2585
                printf("\n m_LanguageVec.size()=%d ", m_LanguageVec.size() );
2586
2587
        if ( vect_Adm.size() == 0 )
2588
        {
2589
                createStandardActions();
2590
                return;
2591
        }
2592
        
2593
        vect_QActions.resize( 50 );
2594
2595
        int idx =0;
2596
        int txtidx = 0;
2597
        QWidget* view = myView->getWidget();
2598
2599
        for (int i=0; i < vect_Adm.size(); i++)
2600
        {
2601
                AdmElem * pCtrl = &vect_Adm[i];
2602
                
2603
                if ( pCtrl->elemtype == EMOD_Panning )
2604
                {
2605
                        pCtrl->start = idx;
2606
                        pCtrl->cnt   = 4;
2607
2608
                        vect_QActions[idx] = new QAction(QIcon(":/left-icon"), "Panning left (CTRL+arrowLEFT)", this);
2609
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2610
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(siftWindowOnLeft()));
2611
2612
                        vect_QActions[idx] = new QAction(QIcon(":/right-icon"), "Panning right (CTRL+arrowRIGHT)", this);
2613
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2614
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(siftWindowOnRight()));
2615
2616
                        vect_QActions[idx] = new QAction(QIcon(":/up-icon"), "Panning up (CTRL+arrowUP)", this);
2617
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2618
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(siftWindowOnUp()));
2619
2620
                        vect_QActions[idx] = new QAction(QIcon(":/down-icon"), "Panning down (CTRL+arrowDOWN)", this);
2621
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2622
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(siftWindowOnDown()) );                
2623
                }
2624
2625
                if ( pCtrl->elemtype == EMOD_Zoom ) {
2626
                        pCtrl->start = idx;
2627
                        pCtrl->cnt   = 4;
2628
                        vect_QActions[idx] = new QAction(QIcon(":/zoom_x1-icon"), "Zoom x1 (CTRL+P)", this);
2629
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2630
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(resetZoom()));
2631
2632
                        vect_QActions[idx] = new QAction(QIcon(":/imgRegion-icon"), tr("Zoom x%1 (see label) (CTRL+X)").arg(threshold_zoom_img_region), this);
2633
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2634
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(imgRegion()));
2635
2636
                        vect_QActions[idx] = new QAction(QIcon(":/zoom_in-icon"), "Zoom in (CTRL++)", this);
2637
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2638
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(ZoomIn()));
2639
2640
                        vect_QActions[idx] = new QAction(QIcon(":/zoom_out-icon"), "Zoom out (CTRL+-)", this);
2641
                        vect_QActions[idx]->setIconVisibleInMenu(true);
2642
                        QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(ZoomOut()));
2643
                }
2644
2645
        if ( pCtrl->elemtype == EMOD_SaveImg ) {
2646
                        pCtrl->start = idx;
2647
                        pCtrl->cnt   = 1;
2648
                        vect_QActions[idx] = new QAction(QIcon(":/save-icon"), "Save current image (CTRL+S)", this);
2649
            vect_QActions[idx]->setIconVisibleInMenu(true);
2650
            QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), view, SLOT(saveView()));
2651
        }
2652
2653
        if ( pCtrl->elemtype == EMOD_PropWnd ) {
2654
                        pCtrl->start = idx;
2655
                        pCtrl->cnt   = 1;
2656
2657
                        m_idxPropWnd = idx;
2658
2659
                        vect_QActions[idx] = new QAction(QIcon(":/properties-icon"), "Display properties window (CTRL+P)", this);
2660
            vect_QActions[idx]->setIconVisibleInMenu(true);
2661
            if (global_control_panel->myLayout->count() == 0)
2662
                    vect_QActions[idx]->setDisabled(true);
2663
            QObject::connect(vect_QActions[idx++], SIGNAL(triggered()), this, SLOT(displayPropertiesWin()));
2664
        }
2665
2666
                if ( pCtrl->elemtype == EMOD_TxtButton ) {                
2667
                        vect_QActions[idx] = new QAction( vecString[txtidx] , this);        // Add Text Button
2668
                        if ( txtidx == 0 )
2669
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_0() ));
2670
                        if ( txtidx == 1 )
2671
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_1() ));
2672
                        if ( txtidx == 2 )
2673
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_2() ));
2674
                        if ( txtidx == 3 )
2675
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_3() ));
2676
                        if ( txtidx == 4 )
2677
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_4() ));
2678
                        if ( txtidx == 5 )
2679
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_5() ));
2680
                        if ( txtidx == 6 )
2681
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_6() ));
2682
                        if ( txtidx == 7 )
2683
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_7() ));
2684
                        if ( txtidx == 8 )
2685
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_8() ));
2686
                        if ( txtidx == 9 )
2687
                                        QObject::connect(vect_QActions[idx], SIGNAL(triggered()), this, SLOT( slotCall_9() ));
2688
2689
                        vect_QActions[idx]->setObjectName( QString("_EMOD_Action_%1").arg(idx) );
2690
                                                                
2691
                        pCtrl->start = idx;
2692
                        pCtrl->cnt   = 1;
2693
                        txtidx++;
2694
                        idx++;
2695
                }                
2696
        }
2697
        vect_QActions.resize(idx);   
2698
}
2699
2700
2701
2702
void CvWindow::createShortcuts()
2703
{
2704
    vect_QShortcuts.resize(10);
2705
2706
    QWidget* view = myView->getWidget();
2707
2708
    vect_QShortcuts[0] = new QShortcut(shortcut_panning_left, this);
2709
    QObject::connect(vect_QShortcuts[0], SIGNAL(activated()), view, SLOT(siftWindowOnLeft()));
2710
2711
    vect_QShortcuts[1] = new QShortcut(shortcut_panning_right, this);
2712
    QObject::connect(vect_QShortcuts[1], SIGNAL(activated()), view, SLOT(siftWindowOnRight()));
2713
2714
    vect_QShortcuts[2] = new QShortcut(shortcut_panning_up, this);
2715
    QObject::connect(vect_QShortcuts[2], SIGNAL(activated()), view, SLOT(siftWindowOnUp()));
2716
2717
    vect_QShortcuts[3] = new QShortcut(shortcut_panning_down, this);
2718
    QObject::connect(vect_QShortcuts[3], SIGNAL(activated()), view, SLOT(siftWindowOnDown()));
2719
2720
    vect_QShortcuts[4] = new QShortcut(shortcut_zoom_normal, this);
2721
    QObject::connect(vect_QShortcuts[4], SIGNAL(activated()), view, SLOT(resetZoom()));
2722
2723
    vect_QShortcuts[5] = new QShortcut(shortcut_zoom_imgRegion, this);
2724
    QObject::connect(vect_QShortcuts[5], SIGNAL(activated()), view, SLOT(imgRegion()));
2725
2726
    vect_QShortcuts[6] = new QShortcut(shortcut_zoom_in, this);
2727
    QObject::connect(vect_QShortcuts[6], SIGNAL(activated()), view, SLOT(ZoomIn()));
2728
2729
    vect_QShortcuts[7] = new QShortcut(shortcut_zoom_out, this);
2730
    QObject::connect(vect_QShortcuts[7], SIGNAL(activated()), view, SLOT(ZoomOut()));
2731
2732
    vect_QShortcuts[8] = new QShortcut(shortcut_save_img, this);
2733
    QObject::connect(vect_QShortcuts[8], SIGNAL(activated()), view, SLOT(saveView()));
2734
2735
    vect_QShortcuts[9] = new QShortcut(shortcut_properties_win, this);
2736
    QObject::connect(vect_QShortcuts[9], SIGNAL(activated()), this, SLOT(displayPropertiesWin()));
2737
}
2738
2739
2740
void CvWindow::createToolBar()
2741
{
2742
        if ( vect_Adm.size() <= 0 ) return;
2743
2744
        myToolBar = new QToolBar(this);
2745
        myToolBar->setFloatable(false); //is not a window
2746
        myToolBar->setFixedHeight(28);  // icon size grows automatical, if incremented
2747
        myToolBar->setMinimumWidth(1);
2748
2749
        for (int i=0; i < vect_Adm.size(); i++)
2750
        {
2751
                // Add some Qt-Controls from *.cfg and build up myToolBar with it.
2752
                AdmElem * pCtrl = &vect_Adm[i];        
2753
                if ( (pCtrl->elemtype == EMOD_PropWnd) || (pCtrl->elemtype == EMOD_SaveImg ) || 
2754
                     (pCtrl->elemtype == EMOD_TxtButton)  )
2755
                {
2756
                        myToolBar->addAction( vect_QActions[pCtrl->start] );
2757
                }
2758
                if ( (pCtrl->elemtype == EMOD_Zoom) || (pCtrl->elemtype == EMOD_Panning )  )
2759
                {
2760
                        for ( int j=pCtrl->start; j < pCtrl->start + pCtrl->cnt ; j++ )
2761
                        {
2762
                                myToolBar->addAction( vect_QActions[j]);
2763
                        }
2764
                }
2765
                if ( pCtrl->elemtype == EMOD_Combo )
2766
                {
2767
                        pCtrl->cnt = 1;
2768
                        QWidget * pWid = (QWidget *) vect_QCombo[pCtrl->start];
2769
                        myToolBar->addWidget( pWid );
2770
                }
2771
                if ( pCtrl->elemtype == EMOD_Edit )
2772
                {
2773
                        pCtrl->cnt = 1;
2774
                        QWidget * pWid = (QWidget *) vect_QLineEdit[pCtrl->start];
2775
                        QString name = pWid->objectName();
2776
                        myToolBar->addWidget( pWid  );
2777
                }
2778
                
2779
                if ( pCtrl->elemtype == EMOD_Pulldown )
2780
                {
2781
                        pCtrl->cnt = 1;
2782
                        QWidget * pWid = (QWidget *) vect_QToolButton[pCtrl->start];
2783
                        QString name = pWid->objectName();
2784
                        myToolBar->addWidget( pWid  );
2785
                }
2786
2787
                if ( pCtrl->elemtype == EMOD_Label )
2788
                {
2789
                        QWidget * pWid = (QWidget *) vect_QLabel[pCtrl->start];
2790
                        pWid->setObjectName(QString("EMOD_Label_%1").arg(pCtrl->start));
2791
                        myToolBar->addWidget( pWid );
2792
                }
2793
                if ( pCtrl->elemtype == EMOD_CheckBox )
2794
                {
2795
                        QWidget * pWid = (QWidget *) vect_QCheckBox[pCtrl->start];
2796
                        myToolBar->addWidget( pWid );
2797
                }
2798
                if ( pCtrl->elemtype == EMOD_CheckText )
2799
                {
2800
                        QWidget * pWid = (QWidget *) vect_QButton[pCtrl->start];
2801
                        myToolBar->addWidget( pWid );
2802
                }
2803
                if ( pCtrl->elemtype == EMOD_PushText )
2804
                {
2805
                        QWidget * pWid = (QWidget *) vect_QButton[pCtrl->start];
2806
                        myToolBar->addWidget( pWid );
2807
                }
2808
                if ( pCtrl->elemtype == EMOD_Slider )
2809
                {
2810
                        QWidget * pWid = (QWidget *) vect_QSlider[pCtrl->start];
2811
                        myToolBar->addWidget( pWid );
2812
                }
2813
                if ( pCtrl->elemtype == EMOD_Spin )
2814
                {
2815
                        QWidget * pWid = (QWidget *) vect_QSpinBox[pCtrl->start];
2816
                        myToolBar->addWidget( pWid );
2817
                }
2818
        }
2819
2820
        if ( m_bApplyLanguage )
2821
                        applyTransTab();
2822
        
2823
        InitExchange(-1);
2824
}
2825
2826
2827
void CvWindow::createStatusBar()
2828
{
2829
    myStatusBar = new QStatusBar(this);
2830
    myStatusBar->setSizeGripEnabled(false);
2831
    myStatusBar->setFixedHeight(20);
2832
    myStatusBar->setMinimumWidth(1);
2833
    myStatusBar_msg = new QLabel;
2834
2835
    //I comment this because if we change the style, myview (the picture)
2836
    //will not be the correct size anymore (will lost 2 pixel because of the borders)
2837
2838
    //myStatusBar_msg->setFrameStyle(QFrame::Raised);
2839
2840
    myStatusBar_msg->setAlignment(Qt::AlignHCenter);
2841
    myStatusBar->addWidget(myStatusBar_msg);
2842
}
2843
2844
2845
void CvWindow::hideTools()
2846
{
2847
    if (myToolBar)
2848
        myToolBar->hide();
2849
2850
    if (myStatusBar)
2851
        myStatusBar->hide();
2852
2853
    if (global_control_panel)
2854
        global_control_panel->hide();
2855
}
2856
2857
2858
void CvWindow::showTools()
2859
{
2860
    if (myToolBar)
2861
        myToolBar->show();
2862
2863
    if (myStatusBar)
2864
        myStatusBar->show();
2865
}
2866
2867
2868
void CvWindow::applyTransTab()
2869
{
2870
        // translation of strings for purpose of display
2871
        int TransCnt = 0;
2872
        QList<QObject*> ObjList = myToolBar->children();         
2873
        for ( int iobj=0 ; iobj < ObjList.count(); iobj++  )
2874
        {
2875
                 QObject* pObj = ObjList.at(iobj);
2876
                 QString ObjName = pObj->objectName();                
2877
                 QString metaName = QString(pObj->metaObject()->className());
2878
2879
                 if (metaName == "QToolButton" )
2880
                 {
2881
                                QToolButton * pBut = (QToolButton * ) pObj;
2882
                                for ( int j=0; j < m_LanguageVec.size() ; j++ )
2883
                                {
2884
                                        QString txt1 = "";
2885
                                        QString txt2 = "";
2886
                                        QString * pTxt = &m_LanguageVec[j];
2887
                                        int ipos = pTxt->indexOf(" <-> ");
2888
                                        if ( ipos > 0 )
2889
                                        {
2890
                                                txt1 = pTxt->mid(0,ipos);
2891
                                                txt2 = pTxt->mid(ipos+5,999);
2892
                                                if ( txt1 == pBut->text() ) {
2893
                                                        pBut->setText(txt2);
2894
                                                        TransCnt++;
2895
                                                }
2896
                                        }
2897
                                }
2898
                 }
2899
2900
                 if (metaName == "QPushButton" )
2901
                 {
2902
                                QPushButton * pBut = (QPushButton * ) pObj;
2903
                                for ( int i=0; i < m_LanguageVec.size() ; i++ )
2904
                                {
2905
                                        QString txt1 = "";
2906
                                        QString txt2 = "";
2907
                                        QString * pTxt = &m_LanguageVec[i];
2908
                                        int ipos = pTxt->indexOf(" <-> ");
2909
                                        if ( ipos > 0 )
2910
                                        {
2911
                                                txt1 = pTxt->mid(0,ipos);
2912
                                                txt2 = pTxt->mid(ipos+5,999);
2913
                                                if ( txt1 == pBut->text() ) {
2914
                                                        pBut->setText(txt2);
2915
                                                        TransCnt++;
2916
                                                }
2917
                                        }
2918
                                }
2919
                 }
2920
2921
2922
                 if (metaName == "QLabel" )
2923
                 {
2924
                                QLabel * pBut = (QLabel * ) pObj;
2925
                                for ( int i=0; i < m_LanguageVec.size() ; i++ )
2926
                                {
2927
                                        QString txt1 = "";
2928
                                        QString txt2 = "";
2929
                                        QString * pTxt = &m_LanguageVec[i];
2930
                                        int ipos = pTxt->indexOf(" <-> ");
2931
                                        if ( ipos > 0 )
2932
                                        {
2933
                                                txt1 = pTxt->mid(0,ipos);
2934
                                                txt2 = pTxt->mid(ipos+5,999);
2935
                                                if ( txt1 == pBut->text() ) {
2936
                            // printf("   [%s][%s->%s]   ", qPrintable(txt1),
2937
                            //  qPrintable(txt2), qPrintable(pBut->text())  );
2938
                                                        pBut->setText(txt2);
2939
                                                        if(txt2.contains("<font color"))
2940
                                                        {
2941
                                                         pBut->setFrameStyle(QFrame::Panel | QFrame::Raised);                
2942
                                                        }
2943
                                                        TransCnt++;
2944
                                                }
2945
                                        }
2946
                                }
2947
                 }
2948
2949
                 if (metaName == "QLineEdit" )
2950
                 {
2951
                                QLineEdit * pBut = ( QLineEdit * ) pObj;
2952
                                for ( int i=0; i < m_LanguageVec.size() ; i++ )
2953
                                {
2954
                                        QString txt1 = "";
2955
                                        QString txt2 = "";
2956
                                        QString * pTxt = &m_LanguageVec[i];
2957
                                        int ipos = pTxt->indexOf(" <-> ");
2958
                                        if ( ipos > 0 )
2959
                                        {
2960
                                                txt1 = pTxt->mid(0,ipos);
2961
                                                txt2 = pTxt->mid(ipos+5,999);
2962
                                                if ( txt1 == pBut->text() ) {
2963
                                                        printf("   [%s][%s->%s]   ", qPrintable(txt1), qPrintable(txt2), qPrintable(pBut->text())  );
2964
                                                        pBut->setText(txt2);
2965
                                                        TransCnt++;
2966
                                                }
2967
                                        }
2968
                                }
2969
2970
                 }
2971
2972
                 if (metaName == "QAction" )
2973
                 {
2974
                                QAction * pBut = ( QAction * ) pObj;
2975
                                for ( int i=0; i < m_LanguageVec.size() ; i++ )
2976
                                {
2977
                                        QString txt1 = "";
2978
                                        QString txt2 = "";
2979
                                        QString * pTxt = &m_LanguageVec[i];
2980
                                        int ipos = pTxt->indexOf(" <-> ");
2981
                                        if ( ipos > 0 )
2982
                                        {
2983
                                                txt1 = pTxt->mid(0,ipos);
2984
                                                txt2 = pTxt->mid(ipos+5,999);
2985
                                                if ( txt1 == pBut->text() ) {
2986
                                                        printf("   [%s][%s->%s]   ", qPrintable(txt1), qPrintable(txt2), qPrintable(pBut->text())  );
2987
                                                        pBut->setText(txt2);
2988
                                                        TransCnt++;
2989
                                                }
2990
                                        }
2991
                                }
2992
                 }
2993
        }
2994
        if ( bVerbose )
2995
                printf("\n %s --> Language Translation for %d Words done ", qPrintable(m_WndName), TransCnt );
2996
                
2997
}
2998
2999
void CvWindow::InitExchange(int idx)
3000
{
3001
        // Some Qt-Controls in the Toolbar may be changed by user interaction
3002
        // fill up CvWindow::m_ContentVec[i] with the content of controls
3003
3004
        if ( myToolBar == NULL ) return;
3005
3006
         QList<QObject*> ObjList = myToolBar->children();         
3007
         m_ContentVec.clear();
3008
         for ( int i=0 ; i < ObjList.count(); i++  )
3009
         {
3010
                 QObject* pObj = ObjList.at(i);
3011
                 QString ObjName = pObj->objectName();        
3012
3013
                 // collect all contents of all buttonbar controls
3014
                 // a simple button will not have a content
3015
                 // but may be you have defined pBut->setCheckable(true)
3016
3017
                 QString metaName = QString(pObj->metaObject()->className());
3018
3019
                 if (metaName == "QToolButton" )
3020
                 {
3021
                // QToolButton * pBut = (QToolButton * ) pObj;
3022
                // printf("\n%3d [meta=    QToolButton][Text=%s]", i,  qPrintable(pBut->text()) );
3023
                 }
3024
3025
                 if (ObjName.contains("EMOD_CheckText") ) 
3026
                 {
3027
                        // Button with on/off status, comparable with a CheckBox
3028
                        bool bVal = false;
3029
                        QPushButton * pBut = (QPushButton *) pObj;
3030
                        if ( pBut->isChecked() ) bVal = true;
3031
                        int ipos = ObjName.lastIndexOf("_");
3032
                        QString num = ObjName.mid(ipos+1);          //--->linuxErr
3033
                        ipos = ObjName.indexOf("_");
3034
                        QString Name = ObjName.left(ipos);                        
3035
                        if ( bVal ) {
3036
                                m_ContentVec.push_back( Name + "|1" );
3037
                        } else {
3038
                                m_ContentVec.push_back( Name + "|0" );
3039
                        }
3040
                 }
3041
3042
                 if (ObjName.contains("EMOD_CheckBox") ) 
3043
                 {
3044
                        bool bVal = false;
3045
                        QCheckBox * pCheck = (QCheckBox *) pObj;
3046
                        if ( pCheck->isChecked() ) bVal = true;
3047
                        int ipos = ObjName.indexOf("_");
3048
                        QString Name = ObjName.left(ipos);                        
3049
                        if ( bVal ) {
3050
                                m_ContentVec.push_back( Name + "|1" );
3051
                        } else {
3052
                                m_ContentVec.push_back( Name + "|0" );
3053
                        }
3054
                 }
3055
3056
                 if (ObjName.contains("EMOD_Combo") ) 
3057
                 {
3058
                        int ipos = ObjName.lastIndexOf("_");
3059
                        QString content = ObjName.mid(ipos+1);      //--->linuxErr
3060
                        ipos = ObjName.indexOf("_");
3061
                        QString Name = ObjName.left(ipos);
3062
                        QComboBox * pCombo = (QComboBox *) pObj;
3063
                        m_ContentVec.push_back( Name + "|" + pCombo->currentText() );
3064
                 }
3065
3066
                 if (ObjName.contains("EMOD_Edit") ) 
3067
                 {
3068
                        int ipos = ObjName.lastIndexOf("_");
3069
                        QString content = ObjName.mid(ipos+1);    //--->linuxErr
3070
                        ipos = ObjName.indexOf("_");
3071
                        QString Name = ObjName.left(ipos);
3072
                        QLineEdit * pEdit = (QLineEdit *) pObj;
3073
                        m_ContentVec.push_back( Name + "|" + pEdit->text() );
3074
                 }
3075
3076
                 if (ObjName.contains("EMOD_Slider") ) 
3077
                 {
3078
                        int ipos = ObjName.lastIndexOf("_");
3079
                        QString content = ObjName.mid(ipos+1);   //--->linuxErr
3080
                        ipos = ObjName.indexOf("_");
3081
                        QString Name = ObjName.left(ipos);
3082
                        QSlider * pSlider = (QSlider *) pObj;
3083
                        int iVal = pSlider->value();
3084
                        m_ContentVec.push_back( Name + "|" + QString("%1").arg(iVal) );
3085
                 }
3086
3087
                 if (ObjName.contains("EMOD_Spin") ) 
3088
                 {
3089
                        int ipos = ObjName.lastIndexOf("_");
3090
                        QString content = ObjName.mid(ipos+1);;    // //--->linuxErr
3091
                        ipos = ObjName.indexOf("_");
3092
                        QString Name = ObjName.left(ipos);
3093
                        QSpinBox * pSpin = (QSpinBox *) pObj;
3094
                        int iVal = pSpin->value();
3095
                        m_ContentVec.push_back( Name + "|" + QString("%1").arg(iVal) );
3096
                 }         
3097
        }
3098
        
3099
}
3100
3101
3102
void CvWindow::modifyContent(QString WndName, int eType,  int idx, QString text)
3103
{
3104
        // function called by cvSetButtonBarContent() 
3105
        QString Name = "abcd1234";
3106
        QString wd_old = "";
3107
        QString wd_new = "";
3108
        
3109
        if (idx < 0)
3110
        {
3111
                 // use unidirectional translation included in text
3112
                 int ipos = text.indexOf("->"); 
3113
                 if ( ipos >= 0 )
3114
                 {
3115
                         wd_old = text.mid(0,ipos);
3116
                         wd_new = text.mid(ipos+2,999);
3117
                         // split in 2 words done
3118
                 }
3119
        } else {
3120
                 // use index to identify field
3121
                 if ( eType == EMOD_Label )
3122
                 {
3123
                        Name = QString("EMOD_Label_%1").arg(idx);
3124
                 }
3125
                 if ( eType == EMOD_Edit )
3126
                 {
3127
                        Name = QString("EMOD_Edit_%1").arg(idx);
3128
                 }
3129
        }
3130
3131
         if ( bVerbose)
3132
         {
3133
                printf("\n CvWindow::modifyContent [%s] ", qPrintable(WndName) );  // //--->linuxWarn
3134
         }
3135
3136
         if ( myToolBar == NULL ) return;
3137
3138
         QList<QObject*> ObjList = myToolBar->children();         
3139
3140
         int FitCnt = 0;
3141
         for ( int i=0 ; i < ObjList.count(); i++  )
3142
         {
3143
                 QObject* pObj    = ObjList.at(i);
3144
                 QString ObjName  = pObj->objectName();
3145
                 QString metaName = QString(pObj->metaObject()->className());
3146
3147
                 if ( wd_new.length() > 0 )
3148
                 {
3149
                         if (metaName == "QToolButton" )
3150
                         {
3151
                                        QToolButton * pBut = ( QToolButton * ) pObj;
3152
                                        if ( eType == EMOD_TxtButton )
3153
                                        {
3154
                                                if ( wd_old == pBut->text() )
3155
                                                {
3156
                                                        pBut->setText(wd_new);
3157
                                                }
3158
                                        }
3159
                         }
3160
                         if (metaName == "QCheckBox" )
3161
                         {
3162
                                         QCheckBox * pCheck = ( QCheckBox * ) pObj;
3163
                                        if ( wd_old == pCheck->text() )
3164
                                        {
3165
                                                        pCheck->setText(wd_new);
3166
                                        }
3167
                         }
3168
                         if (metaName == "QPushButton" )
3169
                         {
3170
                                         QPushButton * pPush = ( QPushButton * ) pObj;
3171
                                        if ( wd_old == pPush->text() )
3172
                                        {
3173
                                                        pPush->setText(wd_new);
3174
                                        }
3175
                         }                        
3176
                 } else {
3177
3178
                         if (  ObjName.contains(Name)  )
3179
                         {
3180
                                if ( bVerbose )
3181
                                {
3182
                                        printf("\n[pObj->objectName=%s] --->[%s]", qPrintable( ObjName ), qPrintable(text) );
3183
                                }
3184
                                if ( eType == EMOD_Label )
3185
                                {
3186
                                        QLabel * pLabel = (QLabel *) pObj;
3187
                                        pLabel->setText(text);
3188
                                        FitCnt++;
3189
                                }
3190
                                if ( eType == EMOD_Edit )
3191
                                {
3192
                                        QLineEdit * pEdit = (QLineEdit *) pObj;
3193
                                        pEdit->setText(text);
3194
                                        FitCnt++;
3195
                                }
3196
                         }
3197
3198
                 }
3199
         }
3200
         
3201
         if ( bVerbose)
3202
         {
3203
                if ( FitCnt == 0 ) printf("\n [%s] not fitting <--- [%s]", qPrintable(Name), qPrintable(text) );
3204
                printf("\n");
3205
         }         
3206
}
3207
3208
void CvWindow::MsgBoxInfo(char * pCaption, std::string Info )
3209
{
3210
         QMessageBox::information( this, pCaption, Info.c_str() );
3211
}   
3212
3213
3214
CvWinProperties* CvWindow::createParameterWindow()
3215
{
3216
    QString name_paraWindow = QFileInfo(QApplication::applicationFilePath()).fileName() + " settings";
3217
3218
    CvWinProperties* result = new CvWinProperties(name_paraWindow, guiMainThread);
3219
3220
    return result;
3221
}
3222
3223
3224
void CvWindow::displayPropertiesWin()
3225
{
3226
    if (global_control_panel->isHidden())
3227
        global_control_panel->show();
3228
    else
3229
        global_control_panel->hide();
3230
}
3231
3232
3233
3234
//-------------------------------------
3235
//   simple TextButtons 
3236
//   (without name definition in *.cfg)
3237
3238
void CvWindow::slotCall_0()
3239
{
3240
        m_CmdVec.push_back(vecString[0]);
3241
        InitExchange(0);
3242
}
3243
void CvWindow::slotCall_1()
3244
{
3245
        m_CmdVec.push_back(vecString[1]);
3246
        InitExchange(1);
3247
}
3248
void CvWindow::slotCall_2()
3249
{
3250
        m_CmdVec.push_back(vecString[2]);
3251
        InitExchange(2);
3252
}
3253
void CvWindow::slotCall_3()
3254
{
3255
        m_CmdVec.push_back(vecString[3]);
3256
        InitExchange(3);
3257
}
3258
void CvWindow::slotCall_4()
3259
{
3260
        m_CmdVec.push_back(vecString[4]);
3261
        InitExchange(4);
3262
}
3263
void CvWindow::slotCall_5()
3264
{
3265
        m_CmdVec.push_back(vecString[5]);
3266
        InitExchange(5);
3267
}
3268
void CvWindow::slotCall_6()
3269
{
3270
        m_CmdVec.push_back(vecString[6]);
3271
        InitExchange(6);
3272
}
3273
void CvWindow::slotCall_7()
3274
{
3275
        m_CmdVec.push_back(vecString[7]);
3276
        InitExchange(7);
3277
}
3278
void CvWindow::slotCall_8()
3279
{
3280
        m_CmdVec.push_back(vecString[8]);
3281
        InitExchange(8);
3282
}
3283
void CvWindow::slotCall_9()
3284
{
3285
        m_CmdVec.push_back(vecString[9]);
3286
        InitExchange(9);
3287
}
3288
3289
void CvWindow::slotCallString( const QString & s)
3290
{
3291
        m_CmdVec.push_back(s);
3292
        InitExchange(0);        
3293
}
3294
3295
void CvWindow::slotCallBox()
3296
{
3297
        printf("---- slotCallBox ----");
3298
}
3299
3300
void CvWindow::slotMenuAct0()
3301
{
3302
        QVariant qVar = vect_MenuAct[0]->data();
3303
        QString stng = QString( qVar.toString()  );
3304
        m_CmdVec.push_back(stng);
3305
        InitExchange(0);
3306
}
3307
3308
void CvWindow::slotMenuAct1()
3309
{
3310
        QVariant qVar = vect_MenuAct[1]->data();
3311
        QString stng = QString( qVar.toString()  );
3312
        m_CmdVec.push_back(stng);
3313
        InitExchange(1);
3314
}
3315
void CvWindow::slotMenuAct2()
3316
{
3317
        QVariant qVar = vect_MenuAct[2]->data();
3318
        QString stng = QString( qVar.toString()  );
3319
        m_CmdVec.push_back(stng);
3320
        InitExchange(2);
3321
}
3322
void CvWindow::slotMenuAct3()
3323
{
3324
        QVariant qVar = vect_MenuAct[3]->data();
3325
        QString stng = QString( qVar.toString()  );
3326
        m_CmdVec.push_back(stng);
3327
        InitExchange(3);
3328
}
3329
        
3330
void CvWindow::slotMenuAct4()
3331
{
3332
        QVariant qVar = vect_MenuAct[4]->data();
3333
        QString stng = QString( qVar.toString()  );
3334
        m_CmdVec.push_back(stng);
3335
        InitExchange(4);
3336
}
3337
3338
//-------------------------------------
3339
3340
3341
// EMOD_CheckText_* for Buttons which may have on/off
3342
3343
void CvWindow::slotCallPush_0()
3344
{
3345
        QWidget * pWid = (QWidget*) vect_QButton[0]; 
3346
        m_CmdVec.push_back( pWid->objectName() );
3347
        InitExchange(0);
3348
}
3349
void CvWindow::slotCallPush_1()
3350
{
3351
        QWidget * pWid = (QWidget*) vect_QButton[1]; 
3352
        m_CmdVec.push_back( pWid->objectName() );
3353
        InitExchange(1);
3354
}  
3355
void CvWindow::slotCallPush_2()
3356
{
3357
        QWidget * pWid = (QWidget*) vect_QButton[2]; 
3358
        m_CmdVec.push_back( pWid->objectName() );
3359
        InitExchange(2);
3360
}  
3361
void CvWindow::slotCallPush_3()
3362
{
3363
        QWidget * pWid = (QWidget*) vect_QButton[3]; 
3364
        m_CmdVec.push_back( pWid->objectName() );
3365
        InitExchange(3);
3366
}  
3367
void CvWindow::slotCallPush_4()
3368
{
3369
        QWidget * pWid = (QWidget*) vect_QButton[4]; 
3370
        m_CmdVec.push_back( pWid->objectName() );
3371
        InitExchange(4);
3372
}  
3373
3374
//-------------------------------------
3375
3376
3377
void CvWindow::slotCallCheck_0()
3378
{
3379
        QWidget * pWid = (QWidget*) vect_QCheckBox[0]; 
3380
        m_CmdVec.push_back( pWid->objectName() );
3381
        InitExchange(0);
3382
}  
3383
void CvWindow::slotCallCheck_1()
3384
{
3385
        QWidget * pWid = (QWidget*) vect_QCheckBox[1]; 
3386
        m_CmdVec.push_back( pWid->objectName() );
3387
        InitExchange(1);
3388
}  
3389
void CvWindow::slotCallCheck_2()
3390
{
3391
        QWidget * pWid = (QWidget*) vect_QCheckBox[2]; 
3392
        m_CmdVec.push_back( pWid->objectName() );
3393
        InitExchange(2);
3394
}  
3395
void CvWindow::slotCallCheck_3()
3396
{
3397
        QWidget * pWid = (QWidget*) vect_QCheckBox[2]; 
3398
        m_CmdVec.push_back( pWid->objectName() );
3399
        InitExchange(3);
3400
}  
3401
void CvWindow::slotCallCheck_4()
3402
{
3403
        QWidget * pWid = (QWidget*) vect_QCheckBox[2]; 
3404
        m_CmdVec.push_back( pWid->objectName() );
3405
        InitExchange(4);
3406
}  
3407
3408
//-------------------------------------
3409
3410
void CvWindow::slotCallSpin_0(int iVal)
3411
{
3412
        QWidget * pWid = (QWidget*) vect_QSpinBox[0]; 
3413
        m_CmdVec.push_back( pWid->objectName() );
3414
        InitExchange(0);
3415
}  
3416
3417
void CvWindow::slotCallSpin_1(int iVal)
3418
{
3419
        QWidget * pWid = (QWidget*) vect_QSpinBox[1]; 
3420
        m_CmdVec.push_back( pWid->objectName() );
3421
        InitExchange(1);
3422
}  
3423
3424
void CvWindow::slotCallSpin_2(int iVal)
3425
{
3426
        QWidget * pWid = (QWidget*) vect_QSpinBox[2]; 
3427
        m_CmdVec.push_back( pWid->objectName() );
3428
        InitExchange(2);
3429
}  
3430
3431
void CvWindow::slotCallSpin_3(int iVal)
3432
{
3433
        QWidget * pWid = (QWidget*) vect_QSpinBox[3]; 
3434
        m_CmdVec.push_back( pWid->objectName() );
3435
        InitExchange(3);
3436
}  
3437
void CvWindow::slotCallSpin_4(int iVal)
3438
{
3439
        QWidget * pWid = (QWidget*) vect_QSpinBox[4]; 
3440
        m_CmdVec.push_back( pWid->objectName() );
3441
        InitExchange(4);
3442
}  
3443
3444
//-------------------------------------
3445
3446
3447
3448
//Need more test here !
3449
void CvWindow::keyPressEvent(QKeyEvent *evnt)
3450
{
3451
    //see http://doc.trolltech.com/4.6/qt.html#Key-enum
3452
    int key = evnt->key();
3453
3454
        Qt::Key qtkey = static_cast<Qt::Key>(key);
3455
        char asciiCode = QTest::keyToAscii(qtkey);
3456
        if (asciiCode != 0)
3457
            key = static_cast<int>(asciiCode);
3458
        else
3459
            key = evnt->nativeVirtualKey(); //same codes as returned by GTK-based backend
3460
3461
    //control plus (Z, +, -, up, down, left, right) are used for zoom/panning functions
3462
        if (evnt->modifiers() != Qt::ControlModifier)
3463
        {
3464
        mutexKey.lock();
3465
        last_key = key;
3466
        mutexKey.unlock();
3467
        key_pressed.wakeAll();
3468
        //evnt->accept();
3469
    }
3470
3471
    QWidget::keyPressEvent(evnt);
3472
}
3473
3474
3475
void CvWindow::icvLoadControlPanel()
3476
{
3477
    QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName() + " control panel");
3478
3479
    int bsize = settings.beginReadArray("bars");
3480
3481
    if (bsize == global_control_panel->myLayout->layout()->count())
3482
    {
3483
        for (int i = 0; i < bsize; ++i)
3484
        {
3485
            CvBar* t = (CvBar*) global_control_panel->myLayout->layout()->itemAt(i);
3486
            settings.setArrayIndex(i);
3487
            if (t->type == type_CvTrackbar)
3488
            {
3489
                if (t->name_bar == settings.value("namebar").toString())
3490
                {
3491
                    ((CvTrackbar*)t)->slider->setValue(settings.value("valuebar").toInt());
3492
                }
3493
            }
3494
            if (t->type == type_CvButtonbar)
3495
            {
3496
                int subsize = settings.beginReadArray(QString("buttonbar")+i);
3497
3498
                if ( subsize == ((CvButtonbar*)t)->layout()->count() )
3499
                    icvLoadButtonbar((CvButtonbar*)t,&settings);
3500
3501
                settings.endArray();
3502
            }
3503
        }
3504
    }
3505
3506
    settings.endArray();
3507
}
3508
3509
3510
void CvWindow::icvSaveControlPanel()
3511
{
3512
    QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName()+" control panel");
3513
3514
    settings.beginWriteArray("bars");
3515
3516
    for (int i = 0; i < global_control_panel->myLayout->layout()->count(); ++i)
3517
    {
3518
        CvBar* t = (CvBar*) global_control_panel->myLayout->layout()->itemAt(i);
3519
        settings.setArrayIndex(i);
3520
        if (t->type == type_CvTrackbar)
3521
        {
3522
            settings.setValue("namebar", QString(t->name_bar));
3523
            settings.setValue("valuebar",((CvTrackbar*)t)->slider->value());
3524
        }
3525
        if (t->type == type_CvButtonbar)
3526
        {
3527
            settings.beginWriteArray(QString("buttonbar")+i);
3528
            icvSaveButtonbar((CvButtonbar*)t,&settings);
3529
            settings.endArray();
3530
        }
3531
    }
3532
3533
    settings.endArray();
3534
}
3535
3536
3537
void CvWindow::icvSaveButtonbar(CvButtonbar* b, QSettings* settings)
3538
{
3539
    for (int i = 0, count = b->layout()->count(); i < count; ++i)
3540
    {
3541
        settings->setArrayIndex(i);
3542
3543
        QWidget* temp = (QWidget*) b->layout()->itemAt(i)->widget();
3544
        QString myclass(QLatin1String(temp->metaObject()->className()));
3545
3546
        if (myclass == "CvPushButton")
3547
        {
3548
            CvPushButton* button = (CvPushButton*) temp;
3549
            settings->setValue("namebutton", button->text());
3550
            settings->setValue("valuebutton", int(button->isChecked()));
3551
        }
3552
        else if (myclass == "CvCheckBox")
3553
        {
3554
            CvCheckBox* button = (CvCheckBox*) temp;
3555
            settings->setValue("namebutton", button->text());
3556
            settings->setValue("valuebutton", int(button->isChecked()));
3557
        }
3558
        else if (myclass == "CvRadioButton")
3559
        {
3560
            CvRadioButton* button = (CvRadioButton*) temp;
3561
            settings->setValue("namebutton", button->text());
3562
            settings->setValue("valuebutton", int(button->isChecked()));
3563
        }
3564
    }
3565
}
3566
3567
3568
void CvWindow::icvLoadButtonbar(CvButtonbar* b, QSettings* settings)
3569
{
3570
    for (int i = 0, count = b->layout()->count(); i < count; ++i)
3571
    {
3572
        settings->setArrayIndex(i);
3573
3574
        QWidget* temp = (QWidget*) b->layout()->itemAt(i)->widget();
3575
        QString myclass(QLatin1String(temp->metaObject()->className()));
3576
3577
        if (myclass == "CvPushButton")
3578
        {
3579
            CvPushButton* button = (CvPushButton*) temp;
3580
3581
            if (button->text() == settings->value("namebutton").toString())
3582
                button->setChecked(settings->value("valuebutton").toInt());
3583
        }
3584
        else if (myclass == "CvCheckBox")
3585
        {
3586
            CvCheckBox* button = (CvCheckBox*) temp;
3587
3588
            if (button->text() == settings->value("namebutton").toString())
3589
                button->setChecked(settings->value("valuebutton").toInt());
3590
        }
3591
        else if (myclass == "CvRadioButton")
3592
        {
3593
            CvRadioButton* button = (CvRadioButton*) temp;
3594
3595
            if (button->text() == settings->value("namebutton").toString())
3596
                button->setChecked(settings->value("valuebutton").toInt());
3597
        }
3598
3599
    }
3600
}
3601
3602
3603
void CvWindow::icvLoadTrackbars(QSettings* settings)
3604
{
3605
    int bsize = settings->beginReadArray("trackbars");
3606
3607
    //trackbar are saved in the same order, so no need to use icvFindTrackbarByName
3608
3609
    if (myBarLayout->layout()->count() == bsize) //if not the same number, the window saved and loaded is not the same (nb trackbar not equal)
3610
    {
3611
        for (int i = 0; i < bsize; ++i)
3612
        {
3613
            settings->setArrayIndex(i);
3614
3615
            CvTrackbar* t = (CvTrackbar*) myBarLayout->layout()->itemAt(i);
3616
3617
            if (t->name_bar == settings->value("name").toString())
3618
                t->slider->setValue(settings->value("value").toInt());
3619
3620
        }
3621
    }
3622
3623
    settings->endArray();
3624
}
3625
3626
3627
void CvWindow::icvSaveTrackbars(QSettings* settings)
3628
{
3629
    settings->beginWriteArray("trackbars");
3630
3631
    for (int i = 0; i < myBarLayout->layout()->count(); ++i)
3632
    {
3633
        settings->setArrayIndex(i);
3634
3635
        CvTrackbar* t = (CvTrackbar*) myBarLayout->layout()->itemAt(i);
3636
3637
        settings->setValue("name", t->name_bar);
3638
        settings->setValue("value", t->slider->value());
3639
    }
3640
3641
    settings->endArray();
3642
}
3643
3644
3645
//////////////////////////////////////////////////////
3646
// DefaultViewPort
3647
3648
3649
DefaultViewPort::DefaultViewPort(CvWindow* arg, int arg2) : QGraphicsView(arg), image2Draw_mat(0)
3650
{
3651
    centralWidget = arg;
3652
    param_keepRatio = arg2;
3653
3654
    setContentsMargins(0, 0, 0, 0);
3655
    setMinimumSize(1, 1);
3656
    setAlignment(Qt::AlignHCenter);
3657
3658
    setObjectName(QString::fromUtf8("graphicsView"));
3659
3660
    timerDisplay = new QTimer(this);
3661
    timerDisplay->setSingleShot(true);
3662
    connect(timerDisplay, SIGNAL(timeout()), this, SLOT(stopDisplayInfo()));
3663
3664
    drawInfo = false;
3665
    positionGrabbing = QPointF(0, 0);
3666
    positionCorners = QRect(0, 0, size().width(), size().height());
3667
3668
    on_mouse = 0;
3669
    on_mouse_param = 0;
3670
    mouseCoordinate = QPoint(-1, -1);
3671
3672
    //no border
3673
    setStyleSheet( "QGraphicsView { border-style: none; }" );
3674
3675
    image2Draw_mat = cvCreateMat(viewport()->height(), viewport()->width(), CV_8UC3);
3676
    cvZero(image2Draw_mat);
3677
3678
    nbChannelOriginImage = 0;
3679
3680
    setInteractive(false);
3681
    setMouseTracking(true); //receive mouse event everytime
3682
}
3683
3684
3685
DefaultViewPort::~DefaultViewPort()
3686
{
3687
    if (image2Draw_mat)
3688
        cvReleaseMat(&image2Draw_mat);
3689
}
3690
3691
3692
QWidget* DefaultViewPort::getWidget()
3693
{
3694
    return this;
3695
}
3696
3697
3698
void DefaultViewPort::setMouseCallBack(CvMouseCallback m, void* param)
3699
{
3700
    on_mouse = m;
3701
3702
    on_mouse_param = param;
3703
}
3704
3705
void DefaultViewPort::writeSettings(QSettings& settings)
3706
{
3707
    settings.setValue("matrix_view.m11", param_matrixWorld.m11());
3708
    settings.setValue("matrix_view.m12", param_matrixWorld.m12());
3709
    settings.setValue("matrix_view.m13", param_matrixWorld.m13());
3710
    settings.setValue("matrix_view.m21", param_matrixWorld.m21());
3711
    settings.setValue("matrix_view.m22", param_matrixWorld.m22());
3712
    settings.setValue("matrix_view.m23", param_matrixWorld.m23());
3713
    settings.setValue("matrix_view.m31", param_matrixWorld.m31());
3714
    settings.setValue("matrix_view.m32", param_matrixWorld.m32());
3715
    settings.setValue("matrix_view.m33", param_matrixWorld.m33());
3716
}
3717
3718
3719
void DefaultViewPort::readSettings(QSettings& settings)
3720
{
3721
    qreal m11 = settings.value("matrix_view.m11", param_matrixWorld.m11()).toDouble();
3722
    qreal m12 = settings.value("matrix_view.m12", param_matrixWorld.m12()).toDouble();
3723
    qreal m13 = settings.value("matrix_view.m13", param_matrixWorld.m13()).toDouble();
3724
    qreal m21 = settings.value("matrix_view.m21", param_matrixWorld.m21()).toDouble();
3725
    qreal m22 = settings.value("matrix_view.m22", param_matrixWorld.m22()).toDouble();
3726
    qreal m23 = settings.value("matrix_view.m23", param_matrixWorld.m23()).toDouble();
3727
    qreal m31 = settings.value("matrix_view.m31", param_matrixWorld.m31()).toDouble();
3728
    qreal m32 = settings.value("matrix_view.m32", param_matrixWorld.m32()).toDouble();
3729
    qreal m33 = settings.value("matrix_view.m33", param_matrixWorld.m33()).toDouble();
3730
3731
    param_matrixWorld = QTransform(m11, m12, m13, m21, m22, m23, m31, m32, m33);
3732
}
3733
3734
3735
double DefaultViewPort::getRatio()
3736
{
3737
    return param_keepRatio;
3738
}
3739
3740
3741
void DefaultViewPort::setRatio(int flags)
3742
{
3743
    if (getRatio() == flags) //nothing to do
3744
        return;
3745
3746
    //if valid flags
3747
    if (flags == CV_WINDOW_FREERATIO || flags == CV_WINDOW_KEEPRATIO)
3748
    {
3749
        centralWidget->param_ratio_mode = flags;
3750
        param_keepRatio = flags;
3751
        updateGeometry();
3752
        viewport()->update();
3753
    }
3754
}
3755
3756
3757
void DefaultViewPort::updateImage(const CvArr* arr)
3758
{
3759
    CV_Assert(arr);
3760
3761
    CvMat* mat, stub;
3762
    int origin = 0;
3763
3764
    if (CV_IS_IMAGE_HDR(arr))
3765
        origin = ((IplImage*)arr)->origin;
3766
3767
    mat = cvGetMat(arr, &stub);
3768
3769
    if (!image2Draw_mat || !CV_ARE_SIZES_EQ(image2Draw_mat, mat))
3770
    {
3771
        if (image2Draw_mat)
3772
            cvReleaseMat(&image2Draw_mat);
3773
3774
        //the image in ipl (to do a deep copy with cvCvtColor)
3775
        image2Draw_mat = cvCreateMat(mat->rows, mat->cols, CV_8UC3);
3776
        image2Draw_qt = QImage(image2Draw_mat->data.ptr, image2Draw_mat->cols, image2Draw_mat->rows, image2Draw_mat->step, QImage::Format_RGB888);
3777
3778
        //use to compute mouse coordinate, I need to update the ratio here and in resizeEvent
3779
        ratioX = width() / float(image2Draw_mat->cols);
3780
        ratioY = height() / float(image2Draw_mat->rows);
3781
3782
        updateGeometry();
3783
    }
3784
3785
    nbChannelOriginImage = cvGetElemType(mat);
3786
3787
    cvConvertImage(mat, image2Draw_mat, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB);
3788
3789
    viewport()->update();
3790
}
3791
3792
3793
void DefaultViewPort::startDisplayInfo(QString text, int delayms)
3794
{
3795
    if (timerDisplay->isActive())
3796
        stopDisplayInfo();
3797
3798
    infoText = text;
3799
    if (delayms > 0) timerDisplay->start(delayms);
3800
    drawInfo = true;
3801
}
3802
3803
3804
void DefaultViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback /*callback*/, void* /*userdata*/)
3805
{
3806
    CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL");
3807
}
3808
3809
3810
void DefaultViewPort::setOpenGlCleanCallback(CvOpenGlCleanCallback /*callback*/, void* /*userdata*/)
3811
{
3812
    CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL");
3813
}
3814
3815
3816
void DefaultViewPort::makeCurrentOpenGlContext()
3817
{
3818
    CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL");
3819
}
3820
3821
3822
void DefaultViewPort::updateGl()
3823
{
3824
    CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL");
3825
}
3826
3827
3828
//Note: move 2 percent of the window
3829
void DefaultViewPort::siftWindowOnLeft()
3830
{
3831
    float delta = 2 * width() / (100.0 * param_matrixWorld.m11());
3832
    moveView(QPointF(delta, 0));
3833
}
3834
3835
3836
//Note: move 2 percent of the window
3837
void DefaultViewPort::siftWindowOnRight()
3838
{
3839
    float delta = -2 * width() / (100.0 * param_matrixWorld.m11());
3840
    moveView(QPointF(delta, 0));
3841
}
3842
3843
3844
//Note: move 2 percent of the window
3845
void DefaultViewPort::siftWindowOnUp()
3846
{
3847
    float delta = 2 * height() / (100.0 * param_matrixWorld.m11());
3848
    moveView(QPointF(0, delta));
3849
}
3850
3851
3852
//Note: move 2 percent of the window
3853
void DefaultViewPort::siftWindowOnDown()
3854
{
3855
    float delta = -2 * height() / (100.0 * param_matrixWorld.m11());
3856
    moveView(QPointF(0, delta));
3857
}
3858
3859
3860
void DefaultViewPort::imgRegion()
3861
{
3862
    scaleView((threshold_zoom_img_region / param_matrixWorld.m11() - 1) * 5, QPointF(size().width() / 2, size().height() / 2));
3863
}
3864
3865
3866
void DefaultViewPort::resetZoom()
3867
{
3868
    param_matrixWorld.reset();
3869
    controlImagePosition();
3870
}
3871
3872
3873
void DefaultViewPort::ZoomIn()
3874
{
3875
    scaleView(0.5, QPointF(size().width() / 2, size().height() / 2));
3876
}
3877
3878
3879
void DefaultViewPort::ZoomOut()
3880
{
3881
    scaleView(-0.5, QPointF(size().width() / 2, size().height() / 2));
3882
}
3883
3884
3885
//can save as JPG, JPEG, BMP, PNG
3886
void DefaultViewPort::saveView()
3887
{
3888
    QDate date_d = QDate::currentDate();
3889
    QString date_s = date_d.toString("dd.MM.yyyy");
3890
    QString name_s = centralWidget->windowTitle() + "_screenshot_" + date_s;
3891
3892
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File %1").arg(name_s), name_s + ".png", tr("Images (*.png *.jpg *.bmp *.jpeg)"));
3893
3894
    if (!fileName.isEmpty()) //save the picture
3895
    {
3896
        QString extension = fileName.right(3);
3897
3898
        //   (no need anymore) create the image resized to receive the 'screenshot'
3899
        //    image2Draw_qt_resized = QImage(viewport()->width(), viewport()->height(),QImage::Format_RGB888);
3900
3901
        QPainter saveimage(&image2Draw_qt_resized);
3902
        this->render(&saveimage);
3903
3904
        // Save it..
3905
        if (QString::compare(extension, "png", Qt::CaseInsensitive) == 0)
3906
        {
3907
            image2Draw_qt_resized.save(fileName, "PNG");
3908
            return;
3909
        }
3910
3911
        if (QString::compare(extension, "jpg", Qt::CaseInsensitive) == 0)
3912
        {
3913
            image2Draw_qt_resized.save(fileName, "JPG");
3914
            return;
3915
        }
3916
3917
        if (QString::compare(extension, "bmp", Qt::CaseInsensitive) == 0)
3918
        {
3919
            image2Draw_qt_resized.save(fileName, "BMP");
3920
            return;
3921
        }
3922
3923
        if (QString::compare(extension, "jpeg", Qt::CaseInsensitive) == 0)
3924
        {
3925
            image2Draw_qt_resized.save(fileName, "JPEG");
3926
            return;
3927
        }
3928
3929
        CV_Error(CV_StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG");
3930
    }
3931
}
3932
3933
3934
void DefaultViewPort::contextMenuEvent(QContextMenuEvent* evnt)
3935
{
3936
    if (centralWidget->vect_QActions.size() > 0)
3937
    {
3938
        QMenu menu(this);
3939
3940
        foreach (QAction *a, centralWidget->vect_QActions)
3941
            menu.addAction(a);
3942
3943
        menu.exec(evnt->globalPos());
3944
    }
3945
}
3946
3947
3948
void DefaultViewPort::resizeEvent(QResizeEvent* evnt)
3949
{
3950
    controlImagePosition();
3951
3952
    //use to compute mouse coordinate, I need to update the ratio here and in resizeEvent
3953
    ratioX = width() / float(image2Draw_mat->cols);
3954
    ratioY = height() / float(image2Draw_mat->rows);
3955
3956
    if (param_keepRatio == CV_WINDOW_KEEPRATIO)//to keep the same aspect ratio
3957
    {
3958
        QSize newSize = QSize(image2Draw_mat->cols, image2Draw_mat->rows);
3959
        newSize.scale(evnt->size(), Qt::KeepAspectRatio);
3960
3961
        //imageWidth/imageHeight = newWidth/newHeight +/- epsilon
3962
        //ratioX = ratioY +/- epsilon
3963
        //||ratioX - ratioY|| = epsilon
3964
        if (fabs(ratioX - ratioY) * 100 > ratioX) //avoid infinity loop / epsilon = 1% of ratioX
3965
        {
3966
            resize(newSize);
3967
3968
            //move to the middle
3969
            //newSize get the delta offset to place the picture in the middle of its parent
3970
            newSize = (evnt->size() - newSize) / 2;
3971
3972
            //if the toolbar is displayed, avoid drawing myview on top of it
3973
            if (centralWidget->myToolBar)
3974
                if(!centralWidget->myToolBar->isHidden())
3975
                    newSize += QSize(0, centralWidget->myToolBar->height());
3976
3977
            move(newSize.width(), newSize.height());
3978
        }
3979
    }
3980
3981
    return QGraphicsView::resizeEvent(evnt);
3982
}
3983
3984
3985
void DefaultViewPort::wheelEvent(QWheelEvent* evnt)
3986
{
3987
    scaleView(evnt->delta() / 240.0, evnt->pos());
3988
    viewport()->update();
3989
}
3990
3991
3992
void DefaultViewPort::mousePressEvent(QMouseEvent* evnt)
3993
{
3994
    int cv_event = -1, flags = 0;
3995
    QPoint pt = evnt->pos();
3996
3997
    //icvmouseHandler: pass parameters for cv_event, flags
3998
    icvmouseHandler(evnt, mouse_down, cv_event, flags);
3999
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4000
4001
    if (param_matrixWorld.m11()>1)
4002
    {
4003
        setCursor(Qt::ClosedHandCursor);
4004
        positionGrabbing = evnt->pos();
4005
    }
4006
4007
    QWidget::mousePressEvent(evnt);
4008
}
4009
4010
4011
void DefaultViewPort::mouseReleaseEvent(QMouseEvent* evnt)
4012
{
4013
    int cv_event = -1, flags = 0;
4014
    QPoint pt = evnt->pos();
4015
4016
    //icvmouseHandler: pass parameters for cv_event, flags
4017
    icvmouseHandler(evnt, mouse_up, cv_event, flags);
4018
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4019
4020
    if (param_matrixWorld.m11()>1)
4021
        setCursor(Qt::OpenHandCursor);
4022
4023
    QWidget::mouseReleaseEvent(evnt);
4024
}
4025
4026
4027
void DefaultViewPort::mouseDoubleClickEvent(QMouseEvent* evnt)
4028
{
4029
    int cv_event = -1, flags = 0;
4030
    QPoint pt = evnt->pos();
4031
4032
    //icvmouseHandler: pass parameters for cv_event, flags
4033
    icvmouseHandler(evnt, mouse_dbclick, cv_event, flags);
4034
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4035
4036
    QWidget::mouseDoubleClickEvent(evnt);
4037
}
4038
4039
4040
void DefaultViewPort::mouseMoveEvent(QMouseEvent* evnt)
4041
{
4042
    int cv_event = CV_EVENT_MOUSEMOVE, flags = 0;
4043
    QPoint pt = evnt->pos();
4044
4045
    //icvmouseHandler: pass parameters for cv_event, flags
4046
    icvmouseHandler(evnt, mouse_move, cv_event, flags);
4047
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4048
4049
    if (param_matrixWorld.m11() > 1 && evnt->buttons() == Qt::LeftButton)
4050
    {
4051
        QPointF dxy = (pt - positionGrabbing)/param_matrixWorld.m11();
4052
        positionGrabbing = evnt->pos();
4053
        moveView(dxy);
4054
    }
4055
4056
    //I update the statusbar here because if the user does a cvWaitkey(0) (like with inpaint.cpp)
4057
    //the status bar will only be repaint when a click occurs.
4058
    if (centralWidget->myStatusBar)
4059
        viewport()->update();
4060
4061
    QWidget::mouseMoveEvent(evnt);
4062
}
4063
4064
4065
void DefaultViewPort::paintEvent(QPaintEvent* evnt)
4066
{
4067
    QPainter myPainter(viewport());
4068
    myPainter.setWorldTransform(param_matrixWorld);
4069
4070
    draw2D(&myPainter);
4071
4072
    //Now disable matrixWorld for overlay display
4073
    myPainter.setWorldMatrixEnabled(false);
4074
4075
    //in mode zoom/panning
4076
    if (param_matrixWorld.m11() > 1)
4077
    {
4078
        if (param_matrixWorld.m11() >= threshold_zoom_img_region)
4079
        {
4080
            if (centralWidget->param_flags == CV_WINDOW_NORMAL)
4081
                startDisplayInfo("WARNING: The values displayed are the resized image's values. If you want the original image's values, use CV_WINDOW_AUTOSIZE", 1000);
4082
4083
            drawImgRegion(&myPainter);
4084
        }
4085
4086
        drawViewOverview(&myPainter);
4087
    }
4088
4089
    //for information overlay
4090
    if (drawInfo)
4091
        drawInstructions(&myPainter);
4092
4093
    //for statusbar
4094
    if (centralWidget->myStatusBar)
4095
        drawStatusBar();
4096
4097
    QGraphicsView::paintEvent(evnt);
4098
}
4099
4100
4101
void DefaultViewPort::stopDisplayInfo()
4102
{
4103
    timerDisplay->stop();
4104
    drawInfo = false;
4105
}
4106
4107
4108
inline bool DefaultViewPort::isSameSize(IplImage* img1, IplImage* img2)
4109
{
4110
    return img1->width == img2->width && img1->height == img2->height;
4111
}
4112
4113
4114
void DefaultViewPort::controlImagePosition()
4115
{
4116
    qreal left, top, right, bottom;
4117
4118
    //after check top-left, bottom right corner to avoid getting "out" during zoom/panning
4119
    param_matrixWorld.map(0,0,&left,&top);
4120
4121
    if (left > 0)
4122
    {
4123
        param_matrixWorld.translate(-left,0);
4124
        left = 0;
4125
    }
4126
    if (top > 0)
4127
    {
4128
        param_matrixWorld.translate(0,-top);
4129
        top = 0;
4130
    }
4131
    //-------
4132
4133
    QSize sizeImage = size();
4134
    param_matrixWorld.map(sizeImage.width(),sizeImage.height(),&right,&bottom);
4135
    if (right < sizeImage.width())
4136
    {
4137
        param_matrixWorld.translate(sizeImage.width()-right,0);
4138
        right = sizeImage.width();
4139
    }
4140
    if (bottom < sizeImage.height())
4141
    {
4142
        param_matrixWorld.translate(0,sizeImage.height()-bottom);
4143
        bottom = sizeImage.height();
4144
    }
4145
4146
    //save corner position
4147
    positionCorners.setTopLeft(QPoint(left,top));
4148
    positionCorners.setBottomRight(QPoint(right,bottom));
4149
    //save also the inv matrix
4150
    matrixWorld_inv = param_matrixWorld.inverted();
4151
4152
    //viewport()->update();
4153
}
4154
4155
void DefaultViewPort::moveView(QPointF delta)
4156
{
4157
    param_matrixWorld.translate(delta.x(),delta.y());
4158
    controlImagePosition();
4159
    viewport()->update();
4160
}
4161
4162
//factor is -0.5 (zoom out) or 0.5 (zoom in)
4163
void DefaultViewPort::scaleView(qreal factor,QPointF center)
4164
{
4165
    factor/=5;//-0.1 <-> 0.1
4166
    factor+=1;//0.9 <-> 1.1
4167
4168
    //limit zoom out ---
4169
    if (param_matrixWorld.m11()==1 && factor < 1)
4170
        return;
4171
4172
    if (param_matrixWorld.m11()*factor<1)
4173
        factor = 1/param_matrixWorld.m11();
4174
4175
4176
    //limit zoom int ---
4177
    if (param_matrixWorld.m11()>100 && factor > 1)
4178
        return;
4179
4180
    //inverse the transform
4181
    int a, b;
4182
    matrixWorld_inv.map(center.x(),center.y(),&a,&b);
4183
4184
    param_matrixWorld.translate(a-factor*a,b-factor*b);
4185
    param_matrixWorld.scale(factor,factor);
4186
4187
    controlImagePosition();
4188
4189
    //display new zoom
4190
    if (centralWidget->myStatusBar)
4191
        centralWidget->displayStatusBar(tr("Zoom: %1%").arg(param_matrixWorld.m11()*100),1000);
4192
4193
    if (param_matrixWorld.m11()>1)
4194
        setCursor(Qt::OpenHandCursor);
4195
    else
4196
        unsetCursor();
4197
}
4198
4199
4200
//up, down, dclick, move
4201
void DefaultViewPort::icvmouseHandler(QMouseEvent *evnt, type_mouse_event category, int &cv_event, int &flags)
4202
{
4203
    Qt::KeyboardModifiers modifiers = evnt->modifiers();
4204
    Qt::MouseButtons buttons = evnt->buttons();
4205
4206
    flags = 0;
4207
    if(modifiers & Qt::ShiftModifier)
4208
        flags |= CV_EVENT_FLAG_SHIFTKEY;
4209
    if(modifiers & Qt::ControlModifier)
4210
        flags |= CV_EVENT_FLAG_CTRLKEY;
4211
    if(modifiers & Qt::AltModifier)
4212
        flags |= CV_EVENT_FLAG_ALTKEY;
4213
4214
    if(buttons & Qt::LeftButton)
4215
        flags |= CV_EVENT_FLAG_LBUTTON;
4216
    if(buttons & Qt::RightButton)
4217
        flags |= CV_EVENT_FLAG_RBUTTON;
4218
    if(buttons & Qt::MidButton)
4219
        flags |= CV_EVENT_FLAG_MBUTTON;
4220
4221
    cv_event = CV_EVENT_MOUSEMOVE;
4222
    switch(evnt->button())
4223
    {
4224
    case Qt::LeftButton:
4225
        cv_event = tableMouseButtons[category][0];
4226
        flags |= CV_EVENT_FLAG_LBUTTON;
4227
        break;
4228
    case Qt::RightButton:
4229
        cv_event = tableMouseButtons[category][1];
4230
        flags |= CV_EVENT_FLAG_RBUTTON;
4231
        break;
4232
    case Qt::MidButton:
4233
        cv_event = tableMouseButtons[category][2];
4234
        flags |= CV_EVENT_FLAG_MBUTTON;
4235
        break;
4236
    default:;
4237
    }
4238
}
4239
4240
4241
void DefaultViewPort::icvmouseProcessing(QPointF pt, int cv_event, int flags)
4242
{
4243
    //to convert mouse coordinate
4244
    qreal pfx, pfy;
4245
    matrixWorld_inv.map(pt.x(),pt.y(),&pfx,&pfy);
4246
4247
    mouseCoordinate.rx()=floor(pfx/ratioX);
4248
    mouseCoordinate.ry()=floor(pfy/ratioY);
4249
4250
    if (on_mouse)
4251
        on_mouse( cv_event, mouseCoordinate.x(),
4252
            mouseCoordinate.y(), flags, on_mouse_param );
4253
}
4254
4255
4256
QSize DefaultViewPort::sizeHint() const
4257
{
4258
    if(image2Draw_mat)
4259
        return QSize(image2Draw_mat->cols, image2Draw_mat->rows);
4260
    else
4261
        return QGraphicsView::sizeHint();
4262
}
4263
4264
4265
void DefaultViewPort::draw2D(QPainter *painter)
4266
{
4267
    image2Draw_qt = QImage(image2Draw_mat->data.ptr, image2Draw_mat->cols, image2Draw_mat->rows,image2Draw_mat->step,QImage::Format_RGB888);
4268
    image2Draw_qt_resized = image2Draw_qt.scaled(viewport()->width(),viewport()->height(),Qt::IgnoreAspectRatio,Qt::FastTransformation);//Qt::SmoothTransformation);
4269
    painter->drawImage(0,0,image2Draw_qt_resized);
4270
}
4271
4272
//only if CV_8UC1 or CV_8UC3
4273
void DefaultViewPort::drawStatusBar()
4274
{
4275
    if (nbChannelOriginImage!=CV_8UC1 && nbChannelOriginImage!=CV_8UC3)
4276
        return;
4277
4278
    if (mouseCoordinate.x()>=0 &&
4279
        mouseCoordinate.y()>=0 &&
4280
        mouseCoordinate.x()<image2Draw_qt.width() &&
4281
        mouseCoordinate.y()<image2Draw_qt.height())
4282
//  if (mouseCoordinate.x()>=0 && mouseCoordinate.y()>=0)
4283
    {
4284
        QRgb rgbValue = image2Draw_qt.pixel(mouseCoordinate);
4285
4286
        if (nbChannelOriginImage==CV_8UC3 )
4287
        {
4288
            centralWidget->myStatusBar_msg->setText(tr("<font color='black'>(x=%1, y=%2) ~ </font>")
4289
                .arg(mouseCoordinate.x())
4290
                .arg(mouseCoordinate.y())+
4291
                tr("<font color='red'>R:%3 </font>").arg(qRed(rgbValue))+//.arg(value.val[0])+
4292
                tr("<font color='green'>G:%4 </font>").arg(qGreen(rgbValue))+//.arg(value.val[1])+
4293
                tr("<font color='blue'>B:%5</font>").arg(qBlue(rgbValue))//.arg(value.val[2])
4294
                );
4295
        }
4296
4297
        if (nbChannelOriginImage==CV_8UC1)
4298
        {
4299
            //all the channel have the same value (because of cvconvertimage), so only the r channel is dsplayed
4300
            centralWidget->myStatusBar_msg->setText(tr("<font color='black'>(x=%1, y=%2) ~ </font>")
4301
                .arg(mouseCoordinate.x())
4302
                .arg(mouseCoordinate.y())+
4303
                tr("<font color='grey'>L:%3 </font>").arg(qRed(rgbValue))
4304
                );
4305
        }
4306
    }
4307
}
4308
4309
//accept only CV_8UC1 and CV_8UC8 image for now
4310
void DefaultViewPort::drawImgRegion(QPainter *painter)
4311
{
4312
4313
    if (nbChannelOriginImage!=CV_8UC1 && nbChannelOriginImage!=CV_8UC3)
4314
        return;
4315
4316
    qreal offsetX = param_matrixWorld.dx()/param_matrixWorld.m11();
4317
    offsetX = offsetX - floor(offsetX);
4318
    qreal offsetY = param_matrixWorld.dy()/param_matrixWorld.m11();
4319
    offsetY = offsetY - floor(offsetY);
4320
4321
    QSize view = size();
4322
    QVarLengthArray<QLineF, 30> linesX;
4323
    for (qreal _x = offsetX*param_matrixWorld.m11(); _x < view.width(); _x += param_matrixWorld.m11() )
4324
        linesX.append(QLineF(_x, 0, _x, view.height()));
4325
4326
    QVarLengthArray<QLineF, 30> linesY;
4327
    for (qreal _y = offsetY*param_matrixWorld.m11(); _y < view.height(); _y += param_matrixWorld.m11() )
4328
        linesY.append(QLineF(0, _y, view.width(), _y));
4329
4330
4331
    QFont f = painter->font();
4332
    int original_font_size = f.pointSize();
4333
    //change font size
4334
    //f.setPointSize(4+(param_matrixWorld.m11()-threshold_zoom_img_region)/5);
4335
    f.setPixelSize(10+(param_matrixWorld.m11()-threshold_zoom_img_region)/5);
4336
    painter->setFont(f);
4337
    QString val;
4338
    QRgb rgbValue;
4339
4340
    QPointF point1;//sorry, I do not know how to name it
4341
    QPointF point2;//idem
4342
4343
    for (int j=-1;j<height()/param_matrixWorld.m11();j++)//-1 because display the pixels top rows left colums
4344
        for (int i=-1;i<width()/param_matrixWorld.m11();i++)//-1
4345
        {
4346
            point1.setX((i+offsetX)*param_matrixWorld.m11());
4347
            point1.setY((j+offsetY)*param_matrixWorld.m11());
4348
4349
            matrixWorld_inv.map(point1.x(),point1.y(),&point2.rx(),&point2.ry());
4350
4351
            point2.rx()= (long) (point2.x() + 0.5);
4352
            point2.ry()= (long) (point2.y() + 0.5);
4353
4354
            if (point2.x() >= 0 && point2.y() >= 0)
4355
                rgbValue = image2Draw_qt_resized.pixel(QPoint(point2.x(),point2.y()));
4356
            else
4357
                rgbValue = qRgb(0,0,0);
4358
4359
            if (nbChannelOriginImage==CV_8UC3)
4360
            {
4361
                //for debug
4362
                /*
4363
                val = tr("%1 %2").arg(point2.x()).arg(point2.y());
4364
                painter->setPen(QPen(Qt::black, 1));
4365
                painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/2),
4366
                    Qt::AlignCenter, val);
4367
                */
4368
4369
                val = tr("%1").arg(qRed(rgbValue));
4370
                painter->setPen(QPen(Qt::red, 1));
4371
                painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/3),
4372
                    Qt::AlignCenter, val);
4373
4374
                val = tr("%1").arg(qGreen(rgbValue));
4375
                painter->setPen(QPen(Qt::green, 1));
4376
                painter->drawText(QRect(point1.x(),point1.y()+param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3),
4377
                    Qt::AlignCenter, val);
4378
4379
                val = tr("%1").arg(qBlue(rgbValue));
4380
                painter->setPen(QPen(Qt::blue, 1));
4381
                painter->drawText(QRect(point1.x(),point1.y()+2*param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3),
4382
                    Qt::AlignCenter, val);
4383
4384
            }
4385
4386
            if (nbChannelOriginImage==CV_8UC1)
4387
            {
4388
4389
                val = tr("%1").arg(qRed(rgbValue));
4390
                painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()),
4391
                    Qt::AlignCenter, val);
4392
            }
4393
        }
4394
4395
        painter->setPen(QPen(Qt::black, 1));
4396
        painter->drawLines(linesX.data(), linesX.size());
4397
        painter->drawLines(linesY.data(), linesY.size());
4398
4399
        //restore font size
4400
        f.setPointSize(original_font_size);
4401
        painter->setFont(f);
4402
4403
}
4404
4405
void DefaultViewPort::drawViewOverview(QPainter *painter)
4406
{
4407
    QSize viewSize = size();
4408
    viewSize.scale ( 100, 100,Qt::KeepAspectRatio );
4409
4410
    const int margin = 5;
4411
4412
    //draw the image's location
4413
    painter->setBrush(QColor(0, 0, 0, 127));
4414
    painter->setPen(Qt::darkGreen);
4415
    painter->drawRect(QRect(width()-viewSize.width()-margin, 0,viewSize.width(),viewSize.height()));
4416
4417
    //daw the view's location inside the image
4418
    qreal ratioSize = 1/param_matrixWorld.m11();
4419
    qreal ratioWindow = (qreal)(viewSize.height())/(qreal)(size().height());
4420
    painter->setPen(Qt::darkBlue);
4421
    painter->drawRect(QRectF(width()-viewSize.width()-positionCorners.left()*ratioSize*ratioWindow-margin,
4422
        -positionCorners.top()*ratioSize*ratioWindow,
4423
        (viewSize.width()-1)*ratioSize,
4424
        (viewSize.height()-1)*ratioSize)
4425
        );
4426
}
4427
4428
void DefaultViewPort::drawInstructions(QPainter *painter)
4429
{
4430
    QFontMetrics metrics = QFontMetrics(font());
4431
    int border = qMax(4, metrics.leading());
4432
4433
    QRect qrect = metrics.boundingRect(0, 0, width() - 2*border, int(height()*0.125),
4434
        Qt::AlignCenter | Qt::TextWordWrap, infoText);
4435
    painter->setRenderHint(QPainter::TextAntialiasing);
4436
    painter->fillRect(QRect(0, 0, width(), qrect.height() + 2*border),
4437
        QColor(0, 0, 0, 127));
4438
    painter->setPen(Qt::white);
4439
    painter->fillRect(QRect(0, 0, width(), qrect.height() + 2*border),
4440
        QColor(0, 0, 0, 127));
4441
4442
    painter->drawText((width() - qrect.width())/2, border,
4443
        qrect.width(), qrect.height(),
4444
        Qt::AlignCenter | Qt::TextWordWrap, infoText);
4445
}
4446
4447
4448
void DefaultViewPort::setSize(QSize /*size_*/)
4449
{
4450
}
4451
4452
4453
//////////////////////////////////////////////////////
4454
// OpenGlViewPort
4455
4456
#ifdef HAVE_QT_OPENGL
4457
4458
OpenGlViewPort::OpenGlViewPort(QWidget* _parent) : QGLWidget(_parent), size(-1, -1)
4459
{
4460
    mouseCallback = 0;
4461
    mouseData = 0;
4462
4463
    glDrawCallback = 0;
4464
    glDrawData = 0;
4465
4466
    glCleanCallback = 0;
4467
    glCleanData = 0;
4468
4469
    glFuncTab = 0;
4470
}
4471
4472
OpenGlViewPort::~OpenGlViewPort()
4473
{
4474
    if (glFuncTab)
4475
        delete glFuncTab;
4476
4477
    setOpenGlCleanCallback(0, 0);
4478
}
4479
4480
QWidget* OpenGlViewPort::getWidget()
4481
{
4482
    return this;
4483
}
4484
4485
void OpenGlViewPort::setMouseCallBack(CvMouseCallback callback, void* param)
4486
{
4487
    mouseCallback = callback;
4488
    mouseData = param;
4489
}
4490
4491
void OpenGlViewPort::writeSettings(QSettings& /*settings*/)
4492
{
4493
}
4494
4495
void OpenGlViewPort::readSettings(QSettings& /*settings*/)
4496
{
4497
}
4498
4499
double OpenGlViewPort::getRatio()
4500
{
4501
    return (double)width() / height();
4502
}
4503
4504
void OpenGlViewPort::setRatio(int /*flags*/)
4505
{
4506
}
4507
4508
void OpenGlViewPort::updateImage(const CvArr* /*arr*/)
4509
{
4510
}
4511
4512
void OpenGlViewPort::startDisplayInfo(QString /*text*/, int /*delayms*/)
4513
{
4514
}
4515
4516
void OpenGlViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata)
4517
{
4518
    glDrawCallback = callback;
4519
    glDrawData = userdata;
4520
}
4521
4522
void OpenGlViewPort::setOpenGlCleanCallback(CvOpenGlCleanCallback callback, void* userdata)
4523
{
4524
    makeCurrentOpenGlContext();
4525
4526
    if (glCleanCallback)
4527
        glCleanCallback(glCleanData);
4528
4529
    glCleanCallback = callback;
4530
    glCleanData = userdata;
4531
}
4532
4533
void OpenGlViewPort::makeCurrentOpenGlContext()
4534
{
4535
    makeCurrent();
4536
    icvSetOpenGlFuncTab(glFuncTab);
4537
}
4538
4539
void OpenGlViewPort::updateGl()
4540
{
4541
    QGLWidget::updateGL();
4542
}
4543
4544
#ifndef APIENTRY
4545
    #define APIENTRY
4546
#endif
4547
4548
#ifndef APIENTRYP
4549
    #define APIENTRYP APIENTRY *
4550
#endif
4551
4552
#ifndef GL_VERSION_1_5
4553
    /* GL types for handling large vertex buffer objects */
4554
    typedef ptrdiff_t GLintptr;
4555
    typedef ptrdiff_t GLsizeiptr;
4556
#endif
4557
4558
typedef void (APIENTRYP PFNGLGENBUFFERSPROC   ) (GLsizei n, GLuint *buffers);
4559
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
4560
4561
typedef void (APIENTRYP PFNGLBUFFERDATAPROC   ) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
4562
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
4563
4564
typedef void (APIENTRYP PFNGLBINDBUFFERPROC   ) (GLenum target, GLuint buffer);
4565
4566
typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
4567
typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
4568
4569
class GlFuncTab_QT : public CvOpenGlFuncTab
4570
{
4571
public:
4572
#ifdef Q_WS_WIN
4573
    GlFuncTab_QT(HDC hDC);
4574
#else
4575
    GlFuncTab_QT();
4576
#endif
4577
4578
    void genBuffers(int n, unsigned int* buffers) const;
4579
    void deleteBuffers(int n, const unsigned int* buffers) const;
4580
4581
    void bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const;
4582
    void bufferSubData(unsigned int target, ptrdiff_t offset, ptrdiff_t size, const void* data) const;
4583
4584
    void bindBuffer(unsigned int target, unsigned int buffer) const;
4585
4586
    void* mapBuffer(unsigned int target, unsigned int access) const;
4587
    void unmapBuffer(unsigned int target) const;
4588
4589
    void generateBitmapFont(const std::string& family, int height, int weight, bool italic, bool underline, int start, int count, int base) const;
4590
4591
    bool isGlContextInitialized() const;
4592
4593
    PFNGLGENBUFFERSPROC    glGenBuffersExt;
4594
    PFNGLDELETEBUFFERSPROC glDeleteBuffersExt;
4595
4596
    PFNGLBUFFERDATAPROC    glBufferDataExt;
4597
    PFNGLBUFFERSUBDATAPROC glBufferSubDataExt;
4598
4599
    PFNGLBINDBUFFERPROC    glBindBufferExt;
4600
4601
    PFNGLMAPBUFFERPROC     glMapBufferExt;
4602
    PFNGLUNMAPBUFFERPROC   glUnmapBufferExt;
4603
4604
    bool initialized;
4605
4606
#ifdef Q_WS_WIN
4607
    HDC hDC;
4608
#endif
4609
};
4610
4611
#ifdef Q_WS_WIN
4612
    GlFuncTab_QT::GlFuncTab_QT(HDC hDC_) : hDC(hDC_)
4613
#else
4614
    GlFuncTab_QT::GlFuncTab_QT()
4615
#endif
4616
{
4617
    glGenBuffersExt    = 0;
4618
    glDeleteBuffersExt = 0;
4619
4620
    glBufferDataExt    = 0;
4621
    glBufferSubDataExt = 0;
4622
4623
    glBindBufferExt    = 0;
4624
4625
    glMapBufferExt     = 0;
4626
    glUnmapBufferExt   = 0;
4627
4628
    initialized = false;
4629
}
4630
4631
void GlFuncTab_QT::genBuffers(int n, unsigned int* buffers) const
4632
{
4633
    CV_FUNCNAME( "GlFuncTab_QT::genBuffers" );
4634
4635
    __BEGIN__;
4636
4637
    if (!glGenBuffersExt)
4638
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4639
4640
    glGenBuffersExt(n, buffers);
4641
    CV_CheckGlError();
4642
4643
    __END__;
4644
}
4645
4646
void GlFuncTab_QT::deleteBuffers(int n, const unsigned int* buffers) const
4647
{
4648
    CV_FUNCNAME( "GlFuncTab_QT::deleteBuffers" );
4649
4650
    __BEGIN__;
4651
4652
    if (!glDeleteBuffersExt)
4653
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4654
4655
    glDeleteBuffersExt(n, buffers);
4656
    CV_CheckGlError();
4657
4658
    __END__;
4659
}
4660
4661
void GlFuncTab_QT::bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const
4662
{
4663
    CV_FUNCNAME( "GlFuncTab_QT::bufferData" );
4664
4665
    __BEGIN__;
4666
4667
    if (!glBufferDataExt)
4668
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4669
4670
    glBufferDataExt(target, size, data, usage);
4671
    CV_CheckGlError();
4672
4673
    __END__;
4674
}
4675
4676
void GlFuncTab_QT::bufferSubData(unsigned int target, ptrdiff_t offset, ptrdiff_t size, const void* data) const
4677
{
4678
    CV_FUNCNAME( "GlFuncTab_QT::bufferSubData" );
4679
4680
    __BEGIN__;
4681
4682
    if (!glBufferSubDataExt)
4683
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4684
4685
    glBufferSubDataExt(target, offset, size, data);
4686
    CV_CheckGlError();
4687
4688
    __END__;
4689
}
4690
4691
void GlFuncTab_QT::bindBuffer(unsigned int target, unsigned int buffer) const
4692
{
4693
    CV_FUNCNAME( "GlFuncTab_QT::bindBuffer" );
4694
4695
    __BEGIN__;
4696
4697
    if (!glBindBufferExt)
4698
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4699
4700
    glBindBufferExt(target, buffer);
4701
    CV_CheckGlError();
4702
4703
    __END__;
4704
}
4705
4706
void* GlFuncTab_QT::mapBuffer(unsigned int target, unsigned int access) const
4707
{
4708
    CV_FUNCNAME( "GlFuncTab_QT::mapBuffer" );
4709
4710
    void* res = 0;
4711
4712
    __BEGIN__;
4713
4714
    if (!glMapBufferExt)
4715
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4716
4717
    res = glMapBufferExt(target, access);
4718
    CV_CheckGlError();
4719
4720
    __END__;
4721
4722
    return res;
4723
}
4724
4725
void GlFuncTab_QT::unmapBuffer(unsigned int target) const
4726
{
4727
    CV_FUNCNAME( "GlFuncTab_QT::unmapBuffer" );
4728
4729
    __BEGIN__;
4730
4731
    if (!glUnmapBufferExt)
4732
        CV_ERROR(CV_OpenGlApiCallError, "Current OpenGL implementation doesn't support required extension");
4733
4734
    glUnmapBufferExt(target);
4735
    CV_CheckGlError();
4736
4737
    __END__;
4738
}
4739
4740
void GlFuncTab_QT::generateBitmapFont(const std::string& family, int height, int weight, bool italic, bool /*underline*/, int start, int count, int base) const
4741
{
4742
#ifdef Q_WS_WIN
4743
    CV_FUNCNAME( "GlFuncTab_QT::generateBitmapFont" );
4744
#endif
4745
4746
    QFont font(QString(family.c_str()), height, weight, italic);
4747
4748
    __BEGIN__;
4749
4750
#ifndef Q_WS_WIN
4751
    font.setStyleStrategy(QFont::OpenGLCompatible);
4752
    if (font.handle())
4753
        glXUseXFont(font.handle(), start, count, base);
4754
#else
4755
    SelectObject(hDC, font.handle());
4756
    if (!wglUseFontBitmaps(hDC, start, count, base))
4757
        CV_ERROR(CV_OpenGlApiCallError, "Can't create font");
4758
#endif
4759
4760
    __END__;
4761
}
4762
4763
bool GlFuncTab_QT::isGlContextInitialized() const
4764
{
4765
    return initialized;
4766
}
4767
4768
void OpenGlViewPort::initializeGL()
4769
{
4770
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
4771
4772
#ifdef Q_WS_WIN
4773
    std::auto_ptr<GlFuncTab_QT> qglFuncTab(new GlFuncTab_QT(getDC()));
4774
#else
4775
    std::auto_ptr<GlFuncTab_QT> qglFuncTab(new GlFuncTab_QT);
4776
#endif
4777
4778
    // Load extensions
4779
4780
    qglFuncTab->glGenBuffersExt = (PFNGLGENBUFFERSPROC)context()->getProcAddress("glGenBuffers");
4781
    qglFuncTab->glDeleteBuffersExt = (PFNGLDELETEBUFFERSPROC)context()->getProcAddress("glDeleteBuffers");
4782
    qglFuncTab->glBufferDataExt = (PFNGLBUFFERDATAPROC)context()->getProcAddress("glBufferData");
4783
    qglFuncTab->glBufferSubDataExt = (PFNGLBUFFERSUBDATAPROC)context()->getProcAddress("glBufferSubData");
4784
    qglFuncTab->glBindBufferExt = (PFNGLBINDBUFFERPROC)context()->getProcAddress("glBindBuffer");
4785
    qglFuncTab->glMapBufferExt = (PFNGLMAPBUFFERPROC)context()->getProcAddress("glMapBuffer");
4786
    qglFuncTab->glUnmapBufferExt = (PFNGLUNMAPBUFFERPROC)context()->getProcAddress("glUnmapBuffer");
4787
4788
    qglFuncTab->initialized = true;
4789
4790
    glFuncTab = qglFuncTab.release();
4791
4792
    icvSetOpenGlFuncTab(glFuncTab);
4793
}
4794
4795
void OpenGlViewPort::resizeGL(int w, int h)
4796
{
4797
    glViewport(0, 0, w, h);
4798
}
4799
4800
void OpenGlViewPort::paintGL()
4801
{
4802
    icvSetOpenGlFuncTab(glFuncTab);
4803
4804
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4805
4806
    if (glDrawCallback)
4807
        glDrawCallback(glDrawData);
4808
4809
    CV_CheckGlError();
4810
}
4811
4812
void OpenGlViewPort::mousePressEvent(QMouseEvent* evnt)
4813
{
4814
    int cv_event = -1, flags = 0;
4815
    QPoint pt = evnt->pos();
4816
4817
    icvmouseHandler(evnt, mouse_down, cv_event, flags);
4818
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4819
4820
    QGLWidget::mousePressEvent(evnt);
4821
}
4822
4823
4824
void OpenGlViewPort::mouseReleaseEvent(QMouseEvent* evnt)
4825
{
4826
    int cv_event = -1, flags = 0;
4827
    QPoint pt = evnt->pos();
4828
4829
    icvmouseHandler(evnt, mouse_up, cv_event, flags);
4830
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4831
4832
    QGLWidget::mouseReleaseEvent(evnt);
4833
}
4834
4835
4836
void OpenGlViewPort::mouseDoubleClickEvent(QMouseEvent* evnt)
4837
{
4838
    int cv_event = -1, flags = 0;
4839
    QPoint pt = evnt->pos();
4840
4841
    icvmouseHandler(evnt, mouse_dbclick, cv_event, flags);
4842
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4843
4844
    QGLWidget::mouseDoubleClickEvent(evnt);
4845
}
4846
4847
4848
void OpenGlViewPort::mouseMoveEvent(QMouseEvent* evnt)
4849
{
4850
    int cv_event = CV_EVENT_MOUSEMOVE, flags = 0;
4851
    QPoint pt = evnt->pos();
4852
4853
    //icvmouseHandler: pass parameters for cv_event, flags
4854
    icvmouseHandler(evnt, mouse_move, cv_event, flags);
4855
    icvmouseProcessing(QPointF(pt), cv_event, flags);
4856
4857
    QGLWidget::mouseMoveEvent(evnt);
4858
}
4859
4860
void OpenGlViewPort::icvmouseHandler(QMouseEvent* evnt, type_mouse_event category, int& cv_event, int& flags)
4861
{
4862
    Qt::KeyboardModifiers modifiers = evnt->modifiers();
4863
    Qt::MouseButtons buttons = evnt->buttons();
4864
4865
    flags = 0;
4866
    if (modifiers & Qt::ShiftModifier)
4867
        flags |= CV_EVENT_FLAG_SHIFTKEY;
4868
    if (modifiers & Qt::ControlModifier)
4869
        flags |= CV_EVENT_FLAG_CTRLKEY;
4870
    if (modifiers & Qt::AltModifier)
4871
        flags |= CV_EVENT_FLAG_ALTKEY;
4872
4873
    if (buttons & Qt::LeftButton)
4874
        flags |= CV_EVENT_FLAG_LBUTTON;
4875
    if (buttons & Qt::RightButton)
4876
        flags |= CV_EVENT_FLAG_RBUTTON;
4877
    if (buttons & Qt::MidButton)
4878
        flags |= CV_EVENT_FLAG_MBUTTON;
4879
4880
    cv_event = CV_EVENT_MOUSEMOVE;
4881
    switch (evnt->button())
4882
    {
4883
    case Qt::LeftButton:
4884
        cv_event = tableMouseButtons[category][0];
4885
        flags |= CV_EVENT_FLAG_LBUTTON;
4886
        break;
4887
4888
    case Qt::RightButton:
4889
        cv_event = tableMouseButtons[category][1];
4890
        flags |= CV_EVENT_FLAG_RBUTTON;
4891
        break;
4892
4893
    case Qt::MidButton:
4894
        cv_event = tableMouseButtons[category][2];
4895
        flags |= CV_EVENT_FLAG_MBUTTON;
4896
        break;
4897
4898
    default:
4899
        ;
4900
    }
4901
}
4902
4903
4904
void OpenGlViewPort::icvmouseProcessing(QPointF pt, int cv_event, int flags)
4905
{
4906
    if (mouseCallback)
4907
        mouseCallback(cv_event, pt.x(), pt.y(), flags, mouseData);
4908
}
4909
4910
4911
QSize OpenGlViewPort::sizeHint() const
4912
{
4913
    if (size.width() > 0 && size.height() > 0)
4914
        return size;
4915
4916
    return QGLWidget::sizeHint();
4917
}
4918
4919
void OpenGlViewPort::setSize(QSize size_)
4920
{
4921
    size = size_;
4922
    updateGeometry();
4923
}
4924
4925
#endif
4926
4927
4928
#endif // HAVE_QT