Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
widgetbox.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant reason:default
4
5#include "widgetbox.h"
8
9#include <QtDesigner/abstractformeditor.h>
10#include <QtDesigner/abstractformwindowmanager.h>
11
12#include <iconloader_p.h>
13#include <qdesigner_utils_p.h>
14
15#include <QtGui/qevent.h>
16#include <QtWidgets/qboxlayout.h>
17#include <QtWidgets/qapplication.h>
18#include <QtWidgets/qtoolbar.h>
19#include <QtWidgets/qlineedit.h>
20#include <QtGui/qicon.h>
21
23
24namespace qdesigner_internal {
25
26/* WidgetBoxFilterLineEdit: This widget should never have initial focus
27 * (ie, be the first widget of a dialog, else, the hint cannot be displayed.
28 * As it is the only focusable control in the widget box, it clears the focus
29 * policy and focusses explicitly on click only (note that setting Qt::ClickFocus
30 * is not sufficient for that as an ActivationFocus will occur). */
31
33public:
34 explicit WidgetBoxFilterLineEdit(QWidget *parent = nullptr) : QLineEdit(parent), m_defaultFocusPolicy(focusPolicy())
35 { setFocusPolicy(Qt::NoFocus); }
36
37protected:
38 void mousePressEvent(QMouseEvent *event) override;
39 void focusInEvent(QFocusEvent *e) override;
40
41private:
42 const Qt::FocusPolicy m_defaultFocusPolicy;
43};
44
46{
47 if (!hasFocus()) // Explicitly focus on click.
48 setFocus(Qt::OtherFocusReason);
49 QLineEdit::mousePressEvent(e);
50}
51
53{
54 // Refuse the focus if the mouse it outside. In addition to the mouse
55 // press logic, this prevents a re-focussing which occurs once
56 // we actually had focus
57 const Qt::FocusReason reason = e->reason();
58 if (reason == Qt::ActiveWindowFocusReason || reason == Qt::PopupFocusReason) {
59 const QPoint mousePos = mapFromGlobal(QCursor::pos());
60 const bool refuse = !geometry().contains(mousePos);
61 if (refuse) {
62 e->ignore();
63 return;
64 }
65 }
66 QLineEdit::focusInEvent(e);
67}
68
69WidgetBox::WidgetBox(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags)
70 : QDesignerWidgetBox(parent, flags),
71 m_core(core),
72 m_view(new WidgetBoxTreeWidget(m_core))
73{
74
75 QVBoxLayout *l = new QVBoxLayout(this);
76 l->setContentsMargins(QMargins());
77 l->setSpacing(0);
78
79 // Prevent the filter from grabbing focus since Our view has Qt::NoFocus
80 QToolBar *toolBar = new QToolBar(this);
81 QLineEdit *filterWidget = new WidgetBoxFilterLineEdit(toolBar);
82 filterWidget->setPlaceholderText(tr("Filter"));
83 filterWidget->setClearButtonEnabled(true);
84 connect(filterWidget, &QLineEdit::textChanged, m_view, &WidgetBoxTreeWidget::filter);
85 toolBar->addWidget(filterWidget);
86 l->addWidget(toolBar);
87
88 // View
89 connect(m_view, &WidgetBoxTreeWidget::widgetBoxPressed,
90 this, &WidgetBox::handleMousePress);
91 l->addWidget(m_view);
92
93 setAcceptDrops (true);
94}
95
96WidgetBox::~WidgetBox() = default;
97
98QDesignerFormEditorInterface *WidgetBox::core() const
99{
100 return m_core;
101}
102
103void WidgetBox::handleMousePress(const QString &name, const QString &xml, const QPoint &global_mouse_pos)
104{
105 if (QApplication::mouseButtons() != Qt::LeftButton)
106 return;
107
108 DomUI *ui = xmlToUi(name, xml, true);
109 if (ui == nullptr)
110 return;
111 QList<QDesignerDnDItemInterface*> item_list;
112 item_list.append(new WidgetBoxDnDItem(core(), ui, global_mouse_pos));
113 m_core->formWindowManager()->dragItems(item_list);
114}
115
117{
118 return m_view->categoryCount();
119}
120
122{
123 return m_view->category(cat_idx);
124}
125
126void WidgetBox::addCategory(const Category &cat)
127{
128 m_view->addCategory(cat);
129}
130
131void WidgetBox::removeCategory(int cat_idx)
132{
133 m_view->removeCategory(cat_idx);
134}
135
136int WidgetBox::widgetCount(int cat_idx) const
137{
138 return m_view->widgetCount(cat_idx);
139}
140
141QDesignerWidgetBoxInterface::Widget WidgetBox::widget(int cat_idx, int wgt_idx) const
142{
143 return m_view->widget(cat_idx, wgt_idx);
144}
145
146void WidgetBox::addWidget(int cat_idx, const Widget &wgt)
147{
148 m_view->addWidget(cat_idx, wgt);
149}
150
151void WidgetBox::removeWidget(int cat_idx, int wgt_idx)
152{
153 m_view->removeWidget(cat_idx, wgt_idx);
154}
155
156void WidgetBox::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, const QPoint&)
157{
158 m_view->dropWidgets(item_list);
159}
160
161void WidgetBox::setFileName(const QString &file_name)
162{
163 m_view->setFileName(file_name);
164}
165
166QString WidgetBox::fileName() const
167{
168 return m_view->fileName();
169}
170
172{
173 return m_view->load(loadMode());
174}
175
176bool WidgetBox::loadContents(const QString &contents)
177{
178 return m_view->loadContents(contents);
179}
180
182{
183 return m_view->save();
184}
185
186static const QDesignerMimeData *checkDragEvent(QDropEvent * event,
187 bool acceptEventsFromWidgetBox)
188{
189 const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(event->mimeData());
190 if (!mimeData) {
191 event->ignore();
192 return nullptr;
193 }
194 // If desired, ignore a widget box drag and drop, where widget==0.
195 if (!acceptEventsFromWidgetBox) {
196 const bool fromWidgetBox = !mimeData->items().first()->widget();
197 if (fromWidgetBox) {
198 event->ignore();
199 return nullptr;
200 }
201 }
202
203 mimeData->acceptEvent(event);
204 return mimeData;
205}
206
207void WidgetBox::dragEnterEvent (QDragEnterEvent * event)
208{
209 // We accept event originating from the widget box also here,
210 // because otherwise Windows will not show the DnD pixmap.
211 checkDragEvent(event, true);
212}
213
214void WidgetBox::dragMoveEvent(QDragMoveEvent * event)
215{
216 checkDragEvent(event, true);
217}
218
219void WidgetBox::dropEvent(QDropEvent * event)
220{
221 const QDesignerMimeData *mimeData = checkDragEvent(event, false);
222 if (!mimeData)
223 return;
224
225 dropWidgets(mimeData->items(), event->position().toPoint());
226 QDesignerMimeData::removeMovedWidgetsFromSourceForm(mimeData->items());
227}
228
229QIcon WidgetBox::iconForWidget(const QString &className, const QString &category) const
230{
231 Widget widgetData;
232 if (!findWidget(this, className, category, &widgetData))
233 return QIcon();
234 return m_view->iconForWidget(widgetData.iconName());
235}
236
237} // namespace qdesigner_internal
238
239QT_END_NAMESPACE
void mousePressEvent(QMouseEvent *event) override
\reimp
Definition widgetbox.cpp:45
void focusInEvent(QFocusEvent *e) override
\reimp
Definition widgetbox.cpp:52
WidgetBoxFilterLineEdit(QWidget *parent=nullptr)
Definition widgetbox.cpp:34
void removeWidget(int cat_idx, int wgt_idx)
QString fileName() const override
Returns the name of the XML file \QD is currently using to populate its widget box.
Widget widget(int cat_idx, int wgt_idx) const override
Category category(int cat_idx) const override
bool load() override
Populates \QD's widget box by loading (or reloading) the currently specified XML file.
void dragEnterEvent(QDragEnterEvent *event) override
void dropWidgets(const QList< QDesignerDnDItemInterface * > &item_list, const QPoint &global_mouse_pos) override
void removeCategory(int cat_idx) override
void dragMoveEvent(QDragMoveEvent *event) override
void addWidget(int cat_idx, const Widget &wgt) override
int categoryCount() const override
bool save() override
Saves the contents of \QD's widget box in the file specified by the fileName() function.
void addCategory(const Category &cat) override
QDesignerFormEditorInterface * core() const
Definition widgetbox.cpp:98
int widgetCount(int cat_idx) const override
void removeWidget(int cat_idx, int wgt_idx) override
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static const QDesignerMimeData * checkDragEvent(QDropEvent *event, bool acceptEventsFromWidgetBox)