mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 10:46:35 +01:00
Merge pull request #657 from ff2000/master
"Switch to tab" for completion popup if suggested url is already loaded in another window/tab
This commit is contained in:
commit
d6ec6f67ff
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,3 +26,4 @@ Thumbs.db
|
||||
tests/modeltest
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.kdev4
|
||||
|
@ -325,7 +325,6 @@ HEADERS += \
|
||||
tools/focusselectlineedit.h \
|
||||
navigation/completer/locationcompleterdelegate.h \
|
||||
navigation/completer/locationcompleter.h \
|
||||
navigation/completer/locationcompletermodel.h \
|
||||
navigation/completer/locationcompleterview.h \
|
||||
history/history.h \
|
||||
history/historymodel.h \
|
||||
|
@ -77,6 +77,7 @@ void LocationCompleter::popupClosed()
|
||||
disconnect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex)));
|
||||
disconnect(s_view, SIGNAL(clicked(QModelIndex)), this, SIGNAL(completionActivated()));
|
||||
disconnect(s_view, SIGNAL(closed()), this, SLOT(popupClosed()));
|
||||
disconnect(s_view, SIGNAL(aboutToActivateTab(TabPosition)), m_locationBar, SLOT(clear()));
|
||||
}
|
||||
|
||||
void LocationCompleter::showPopup()
|
||||
@ -102,6 +103,7 @@ void LocationCompleter::showPopup()
|
||||
connect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex)));
|
||||
connect(s_view, SIGNAL(clicked(QModelIndex)), this, SIGNAL(completionActivated()));
|
||||
connect(s_view, SIGNAL(closed()), this, SLOT(popupClosed()));
|
||||
connect(s_view, SIGNAL(aboutToActivateTab(TabPosition)), m_locationBar, SLOT(clear()));
|
||||
|
||||
adjustPopupSize();
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ LocationCompleterDelegate::LocationCompleterDelegate(LocationCompleterView* pare
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_rowHeight(0)
|
||||
, m_padding(0)
|
||||
, m_drawSwitchToTab(true)
|
||||
, m_view(parent)
|
||||
{
|
||||
}
|
||||
@ -109,8 +110,14 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
|
||||
QRect linkRect(titleRect.x(), infoYPos, titleRect.width(), opt.fontMetrics.height());
|
||||
QString link(opt.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, linkRect.width()));
|
||||
painter->setFont(opt.font);
|
||||
|
||||
TabPosition pos = index.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
|
||||
if(m_drawSwitchToTab && pos.windowIndex != -1) {
|
||||
// TODO: select and paint a nice icon to give better feedback to the user.
|
||||
drawTextLine(linkRect, tr("Switch to tab"), painter, style, opt, colorLinkRole);
|
||||
}
|
||||
else {
|
||||
drawHighlightedTextLine(linkRect, link, searchText, painter, style, opt, colorLinkRole);
|
||||
}
|
||||
|
||||
// Draw line at the very bottom of item if the item is not highlighted
|
||||
if (!(opt.state & QStyle::State_Selected)) {
|
||||
@ -288,3 +295,9 @@ QSize LocationCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, co
|
||||
|
||||
return QSize(200, m_rowHeight);
|
||||
}
|
||||
|
||||
void LocationCompleterDelegate::drawSwitchToTab(bool enable)
|
||||
{
|
||||
m_drawSwitchToTab = enable;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
void drawSwitchToTab(bool enable);
|
||||
|
||||
private:
|
||||
void drawHighlightedTextLine(const QRect &rect, QString text, const QString &searchText,
|
||||
QPainter* painter, const QStyle* style, const QStyleOptionViewItemV4 &option,
|
||||
@ -45,6 +47,7 @@ private:
|
||||
|
||||
mutable int m_rowHeight;
|
||||
mutable int m_padding;
|
||||
bool m_drawSwitchToTab;
|
||||
|
||||
LocationCompleterView* m_view;
|
||||
};
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "iconprovider.h"
|
||||
#include "qzsettings.h"
|
||||
#include "mainapplication.h"
|
||||
#include "qupzilla.h"
|
||||
#include "tabwidget.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
|
||||
@ -70,6 +72,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
|
||||
item->setData(query.value(3), CountRole);
|
||||
item->setData(QVariant(true), BookmarkRole);
|
||||
item->setData(string, SearchStringRole);
|
||||
if(qzSettings->showSwitchTab) {
|
||||
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
|
||||
}
|
||||
|
||||
urlList.append(url);
|
||||
itemList.append(item);
|
||||
@ -93,6 +98,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
|
||||
item->setData(query.value(3), CountRole);
|
||||
item->setData(QVariant(false), BookmarkRole);
|
||||
item->setData(string, SearchStringRole);
|
||||
if(qzSettings->showSwitchTab) {
|
||||
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
|
||||
}
|
||||
|
||||
itemList.append(item);
|
||||
}
|
||||
@ -120,6 +128,9 @@ void LocationCompleterModel::showMostVisited()
|
||||
item->setData(query.value(0), IdRole);
|
||||
item->setData(query.value(2), TitleRole);
|
||||
item->setData(QVariant(false), BookmarkRole);
|
||||
if(qzSettings->showSwitchTab) {
|
||||
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
|
||||
}
|
||||
|
||||
appendRow(item);
|
||||
}
|
||||
@ -186,3 +197,20 @@ QSqlQuery LocationCompleterModel::createQuery(const QString &searchString, const
|
||||
|
||||
return sqlQuery;
|
||||
}
|
||||
|
||||
TabPosition LocationCompleterModel::tabPositionForUrl(const QUrl& url) const
|
||||
{
|
||||
for(int win=0; win < mApp->windowCount(); ++win) {
|
||||
QupZilla* mainWin = mApp->mainWindows().at(win);
|
||||
QList<WebTab*> tabs = mainWin->tabWidget()->allTabs();
|
||||
for(int tab=0; tab < tabs.count(); ++tab) {
|
||||
if(tabs[tab]->url() == url) {
|
||||
TabPosition pos;
|
||||
pos.windowIndex = win;
|
||||
pos.tabIndex = tab;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TabPosition();
|
||||
}
|
||||
|
@ -20,9 +20,21 @@
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class QSqlQuery;
|
||||
class QUrl;
|
||||
|
||||
struct TabPosition {
|
||||
int windowIndex;
|
||||
int tabIndex;
|
||||
TabPosition()
|
||||
: windowIndex(-1)
|
||||
, tabIndex(-1)
|
||||
{}
|
||||
};
|
||||
Q_DECLARE_METATYPE(TabPosition)
|
||||
|
||||
class LocationCompleterModel : public QStandardItemModel
|
||||
{
|
||||
public:
|
||||
@ -31,17 +43,14 @@ public:
|
||||
BookmarkRole = Qt::UserRole + 2,
|
||||
IdRole = Qt::UserRole + 3,
|
||||
SearchStringRole = Qt::UserRole + 4,
|
||||
CountRole = Qt::UserRole + 5
|
||||
CountRole = Qt::UserRole + 5,
|
||||
TabPositionRole = Qt::UserRole + 6
|
||||
};
|
||||
explicit LocationCompleterModel(QObject* parent = 0);
|
||||
|
||||
void refreshCompletions(const QString &string);
|
||||
void showMostVisited();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
HistoryAndBookmarks = 0,
|
||||
@ -52,9 +61,9 @@ private:
|
||||
|
||||
QSqlQuery createQuery(const QString &searchString, const QString &orderBy, const QList<QUrl> &alreadyFound,
|
||||
int limit, bool bookmarks = false, bool exactMatch = false);
|
||||
TabPosition tabPositionForUrl(const QUrl& url) const;
|
||||
|
||||
QString m_lastCompletion;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOCATIONCOMPLETERMODEL_H
|
||||
|
@ -17,8 +17,12 @@
|
||||
* ============================================================ */
|
||||
#include "locationcompleterview.h"
|
||||
#include "locationcompletermodel.h"
|
||||
#include "locationcompleterdelegate.h"
|
||||
#include "mainapplication.h"
|
||||
#include "qupzilla.h"
|
||||
#include "history.h"
|
||||
#include "tabwidget.h"
|
||||
#include "qzsettings.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QApplication>
|
||||
@ -63,6 +67,21 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
|
||||
}
|
||||
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
if(qzSettings->showSwitchTab && !(keyEvent->modifiers() & Qt::ShiftModifier)) {
|
||||
QModelIndex idx = selectionModel()->currentIndex();
|
||||
if(idx.isValid()) {
|
||||
TabPosition pos = idx.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
|
||||
if(pos.windowIndex!= -1) {
|
||||
activateTab(pos);
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_End:
|
||||
case Qt::Key_Home:
|
||||
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
||||
@ -134,12 +153,35 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
|
||||
case Qt::Key_PageUp:
|
||||
case Qt::Key_PageDown:
|
||||
return false;
|
||||
|
||||
case Qt::Key_Shift:
|
||||
// don't switch if there is no hovered or selected index to not disturb typing
|
||||
if(qzSettings->showSwitchTab && (selectionModel()->currentIndex().isValid() || m_hoveredIndex.isValid())) {
|
||||
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(false);
|
||||
viewport()->update();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
} // switch (keyEvent->key())
|
||||
|
||||
(static_cast<QObject*>(focusProxy()))->event(keyEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::KeyRelease: {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
|
||||
switch(keyEvent->key()) {
|
||||
case Qt::Key_Shift:
|
||||
if(qzSettings->showSwitchTab) {
|
||||
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
|
||||
viewport()->update();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case QEvent::Show:
|
||||
m_ignoreNextMouseMove = true;
|
||||
break;
|
||||
@ -170,6 +212,9 @@ void LocationCompleterView::close()
|
||||
|
||||
QListView::hide();
|
||||
verticalScrollBar()->setValue(0);
|
||||
if(qzSettings->showSwitchTab) {
|
||||
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationCompleterView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
@ -203,3 +248,29 @@ void LocationCompleterView::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void LocationCompleterView::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if(qzSettings->showSwitchTab && !(event->modifiers() & Qt::ShiftModifier) && m_hoveredIndex.isValid()) {
|
||||
TabPosition pos = m_hoveredIndex.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
|
||||
if(pos.windowIndex != -1) {
|
||||
event->accept();
|
||||
activateTab(pos);
|
||||
close();
|
||||
}
|
||||
else {
|
||||
QListView::mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
else {
|
||||
QListView::mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationCompleterView::activateTab(TabPosition pos)
|
||||
{
|
||||
emit aboutToActivateTab(pos);
|
||||
QupZilla* win = mApp->mainWindows().at(pos.windowIndex);
|
||||
win->activateWindow();
|
||||
win->tabWidget()->setCurrentIndex(pos.tabIndex);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QListView>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
#include "locationcompletermodel.h"
|
||||
|
||||
class QT_QUPZILLA_EXPORT LocationCompleterView : public QListView
|
||||
{
|
||||
@ -34,15 +35,18 @@ public:
|
||||
|
||||
signals:
|
||||
void closed();
|
||||
void aboutToActivateTab(TabPosition pos);
|
||||
|
||||
public slots:
|
||||
void close();
|
||||
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void activateTab(TabPosition pos);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
bool m_ignoreNextMouseMove;
|
||||
|
@ -174,6 +174,8 @@ void WebSearchBar::setupEngines()
|
||||
|
||||
void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item)
|
||||
{
|
||||
selectAll();
|
||||
setFocus();
|
||||
setPlaceholderText(item.text);
|
||||
m_completerModel->setStringList(QStringList());
|
||||
|
||||
|
@ -32,6 +32,7 @@ void QzSettings::loadSettings()
|
||||
addCountryWithAlt = settings.value("AddCountryDomainWithAltKey", true).toBool();
|
||||
showLoadingProgress = settings.value("ShowLoadingProgress", false).toBool();
|
||||
showLocationSuggestions = settings.value("showSuggestions", 0).toInt();
|
||||
showSwitchTab = settings.value("showSwitchTab", true).toBool();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("SearchEngines");
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
bool addCountryWithAlt;
|
||||
bool showLoadingProgress;
|
||||
int showLocationSuggestions;
|
||||
bool showSwitchTab;
|
||||
|
||||
// SearchEngines
|
||||
bool showSearchSuggestions;
|
||||
|
@ -214,6 +214,7 @@ Preferences::Preferences(QupZilla* mainClass, QWidget* parent)
|
||||
//AddressBar
|
||||
settings.beginGroup("AddressBar");
|
||||
ui->addressbarCompletion->setCurrentIndex(settings.value("showSuggestions", 0).toInt());
|
||||
ui->completionShowSwitchTab->setChecked(settings.value("showSwitchTab", true).toBool());
|
||||
ui->selectAllOnFocus->setChecked(settings.value("SelectAllTextOnDoubleClick", true).toBool());
|
||||
ui->selectAllOnClick->setChecked(settings.value("SelectAllTextOnClick", false).toBool());
|
||||
ui->addCountryWithAlt->setChecked(settings.value("AddCountryDomainWithAltKey", true).toBool());
|
||||
@ -937,6 +938,7 @@ void Preferences::saveSettings()
|
||||
//AddressBar
|
||||
settings.beginGroup("AddressBar");
|
||||
settings.setValue("showSuggestions", ui->addressbarCompletion->currentIndex());
|
||||
settings.setValue("showSwitchTab", ui->completionShowSwitchTab->isChecked());
|
||||
settings.setValue("SelectAllTextOnDoubleClick", ui->selectAllOnFocus->isChecked());
|
||||
settings.setValue("SelectAllTextOnClick", ui->selectAllOnClick->isChecked());
|
||||
settings.setValue("AddCountryDomainWithAltKey", ui->addCountryWithAlt->isChecked());
|
||||
|
@ -160,9 +160,9 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="stackedWidgetPage1">
|
||||
<widget class="QWidget" name="generalPage">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="4" column="2">
|
||||
<widget class="QFrame" name="newTabFrame">
|
||||
@ -486,7 +486,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage2">
|
||||
<widget class="QWidget" name="appearancePage">
|
||||
<layout class="QGridLayout" name="gridLayout_21">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget_2">
|
||||
@ -647,14 +647,14 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage3">
|
||||
<widget class="QWidget" name="tabsPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget_3">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_6">
|
||||
<widget class="QWidget" name="tabsBehaviourPage">
|
||||
<attribute name="title">
|
||||
<string>Tabs behavior</string>
|
||||
</attribute>
|
||||
@ -770,7 +770,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_7">
|
||||
<widget class="QWidget" name="addressBarBehaviourPage">
|
||||
<attribute name="title">
|
||||
<string>Address Bar behavior</string>
|
||||
</attribute>
|
||||
@ -832,6 +832,16 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="completionShowSwitchTab">
|
||||
<property name="toolTip">
|
||||
<string>Press "Shift" to not switch the tab but load the url in the current tab.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Propose to switch tab if completed url is already loaded.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showLoadingInAddressBar">
|
||||
<property name="text">
|
||||
@ -963,7 +973,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage4">
|
||||
<widget class="QWidget" name="browsingPage">
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
@ -1552,7 +1562,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<widget class="QWidget" name="fontsPage">
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
<item row="0" column="0" rowspan="2" colspan="3">
|
||||
<widget class="QLabel" name="label_27">
|
||||
@ -1744,7 +1754,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_4">
|
||||
<widget class="QWidget" name="shortcutsPage">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
@ -1782,7 +1792,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="downloadPage">
|
||||
<widget class="QWidget" name="downloadsPage">
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_23">
|
||||
@ -1941,7 +1951,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage5">
|
||||
<widget class="QWidget" name="passwordManagerPage">
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_20">
|
||||
@ -2003,7 +2013,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage6">
|
||||
<widget class="QWidget" name="privacyPage">
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="26" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="jscanAccessClipboard">
|
||||
@ -2188,7 +2198,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_3">
|
||||
<widget class="QWidget" name="notificationsPage">
|
||||
<layout class="QGridLayout" name="gridLayout_17">
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_41">
|
||||
@ -2315,7 +2325,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page">
|
||||
<widget class="QWidget" name="extensionsPage">
|
||||
<layout class="QGridLayout" name="gridLayout_14">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QFrame" name="horizontalFrame">
|
||||
@ -2334,7 +2344,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedWidgetPage7">
|
||||
<widget class="QWidget" name="otherPage">
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<item row="9" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_9">
|
||||
|
Loading…
Reference in New Issue
Block a user