toolbar.cpp 25.6 KB
Newer Older
1
/*****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
2
 * ToolbarEdit.cpp : ToolbarEdit dialog
3
 ****************************************************************************
4
 * Copyright (C) 2008-2009 the VideoLAN team
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "dialogs/toolbar.hpp"

#include "util/input_slider.hpp"
#include "util/customwidgets.hpp"
#include "components/interface_widgets.hpp"

#include <QScrollArea>
#include <QGroupBox>
#include <QLabel>
#include <QComboBox>
#include <QListWidget>

#include <QDragEnterEvent>
41
#include <QDialogButtonBox>
42
#include <QInputDialog>
43

44
45
ToolbarEditDialog::ToolbarEditDialog( QWidget *_w, intf_thread_t *_p_intf)
                  : QVLCDialog( _w,  _p_intf )
46
{
47
    setWindowTitle( qtr( "Toolbars Editor" ) );
48
49
    QGridLayout *mainLayout = new QGridLayout( this );
    setMinimumWidth( 600 );
50
    setAttribute( Qt::WA_DeleteOnClose );
51
52

    /* main GroupBox */
Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
53
    QGroupBox *widgetBox = new QGroupBox( qtr( "Toolbar Elements") , this );
54
55
56
57
    widgetBox->setSizePolicy( QSizePolicy::Preferred,
                              QSizePolicy::MinimumExpanding );
    QGridLayout *boxLayout = new QGridLayout( widgetBox );

58
    QLabel *styleLabel = new QLabel( qtr( "Next widget style:" ) );
59
60
61
    flatBox = new QCheckBox( qtr( "Flat Button" ) );
    bigBox = new QCheckBox( qtr( "Big Button" ) );
    shinyBox = new QCheckBox( qtr( "Native Slider" ) );
62
63

    boxLayout->addWidget( new WidgetListing( p_intf, this ), 0, 0, 1, -1);
64
65
66
    boxLayout->addWidget( styleLabel, 1, 0 );
    boxLayout->addWidget( flatBox, 1, 1 );
    boxLayout->addWidget( bigBox, 1, 2 );
67
68
    boxLayout->addWidget( shinyBox, 2, 1 );
    mainLayout->addWidget( widgetBox, 0, 0, 5, 1 );
69
70
71


    /* Main ToolBar */
Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
72
    QGroupBox *mainToolbarBox = new QGroupBox( qtr( "Main Toolbar" ), this );
73
74
    QGridLayout *mainTboxLayout = new QGridLayout( mainToolbarBox );

Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
75
    QLabel *label = new QLabel( qtr( "Toolbar position:" ) );
76
    mainTboxLayout->addWidget(label, 0, 0, 1, 2);
77

78
79
80
    positionCombo = new QComboBox;
    positionCombo->addItem( qtr( "Under the Video" ), QVariant( 0 ) );
    positionCombo->addItem( qtr( "Above the Video" ), QVariant( 1 ) );
81
82
    positionCombo->setCurrentIndex( positionCombo->findData(
                getSettings()->value( "MainWindow/ToolbarPos", 0 ).toInt() ) );
83
    mainTboxLayout->addWidget( positionCombo, 0, 2, 1, 1 );
84

85
    QLabel *line1Label = new QLabel( "Line 1:" );
86
87
    QString line1 = getSettings()->value( "MainWindow/MainToolbar1",
                                          MAIN_TB1_DEFAULT ).toString();
88
    controller1 = new DroppingController( p_intf, line1,
89
            this );
90
91
    mainTboxLayout->addWidget( line1Label, 1, 0, 1, 1 );
    mainTboxLayout->addWidget( controller1, 1, 1, 1, 2 );
92

93
    QLabel *line2Label = new QLabel( "Line 2:" );
94
95
    QString line2 = getSettings()->value( "MainWindow/MainToolbar2",
                                          MAIN_TB2_DEFAULT ).toString();
96
    controller2 = new DroppingController( p_intf, line2,
97
            this );
98
99
100
101
    mainTboxLayout->addWidget( line2Label, 2, 0, 1, 1 );
    mainTboxLayout->addWidget( controller2, 2, 1, 1, 2);

    /* Advanced ToolBar */
Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
102
    QLabel *advLabel = new QLabel( qtr( "Advanced Widget toolbar:" ) );
103
104
    QString lineA = getSettings()->value( "MainWindow/AdvToolbar",
                                          ADV_TB_DEFAULT ).toString();
105
    controllerA = new DroppingController( p_intf, lineA,
106
107
108
            this );
    mainTboxLayout->addWidget( advLabel, 3, 0, 1, 2 );
    mainTboxLayout->addWidget( controllerA, 3, 2, 1, 1 );
109

110
    mainLayout->addWidget( mainToolbarBox, 0, 1, 1, -1 );
111
112

    /* TimeToolBar */
Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
113
    QGroupBox *timeToolbarBox = new QGroupBox( qtr( "Time Toolbar" ) , this );
114
115
    QGridLayout *timeTboxLayout = new QGridLayout( timeToolbarBox );

116
117
    QString line = getSettings()->value( "MainWindow/InputToolbar",
                                         INPT_TB_DEFAULT ).toString();
118
    controller = new DroppingController( p_intf, line,
119
120
121
            this );
    timeTboxLayout->addWidget( controller, 0, 0, 1, -1 );

122
    mainLayout->addWidget( timeToolbarBox, 1, 1, 1, -1 );
123
124

    /* FSCToolBar */
Christophe Mutricy's avatar
i18n    
Christophe Mutricy committed
125
126
    QGroupBox *FSCToolbarBox = new QGroupBox( qtr( "Fullscreen Controller" ),
                                              this );
127
128
    QGridLayout *FSCTboxLayout = new QGridLayout( FSCToolbarBox );

129
130
    QString lineFSC = getSettings()->value( "MainWindow/FSCtoolbar",
                                            FSC_TB_DEFAULT ).toString();
131
    controllerFSC = new DroppingController( p_intf,
132
133
134
            lineFSC, this );
    FSCTboxLayout->addWidget( controllerFSC, 0, 0, 1, -1 );

135
    mainLayout->addWidget( FSCToolbarBox, 2, 1, 1, -1 );
136

137
138
139
140
141
142
143
144
145
146
    /* Profile */
    QGroupBox *profileBox = new QGroupBox( qtr( "Profile" ), this );
    QGridLayout *profileBoxLayout = new QGridLayout( profileBox );

    profileCombo = new QComboBox;
    QLabel *profileLabel = new QLabel( qtr( "Select profile:" ), this );

    QToolButton *newButton = new QToolButton;
    newButton->setIcon( QIcon( ":/new" ) );
    QToolButton *deleteButton = new QToolButton;
147
    deleteButton->setIcon( QIcon( ":/toolbar/clear" ) );
148
149
150
151
152
153
154
    deleteButton->setToolTip( qtr( "Delete the current profile" ) );

    profileBoxLayout->addWidget( profileLabel, 0, 0 );
    profileBoxLayout->addWidget( profileCombo, 0, 1 );
    profileBoxLayout->addWidget( newButton, 0, 2 );
    profileBoxLayout->addWidget( deleteButton, 0, 3 );

155
    mainLayout->addWidget( profileBox, 3, 1, 1, -1 );
156
157
158
159
160
161
162
163
164
165

    /* Fill combos */
    int i_size = getSettings()->beginReadArray( "ToolbarProfiles" );
    for( int i = 0; i < i_size; i++ )
    {
        getSettings()->setArrayIndex(i);
        profileCombo->addItem( getSettings()->value( "ProfileName" ).toString(),
                               getSettings()->value( "Value" ).toString() );
    }
    getSettings()->endArray();
166
167
168
169
170
171
172
173
174
175
176

    /* Load defaults ones if we have no combos */
    /* We could decide that we load defaults on first launch of the dialog
       or when the combo is back to 0. I choose the second solution, because some clueless
       user might hit on delete a bit too much, but discussion is opened. -- jb */
    if( i_size == 0 )
    {
        profileCombo->addItem( PROFILE_NAME_1, QString( VALUE_1 ) );
        profileCombo->addItem( PROFILE_NAME_2, QString( VALUE_2 ) );
        profileCombo->addItem( PROFILE_NAME_3, QString( VALUE_3 ) );
        profileCombo->addItem( PROFILE_NAME_4, QString( VALUE_4 ) );
177
        profileCombo->addItem( PROFILE_NAME_5, QString( VALUE_5 ) );
178
    }
179
180
    profileCombo->setCurrentIndex( -1 );

181
182
183
    /* Buttons */
    QDialogButtonBox *okCancel = new QDialogButtonBox;
    QPushButton *okButton = new QPushButton( qtr( "Cl&ose" ), this );
184
    okButton->setDefault( true );
185
186
187
    QPushButton *cancelButton = new QPushButton( qtr( "&Cancel" ), this );
    okCancel->addButton( okButton, QDialogButtonBox::AcceptRole );
    okCancel->addButton( cancelButton, QDialogButtonBox::RejectRole );
188

189
190
191
    BUTTONACT( deleteButton, deleteProfile() );
    BUTTONACT( newButton, newProfile() );
    CONNECT( profileCombo, currentIndexChanged( int ), this, changeProfile( int ) );
192
193
    BUTTONACT( okButton, close() );
    BUTTONACT( cancelButton, cancel() );
194
    mainLayout->addWidget( okCancel, 5, 2 );
195
196
197
198
199
}


ToolbarEditDialog::~ToolbarEditDialog()
{
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    getSettings()->beginWriteArray( "ToolbarProfiles" );
    for( int i = 0; i < profileCombo->count(); i++ )
    {
        getSettings()->setArrayIndex(i);
        getSettings()->setValue( "ProfileName", profileCombo->itemText( i ) );
        getSettings()->setValue( "Value", profileCombo->itemData( i ) );
    }
    getSettings()->endArray();
}

void ToolbarEditDialog::newProfile()
{
    bool ok;
    QString name =  QInputDialog::getText( this, qtr( "Profile Name" ),
                 qtr( "Please enter the new profile name." ), QLineEdit::Normal, 0, &ok );
    if( !ok ) return;

    QString temp = QString::number( positionCombo->currentIndex() );
    temp += "|" + controller1->getValue();
    temp += "|" + controller2->getValue();
    temp += "|" + controllerA->getValue();
    temp += "|" + controller->getValue();
    temp += "|" + controllerFSC->getValue();

    profileCombo->addItem( name, temp );
    profileCombo->setCurrentIndex( profileCombo->count() - 1 );
}

void ToolbarEditDialog::deleteProfile()
{
    profileCombo->removeItem( profileCombo->currentIndex() );
}

void ToolbarEditDialog::changeProfile( int i )
{
    QStringList qs_list = profileCombo->itemData( i ).toString().split( "|" );
    if( qs_list.count() < 6 )
        return;

    positionCombo->setCurrentIndex( positionCombo->findData( qs_list[0].toInt() ) );
    controller1->resetLine( qs_list[1] );
    controller2->resetLine( qs_list[2] );
    controllerA->resetLine( qs_list[3] );
    controller->resetLine( qs_list[4] );
    controllerFSC->resetLine( qs_list[5] );
245
246
}

247
248
249
void ToolbarEditDialog::close()
{
    msg_Dbg( p_intf, "Close and save" );
250
251
    getSettings()->setValue( "MainWindow/ToolbarPos",
            positionCombo->itemData( positionCombo->currentIndex() ).toInt() );
252
253
254
255
256
    getSettings()->setValue( "MainWindow/MainToolbar1", controller1->getValue() );
    getSettings()->setValue( "MainWindow/MainToolbar2", controller2->getValue() );
    getSettings()->setValue( "MainWindow/AdvToolbar", controllerA->getValue() );
    getSettings()->setValue( "MainWindow/InputToolbar", controller->getValue() );
    getSettings()->setValue( "MainWindow/FSCtoolbar", controllerFSC->getValue() );
257
258
    getSettings()->sync();
    accept();
259
260
261
262
}

void ToolbarEditDialog::cancel()
{
263
    reject();
264
265
}

266
267
268
269
/************************************************
 *  Widget Listing:
 * Creation of the list of drawed lovely buttons
 ************************************************/
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
WidgetListing::WidgetListing( intf_thread_t *p_intf, QWidget *_parent )
              : QListWidget( _parent )
{
    /* We need the parent to know the options checked */
    parent = qobject_cast<ToolbarEditDialog *>(_parent);
    assert( parent );

    /* Normal options */
    setViewMode( QListView::IconMode );
    setSpacing( 20 );
    setDragEnabled( true );

    /* All the buttons do not need a special rendering */
    for( int i = 0; i < BUTTON_MAX; i++ )
    {
        QListWidgetItem *widgetItem = new QListWidgetItem( this );
Christophe Mutricy's avatar
Christophe Mutricy committed
286
        widgetItem->setText( qtr( nameL[i] ) );
287
288
289
290
291
292
        widgetItem->setIcon( QIcon( iconL[i] ) );
        widgetItem->setData( Qt::UserRole, QVariant( i ) );
        addItem( widgetItem );
    }

    /* Spacers are yet again a different thing */
293
    QListWidgetItem *widgetItem = new QListWidgetItem( QIcon( ":/toolbar/space" ),
294
295
296
297
            qtr( "Spacer" ), this );
    widgetItem->setData( Qt::UserRole, WIDGET_SPACER );
    addItem( widgetItem );

298
    widgetItem = new QListWidgetItem( QIcon( ":/toolbar/space" ),
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
            qtr( "Expanding Spacer" ), this );
    widgetItem->setData( Qt::UserRole, WIDGET_SPACER_EXTEND );
    addItem( widgetItem );

    /**
     * For all other widgets, we create then, do a pseudo rendering in
     * a pixmaps for the view, and delete the object
     *
     * A lot of code is retaken from the Abstract, but not exactly...
     * So, rewrite.
     * They are better ways to deal with this, but I doubt that this is
     * necessary. If you feel like you have the time, be my guest.
     * --
     * jb
     **/
    for( int i = SPLITTER; i < SPECIAL_MAX; i++ )
    {
        QWidget *widget = NULL;
        QListWidgetItem *widgetItem = new QListWidgetItem( this );
        switch( i )
        {
        case SPLITTER:
            {
                QFrame *line = new QFrame( this );
                line->setFrameShape( QFrame::VLine );
                line->setFrameShadow( QFrame::Raised );
                line->setLineWidth( 0 ); line->setMidLineWidth( 1 );
                widget = line;
            }
            widgetItem->setText( qtr("Splitter") );
            break;
        case INPUT_SLIDER:
            {
                InputSlider *slider = new InputSlider( Qt::Horizontal, this );
                widget = slider;
            }
            widgetItem->setText( qtr("Time Slider") );
            break;
        case VOLUME:
            {
339
340
                SoundWidget *snd = new SoundWidget( this, p_intf,
                        parent->getOptions() & WIDGET_SHINY );
341
342
343
344
                widget = snd;
            }
            widgetItem->setText( qtr("Volume") );
            break;
345
346
347
        case VOLUME_SPECIAL:
            {
                QListWidgetItem *widgetItem = new QListWidgetItem( this );
Eric Lassauge's avatar
Eric Lassauge committed
348
                widgetItem->setText( qtr("Small Volume") );
349
                widgetItem->setIcon( QIcon( ":/toolbar/volume-medium" ) );
350
351
352
353
                widgetItem->setData( Qt::UserRole, QVariant( i ) );
                addItem( widgetItem );
            }
            continue;
354
355
356
357
358
359
360
361
362
363
        case TIME_LABEL:
            {
                QLabel *timeLabel = new QLabel( "12:42/2:12:42", this );
                widget = timeLabel;
            }
            widgetItem->setText( qtr("Time") );
            break;
        case MENU_BUTTONS:
            {
                QWidget *discFrame = new QWidget( this );
364
                //discFrame->setLineWidth( 1 );
365
366
367
368
                QHBoxLayout *discLayout = new QHBoxLayout( discFrame );
                discLayout->setSpacing( 0 ); discLayout->setMargin( 0 );

                QToolButton *prevSectionButton = new QToolButton( discFrame );
369
                prevSectionButton->setIcon( QIcon( ":/toolbar/dvd_prev" ) );
370
371
372
                discLayout->addWidget( prevSectionButton );

                QToolButton *menuButton = new QToolButton( discFrame );
373
                menuButton->setIcon( QIcon( ":/toolbar/dvd_menu" ) );
374
375
376
                discLayout->addWidget( menuButton );

                QToolButton *nextButton = new QToolButton( discFrame );
377
                nextButton->setIcon( QIcon( ":/toolbar/dvd_next" ) );
378
379
380
381
382
383
384
385
386
387
388
389
390
                discLayout->addWidget( nextButton );

                widget = discFrame;
            }
            widgetItem->setText( qtr("DVD menus") );
            break;
        case TELETEXT_BUTTONS:
            {
                QWidget *telexFrame = new QWidget( this );
                QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame );
                telexLayout->setSpacing( 0 ); telexLayout->setMargin( 0 );

                QToolButton *telexOn = new QToolButton( telexFrame );
391
                telexOn->setIcon( QIcon( ":/toolbar/tv" ) );
392
393
394
                telexLayout->addWidget( telexOn );

                QToolButton *telexTransparent = new QToolButton;
395
                telexOn->setIcon( QIcon( ":/toolbar/tvtelx" ) );
396
397
398
399
400
401
402
403
404
405
406
                telexLayout->addWidget( telexTransparent );

                QSpinBox *telexPage = new QSpinBox;
                telexLayout->addWidget( telexPage );

                widget = telexFrame;
            }
            widgetItem->setText( qtr("Teletext") );
            break;
        case ADVANCED_CONTROLLER:
            {
407
                AdvControlsWidget *advControls = new AdvControlsWidget( p_intf, this );
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
                widget = advControls;
            }
            widgetItem->setText( qtr("Advanced Buttons") );
            break;
        default:
            msg_Warn( p_intf, "This should not happen %i", i );
            break;
        }

        if( widget == NULL ) continue;


        widgetItem->setIcon( QIcon( QPixmap::grabWidget( widget ) ) );
        widget->hide();
        widgetItem->setData( Qt::UserRole, QVariant( i ) );

        addItem( widgetItem );
        delete widget;
    }
}

void WidgetListing::startDrag( Qt::DropActions /*supportedActions*/ )
{
431
    QListWidgetItem *item = currentItem();
432
433
434
435
436
437
438
439

    QByteArray itemData;
    QDataStream dataStream( &itemData, QIODevice::WriteOnly );

    int i_type = item->data( Qt::UserRole ).toInt();
    int i_option = parent->getOptions();
    dataStream << i_type << i_option;

440
441
442
443
    /* Create a new dragging event */
    QDrag *drag = new QDrag( this );

    /* With correct mimedata */
444
445
446
    QMimeData *mimeData = new QMimeData;
    mimeData->setData( "vlc/button-bar", itemData );
    drag->setMimeData( mimeData );
447
448

    /* And correct pixmap */
449
450
451
    QPixmap aPixmap = item->icon().pixmap( QSize( 22, 22 ) );
    drag->setPixmap( aPixmap );
    drag->setHotSpot( QPoint( 20, 20 ) );
452

453
454
455
    /* We want to keep a copy */
    drag->exec( Qt::CopyAction | Qt::MoveAction );
}
456

457
458
459
460
461
462
/*
 * The special controller with drag'n drop abilities.
 * We don't do this in the main controller, since we don't want the OverHead
 * to propagate there too
 */
DroppingController::DroppingController( intf_thread_t *_p_intf,
463
                                        const QString& line,
464
                                        QWidget *_parent )
465
                   : AbstractController( _p_intf, _parent )
466
467
{
    rubberband = NULL;
468
    b_draging = false;
469
470
    setAcceptDrops( true );
    controlLayout = new QHBoxLayout( this );
471
    controlLayout->setSpacing( 5 );
472
473
474
475
    controlLayout->setMargin( 0 );
    setFrameShape( QFrame::StyledPanel );
    setFrameShadow( QFrame::Raised );

476
    parseAndCreate( line, controlLayout );
477
478
}

479
void DroppingController::resetLine( const QString& line )
480
481
482
483
484
485
486
487
488
489
490
491
492
493
{
    hide();
    QLayoutItem *child;
    int i =0;
    while( (child = controlLayout->takeAt( 0 ) ) != 0 )
    {
        child->widget()->hide();
        delete child;
    }

    parseAndCreate( line, controlLayout );
    show();
}

494
/* Overloading the AbstractController one, because we don't manage the
495
   Spacing items in the same ways */
496
497
498
499
500
void DroppingController::createAndAddWidget( QBoxLayout *controlLayout,
                                             int i_index,
                                             buttonType_e i_type,
                                             int i_option )
{
501
502
503
504
    doubleInt *value = new doubleInt;
    value->i_type = i_type;
    value->i_option = i_option;

505
506
507
    /* Special case for SPACERS, who aren't QWidgets */
    if( i_type == WIDGET_SPACER || i_type == WIDGET_SPACER_EXTEND )
    {
508
        QLabel *label = new QLabel( this );
509
        label->setPixmap( QPixmap( ":/toolbar/space" ) );
510
511
512
513
        if( i_type == WIDGET_SPACER_EXTEND )
        {
            label->setSizePolicy( QSizePolicy::MinimumExpanding,
                    QSizePolicy::Preferred );
514
515
516
517
518

            /* Create a box around it */
            label->setFrameStyle( QFrame::Panel | QFrame::Sunken );
            label->setLineWidth ( 1 );
            label->setAlignment( Qt::AlignCenter );
519
520
521
522
523
        }
        else
            label->setSizePolicy( QSizePolicy::Fixed,
                    QSizePolicy::Preferred );

524
525
        /* Install event Filter for drag'n drop */
        label->installEventFilter( this );
526
527
        controlLayout->insertWidget( i_index, label );
    }
528
529

    /* Normal Widgets */
530
531
532
533
534
    else
    {
        QWidget *widg = createWidget( i_type, i_option );
        if( !widg ) return;

535
        /* Install the Event Filter in order to catch the drag */
536
        widg->setParent( this );
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
        widg->installEventFilter( this );

        /* We are in a complex widget, we need to stop events on children too */
        if( i_type >= VOLUME && i_type < SPECIAL_MAX )
        {
            QList<QObject *>children = widg->children();

            QObject *child;
            foreach( child, children )
            {
                QWidget *childWidg;
                if( childWidg = qobject_cast<QWidget *>( child ) )
                {
                    child->installEventFilter( this );
                    childWidg->setEnabled( true );
                }
            }

            /* Decorating the frames when possible */
            QFrame *frame;
            if( i_type >= MENU_BUTTONS  /* Don't bother to check for volume */
                && ( frame = qobject_cast<QFrame *>( widg ) ) != NULL )
            {
                frame->setFrameStyle( QFrame::Panel | QFrame::Raised );
                frame->setLineWidth ( 1 );
            }
        }

565
566
        /* Some Widgets are deactivated at creation */
        widg->setEnabled( true );
567
        widg->show();
568
569
        controlLayout->insertWidget( i_index, widg );
    }
570

571
    /* QList and QBoxLayout don't act the same with insert() */
572
    if( i_index < 0 ) i_index = controlLayout->count() - 1;
573
574
575
576

    widgetList.insert( i_index, value );
}

577
578
579
580
581
582
DroppingController::~DroppingController()
{
    qDeleteAll( widgetList );
    widgetList.clear();
}

583
584
585
586
587
588
589
590
591
592
593
594
595
596
QString DroppingController::getValue()
{
    QString qs = "";

    for( int i = 0; i < controlLayout->count(); i++ )
    {
        doubleInt *dI = widgetList.at( i );
        assert( dI );

        qs.append( QString::number( dI->i_type ) );
        if( dI->i_option ) qs.append( "-" + QString::number( dI->i_option ) );
        qs.append( ';' );
    }
    return qs;
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
}

void DroppingController::dragEnterEvent( QDragEnterEvent * event )
{
    if( event->mimeData()->hasFormat( "vlc/button-bar" ) )
        event->accept();
    else
        event->ignore();
}

void DroppingController::dragMoveEvent( QDragMoveEvent *event )
{
    QPoint origin = event->pos();

    int i_pos = getParentPosInLayout( origin );
    bool b_end = false;

    /* Both sides of the frame */
    if( i_pos == -1 )
    {
        if( rubberband ) rubberband->hide();
        return;
    }

    /* Last item is special because of underlying items */
    if( i_pos >= controlLayout->count() )
    {
        i_pos--;
        b_end = true;
    }

    /* Query the underlying item for size && middles */
    QLayoutItem *tempItem = controlLayout->itemAt( i_pos ); assert( tempItem );
    QWidget *temp = tempItem->widget(); assert( temp );

    /* Position assignment */
    origin.ry() = 0;
    origin.rx() = temp->x() - 2;

    if( b_end ) origin.rx() += temp->width();

    if( !rubberband )
        rubberband = new QRubberBand( QRubberBand::Line, this );
    rubberband->setGeometry( origin.x(), origin.y(), 4, height() );
    rubberband->show();
}

644
inline int DroppingController::getParentPosInLayout( QPoint point )
645
646
647
648
649
{
    point.ry() = height() / 2 ;
    QPoint origin = mapToGlobal ( point );

    QWidget *tempWidg = QApplication::widgetAt( origin );
650
651
    if( tempWidg == NULL )
        return -1;
652

653
654
    int i = controlLayout->indexOf( tempWidg );
    if( i == -1 )
655
    {
656
657
        i = controlLayout->indexOf( tempWidg->parentWidget() );
        tempWidg = tempWidg->parentWidget();
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
    }

    /* Return the nearest position */
    if( ( point.x() - tempWidg->x()  > tempWidg->width() / 2 ) && i != -1 )
        i++;

    //    msg_Dbg( p_intf, "%i", i);
    return i;
}

void DroppingController::dropEvent( QDropEvent *event )
{
    int i = getParentPosInLayout( event->pos() );

    QByteArray data = event->mimeData()->data( "vlc/button-bar" );
    QDataStream dataStream(&data, QIODevice::ReadOnly);

    int i_option = 0, i_type = 0;
    dataStream >> i_type >> i_option;

    createAndAddWidget( controlLayout, i, (buttonType_e)i_type, i_option );

    /* Hide by precaution, you don't exactly know what could have happened in
       between */
    if( rubberband ) rubberband->hide();
}

void DroppingController::dragLeaveEvent ( QDragLeaveEvent * event )
{
    if( rubberband ) rubberband->hide();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
688
    event->accept();
689
690
691
692
693
}

/**
 * Overloading doAction to block any action
 **/
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
694
695
696
697
void DroppingController::doAction( int i )
{
    VLC_UNUSED( i );
}
698

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
bool DroppingController::eventFilter( QObject *obj, QEvent *event )
{
    switch( event->type() )
    {
        case QEvent::MouseButtonPress:
            b_draging = true;
            return true;
        case QEvent::MouseButtonRelease:
            b_draging = false;
            return true;
        case QEvent::MouseMove:
            {
            if( !b_draging ) return true;
            QWidget *widg = static_cast<QWidget*>(obj);

            QByteArray itemData;
            QDataStream dataStream( &itemData, QIODevice::WriteOnly );

            int i = -1;
            i = controlLayout->indexOf( widg );
            if( i == -1 )
            {
                i = controlLayout->indexOf( widg->parentWidget() );
                widg = widg->parentWidget();
                /* NOTE: be extra-careful Now with widg access */
            }

            if( i == -1 ) return true;
            doubleInt *dI = widgetList.at( i );

            int i_type = dI->i_type;
            int i_option = dI->i_option;
            dataStream << i_type << i_option;

            /* With correct mimedata */
            QMimeData *mimeData = new QMimeData;
            mimeData->setData( "vlc/button-bar", itemData );

            QDrag *drag = new QDrag( widg );
            drag->setMimeData( mimeData );

740
741
742
743
            /* Remove before the drag to not mess DropEvent,
               that will createAndAddWidget */
            widgetList.removeAt( i );

744
745
746
            /* Start the effective drag */
            drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::MoveAction);
            widg->hide();
747
            controlLayout->removeWidget( widg );
748
749
750
751
            b_draging = false;
            }
            return true;

752
        case QEvent::MouseButtonDblClick:
753
754
755
756
757
758
759
760
761
762
763
        case QEvent::EnabledChange:
        case QEvent::Hide:
        case QEvent::HideToParent:
        case QEvent::Move:
        case QEvent::ZOrderChange:
            return true;
        default:
            return false;
    }
}