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