toolbar.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:26k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ToolbarEdit.cpp : ToolbarEdit and About dialogs
  3.  ****************************************************************************
  4.  * Copyright (C) 2008 the VideoLAN team
  5.  * $Id: 78aab015c460794e1a194cb64ef2dd066f181a0b $
  6.  *
  7.  * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include "dialogs/toolbar.hpp"
  27. #include "util/input_slider.hpp"
  28. #include "util/customwidgets.hpp"
  29. #include "components/interface_widgets.hpp"
  30. #include <QScrollArea>
  31. #include <QGroupBox>
  32. #include <QLabel>
  33. #include <QComboBox>
  34. #include <QListWidget>
  35. #include <QDragEnterEvent>
  36. #include <QDialogButtonBox>
  37. #include <QInputDialog>
  38. ToolbarEditDialog::ToolbarEditDialog( QWidget *_w, intf_thread_t *_p_intf)
  39.                   : QVLCDialog( _w,  _p_intf )
  40. {
  41.     setWindowTitle( qtr( "Toolbars Editor" ) );
  42.     QGridLayout *mainLayout = new QGridLayout( this );
  43.     setMinimumWidth( 600 );
  44.     setAttribute( Qt::WA_DeleteOnClose );
  45.     /* main GroupBox */
  46.     QGroupBox *widgetBox = new QGroupBox( qtr( "Toolbar Elements") , this );
  47.     widgetBox->setSizePolicy( QSizePolicy::Preferred,
  48.                               QSizePolicy::MinimumExpanding );
  49.     QGridLayout *boxLayout = new QGridLayout( widgetBox );
  50.     QLabel *styleLabel = new QLabel( qtr( "Next widget style:" ) );
  51.     flatBox = new QCheckBox( qtr( "Flat Button" ) );
  52.     bigBox = new QCheckBox( qtr( "Big Button" ) );
  53.     shinyBox = new QCheckBox( qtr( "Native Slider" ) );
  54.     boxLayout->addWidget( new WidgetListing( p_intf, this ), 0, 0, 1, -1);
  55.     boxLayout->addWidget( styleLabel, 1, 0 );
  56.     boxLayout->addWidget( flatBox, 1, 1 );
  57.     boxLayout->addWidget( bigBox, 1, 2 );
  58.     boxLayout->addWidget( shinyBox, 2, 1 );
  59.     mainLayout->addWidget( widgetBox, 0, 0, 5, 1 );
  60.     /* Main ToolBar */
  61.     QGroupBox *mainToolbarBox = new QGroupBox( qtr( "Main Toolbar" ), this );
  62.     QGridLayout *mainTboxLayout = new QGridLayout( mainToolbarBox );
  63.     QLabel *label = new QLabel( qtr( "Toolbar position:" ) );
  64.     mainTboxLayout->addWidget(label, 0, 0, 1, 2);
  65.     positionCombo = new QComboBox;
  66.     positionCombo->addItem( qtr( "Under the Video" ), QVariant( 0 ) );
  67.     positionCombo->addItem( qtr( "Above the Video" ), QVariant( 1 ) );
  68.     positionCombo->setCurrentIndex( positionCombo->findData(
  69.                 getSettings()->value( "MainWindow/ToolbarPos", 0 ).toInt() ) );
  70.     mainTboxLayout->addWidget( positionCombo, 0, 2, 1, 1 );
  71.     QLabel *line1Label = new QLabel( "Line 1:" );
  72.     QString line1 = getSettings()->value( "MainWindow/MainToolbar1",
  73.                                           MAIN_TB1_DEFAULT ).toString();
  74.     controller1 = new DroppingController( p_intf, line1,
  75.             this );
  76.     mainTboxLayout->addWidget( line1Label, 1, 0, 1, 1 );
  77.     mainTboxLayout->addWidget( controller1, 1, 1, 1, 2 );
  78.     QLabel *line2Label = new QLabel( "Line 2:" );
  79.     QString line2 = getSettings()->value( "MainWindow/MainToolbar2",
  80.                                           MAIN_TB2_DEFAULT ).toString();
  81.     controller2 = new DroppingController( p_intf, line2,
  82.             this );
  83.     mainTboxLayout->addWidget( line2Label, 2, 0, 1, 1 );
  84.     mainTboxLayout->addWidget( controller2, 2, 1, 1, 2);
  85.     /* Advanced ToolBar */
  86.     QLabel *advLabel = new QLabel( qtr( "Advanced Widget toolbar:" ) );
  87.     QString lineA = getSettings()->value( "MainWindow/AdvToolbar",
  88.                                           ADV_TB_DEFAULT ).toString();
  89.     controllerA = new DroppingController( p_intf, lineA,
  90.             this );
  91.     mainTboxLayout->addWidget( advLabel, 3, 0, 1, 2 );
  92.     mainTboxLayout->addWidget( controllerA, 3, 2, 1, 1 );
  93.     mainLayout->addWidget( mainToolbarBox, 0, 1, 1, -1 );
  94.     /* TimeToolBar */
  95.     QGroupBox *timeToolbarBox = new QGroupBox( qtr( "Time Toolbar" ) , this );
  96.     QGridLayout *timeTboxLayout = new QGridLayout( timeToolbarBox );
  97.     QString line = getSettings()->value( "MainWindow/InputToolbar",
  98.                                          INPT_TB_DEFAULT ).toString();
  99.     controller = new DroppingController( p_intf, line,
  100.             this );
  101.     timeTboxLayout->addWidget( controller, 0, 0, 1, -1 );
  102.     mainLayout->addWidget( timeToolbarBox, 1, 1, 1, -1 );
  103.     /* FSCToolBar */
  104.     QGroupBox *FSCToolbarBox = new QGroupBox( qtr( "Fullscreen Controller" ),
  105.                                               this );
  106.     QGridLayout *FSCTboxLayout = new QGridLayout( FSCToolbarBox );
  107.     QString lineFSC = getSettings()->value( "MainWindow/FSCtoolbar",
  108.                                             FSC_TB_DEFAULT ).toString();
  109.     controllerFSC = new DroppingController( p_intf,
  110.             lineFSC, this );
  111.     FSCTboxLayout->addWidget( controllerFSC, 0, 0, 1, -1 );
  112.     mainLayout->addWidget( FSCToolbarBox, 2, 1, 1, -1 );
  113.     /* Profile */
  114.     QGroupBox *profileBox = new QGroupBox( qtr( "Profile" ), this );
  115.     QGridLayout *profileBoxLayout = new QGridLayout( profileBox );
  116.     profileCombo = new QComboBox;
  117.     QLabel *profileLabel = new QLabel( qtr( "Select profile:" ), this );
  118.     QToolButton *newButton = new QToolButton;
  119.     newButton->setIcon( QIcon( ":/new" ) );
  120.     QToolButton *deleteButton = new QToolButton;
  121.     deleteButton->setIcon( QIcon( ":/clear" ) );
  122.     deleteButton->setToolTip( qtr( "Delete the current profile" ) );
  123.     profileBoxLayout->addWidget( profileLabel, 0, 0 );
  124.     profileBoxLayout->addWidget( profileCombo, 0, 1 );
  125.     profileBoxLayout->addWidget( newButton, 0, 2 );
  126.     profileBoxLayout->addWidget( deleteButton, 0, 3 );
  127.     mainLayout->addWidget( profileBox, 3, 1, 1, -1 );
  128.     /* Fill combos */
  129.     int i_size = getSettings()->beginReadArray( "ToolbarProfiles" );
  130.     for( int i = 0; i < i_size; i++ )
  131.     {
  132.         getSettings()->setArrayIndex(i);
  133.         profileCombo->addItem( getSettings()->value( "ProfileName" ).toString(),
  134.                                getSettings()->value( "Value" ).toString() );
  135.     }
  136.     getSettings()->endArray();
  137.     /* Load defaults ones if we have no combos */
  138.     /* We could decide that we load defaults on first launch of the dialog
  139.        or when the combo is back to 0. I choose the second solution, because some clueless
  140.        user might hit on delete a bit too much, but discussion is opened. -- jb */
  141.     if( i_size == 0 )
  142.     {
  143.         profileCombo->addItem( PROFILE_NAME_1, QString( VALUE_1 ) );
  144.         profileCombo->addItem( PROFILE_NAME_2, QString( VALUE_2 ) );
  145.         profileCombo->addItem( PROFILE_NAME_3, QString( VALUE_3 ) );
  146.         profileCombo->addItem( PROFILE_NAME_4, QString( VALUE_4 ) );
  147.         profileCombo->addItem( PROFILE_NAME_5, QString( VALUE_5 ) );
  148.     }
  149.     profileCombo->setCurrentIndex( -1 );
  150.     /* Buttons */
  151.     QDialogButtonBox *okCancel = new QDialogButtonBox;
  152.     QPushButton *okButton = new QPushButton( qtr( "Cl&ose" ), this );
  153.     okButton->setDefault( true );
  154.     QPushButton *cancelButton = new QPushButton( qtr( "&Cancel" ), this );
  155.     okCancel->addButton( okButton, QDialogButtonBox::AcceptRole );
  156.     okCancel->addButton( cancelButton, QDialogButtonBox::RejectRole );
  157.     BUTTONACT( deleteButton, deleteProfile() );
  158.     BUTTONACT( newButton, newProfile() );
  159.     CONNECT( profileCombo, currentIndexChanged( int ), this, changeProfile( int ) );
  160.     BUTTONACT( okButton, close() );
  161.     BUTTONACT( cancelButton, cancel() );
  162.     mainLayout->addWidget( okCancel, 5, 2 );
  163. }
  164. ToolbarEditDialog::~ToolbarEditDialog()
  165. {
  166.     getSettings()->beginWriteArray( "ToolbarProfiles" );
  167.     for( int i = 0; i < profileCombo->count(); i++ )
  168.     {
  169.         getSettings()->setArrayIndex(i);
  170.         getSettings()->setValue( "ProfileName", profileCombo->itemText( i ) );
  171.         getSettings()->setValue( "Value", profileCombo->itemData( i ) );
  172.     }
  173.     getSettings()->endArray();
  174. }
  175. void ToolbarEditDialog::newProfile()
  176. {
  177.     bool ok;
  178.     QString name =  QInputDialog::getText( this, qtr( "Profile Name" ),
  179.                  qtr( "Please enter the new profile name." ), QLineEdit::Normal, 0, &ok );
  180.     if( !ok ) return;
  181.     QString temp = QString::number( positionCombo->currentIndex() );
  182.     temp += "|" + controller1->getValue();
  183.     temp += "|" + controller2->getValue();
  184.     temp += "|" + controllerA->getValue();
  185.     temp += "|" + controller->getValue();
  186.     temp += "|" + controllerFSC->getValue();
  187.     profileCombo->addItem( name, temp );
  188.     profileCombo->setCurrentIndex( profileCombo->count() - 1 );
  189. }
  190. void ToolbarEditDialog::deleteProfile()
  191. {
  192.     profileCombo->removeItem( profileCombo->currentIndex() );
  193. }
  194. void ToolbarEditDialog::changeProfile( int i )
  195. {
  196.     QStringList qs_list = profileCombo->itemData( i ).toString().split( "|" );
  197.     if( qs_list.count() < 6 )
  198.         return;
  199.     positionCombo->setCurrentIndex( positionCombo->findData( qs_list[0].toInt() ) );
  200.     controller1->resetLine( qs_list[1] );
  201.     controller2->resetLine( qs_list[2] );
  202.     controllerA->resetLine( qs_list[3] );
  203.     controller->resetLine( qs_list[4] );
  204.     controllerFSC->resetLine( qs_list[5] );
  205. }
  206. void ToolbarEditDialog::close()
  207. {
  208.     msg_Dbg( p_intf, "Close and save" );
  209.     getSettings()->setValue( "MainWindow/ToolbarPos",
  210.             positionCombo->itemData( positionCombo->currentIndex() ).toInt() );
  211.     getSettings()->setValue( "MainWindow/MainToolbar1", controller1->getValue() );
  212.     getSettings()->setValue( "MainWindow/MainToolbar2", controller2->getValue() );
  213.     getSettings()->setValue( "MainWindow/AdvToolbar", controllerA->getValue() );
  214.     getSettings()->setValue( "MainWindow/InputToolbar", controller->getValue() );
  215.     getSettings()->setValue( "MainWindow/FSCtoolbar", controllerFSC->getValue() );
  216.     getSettings()->sync();
  217.     accept();
  218. }
  219. void ToolbarEditDialog::cancel()
  220. {
  221.     reject();
  222. }
  223. /************************************************
  224.  *  Widget Listing:
  225.  * Creation of the list of drawed lovely buttons
  226.  ************************************************/
  227. WidgetListing::WidgetListing( intf_thread_t *p_intf, QWidget *_parent )
  228.               : QListWidget( _parent )
  229. {
  230.     /* We need the parent to know the options checked */
  231.     parent = qobject_cast<ToolbarEditDialog *>(_parent);
  232.     assert( parent );
  233.     /* Normal options */
  234.     setViewMode( QListView::IconMode );
  235.     setSpacing( 20 );
  236.     setDragEnabled( true );
  237.     /* All the buttons do not need a special rendering */
  238.     for( int i = 0; i < BUTTON_MAX; i++ )
  239.     {
  240.         QListWidgetItem *widgetItem = new QListWidgetItem( this );
  241.         widgetItem->setText( qtr( nameL[i] ) );
  242.         widgetItem->setIcon( QIcon( iconL[i] ) );
  243.         widgetItem->setData( Qt::UserRole, QVariant( i ) );
  244.         addItem( widgetItem );
  245.     }
  246.     /* Spacers are yet again a different thing */
  247.     QListWidgetItem *widgetItem = new QListWidgetItem( QIcon( ":/space" ),
  248.             qtr( "Spacer" ), this );
  249.     widgetItem->setData( Qt::UserRole, WIDGET_SPACER );
  250.     addItem( widgetItem );
  251.     widgetItem = new QListWidgetItem( QIcon( ":/space" ),
  252.             qtr( "Expanding Spacer" ), this );
  253.     widgetItem->setData( Qt::UserRole, WIDGET_SPACER_EXTEND );
  254.     addItem( widgetItem );
  255.     /**
  256.      * For all other widgets, we create then, do a pseudo rendering in
  257.      * a pixmaps for the view, and delete the object
  258.      *
  259.      * A lot of code is retaken from the Abstract, but not exactly...
  260.      * So, rewrite.
  261.      * They are better ways to deal with this, but I doubt that this is
  262.      * necessary. If you feel like you have the time, be my guest.
  263.      * --
  264.      * jb
  265.      **/
  266.     for( int i = SPLITTER; i < SPECIAL_MAX; i++ )
  267.     {
  268.         QWidget *widget = NULL;
  269.         QListWidgetItem *widgetItem = new QListWidgetItem( this );
  270.         switch( i )
  271.         {
  272.         case SPLITTER:
  273.             {
  274.                 QFrame *line = new QFrame( this );
  275.                 line->setFrameShape( QFrame::VLine );
  276.                 line->setFrameShadow( QFrame::Raised );
  277.                 line->setLineWidth( 0 ); line->setMidLineWidth( 1 );
  278.                 widget = line;
  279.             }
  280.             widgetItem->setText( qtr("Splitter") );
  281.             break;
  282.         case INPUT_SLIDER:
  283.             {
  284.                 InputSlider *slider = new InputSlider( Qt::Horizontal, this );
  285.                 widget = slider;
  286.             }
  287.             widgetItem->setText( qtr("Time Slider") );
  288.             break;
  289.         case VOLUME:
  290.             {
  291.                 SoundWidget *snd = new SoundWidget( this, p_intf,
  292.                         parent->getOptions() & WIDGET_SHINY );
  293.                 widget = snd;
  294.             }
  295.             widgetItem->setText( qtr("Volume") );
  296.             break;
  297.         case VOLUME_SPECIAL:
  298.             {
  299.                 QListWidgetItem *widgetItem = new QListWidgetItem( this );
  300.                 widgetItem->setText( qtr("Small Volume") );
  301.                 widgetItem->setIcon( QIcon( ":/volume-medium" ) );
  302.                 widgetItem->setData( Qt::UserRole, QVariant( i ) );
  303.                 addItem( widgetItem );
  304.             }
  305.             continue;
  306.         case TIME_LABEL:
  307.             {
  308.                 QLabel *timeLabel = new QLabel( "12:42/2:12:42", this );
  309.                 widget = timeLabel;
  310.             }
  311.             widgetItem->setText( qtr("Time") );
  312.             break;
  313.         case MENU_BUTTONS:
  314.             {
  315.                 QWidget *discFrame = new QWidget( this );
  316.                 //discFrame->setLineWidth( 1 );
  317.                 QHBoxLayout *discLayout = new QHBoxLayout( discFrame );
  318.                 discLayout->setSpacing( 0 ); discLayout->setMargin( 0 );
  319.                 QToolButton *prevSectionButton = new QToolButton( discFrame );
  320.                 prevSectionButton->setIcon( QIcon( ":/dvd_prev" ) );
  321.                 discLayout->addWidget( prevSectionButton );
  322.                 QToolButton *menuButton = new QToolButton( discFrame );
  323.                 menuButton->setIcon( QIcon( ":/dvd_menu" ) );
  324.                 discLayout->addWidget( menuButton );
  325.                 QToolButton *nextButton = new QToolButton( discFrame );
  326.                 nextButton->setIcon( QIcon( ":/dvd_next" ) );
  327.                 discLayout->addWidget( nextButton );
  328.                 widget = discFrame;
  329.             }
  330.             widgetItem->setText( qtr("DVD menus") );
  331.             break;
  332.         case TELETEXT_BUTTONS:
  333.             {
  334.                 QWidget *telexFrame = new QWidget( this );
  335.                 QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame );
  336.                 telexLayout->setSpacing( 0 ); telexLayout->setMargin( 0 );
  337.                 QToolButton *telexOn = new QToolButton( telexFrame );
  338.                 telexOn->setIcon( QIcon( ":/tv" ) );
  339.                 telexLayout->addWidget( telexOn );
  340.                 QToolButton *telexTransparent = new QToolButton;
  341.                 telexOn->setIcon( QIcon( ":/tvtelx" ) );
  342.                 telexLayout->addWidget( telexTransparent );
  343.                 QSpinBox *telexPage = new QSpinBox;
  344.                 telexLayout->addWidget( telexPage );
  345.                 widget = telexFrame;
  346.             }
  347.             widgetItem->setText( qtr("Teletext") );
  348.             break;
  349.         case ADVANCED_CONTROLLER:
  350.             {
  351.                 AdvControlsWidget *advControls = new AdvControlsWidget( p_intf, this );
  352.                 widget = advControls;
  353.             }
  354.             widgetItem->setText( qtr("Advanced Buttons") );
  355.             break;
  356.         default:
  357.             msg_Warn( p_intf, "This should not happen %i", i );
  358.             break;
  359.         }
  360.         if( widget == NULL ) continue;
  361.         widgetItem->setIcon( QIcon( QPixmap::grabWidget( widget ) ) );
  362.         widget->hide();
  363.         widgetItem->setData( Qt::UserRole, QVariant( i ) );
  364.         addItem( widgetItem );
  365.         delete widget;
  366.     }
  367. }
  368. void WidgetListing::startDrag( Qt::DropActions /*supportedActions*/ )
  369. {
  370.     QListWidgetItem *item = currentItem();
  371.     QByteArray itemData;
  372.     QDataStream dataStream( &itemData, QIODevice::WriteOnly );
  373.     int i_type = item->data( Qt::UserRole ).toInt();
  374.     int i_option = parent->getOptions();
  375.     dataStream << i_type << i_option;
  376.     /* Create a new dragging event */
  377.     QDrag *drag = new QDrag( this );
  378.     /* With correct mimedata */
  379.     QMimeData *mimeData = new QMimeData;
  380.     mimeData->setData( "vlc/button-bar", itemData );
  381.     drag->setMimeData( mimeData );
  382.     /* And correct pixmap */
  383.     QPixmap aPixmap = item->icon().pixmap( QSize( 22, 22 ) );
  384.     drag->setPixmap( aPixmap );
  385.     drag->setHotSpot( QPoint( 20, 20 ) );
  386.     /* We want to keep a copy */
  387.     drag->exec( Qt::CopyAction | Qt::MoveAction );
  388. }
  389. /*
  390.  * The special controller with drag'n drop abilities.
  391.  * We don't do this in the main controller, since we don't want the OverHead
  392.  * to propagate there too
  393.  */
  394. DroppingController::DroppingController( intf_thread_t *_p_intf,
  395.                                         const QString& line,
  396.                                         QWidget *_parent )
  397.                    : AbstractController( _p_intf, _parent )
  398. {
  399.     rubberband = NULL;
  400.     b_draging = false;
  401.     setAcceptDrops( true );
  402.     controlLayout = new QHBoxLayout( this );
  403.     controlLayout->setSpacing( 5 );
  404.     controlLayout->setMargin( 0 );
  405.     setFrameShape( QFrame::StyledPanel );
  406.     setFrameShadow( QFrame::Raised );
  407.     parseAndCreate( line, controlLayout );
  408. }
  409. void DroppingController::resetLine( const QString& line )
  410. {
  411.     hide();
  412.     QLayoutItem *child;
  413.     while( (child = controlLayout->takeAt( 0 ) ) != 0 )
  414.     {
  415.         child->widget()->hide();
  416.         delete child;
  417.     }
  418.     parseAndCreate( line, controlLayout );
  419.     show();
  420. }
  421. /* Overloading the AbstractController one, because we don't manage the
  422.    Spacing items in the same ways */
  423. void DroppingController::createAndAddWidget( QBoxLayout *controlLayout,
  424.                                              int i_index,
  425.                                              buttonType_e i_type,
  426.                                              int i_option )
  427. {
  428.     doubleInt *value = new doubleInt;
  429.     value->i_type = i_type;
  430.     value->i_option = i_option;
  431.     /* Special case for SPACERS, who aren't QWidgets */
  432.     if( i_type == WIDGET_SPACER || i_type == WIDGET_SPACER_EXTEND )
  433.     {
  434.         QLabel *label = new QLabel( this );
  435.         label->setPixmap( QPixmap( ":/space" ) );
  436.         if( i_type == WIDGET_SPACER_EXTEND )
  437.         {
  438.             label->setSizePolicy( QSizePolicy::MinimumExpanding,
  439.                     QSizePolicy::Preferred );
  440.             /* Create a box around it */
  441.             label->setFrameStyle( QFrame::Panel | QFrame::Sunken );
  442.             label->setLineWidth ( 1 );
  443.             label->setAlignment( Qt::AlignCenter );
  444.         }
  445.         else
  446.             label->setSizePolicy( QSizePolicy::Fixed,
  447.                     QSizePolicy::Preferred );
  448.         /* Install event Filter for drag'n drop */
  449.         label->installEventFilter( this );
  450.         controlLayout->insertWidget( i_index, label );
  451.     }
  452.     /* Normal Widgets */
  453.     else
  454.     {
  455.         QWidget *widg = createWidget( i_type, i_option );
  456.         if( !widg ) return;
  457.         /* Install the Event Filter in order to catch the drag */
  458.         widg->setParent( this );
  459.         widg->installEventFilter( this );
  460.         /* We are in a complex widget, we need to stop events on children too */
  461.         if( i_type >= VOLUME && i_type < SPECIAL_MAX )
  462.         {
  463.             QList<QObject *>children = widg->children();
  464.             QObject *child;
  465.             foreach( child, children )
  466.             {
  467.                 QWidget *childWidg;
  468.                 if( ( childWidg = qobject_cast<QWidget *>( child ) ) )
  469.                 {
  470.                     child->installEventFilter( this );
  471.                     childWidg->setEnabled( true );
  472.                 }
  473.             }
  474.             /* Decorating the frames when possible */
  475.             QFrame *frame;
  476.             if( i_type >= MENU_BUTTONS  /* Don't bother to check for volume */
  477.                 && ( frame = qobject_cast<QFrame *>( widg ) ) != NULL )
  478.             {
  479.                 frame->setFrameStyle( QFrame::Panel | QFrame::Raised );
  480.                 frame->setLineWidth ( 1 );
  481.             }
  482.         }
  483.         /* Some Widgets are deactivated at creation */
  484.         widg->setEnabled( true );
  485.         widg->show();
  486.         controlLayout->insertWidget( i_index, widg );
  487.     }
  488.     /* QList and QBoxLayout don't act the same with insert() */
  489.     if( i_index < 0 ) i_index = controlLayout->count() - 1;
  490.     widgetList.insert( i_index, value );
  491. }
  492. DroppingController::~DroppingController()
  493. {
  494.     qDeleteAll( widgetList );
  495.     widgetList.clear();
  496. }
  497. QString DroppingController::getValue()
  498. {
  499.     QString qs = "";
  500.     for( int i = 0; i < controlLayout->count(); i++ )
  501.     {
  502.         doubleInt *dI = widgetList.at( i );
  503.         assert( dI );
  504.         qs.append( QString::number( dI->i_type ) );
  505.         if( dI->i_option ) qs.append( "-" + QString::number( dI->i_option ) );
  506.         qs.append( ';' );
  507.     }
  508.     return qs;
  509. }
  510. void DroppingController::dragEnterEvent( QDragEnterEvent * event )
  511. {
  512.     if( event->mimeData()->hasFormat( "vlc/button-bar" ) )
  513.         event->accept();
  514.     else
  515.         event->ignore();
  516. }
  517. void DroppingController::dragMoveEvent( QDragMoveEvent *event )
  518. {
  519.     QPoint origin = event->pos();
  520.     int i_pos = getParentPosInLayout( origin );
  521.     bool b_end = false;
  522.     /* Both sides of the frame */
  523.     if( i_pos == -1 )
  524.     {
  525.         if( rubberband ) rubberband->hide();
  526.         return;
  527.     }
  528.     /* Last item is special because of underlying items */
  529.     if( i_pos >= controlLayout->count() )
  530.     {
  531.         i_pos--;
  532.         b_end = true;
  533.     }
  534.     /* Query the underlying item for size && middles */
  535.     QLayoutItem *tempItem = controlLayout->itemAt( i_pos ); assert( tempItem );
  536.     QWidget *temp = tempItem->widget(); assert( temp );
  537.     /* Position assignment */
  538.     origin.ry() = 0;
  539.     origin.rx() = temp->x() - 2;
  540.     if( b_end ) origin.rx() += temp->width();
  541.     if( !rubberband )
  542.         rubberband = new QRubberBand( QRubberBand::Line, this );
  543.     rubberband->setGeometry( origin.x(), origin.y(), 4, height() );
  544.     rubberband->show();
  545. }
  546. inline int DroppingController::getParentPosInLayout( QPoint point )
  547. {
  548.     point.ry() = height() / 2 ;
  549.     QPoint origin = mapToGlobal ( point );
  550.     QWidget *tempWidg = QApplication::widgetAt( origin );
  551.     if( tempWidg == NULL )
  552.         return -1;
  553.     int i = controlLayout->indexOf( tempWidg );
  554.     if( i == -1 )
  555.     {
  556.         i = controlLayout->indexOf( tempWidg->parentWidget() );
  557.         tempWidg = tempWidg->parentWidget();
  558.     }
  559.     /* Return the nearest position */
  560.     if( ( point.x() - tempWidg->x()  > tempWidg->width() / 2 ) && i != -1 )
  561.         i++;
  562.     //    msg_Dbg( p_intf, "%i", i);
  563.     return i;
  564. }
  565. void DroppingController::dropEvent( QDropEvent *event )
  566. {
  567.     int i = getParentPosInLayout( event->pos() );
  568.     QByteArray data = event->mimeData()->data( "vlc/button-bar" );
  569.     QDataStream dataStream(&data, QIODevice::ReadOnly);
  570.     int i_option = 0, i_type = 0;
  571.     dataStream >> i_type >> i_option;
  572.     createAndAddWidget( controlLayout, i, (buttonType_e)i_type, i_option );
  573.     /* Hide by precaution, you don't exactly know what could have happened in
  574.        between */
  575.     if( rubberband ) rubberband->hide();
  576. }
  577. void DroppingController::dragLeaveEvent ( QDragLeaveEvent * event )
  578. {
  579.     if( rubberband ) rubberband->hide();
  580.     event->accept();
  581. }
  582. /**
  583.  * Overloading doAction to block any action
  584.  **/
  585. void DroppingController::doAction( int i )
  586. {
  587.     VLC_UNUSED( i );
  588. }
  589. bool DroppingController::eventFilter( QObject *obj, QEvent *event )
  590. {
  591.     switch( event->type() )
  592.     {
  593.         case QEvent::MouseButtonPress:
  594.             b_draging = true;
  595.             return true;
  596.         case QEvent::MouseButtonRelease:
  597.             b_draging = false;
  598.             return true;
  599.         case QEvent::MouseMove:
  600.             {
  601.             if( !b_draging ) return true;
  602.             QWidget *widg = static_cast<QWidget*>(obj);
  603.             QByteArray itemData;
  604.             QDataStream dataStream( &itemData, QIODevice::WriteOnly );
  605.             int i = -1;
  606.             i = controlLayout->indexOf( widg );
  607.             if( i == -1 )
  608.             {
  609.                 i = controlLayout->indexOf( widg->parentWidget() );
  610.                 widg = widg->parentWidget();
  611.                 /* NOTE: be extra-careful Now with widg access */
  612.             }
  613.             if( i == -1 ) return true;
  614.             doubleInt *dI = widgetList.at( i );
  615.             int i_type = dI->i_type;
  616.             int i_option = dI->i_option;
  617.             dataStream << i_type << i_option;
  618.             /* With correct mimedata */
  619.             QMimeData *mimeData = new QMimeData;
  620.             mimeData->setData( "vlc/button-bar", itemData );
  621.             QDrag *drag = new QDrag( widg );
  622.             drag->setMimeData( mimeData );
  623.             /* Remove before the drag to not mess DropEvent,
  624.                that will createAndAddWidget */
  625.             widgetList.removeAt( i );
  626.             /* Start the effective drag */
  627.             drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::MoveAction);
  628.             widg->hide();
  629.             controlLayout->removeWidget( widg );
  630.             b_draging = false;
  631.             }
  632.             return true;
  633.         case QEvent::MouseButtonDblClick:
  634.         case QEvent::EnabledChange:
  635.         case QEvent::Hide:
  636.         case QEvent::HideToParent:
  637.         case QEvent::Move:
  638.         case QEvent::ZOrderChange:
  639.             return true;
  640.         default:
  641.             return false;
  642.     }
  643. }