mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-23 16:15:02 +00:00
Merge pull request #873 from sambhav/picard1213
PICARD-1213: Refactor CoverArt and UI options code
This commit is contained in:
34
picard/ui/checkbox_list_item.py
Normal file
34
picard/ui/checkbox_list_item.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2018 Sambhav Kothari
|
||||
#
|
||||
# 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.
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QListWidgetItem
|
||||
|
||||
class CheckboxListItem(QListWidgetItem):
|
||||
|
||||
def __init__(self, text='', checked=False, data=None):
|
||||
super().__init__()
|
||||
self.setText(text)
|
||||
self.setFlags(self.flags() | Qt.ItemIsUserCheckable)
|
||||
self.setCheckState(Qt.Checked if checked else Qt.Unchecked)
|
||||
self.data = data
|
||||
|
||||
@property
|
||||
def checked(self):
|
||||
return self.checkState() == Qt.Checked
|
||||
51
picard/ui/moveable_list_view.py
Normal file
51
picard/ui/moveable_list_view.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2018 Sambhav Kothari
|
||||
#
|
||||
# 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.
|
||||
|
||||
from functools import partial
|
||||
from PyQt5 import QtWidgets, QtCore
|
||||
|
||||
class MoveableListView:
|
||||
|
||||
def __init__(self, list_widget, up_button, down_button, callback=None):
|
||||
self.list_widget = list_widget
|
||||
self.up_button = up_button
|
||||
self.down_button = down_button
|
||||
self.update_callback = callback
|
||||
self.up_button.clicked.connect(partial(self.move_item, 1))
|
||||
self.down_button.clicked.connect(partial(self.move_item, -1))
|
||||
self.list_widget.currentRowChanged.connect(self.update_buttons)
|
||||
self.list_widget.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
|
||||
self.list_widget.setDefaultDropAction(QtCore.Qt.MoveAction)
|
||||
|
||||
def move_item(self, offset):
|
||||
current_index = self.list_widget.currentRow()
|
||||
offset_index = current_index - offset
|
||||
offset_item = self.list_widget.item(offset_index)
|
||||
if offset_item:
|
||||
current_item = self.list_widget.takeItem(current_index)
|
||||
self.list_widget.insertItem(offset_index, current_item)
|
||||
self.list_widget.setCurrentItem(current_item)
|
||||
self.update_buttons()
|
||||
|
||||
def update_buttons(self):
|
||||
current_row = self.list_widget.currentRow()
|
||||
self.up_button.setEnabled(current_row > 0)
|
||||
self.down_button.setEnabled(current_row < self.list_widget.count() - 1)
|
||||
if self.update_callback:
|
||||
self.update_callback()
|
||||
@@ -21,10 +21,8 @@ from picard import config
|
||||
from picard.ui.options import OptionsPage, register_options_page
|
||||
from picard.ui.ui_options_cover import Ui_CoverOptionsPage
|
||||
from picard.coverart.providers import cover_art_providers, is_provider_enabled
|
||||
from picard.ui.sortablecheckboxlist import (
|
||||
SortableCheckboxListWidget,
|
||||
SortableCheckboxListItem
|
||||
)
|
||||
from picard.ui.moveable_list_view import MoveableListView
|
||||
from picard.ui.checkbox_list_item import CheckboxListItem
|
||||
|
||||
|
||||
class CoverOptionsPage(OptionsPage):
|
||||
@@ -56,9 +54,8 @@ class CoverOptionsPage(OptionsPage):
|
||||
self.ui.setupUi(self)
|
||||
self.ui.save_images_to_files.clicked.connect(self.update_filename)
|
||||
self.ui.save_images_to_tags.clicked.connect(self.update_save_images_to_tags)
|
||||
self.provider_list_widget = SortableCheckboxListWidget()
|
||||
self.ui.ca_providers_list.insertWidget(0, self.provider_list_widget)
|
||||
self.ca_providers = []
|
||||
self.move_view = MoveableListView(self.ui.ca_providers_list, self.ui.up_button,
|
||||
self.ui.down_button)
|
||||
|
||||
def load_cover_art_providers(self):
|
||||
"""Load available providers, initialize provider-specific options, restore state of each
|
||||
@@ -70,25 +67,28 @@ class CoverOptionsPage(OptionsPage):
|
||||
except AttributeError:
|
||||
title = provider.NAME
|
||||
checked = is_provider_enabled(provider.NAME)
|
||||
self.provider_list_widget.addItem(SortableCheckboxListItem(title, checked=checked, data=provider.NAME))
|
||||
|
||||
def update_providers_options(items):
|
||||
self.ca_providers = [(item.data, item.checked) for item in items]
|
||||
self.provider_list_widget.changed.connect(update_providers_options)
|
||||
self.ui.ca_providers_list.addItem(CheckboxListItem(title, checked=checked, data=provider.NAME))
|
||||
|
||||
def restore_defaults(self):
|
||||
# Remove previous entries
|
||||
self.provider_list_widget.clear()
|
||||
super().restore_defaults()
|
||||
|
||||
def ca_providers(self):
|
||||
items = []
|
||||
for i in range(self.ui.ca_providers_list.count()):
|
||||
item = self.ui.ca_providers_list.item(i)
|
||||
items.append((item.data, item.checked))
|
||||
return items
|
||||
|
||||
def load(self):
|
||||
self.ui.save_images_to_tags.setChecked(config.setting["save_images_to_tags"])
|
||||
self.ui.cb_embed_front_only.setChecked(config.setting["embed_only_one_front_image"])
|
||||
self.ui.save_images_to_files.setChecked(config.setting["save_images_to_files"])
|
||||
self.ui.cover_image_filename.setText(config.setting["cover_image_filename"])
|
||||
self.ui.save_images_overwrite.setChecked(config.setting["save_images_overwrite"])
|
||||
self.ca_providers = config.setting["ca_providers"]
|
||||
self.load_cover_art_providers()
|
||||
self.ui.ca_providers_list.setCurrentRow(0)
|
||||
self.update_all()
|
||||
|
||||
def save(self):
|
||||
@@ -97,7 +97,7 @@ class CoverOptionsPage(OptionsPage):
|
||||
config.setting["save_images_to_files"] = self.ui.save_images_to_files.isChecked()
|
||||
config.setting["cover_image_filename"] = self.ui.cover_image_filename.text()
|
||||
config.setting["save_images_overwrite"] = self.ui.save_images_overwrite.isChecked()
|
||||
config.setting["ca_providers"] = self.ca_providers
|
||||
config.setting["ca_providers"] = self.ca_providers()
|
||||
|
||||
def update_all(self):
|
||||
self.update_filename()
|
||||
|
||||
@@ -23,6 +23,7 @@ from PyQt5 import QtCore, QtWidgets
|
||||
from PyQt5.QtCore import QStandardPaths
|
||||
from picard import config
|
||||
from picard.util import icontheme
|
||||
from picard.ui.moveable_list_view import MoveableListView
|
||||
from picard.ui.options import OptionsPage, register_options_page
|
||||
from picard.ui.ui_options_interface import Ui_InterfaceOptionsPage
|
||||
from picard.ui.util import enabledSlot
|
||||
@@ -151,11 +152,9 @@ class InterfaceOptionsPage(OptionsPage):
|
||||
self.ui.add_button.clicked.connect(self.add_to_toolbar)
|
||||
self.ui.insert_separator_button.clicked.connect(self.insert_separator)
|
||||
self.ui.remove_button.clicked.connect(self.remove_action)
|
||||
self.ui.up_button.clicked.connect(partial(self.move_item, 1))
|
||||
self.ui.down_button.clicked.connect(partial(self.move_item, -1))
|
||||
self.ui.toolbar_layout_list.currentRowChanged.connect(self.update_buttons)
|
||||
self.ui.toolbar_layout_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
|
||||
self.ui.toolbar_layout_list.setDefaultDropAction(QtCore.Qt.MoveAction)
|
||||
self.move_view = MoveableListView(self.ui.toolbar_layout_list, self.ui.up_button,
|
||||
self.ui.down_button, self.update_action_buttons)
|
||||
self.update_buttons = self.move_view.update_buttons
|
||||
|
||||
def load(self):
|
||||
self.ui.toolbar_show_labels.setChecked(config.setting["toolbar_show_labels"])
|
||||
@@ -234,11 +233,8 @@ class InterfaceOptionsPage(OptionsPage):
|
||||
if name in self.ACTION_NAMES or name == 'separator':
|
||||
self._insert_item(name)
|
||||
|
||||
def update_buttons(self):
|
||||
def update_action_buttons(self):
|
||||
self.ui.add_button.setEnabled(self._added_actions() != self.ACTION_NAMES)
|
||||
current_row = self.ui.toolbar_layout_list.currentRow()
|
||||
self.ui.up_button.setEnabled(current_row > 0)
|
||||
self.ui.down_button.setEnabled(current_row < self.ui.toolbar_layout_list.count() - 1)
|
||||
|
||||
def add_to_toolbar(self):
|
||||
display_list = set.difference(self.ACTION_NAMES, self._added_actions())
|
||||
@@ -252,16 +248,6 @@ class InterfaceOptionsPage(OptionsPage):
|
||||
insert_index = self.ui.toolbar_layout_list.currentRow() + 1
|
||||
self._insert_item('separator', insert_index)
|
||||
|
||||
def move_item(self, offset):
|
||||
current_index = self.ui.toolbar_layout_list.currentRow()
|
||||
offset_index = current_index - offset
|
||||
offset_item = self.ui.toolbar_layout_list.item(offset_index)
|
||||
if offset_item:
|
||||
current_item = self.ui.toolbar_layout_list.takeItem(current_index)
|
||||
self.ui.toolbar_layout_list.insertItem(offset_index, current_item)
|
||||
self.ui.toolbar_layout_list.setCurrentItem(current_item)
|
||||
self.update_buttons()
|
||||
|
||||
def remove_action(self):
|
||||
item = self.ui.toolbar_layout_list.takeItem(self.ui.toolbar_layout_list.currentRow())
|
||||
del item
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2015 Laurent Monin
|
||||
#
|
||||
# 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.
|
||||
|
||||
from functools import partial
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
|
||||
|
||||
class SortableCheckboxListWidget(QtWidgets.QWidget):
|
||||
_CHECKBOX_POS = 0
|
||||
_BUTTON_UP = 1
|
||||
_BUTTON_DOWN = 2
|
||||
|
||||
__no_emit = False
|
||||
changed = pyqtSignal(list)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
layout = QtWidgets.QGridLayout()
|
||||
layout.setHorizontalSpacing(5)
|
||||
layout.setVerticalSpacing(2)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.setLayout(layout)
|
||||
self.__items = []
|
||||
|
||||
def addItems(self, items):
|
||||
for item in items:
|
||||
self.addItem(item)
|
||||
|
||||
def setSignals(self, row):
|
||||
layout = self.layout()
|
||||
checkbox = layout.itemAtPosition(row, self._CHECKBOX_POS).widget()
|
||||
up = layout.itemAtPosition(row, self._BUTTON_UP).widget()
|
||||
down = layout.itemAtPosition(row, self._BUTTON_DOWN).widget()
|
||||
checkbox.stateChanged.connect(partial(self.checkbox_toggled, row))
|
||||
up.clicked.connect(partial(self.move_button_clicked, row, up=True))
|
||||
down.clicked.connect(partial(self.move_button_clicked, row, up=False))
|
||||
|
||||
def moveItem(self, from_row, to_row):
|
||||
to_row = to_row % len(self.__items)
|
||||
self.__items[to_row], self.__items[from_row] = \
|
||||
self.__items[from_row], self.__items[to_row]
|
||||
self.updateRow(to_row)
|
||||
self.updateRow(from_row)
|
||||
self._emit_changed()
|
||||
|
||||
def checkbox_toggled(self, row, state):
|
||||
self.__items[row].setChecked(state == QtCore.Qt.Checked)
|
||||
self._emit_changed()
|
||||
|
||||
def move_button_clicked(self, row, up):
|
||||
if up:
|
||||
to = row - 1
|
||||
else:
|
||||
to = row + 1
|
||||
self.moveItem(row, to)
|
||||
|
||||
def updateRow(self, row):
|
||||
self.__no_emit = True
|
||||
item = self.__items[row]
|
||||
layout = self.layout()
|
||||
checkbox = layout.itemAtPosition(row, self._CHECKBOX_POS).widget()
|
||||
checkbox.setText(item.text)
|
||||
checkbox.setChecked(item.checked)
|
||||
self.__no_emit = False
|
||||
|
||||
def addItem(self, item):
|
||||
self.__items.append(item)
|
||||
row = len(self.__items) - 1
|
||||
layout = self.layout()
|
||||
layout.addWidget(QtWidgets.QCheckBox(), row, self._CHECKBOX_POS)
|
||||
self.updateRow(row)
|
||||
up_button = QtWidgets.QToolButton()
|
||||
up_button.setArrowType(QtCore.Qt.UpArrow)
|
||||
up_button.setMaximumSize(QtCore.QSize(16, 16))
|
||||
down_button = QtWidgets.QToolButton()
|
||||
down_button.setArrowType(QtCore.Qt.DownArrow)
|
||||
down_button.setMaximumSize(QtCore.QSize(16, 16))
|
||||
layout.addWidget(up_button, row, self._BUTTON_UP)
|
||||
layout.addWidget(down_button, row, self._BUTTON_DOWN)
|
||||
self.setSignals(row)
|
||||
|
||||
def _emit_changed(self):
|
||||
if not self.__no_emit:
|
||||
self.changed.emit(self.__items)
|
||||
|
||||
def clear(self):
|
||||
for i in reversed(range(len(self.__items))):
|
||||
self._remove(i)
|
||||
self.__items = []
|
||||
|
||||
def _remove(self, row):
|
||||
self.layout().itemAtPosition(row, self._CHECKBOX_POS).widget().setParent(None)
|
||||
self.layout().itemAtPosition(row, self._BUTTON_UP).widget().setParent(None)
|
||||
self.layout().itemAtPosition(row, self._BUTTON_DOWN).widget().setParent(None)
|
||||
|
||||
|
||||
class SortableCheckboxListItem(object):
|
||||
|
||||
def __init__(self, text='', checked=False, data=None):
|
||||
self._checked = checked
|
||||
self._text = text
|
||||
self._data = data
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self._text
|
||||
|
||||
def setText(self, text):
|
||||
self._text = text
|
||||
|
||||
@property
|
||||
def checked(self):
|
||||
return self._checked
|
||||
|
||||
def setChecked(self, state):
|
||||
self._checked = state
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
return self._data
|
||||
|
||||
def setData(self, data):
|
||||
self._data = data
|
||||
|
||||
def __repr__(self):
|
||||
params = []
|
||||
params.append('text=' + repr(self.text))
|
||||
params.append('checked=' + repr(self.checked))
|
||||
if self.data is not None:
|
||||
params.append('data=' + repr(self.data))
|
||||
return "%s(%s)" % (self.__class__.__name__, ", ".join(params))
|
||||
@@ -45,12 +45,32 @@ class Ui_CoverOptionsPage(object):
|
||||
self.ca_providers_groupbox.setObjectName("ca_providers_groupbox")
|
||||
self.ca_providers_layout = QtWidgets.QVBoxLayout(self.ca_providers_groupbox)
|
||||
self.ca_providers_layout.setObjectName("ca_providers_layout")
|
||||
self.ca_providers_list = QtWidgets.QHBoxLayout()
|
||||
self.ca_providers_list = QtWidgets.QListWidget(self.ca_providers_groupbox)
|
||||
self.ca_providers_list.setObjectName("ca_providers_list")
|
||||
self.ca_providers_layout.addWidget(self.ca_providers_list)
|
||||
self.ca_layout = QtWidgets.QHBoxLayout()
|
||||
self.ca_layout.setObjectName("ca_layout")
|
||||
self.move_label = QtWidgets.QLabel(self.ca_providers_groupbox)
|
||||
self.move_label.setObjectName("move_label")
|
||||
self.ca_layout.addWidget(self.move_label)
|
||||
self.up_button = QtWidgets.QToolButton(self.ca_providers_groupbox)
|
||||
self.up_button.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.up_button.setText("")
|
||||
self.up_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
|
||||
self.up_button.setAutoRaise(False)
|
||||
self.up_button.setArrowType(QtCore.Qt.UpArrow)
|
||||
self.up_button.setObjectName("up_button")
|
||||
self.ca_layout.addWidget(self.up_button)
|
||||
self.down_button = QtWidgets.QToolButton(self.ca_providers_groupbox)
|
||||
self.down_button.setText("")
|
||||
self.down_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
|
||||
self.down_button.setArrowType(QtCore.Qt.DownArrow)
|
||||
self.down_button.setObjectName("down_button")
|
||||
self.ca_layout.addWidget(self.down_button)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.ca_providers_list.addItem(spacerItem)
|
||||
self.ca_providers_layout.addLayout(self.ca_providers_list)
|
||||
self.verticalLayout.addWidget(self.ca_providers_groupbox)
|
||||
self.ca_layout.addItem(spacerItem)
|
||||
self.ca_providers_layout.addLayout(self.ca_layout)
|
||||
self.verticalLayout.addWidget(self.ca_providers_groupbox, 0, QtCore.Qt.AlignTop)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem1)
|
||||
|
||||
@@ -70,4 +90,7 @@ class Ui_CoverOptionsPage(object):
|
||||
self.label_use_filename.setText(_("Use the following file name for images:"))
|
||||
self.save_images_overwrite.setText(_("Overwrite the file if it already exists"))
|
||||
self.ca_providers_groupbox.setTitle(_("Cover Art Providers"))
|
||||
self.move_label.setText(_("Reorder Priority: "))
|
||||
self.up_button.setToolTip(_("Move selected item up"))
|
||||
self.down_button.setToolTip(_("Move selected item down"))
|
||||
|
||||
|
||||
@@ -20,7 +20,16 @@
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -64,7 +73,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QGroupBox" name="ca_providers_groupbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@@ -77,7 +86,55 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="ca_providers_layout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="ca_providers_list">
|
||||
<widget class="QListWidget" name="ca_providers_list"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="ca_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="move_label">
|
||||
<property name="text">
|
||||
<string>Reorder Priority: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="up_button">
|
||||
<property name="toolTip">
|
||||
<string>Move selected item up</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::UpArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="down_button">
|
||||
<property name="toolTip">
|
||||
<string>Move selected item down</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::DownArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
Reference in New Issue
Block a user