[vlc-commits] [Git][videolan/vlc][master] 9 commits: qt/hotkeys: remove unused attribute

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Thu Mar 3 18:44:00 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
c3297e9a by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: remove unused attribute

- - - - -
8a779cf7 by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: clean up event filter

The `aTable` variable was unnecessary - we check that `obj` equals
`table`, so we can just use `table` rather than making a cast of `obj`.

Also, much cleaner with a switch block.

- - - - -
de622afa by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: reorganise hotkey item handling

Moving the bit that adds global entries to a list before the rest allows
the rest to be moved out of the condition block.

- - - - -
b576c4d3 by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: remove unnecessary check

Every core hotkey item can be expected to have a shorttext label.

- - - - -
a64bb8da by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: remodel data storage

This is primarily prep for the next commit, where we will need to keep
track of default values.

Essentially this is just implementing a custom `QTreeWidgetItem` like
previously done for the advanced preferences tree.

- - - - -
b34dcd00 by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: add context menu to hotkey editor

This primarily complements !1344 with a means to reset individual hotkey
settings.

Note, just like the existing means of triggering the edit dialog, doing so
on the name column enters edit mode for the normal hotkey assignment.

- - - - -
d503d77a by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: remove reundant instructions from label

We now have a context menu. Trying to open a context menu should be the
natural action to take in looking for potential hidden functionality. It is
thus now less necessary to give instructions to help users find a way to
perform editing.

- - - - -
ecefc817 by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: highlight modified assignments

Complementing such highlighting done in the new 'expert' preferences
interface (see !1344).

The name field is highlighted if either of the normal or global assignments
differ from their defaults.

- - - - -
6eab1792 by Lyndon Brown at 2022-03-03T18:17:05+00:00
qt/hotkeys: properly apply row padding

Adding padding was the goal in specifying a row height here. Doing it
via a style sheet seems to be the proper way.

The height with this solution is roughly equivalent.

- - - - -


2 changed files:

- modules/gui/qt/dialogs/preferences/preferences_widgets.cpp
- modules/gui/qt/dialogs/preferences/preferences_widgets.hpp


Changes:

=====================================
modules/gui/qt/dialogs/preferences/preferences_widgets.cpp
=====================================
@@ -47,7 +47,6 @@
 #include <QFileDialog>
 #include <QGroupBox>
 #include <QTreeWidget>
-#include <QTreeWidgetItem>
 #include <QTreeWidgetItemIterator>
 #include <QDialogButtonBox>
 #include <QKeyEvent>
@@ -61,12 +60,14 @@
 #include <QSpinBox>
 #include <QPushButton>
 #include <QFontComboBox>
+#include <QMenu>
+#include <QGuiApplication>
+#include <QClipboard>
+#include <QFont>
 
 #define MINWIDTH_BOX 90
 #define LAST_COLUMN 10
 
-#define HOTKEY_ITEM_HEIGHT 24
-
 QString formatTooltip(const QString & tooltip)
 {
     QString text = tooltip;
@@ -1201,9 +1202,7 @@ void FloatRangeConfigControl::finish()
  **********************************************************************/
 KeySelectorControl::KeySelectorControl( QWidget *p ) : ConfigControl( nullptr )
 {
-    label = new QLabel(
-        qtr( "Action hotkey mappings. Double-click (or select and press Enter) "
-             "to change an action's hotkey. The delete key will unset." ), p );
+    label = new QLabel( qtr( "Action hotkey mappings." ), p );
 
     label->setWordWrap( true );
     searchLabel = new QLabel( qtr( "Search" ), p );
@@ -1225,6 +1224,7 @@ KeySelectorControl::KeySelectorControl( QWidget *p ) : ConfigControl( nullptr )
     table->headerItem()->setToolTip( GLOBAL_HOTKEY_COL, qtr( "Desktop level hotkey" ) );
     table->setAlternatingRowColors( true );
     table->setSelectionBehavior( QAbstractItemView::SelectItems );
+    table->setStyleSheet( "QTreeView::item { padding: 5px 0; }" );
 
     table->installEventFilter( this );
 
@@ -1266,16 +1266,6 @@ void KeySelectorControl::buildAppHotkeysList( QWidget *rootWidget )
 
 void KeySelectorControl::finish()
 {
-    /* Fill the table
-
-       Each table row (action) has the following:
-        - Non-global option name stored in data of column 0 (action name) field.
-        - Translated key assignment strings displayed in columns 1 & 2, global
-          and non-global respectively.
-        - Non-translated (stored) key assignment strings stored in data of
-          columns 1 & 2, global and non-global respectively.
-     */
-
     /* Get the main Module */
     module_t *p_main = module_get_main();
     assert( p_main );
@@ -1286,7 +1276,8 @@ void KeySelectorControl::finish()
 
     p_config = module_config_get (p_main, &confsize);
 
-    QMultiMap<QString, QString> global_keys;
+    QList<module_config_t *> global_keys;
+    global_keys.reserve( 112 );
     for (size_t i = 0; i < confsize; i++)
     {
         module_config_t *p_config_item = p_config + i;
@@ -1294,48 +1285,44 @@ void KeySelectorControl::finish()
         if( p_config_item->i_type != CONFIG_ITEM_KEY )
             continue;
 
-        /* If we are a (non-global) key option not empty */
-        if( strncmp( p_config_item->psz_name, "global-", 7 ) != 0 )
-        {
-            QTreeWidgetItem *treeItem = new QTreeWidgetItem();
-            treeItem->setText( ACTION_COL, p_config_item->psz_text ?
-                                           qfut( p_config_item->psz_text ) : qfu("") );
-            treeItem->setData( ACTION_COL, Qt::UserRole,
-                               QVariant( qfu( p_config_item->psz_name ) ) );
-            if (p_config_item->psz_longtext)
-                treeItem->setToolTip( ACTION_COL, qfut(p_config_item->psz_longtext) );
-
-            QString keys = p_config_item->value.psz ? qfut(p_config_item->value.psz) : qfu("");
-            treeItem->setText( HOTKEY_COL, keys.replace( "\t", ", " ) );
-            treeItem->setToolTip( HOTKEY_COL, qtr("Double click to change.\nDelete key to remove.") );
-            treeItem->setToolTip( GLOBAL_HOTKEY_COL, qtr("Double click to change.\nDelete key to remove.") );
-            treeItem->setData( HOTKEY_COL, Qt::UserRole, QVariant( p_config_item->value.psz ) );
-            table->addTopLevelItem( treeItem );
-        }
-        /* Capture global key option mappings to fill in afterwards */
-        else if( !EMPTY_STR( p_config_item->value.psz ) )
+        /* Capture global key items to fill in afterwards */
+        if( strncmp( p_config_item->psz_name, "global-", 7 ) == 0 )
         {
-            global_keys.insert( qfu( p_config_item->psz_name + 7 ),
-                                qfu( p_config_item->value.psz ) );
+            global_keys.append( p_config_item );
+            continue;
         }
+
+        KeyTableItem *treeItem = new KeyTableItem();
+        treeItem->normal.config_name = p_config_item->psz_name;
+        treeItem->normal.default_keys = qfu( p_config_item->orig.psz );
+        treeItem->global.config_name = nullptr;
+        treeItem->global.default_keys = qfu( "" );
+
+        treeItem->setText( ACTION_COL, qfut( p_config_item->psz_text ) );
+        if (p_config_item->psz_longtext)
+            treeItem->setToolTip( ACTION_COL, qfut(p_config_item->psz_longtext) );
+
+        treeItem->set_keys( p_config_item->value.psz, HOTKEY_COL );
+        treeItem->setToolTip( HOTKEY_COL, qtr("Double click to change.\nDelete key to remove.") );
+        treeItem->setToolTip( GLOBAL_HOTKEY_COL, qtr("Double click to change.\nDelete key to remove.") );
+
+        table->addTopLevelItem( treeItem );
     }
 
-    QMap<QString, QString>::const_iterator i = global_keys.constBegin();
-    while (i != global_keys.constEnd())
+    for (int i = 0; i < global_keys.count(); i++)
     {
         for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
         {
-            QTreeWidgetItem *item = *iter;
+            KeyTableItem *item = static_cast<KeyTableItem *>( *iter );
 
-            if( item->data( ACTION_COL, Qt::UserRole ) == i.key() )
+            if( strcmp( item->normal.config_name, global_keys[i]->psz_name + 7 ) == 0 )
             {
-                QString keys = i.value();
-                item->setText( GLOBAL_HOTKEY_COL, qfut(qtu(keys)).replace( "\t", ", " ) );
-                item->setData( GLOBAL_HOTKEY_COL, Qt::UserRole, keys );
+                item->global.config_name = global_keys[i]->psz_name;
+                item->global.default_keys = qfu( global_keys[i]->orig.psz );
+                item->set_keys( global_keys[i]->value.psz, GLOBAL_HOTKEY_COL );
                 break;
             }
         }
-        ++i;
     }
 
     module_config_free (p_config);
@@ -1344,9 +1331,9 @@ void KeySelectorControl::finish()
     table->resizeColumnToContents( HOTKEY_COL );
 
     table->setUniformRowHeights( true );
-    table->topLevelItem(0)->setSizeHint( 0, QSize( 0, HOTKEY_ITEM_HEIGHT ) );
 
-    connect( table, &QTreeWidget::itemActivated, this, &KeySelectorControl::selectKey );
+    connect( table, &QTreeWidget::itemActivated,
+             this, QOverload<QTreeWidgetItem *, int>::of(&KeySelectorControl::selectKey) );
 }
 
 void KeySelectorControl::changeVisibility( bool visible )
@@ -1381,22 +1368,26 @@ void KeySelectorControl::filter()
     }
 }
 
-void KeySelectorControl::selectKey( QTreeWidgetItem *keyItem, int column )
+void KeySelectorControl::selectKey( QTreeWidgetItem *item, int column )
+{
+    selectKey( static_cast<KeyTableItem *>( item ), (enum ColumnIndex) column );
+}
+
+void KeySelectorControl::selectKey( KeyTableItem *item, enum ColumnIndex column )
 {
     /* This happens when triggered by ClickEater */
-    if( keyItem == NULL ) keyItem = table->currentItem();
+    if( item == NULL )
+        item = static_cast<KeyTableItem *>( table->currentItem() );
 
     /* This can happen when nothing is selected on the treeView
        and the shortcutValue is clicked */
-    if( !keyItem ) return;
+    if( !item ) return;
 
     /* If clicked on the first column, assuming user wants the normal hotkey */
     if( column == ACTION_COL ) column = HOTKEY_COL;
 
-    bool b_global = ( column == GLOBAL_HOTKEY_COL );
-
     /* Launch a small dialog to ask for a new key */
-    KeyInputDialog *d = new KeyInputDialog( table, keyItem, b_global );
+    KeyInputDialog *d = new KeyInputDialog( table, item, column );
     d->setExistingkeysSet( &existingkeys );
     d->exec();
 
@@ -1404,30 +1395,12 @@ void KeySelectorControl::selectKey( QTreeWidgetItem *keyItem, int column )
     {
         /* In case of conflict, reset other keys*/
         if( d->conflicts )
-        {
-            for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
-            {
-                QTreeWidgetItem *it = *iter;
-                if( keyItem == it )
-                    continue;
-                QStringList it_keys = it->data( column, Qt::UserRole ).toString().split( "\t" );
-                if( it_keys.removeAll( d->vlckey ) )
-                {
-                    QString it_filteredkeys = it_keys.join( "\t" );
-                    it->setText( column, it_filteredkeys.replace( "\t", ", " ) );
-                    it->setData( column, Qt::UserRole, it_filteredkeys );
-                }
-            }
-        }
-
-        keyItem->setText( column, d->vlckey_tr );
-        keyItem->setData( column, Qt::UserRole, d->vlckey );
+            reassign_key( item, d->vlckey, column );
+        else
+            item->set_keys( d->vlckey, column );
     }
     else if( d->result() == 2 )
-    {
-        keyItem->setText( column, NULL );
-        keyItem->setData( column, Qt::UserRole, QVariant() );
-    }
+        unset( item, column );
 
     delete d;
 }
@@ -1436,67 +1409,278 @@ void KeySelectorControl::doApply()
 {
     for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
     {
-        QTreeWidgetItem *it = *iter;
-
-        QString option = it->data( ACTION_COL, Qt::UserRole ).toString();
-
-        config_PutPsz( qtu( option ),
-                       qtu( it->data( HOTKEY_COL, Qt::UserRole ).toString() ) );
+        KeyTableItem *item = static_cast<KeyTableItem *>( *iter );
 
-        config_PutPsz( qtu( "global-" + option ),
-                       qtu( it->data( GLOBAL_HOTKEY_COL, Qt::UserRole ).toString() ) );
+        config_PutPsz( item->normal.config_name, qtu( item->normal.keys ) );
+        config_PutPsz( item->global.config_name, qtu( item->global.keys ) );
     }
 }
 
 bool KeySelectorControl::eventFilter( QObject *obj, QEvent *e )
 {
+#ifndef QT_NO_CONTEXTMENU
+    if( obj == table && e->type() == QEvent::ContextMenu )
+    {
+        tableContextMenuEvent( static_cast<QContextMenuEvent*>(e) );
+        return true;
+    }
+#endif
+
     if( obj != table || e->type() != QEvent::KeyPress )
         return ConfigControl::eventFilter(obj, e);
 
-    QKeyEvent *keyEv = static_cast<QKeyEvent*>(e);
-    QTreeWidget *aTable = static_cast<QTreeWidget *>(obj);
-    if( keyEv->key() == Qt::Key_Escape )
+    switch( static_cast<QKeyEvent*>(e)->key() )
     {
-        aTable->clearFocus();
-        return true;
+        case Qt::Key_Escape:
+            table->clearFocus();
+            return true;
+
+        case Qt::Key_Return:
+        case Qt::Key_Enter:
+            selectKey( table->currentItem(), table->currentColumn() );
+            return true;
+
+        case Qt::Key_Delete:
+            if( table->currentColumn() != ACTION_COL )
+                unset( table->currentItem(), table->currentColumn() );
+            return true;
+
+        default:
+            return false;
     }
-    else if( keyEv->key() == Qt::Key_Return ||
-             keyEv->key() == Qt::Key_Enter )
+}
+
+#ifndef QT_NO_CONTEXTMENU
+void KeySelectorControl::tableContextMenuEvent( QContextMenuEvent *event )
+{
+    KeyTableItem *item = static_cast<KeyTableItem *>( this->table->currentItem() );
+    if( !item || item->isHidden() )
+        return;
+    /* Avoid menu from right-click on empty space after last item */
+    if( event->reason() == QContextMenuEvent::Mouse &&
+        !this->table->itemAt( this->table->viewport()->mapFromGlobal( event->globalPos() ) ) )
+        return;
+
+    enum ColumnIndex column = (enum ColumnIndex) this->table->currentColumn();
+
+    bool empty;
+    bool matches_default;
+    switch ( column )
     {
-        selectKey( aTable->currentItem(), aTable->currentColumn() );
-        return true;
+        case ACTION_COL:
+            empty = (item->normal.keys.isEmpty() && item->global.keys.isEmpty());
+            matches_default = (item->normal.matches_default && item->normal.matches_default);
+            break;
+        case HOTKEY_COL:
+            empty = item->normal.keys.isEmpty();
+            matches_default = item->normal.matches_default;
+            break;
+        case GLOBAL_HOTKEY_COL:
+            empty = item->global.keys.isEmpty();
+            matches_default = item->global.matches_default;
+            break;
+        default:
+            unreachable();
     }
-    else if( keyEv->key() == Qt::Key_Delete )
+
+    QMenu *menu = new QMenu();
+    menu->setAttribute(Qt::WA_DeleteOnClose);
+
+    QAction *modify = new QAction( qtr( "&Modify" ), this->table );
+    connect( modify, &QAction::triggered, [=]() { this->selectKey( item, column ); } );
+    menu->addAction( modify );
+
+    if( column != ACTION_COL )
     {
-        if( aTable->currentColumn() != ACTION_COL )
-        {
-            aTable->currentItem()->setText( aTable->currentColumn(), NULL );
-            aTable->currentItem()->setData( aTable->currentColumn(), Qt::UserRole, QVariant() );
-        }
-        return true;
+        QAction *copy = new QAction( qtr( "&Copy value" ), this->table );
+        if( empty )
+            copy->setEnabled( false );
+        else
+            connect( copy, &QAction::triggered, [=]() {
+                this->copy_value( item, column );
+            } );
+        menu->addAction( copy );
     }
+
+    QAction *unset = new QAction( qtr( "&Unset" ), this->table );
+    if( empty )
+        unset->setEnabled( false );
+    else
+        connect( unset, &QAction::triggered, [=]() { this->unset( item, column ); } );
+    menu->addAction( unset );
+
+    QAction *reset = new QAction( qtr( "&Reset" ), this->table );
+    if( matches_default )
+        reset->setEnabled( false );
     else
-        return false;
+        connect( reset, &QAction::triggered, [=]() {
+            if( column != ACTION_COL )
+                this->reset( item, column );
+            else
+            {
+                this->reset( item, HOTKEY_COL );
+                this->reset( item, GLOBAL_HOTKEY_COL );
+            }
+        } );
+    menu->addAction( reset );
+
+    QString reset_all_label = (column == ACTION_COL) ? qtr( "Reset &all" )
+                                                     : qtr( "Reset &all (column)" );
+    QAction *reset_all = new QAction( reset_all_label, this->table );
+    connect( reset_all, &QAction::triggered, [=]() { this->reset_all( column ); } );
+    menu->addAction( reset_all );
+
+    menu->popup( event->globalPos() );
+}
+#endif // QT_NO_CONTEXTMENU
+
+void KeySelectorControl::unset( QTreeWidgetItem *item, int column )
+{
+    unset( static_cast<KeyTableItem*>( item ), (enum ColumnIndex) column );
+}
+
+void KeySelectorControl::unset( KeyTableItem *item,
+                                enum KeySelectorControl::ColumnIndex column )
+{
+    if( item == nullptr )
+        return;
+    if( column == ACTION_COL )
+        column = HOTKEY_COL;
+    item->set_keys( nullptr, column );
 }
 
+void KeySelectorControl::reset( KeyTableItem *item,
+                                enum KeySelectorControl::ColumnIndex column )
+{
+    QString item_default = item->get_default_keys( column );
+    KeyTableItem *conflict = find_conflict( table, item_default, item, column );
+    if( conflict != nullptr )
+    {
+        KeyConflictDialog *dialog = new KeyConflictDialog( this->table, conflict, column );
+        dialog->exec();
+        if( dialog->result() == QDialog::Accepted )
+            reassign_key( item, item_default, column );
+        delete dialog;
+    }
+    else
+        item->set_keys( item_default, column );
+}
+
+void KeySelectorControl::reset_all( enum KeySelectorControl::ColumnIndex column )
+{
+    for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
+    {
+        KeyTableItem *item = static_cast<KeyTableItem *>( *iter );
+        if( column != GLOBAL_HOTKEY_COL )
+            item->set_keys( item->get_default_keys( HOTKEY_COL ), HOTKEY_COL );
+        if( column != HOTKEY_COL )
+            item->set_keys( item->get_default_keys( GLOBAL_HOTKEY_COL ), GLOBAL_HOTKEY_COL );
+    }
+}
+
+void KeySelectorControl::reassign_key( KeyTableItem *item, QString key,
+                                       enum KeySelectorControl::ColumnIndex column )
+{
+    for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
+    {
+        KeyTableItem *iter_item = static_cast<KeyTableItem *>( *iter );
+        if( iter_item != item )
+            iter_item->remove_key( key, column );
+    }
+    item->set_keys( key, column );
+}
+
+void KeySelectorControl::copy_value( KeyTableItem *item,
+                                     enum KeySelectorControl::ColumnIndex column )
+{
+    QClipboard *clipboard = QGuiApplication::clipboard();
+    clipboard->setText( item->get_keys( column ) );
+}
+
+KeyTableItem * KeySelectorControl::find_conflict( QTreeWidget *table, QString key,
+                                                  KeyTableItem *ignore_item,
+                                                  enum KeySelectorControl::ColumnIndex column )
+{
+    if( key.isEmpty() )
+        return nullptr;
+    for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
+    {
+        KeyTableItem *item = static_cast<KeyTableItem *>( *iter );
+
+        if( item == ignore_item )
+            continue;
+
+        if( item->contains_key( key, column ) )
+            return item;
+    }
+    return nullptr;
+}
+
+const QString &KeyTableItem::get_keys( enum KeySelectorControl::ColumnIndex column )
+{
+    if( column == KeySelectorControl::GLOBAL_HOTKEY_COL )
+        return global.keys;
+    return normal.keys;
+}
+
+QString KeyTableItem::get_default_keys( enum KeySelectorControl::ColumnIndex column )
+{
+    if( column == KeySelectorControl::GLOBAL_HOTKEY_COL )
+        return global.default_keys;
+    return normal.default_keys;
+}
+
+void KeyTableItem::set_keys( QString keys, enum KeySelectorControl::ColumnIndex column )
+{
+    bool matches_default;
+    if( column == KeySelectorControl::GLOBAL_HOTKEY_COL )
+    {
+        global.keys = keys;
+        matches_default = global.matches_default = ( keys == global.default_keys );
+    }
+    else
+    {
+        normal.keys = keys;
+        matches_default = normal.matches_default = ( keys ==  normal.default_keys );
+    }
+    setText( column, keys.replace( "\t", ", " ) );
+    QFont font = this->font( KeySelectorControl::ACTION_COL );
+    font.setWeight( matches_default ? QFont::Weight::Normal : QFont::Weight::Bold );
+    setFont( column,  font );
+    matches_default = (normal.matches_default && global.matches_default);
+    font.setWeight( matches_default ? QFont::Weight::Normal : QFont::Weight::Bold );
+    setFont( KeySelectorControl::ACTION_COL,  font );
+}
+
+bool KeyTableItem::contains_key( QString key, enum KeySelectorControl::ColumnIndex column )
+{
+    return get_keys( column ).split( "\t" ).contains( key );
+}
+
+void KeyTableItem::remove_key( QString key, enum KeySelectorControl::ColumnIndex column )
+{
+    QStringList keys_list = get_keys( column ).split( "\t" );
+    if( keys_list.removeAll( key ) )
+        set_keys( keys_list.join( "\t" ), column );
+}
 
 /**
  * Class KeyInputDialog
  **/
-KeyInputDialog::KeyInputDialog( QTreeWidget *_table,
-                                QTreeWidgetItem * _keyItem,
-                                bool b_global ) :
-                                QDialog( _table ), table( _table ), keyItem( _keyItem )
+KeyInputDialog::KeyInputDialog( QTreeWidget *table_,
+                                KeyTableItem * keyItem_,
+                                enum KeySelectorControl::ColumnIndex column_ ) :
+                                QDialog( table_ ), table( table_ ),
+                                keyItem( keyItem_ ), column( column_ )
 {
     setModal( true );
     conflicts = false;
     existingkeys = NULL;
 
-    column = b_global ? KeySelectorControl::GLOBAL_HOTKEY_COL
-                      : KeySelectorControl::HOTKEY_COL;
+    bool global = ( column == KeySelectorControl::GLOBAL_HOTKEY_COL );
 
-    setWindowTitle( b_global ? qtr( "Global Hotkey change" )
-                             : qtr( "Hotkey change" ) );
+    setWindowTitle( global ? qtr( "Global Hotkey change" )
+                           : qtr( "Hotkey change" ) );
     setWindowRole( "vlc-key-input" );
 
     QVBoxLayout *vLayout = new QVBoxLayout( this );
@@ -1543,19 +1727,12 @@ void KeyInputDialog::checkForConflicts( const QString &sequence )
         return;
     }
 
-    for (QTreeWidgetItemIterator iter(table); *iter; ++iter)
+    KeyTableItem *conflict = KeySelectorControl::find_conflict( table, vlckey, keyItem, column );
+    if( conflict != nullptr )
     {
-        QTreeWidgetItem *item = *iter;
-
-        if( item == keyItem )
-            continue;
-
-        if( !item->data( column, Qt::UserRole ).toString().split( "\t" ).contains( vlckey ) )
-            continue;
-
         warning->setText(
                 qtr("Warning: this key or combination is already assigned to \"<b>%1</b>\"")
-                .arg( item->text( KeySelectorControl::ACTION_COL ) ) );
+                .arg( conflict->text( KeySelectorControl::ACTION_COL ) ) );
         warning->show();
         ok->show();
         unset->hide();
@@ -1607,3 +1784,35 @@ void KeyInputDialog::wheelEvent( QWheelEvent *e )
 }
 
 void KeyInputDialog::unsetAction() { done( 2 ); }
+
+KeyConflictDialog::KeyConflictDialog( QTreeWidget *table, KeyTableItem * item,
+                                      enum KeySelectorControl::ColumnIndex column ) :
+                                      QDialog( table )
+{
+    setModal( true );
+
+    bool global = ( column == KeySelectorControl::GLOBAL_HOTKEY_COL );
+
+    setWindowTitle( global ? qtr( "Global Hotkey assignment conflict" )
+                           : qtr( "Hotkey assignment conflict" ) );
+    setWindowRole( "vlc-key-conflict" );
+
+    QVBoxLayout *vLayout = new QVBoxLayout( this );
+    QLabel *warning = new QLabel;
+    warning->setText(
+            qtr("Warning: this key or combination is already assigned to \"<b>%1</b>\"")
+            .arg( item->text( KeySelectorControl::ACTION_COL ) ) );
+    vLayout->addWidget( warning , Qt::AlignCenter );
+
+    QDialogButtonBox *buttonBox = new QDialogButtonBox;
+    QPushButton *force = new QPushButton( qtr("Assign") );
+    QPushButton *cancel = new QPushButton( qtr("Cancel") );
+    buttonBox->addButton( force, QDialogButtonBox::AcceptRole );
+    buttonBox->addButton( cancel, QDialogButtonBox::RejectRole );
+    force->setDefault( true );
+
+    vLayout->addWidget( buttonBox );
+
+    connect( buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
+    connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
+}


=====================================
modules/gui/qt/dialogs/preferences/preferences_widgets.hpp
=====================================
@@ -32,13 +32,14 @@
 #include "qt.hpp"
 #include <assert.h>
 
+#include <QTreeWidgetItem>
 #include <QLabel>
 #include <QDialog>
 #include <QSet>
+#include <QContextMenuEvent>
 
 class QWidget;
 class QTreeWidget;
-class QTreeWidgetItem;
 class QGroupBox;
 class QGridLayout;
 class QBoxLayout;
@@ -395,6 +396,8 @@ void setfillVLCConfigCombo(const char *configname, QComboBox *combo );
 /**********************************************************************
  * Key selector widget
  **********************************************************************/
+class KeyTableItem;
+
 class KeySelectorControl : public ConfigControl
 {
     Q_OBJECT
@@ -409,13 +412,26 @@ public:
         GLOBAL_HOTKEY_COL = 2,
         ANY_COL = 3 // == count()
     };
+    static KeyTableItem *find_conflict( QTreeWidget *, QString, KeyTableItem *, enum ColumnIndex );
 
 protected:
     bool eventFilter( QObject *, QEvent * ) Q_DECL_OVERRIDE;
+#ifndef QT_NO_CONTEXTMENU
+    void tableContextMenuEvent( QContextMenuEvent * );
+#endif
     void changeVisibility( bool ) Q_DECL_OVERRIDE;
     void fillGrid( QGridLayout*, int ) Q_DECL_OVERRIDE;
+    void unset( KeyTableItem *, enum ColumnIndex );
+    void unset( QTreeWidgetItem *, int );
+    void reset( KeyTableItem *, enum ColumnIndex );
+    void reset_all( enum KeySelectorControl::ColumnIndex column );
+    /** Reassign key to specified item */
+    void reassign_key( KeyTableItem *item, QString keys,
+                       enum KeySelectorControl::ColumnIndex column );
+    void copy_value( KeyTableItem *, enum KeySelectorControl::ColumnIndex );
 
 private:
+    void selectKey( KeyTableItem *, enum ColumnIndex );
     void buildAppHotkeysList( QWidget *rootWidget );
     void finish();
     QLabel *label;
@@ -424,20 +440,44 @@ private:
     QComboBox *searchOption;
     QLabel *searchOptionLabel;
     QTreeWidget *table;
-    QList<module_config_t *> values;
     QSet<QString> existingkeys;
 
 private slots:
-    void selectKey( QTreeWidgetItem * = NULL, int column = 1 );
+    void selectKey( QTreeWidgetItem *, int );
     void filter();
 };
 
+struct KeyItemAttr
+{
+    const char *config_name;
+    QString default_keys;
+    QString keys;
+    bool matches_default;
+};
+
+class KeyTableItem : public QTreeWidgetItem
+{
+public:
+    KeyTableItem() {}
+    const QString &get_keys( enum KeySelectorControl::ColumnIndex );
+    QString get_default_keys( enum KeySelectorControl::ColumnIndex );
+    void set_keys( QString, enum KeySelectorControl::ColumnIndex );
+    void set_keys( const char *keys, enum KeySelectorControl::ColumnIndex column )
+    {
+        set_keys( (keys) ? qfut( keys ) : qfu( "" ), column );
+    }
+    bool contains_key( QString, enum KeySelectorControl::ColumnIndex );
+    void remove_key( QString, enum KeySelectorControl::ColumnIndex );
+    struct KeyItemAttr normal;
+    struct KeyItemAttr global;
+};
+
 class KeyInputDialog : public QDialog
 {
     Q_OBJECT
 
 public:
-    KeyInputDialog( QTreeWidget *, QTreeWidgetItem *, bool b_global = false );
+    KeyInputDialog( QTreeWidget *, KeyTableItem *, enum KeySelectorControl::ColumnIndex );
     bool conflicts;
     QString vlckey, vlckey_tr;
     void setExistingkeysSet( const QSet<QString> *keyset = NULL );
@@ -446,7 +486,7 @@ private:
     QTreeWidget *table;
     QLabel *selected, *warning;
     QPushButton *ok, *unset;
-    QTreeWidgetItem *keyItem;
+    KeyTableItem *keyItem;
     enum KeySelectorControl::ColumnIndex column;
 
     void checkForConflicts( const QString &sequence );
@@ -457,4 +497,12 @@ private:
 private slots:
     void unsetAction();
 };
+
+class KeyConflictDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    KeyConflictDialog( QTreeWidget *, KeyTableItem *, enum KeySelectorControl::ColumnIndex );
+};
 #endif



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4671cfb4255fa28e6319e44fe886dedec7fad8ce...6eab1792ba5e484d27f157b922b1749c4a6d20b6

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4671cfb4255fa28e6319e44fe886dedec7fad8ce...6eab1792ba5e484d27f157b922b1749c4a6d20b6
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list