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
qdesigner_toolbar.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
"qdesigner_toolbar_p.h"
6
#
include
"qdesigner_command_p.h"
7
#
include
"actionrepository_p.h"
8
#
include
"actionprovider_p.h"
9
#
include
"qdesigner_utils_p.h"
10
#
include
"qdesigner_objectinspector_p.h"
11
#
include
"promotiontaskmenu_p.h"
12
13
#
include
<
QtDesigner
/
abstractformwindow
.
h
>
14
#
include
<
QtDesigner
/
abstractpropertyeditor
.
h
>
15
#
include
<
QtDesigner
/
abstractformeditor
.
h
>
16
#
include
<
actionprovider_p
.
h
>
17
#
include
<
QtDesigner
/
qextensionmanager
.
h
>
18
#
include
<
QtDesigner
/
abstractwidgetfactory
.
h
>
19
20
#
include
<
QtWidgets
/
qapplication
.
h
>
21
#
include
<
QtWidgets
/
qtoolbutton
.
h
>
22
#
include
<
QtWidgets
/
qtoolbar
.
h
>
23
#
include
<
QtWidgets
/
qmenu
.
h
>
24
25
#
include
<
QtGui
/
qaction
.
h
>
26
#
include
<
QtGui
/
qevent
.
h
>
27
#
include
<
QtGui
/
qdrag
.
h
>
28
29
#
include
<
QtCore
/
qdebug
.
h
>
30
31
QT_BEGIN_NAMESPACE
32
33
using
namespace
Qt::StringLiterals;
34
35
using
ActionList = QList<QAction *>;
36
37
namespace
qdesigner_internal
{
38
// ------------------- ToolBarEventFilter
39
void
ToolBarEventFilter
::
install
(
QToolBar
*
tb
)
40
{
41
ToolBarEventFilter
*
tf
=
new
ToolBarEventFilter
(
tb
);
42
tb
->
installEventFilter
(
tf
);
43
tb
->
setAcceptDrops
(
true
);
// ### fake
44
}
45
46
ToolBarEventFilter
::
ToolBarEventFilter
(
QToolBar
*
tb
) :
47
QObject
(
tb
),
48
m_toolBar
(
tb
),
49
m_promotionTaskMenu
(
nullptr
)
50
{
51
}
52
53
ToolBarEventFilter
*
ToolBarEventFilter
::
eventFilterOf
(
const
QToolBar
*
tb
)
54
{
55
// Look for 1st order children only..otherwise, we might get filters of nested widgets
56
for
(
QObject
*
o
:
tb
->
children
()) {
57
if
(!
o
->
isWidgetType
())
58
if
(
ToolBarEventFilter
*
ef
=
qobject_cast
<
ToolBarEventFilter
*>(
o
))
59
return
ef
;
60
}
61
return
nullptr
;
62
}
63
64
bool
ToolBarEventFilter
::
eventFilter
(
QObject
*
watched
,
QEvent
*
event
)
65
{
66
if
(
watched
!=
m_toolBar
)
67
return
QObject
::
eventFilter
(
watched
,
event
);
68
69
bool
handled
=
false
;
70
switch
(
event
->
type
()) {
71
case
QEvent
::
ChildAdded
:
// Children should not interact with the mouse
72
if
(
auto
*
c
=
static_cast
<
const
QChildEvent
*>(
event
)->
child
();
c
->
isWidgetType
()) {
73
QWidget
*
w
=
static_cast
<
QWidget
*>(
c
);
74
w
->
setAttribute
(
Qt
::
WA_TransparentForMouseEvents
,
true
);
75
w
->
setFocusPolicy
(
Qt
::
NoFocus
);
76
}
77
break
;
78
case
QEvent
::
ContextMenu
:
79
handled
=
handleContextMenuEvent
(
static_cast
<
QContextMenuEvent
*>(
event
));
80
break
;
81
case
QEvent
::
DragEnter
:
82
case
QEvent
::
DragMove
:
83
handled
=
handleDragEnterMoveEvent
(
static_cast
<
QDragMoveEvent
*>(
event
));
84
break
;
85
case
QEvent
::
DragLeave
:
86
handled
=
handleDragLeaveEvent
(
static_cast
<
QDragLeaveEvent
*>(
event
));
87
break
;
88
case
QEvent
::
Drop
:
89
handled
=
handleDropEvent
(
static_cast
<
QDropEvent
*>(
event
));
90
break
;
91
case
QEvent
::
MouseButtonPress
:
92
handled
=
handleMousePressEvent
(
static_cast
<
QMouseEvent
*>(
event
));
93
break
;
94
case
QEvent
::
MouseButtonRelease
:
95
handled
=
handleMouseReleaseEvent
(
static_cast
<
QMouseEvent
*>(
event
));
96
break
;
97
case
QEvent
::
MouseMove
:
98
handled
=
handleMouseMoveEvent
(
static_cast
<
QMouseEvent
*>(
event
));
99
break
;
100
default
:
101
break
;
102
}
103
104
return
handled
||
QObject
::
eventFilter
(
watched
,
event
);
105
}
106
107
ActionList
ToolBarEventFilter
::
contextMenuActions
(
const
QPoint
&
globalPos
)
108
{
109
ActionList
rc
;
110
const
int
index
=
actionIndexAt
(
m_toolBar
,
m_toolBar
->
mapFromGlobal
(
globalPos
),
m_toolBar
->
orientation
());
111
const
auto
actions
=
m_toolBar
->
actions
();
112
QAction
*
action
=
index
!= -1 ?
actions
.
at
(
index
) : 0;
113
QVariant
itemData
;
114
115
// Insert before
116
if
(
action
&&
index
!= 0 && !
action
->
isSeparator
()) {
117
QAction
*
newSeperatorAct
=
new
QAction
(
tr
(
"Insert Separator before '%1'"
).
arg
(
action
->
objectName
()),
nullptr
);
118
itemData
.
setValue
(
action
);
119
newSeperatorAct
->
setData
(
itemData
);
120
connect
(
newSeperatorAct
, &
QAction
::
triggered
,
this
, &
ToolBarEventFilter
::
slotInsertSeparator
);
121
rc
.
push_back
(
newSeperatorAct
);
122
}
123
124
// Append separator
125
if
(
actions
.
isEmpty
() || !
actions
.
constLast
()->
isSeparator
()) {
126
QAction
*
newSeperatorAct
=
new
QAction
(
tr
(
"Append Separator"
),
nullptr
);
127
itemData
.
setValue
(
static_cast
<
QAction
*>(
nullptr
));
128
newSeperatorAct
->
setData
(
itemData
);
129
connect
(
newSeperatorAct
, &
QAction
::
triggered
,
this
, &
ToolBarEventFilter
::
slotInsertSeparator
);
130
rc
.
push_back
(
newSeperatorAct
);
131
}
132
// Promotion
133
if
(!
m_promotionTaskMenu
)
134
m_promotionTaskMenu
=
new
PromotionTaskMenu
(
m_toolBar
,
PromotionTaskMenu
::
ModeSingleWidget
,
this
);
135
m_promotionTaskMenu
->
addActions
(
formWindow
(),
PromotionTaskMenu
::
LeadingSeparator
|
PromotionTaskMenu
::
TrailingSeparator
,
rc
);
136
// Remove
137
if
(
action
) {
138
QAction
*
a
=
new
QAction
(
tr
(
"Remove action '%1'"
).
arg
(
action
->
objectName
()),
nullptr
);
139
itemData
.
setValue
(
action
);
140
a
->
setData
(
itemData
);
141
connect
(
a
, &
QAction
::
triggered
,
this
, &
ToolBarEventFilter
::
slotRemoveSelectedAction
);
142
rc
.
push_back
(
a
);
143
}
144
145
QAction
*
remove_toolbar
=
new
QAction
(
tr
(
"Remove Toolbar '%1'"
).
arg
(
m_toolBar
->
objectName
()),
nullptr
);
146
connect
(
remove_toolbar
, &
QAction
::
triggered
,
this
, &
ToolBarEventFilter
::
slotRemoveToolBar
);
147
rc
.
push_back
(
remove_toolbar
);
148
return
rc
;
149
}
150
151
bool
ToolBarEventFilter
::
handleContextMenuEvent
(
QContextMenuEvent
*
event
)
152
{
153
event
->
accept
();
154
155
const
QPoint
globalPos
=
event
->
globalPos
();
156
const
ActionList
al
=
contextMenuActions
(
event
->
globalPos
());
157
158
QMenu
menu
(
nullptr
);
159
for
(
auto
*
a
:
al
)
160
menu
.
addAction
(
a
);
161
menu
.
exec
(
globalPos
);
162
return
true
;
163
}
164
165
void
ToolBarEventFilter
::
slotRemoveSelectedAction
()
166
{
167
QAction
*
action
=
qobject_cast
<
QAction
*>(
sender
());
168
if
(!
action
)
169
return
;
170
171
QAction
*
a
=
qvariant_cast
<
QAction
*>(
action
->
data
());
172
Q_ASSERT
(
a
!=
nullptr
);
173
174
QDesignerFormWindowInterface
*
fw
=
formWindow
();
175
Q_ASSERT
(
fw
);
176
177
const
ActionList
actions
=
m_toolBar
->
actions
();
178
const
int
pos
=
actions
.
indexOf
(
a
);
179
QAction
*
action_before
=
nullptr
;
180
if
(
pos
!= -1 &&
actions
.
size
() >
pos
+ 1)
181
action_before
=
actions
.
at
(
pos
+ 1);
182
183
RemoveActionFromCommand
*
cmd
=
new
RemoveActionFromCommand
(
fw
);
184
cmd
->
init
(
m_toolBar
,
a
,
action_before
);
185
fw
->
commandHistory
()->
push
(
cmd
);
186
}
187
188
void
ToolBarEventFilter
::
slotRemoveToolBar
()
189
{
190
QDesignerFormWindowInterface
*
fw
=
formWindow
();
191
Q_ASSERT
(
fw
);
192
DeleteToolBarCommand
*
cmd
=
new
DeleteToolBarCommand
(
fw
);
193
cmd
->
init
(
m_toolBar
);
194
fw
->
commandHistory
()->
push
(
cmd
);
195
}
196
197
void
ToolBarEventFilter
::
slotInsertSeparator
()
198
{
199
QDesignerFormWindowInterface
*
fw
=
formWindow
();
200
QAction
*
theSender
=
qobject_cast
<
QAction
*>(
sender
());
201
QAction
*
previous
=
qvariant_cast
<
QAction
*>(
theSender
->
data
());
202
fw
->
beginCommand
(
tr
(
"Insert Separator"
));
203
QAction
*
action
=
createAction
(
fw
, u"separator"_s,
true
);
204
InsertActionIntoCommand
*
cmd
=
new
InsertActionIntoCommand
(
fw
);
205
cmd
->
init
(
m_toolBar
,
action
,
previous
);
206
fw
->
commandHistory
()->
push
(
cmd
);
207
fw
->
endCommand
();
208
}
209
210
QDesignerFormWindowInterface
*
ToolBarEventFilter
::
formWindow
()
const
211
{
212
return
QDesignerFormWindowInterface
::
findFormWindow
(
m_toolBar
);
213
}
214
215
QAction
*
ToolBarEventFilter
::
createAction
(
QDesignerFormWindowInterface
*
fw
,
const
QString
&
objectName
,
bool
separator
)
216
{
217
QAction
*
action
=
new
QAction
(
fw
);
218
fw
->
core
()->
widgetFactory
()->
initialize
(
action
);
219
if
(
separator
)
220
action
->
setSeparator
(
true
);
221
222
action
->
setObjectName
(
objectName
);
223
fw
->
ensureUniqueObjectName
(
action
);
224
225
qdesigner_internal
::
AddActionCommand
*
cmd
=
new
qdesigner_internal
::
AddActionCommand
(
fw
);
226
cmd
->
init
(
action
);
227
fw
->
commandHistory
()->
push
(
cmd
);
228
229
return
action
;
230
}
231
232
void
ToolBarEventFilter
::
adjustDragIndicator
(
const
QPoint
&
pos
)
233
{
234
if
(
QDesignerFormWindowInterface
*
fw
=
formWindow
()) {
235
QDesignerFormEditorInterface
*
core
=
fw
->
core
();
236
if
(
QDesignerActionProviderExtension
*
a
=
qt_extension
<
QDesignerActionProviderExtension
*>(
core
->
extensionManager
(),
m_toolBar
))
237
a
->
adjustIndicator
(
pos
);
238
}
239
}
240
241
void
ToolBarEventFilter
::
hideDragIndicator
()
242
{
243
adjustDragIndicator
(
QPoint
(-1, -1));
244
}
245
246
bool
ToolBarEventFilter
::
handleMousePressEvent
(
QMouseEvent
*
event
)
247
{
248
if
(
event
->
button
() !=
Qt
::
LeftButton
||
withinHandleArea
(
m_toolBar
,
event
->
position
().
toPoint
()))
249
return
false
;
250
251
if
(
QDesignerFormWindowInterface
*
fw
=
formWindow
()) {
252
QDesignerFormEditorInterface
*
core
=
fw
->
core
();
253
// Keep selection in sync
254
fw
->
clearSelection
(
false
);
255
if
(
QDesignerObjectInspector
*
oi
=
qobject_cast
<
QDesignerObjectInspector
*>(
core
->
objectInspector
())) {
256
oi
->
clearSelection
();
257
oi
->
selectObject
(
m_toolBar
);
258
}
259
core
->
propertyEditor
()->
setObject
(
m_toolBar
);
260
}
261
const
auto
pos
=
m_toolBar
->
mapFromGlobal
(
event
->
globalPosition
().
toPoint
());
262
if
(
actionIndexAt
(
m_toolBar
,
pos
,
m_toolBar
->
orientation
()) != -1) {
263
m_startPosition
=
pos
;
264
event
->
accept
();
265
return
true
;
266
}
267
return
false
;
268
}
269
270
bool
ToolBarEventFilter
::
handleMouseReleaseEvent
(
QMouseEvent
*
event
)
271
{
272
if
(
event
->
button
() !=
Qt
::
LeftButton
||
m_startPosition
.
isNull
() ||
withinHandleArea
(
m_toolBar
,
event
->
position
().
toPoint
()))
273
return
false
;
274
275
// Accept the event, otherwise, form window selection will trigger
276
m_startPosition
=
QPoint
();
277
event
->
accept
();
278
return
true
;
279
}
280
281
bool
ToolBarEventFilter
::
handleMouseMoveEvent
(
QMouseEvent
*
event
)
282
{
283
if
(
m_startPosition
.
isNull
() ||
withinHandleArea
(
m_toolBar
,
event
->
position
().
toPoint
()))
284
return
false
;
285
286
const
QPoint
pos
=
m_toolBar
->
mapFromGlobal
(
event
->
globalPosition
().
toPoint
());
287
if
((
pos
-
m_startPosition
).
manhattanLength
() >
QApplication
::
startDragDistance
()
288
&&
startDrag
(
m_startPosition
,
event
->
modifiers
())) {
289
m_startPosition
=
QPoint
();
290
event
->
accept
();
291
return
true
;
292
}
293
return
false
;
294
}
295
296
bool
ToolBarEventFilter
::
handleDragEnterMoveEvent
(
QDragMoveEvent
*
event
)
297
{
298
const
ActionRepositoryMimeData
*
d
=
qobject_cast
<
const
ActionRepositoryMimeData
*>(
event
->
mimeData
());
299
if
(!
d
)
300
return
false
;
301
302
if
(
d
->
actionList
().
isEmpty
()) {
303
event
->
ignore
();
304
hideDragIndicator
();
305
return
true
;
306
}
307
308
QAction
*
action
=
d
->
actionList
().
first
();
309
if
(!
action
||
action
->
menu
() ||
m_toolBar
->
actions
().
contains
(
action
) || !
Utils
::
isObjectAncestorOf
(
formWindow
()->
mainContainer
(),
action
)) {
310
event
->
ignore
();
311
hideDragIndicator
();
312
return
true
;
313
}
314
315
d
->
accept
(
event
);
316
adjustDragIndicator
(
event
->
position
().
toPoint
());
317
return
true
;
318
}
319
320
bool
ToolBarEventFilter
::
handleDragLeaveEvent
(
QDragLeaveEvent
*)
321
{
322
hideDragIndicator
();
323
return
false
;
324
}
325
326
bool
ToolBarEventFilter
::
handleDropEvent
(
QDropEvent
*
event
)
327
{
328
const
ActionRepositoryMimeData
*
d
=
qobject_cast
<
const
ActionRepositoryMimeData
*>(
event
->
mimeData
());
329
if
(!
d
)
330
return
false
;
331
332
if
(
d
->
actionList
().
isEmpty
()) {
333
event
->
ignore
();
334
hideDragIndicator
();
335
return
true
;
336
}
337
338
QAction
*
action
=
d
->
actionList
().
first
();
339
340
const
ActionList
actions
=
m_toolBar
->
actions
();
341
if
(!
action
||
actions
.
contains
(
action
)) {
342
event
->
ignore
();
343
hideDragIndicator
();
344
return
true
;
345
}
346
347
// Try to find action to 'insert before'. Click on action or in free area, else ignore.
348
QAction
*
beforeAction
=
nullptr
;
349
const
QPoint
pos
=
event
->
position
().
toPoint
();
350
const
int
index
=
actionIndexAt
(
m_toolBar
,
pos
,
m_toolBar
->
orientation
());
351
if
(
index
!= -1) {
352
beforeAction
=
actions
.
at
(
index
);
353
}
else
{
354
if
(!
freeArea
(
m_toolBar
).
contains
(
pos
)) {
355
event
->
ignore
();
356
hideDragIndicator
();
357
return
true
;
358
}
359
}
360
361
event
->
acceptProposedAction
();
362
QDesignerFormWindowInterface
*
fw
=
formWindow
();
363
InsertActionIntoCommand
*
cmd
=
new
InsertActionIntoCommand
(
fw
);
364
cmd
->
init
(
m_toolBar
,
action
,
beforeAction
);
365
fw
->
commandHistory
()->
push
(
cmd
);
366
hideDragIndicator
();
367
return
true
;
368
}
369
370
bool
ToolBarEventFilter
::
startDrag
(
const
QPoint
&
pos
,
Qt
::
KeyboardModifiers
modifiers
)
371
{
372
const
int
index
=
actionIndexAt
(
m_toolBar
,
pos
,
m_toolBar
->
orientation
());
373
if
(
index
== - 1)
374
return
false
;
375
376
const
ActionList
actions
=
m_toolBar
->
actions
();
377
QAction
*
action
=
actions
.
at
(
index
);
378
QDesignerFormWindowInterface
*
fw
=
formWindow
();
379
380
const
Qt
::
DropAction
dropAction
= (
modifiers
&
Qt
::
ControlModifier
) ?
Qt
::
CopyAction
:
Qt
::
MoveAction
;
381
if
(
dropAction
==
Qt
::
MoveAction
) {
382
RemoveActionFromCommand
*
cmd
=
new
RemoveActionFromCommand
(
fw
);
383
const
int
nextIndex
=
index
+ 1;
384
QAction
*
nextAction
=
nextIndex
<
actions
.
size
() ?
actions
.
at
(
nextIndex
) : 0;
385
cmd
->
init
(
m_toolBar
,
action
,
nextAction
);
386
fw
->
commandHistory
()->
push
(
cmd
);
387
}
388
389
QDrag
*
drag
=
new
QDrag
(
m_toolBar
);
390
drag
->
setPixmap
(
ActionRepositoryMimeData
::
actionDragPixmap
(
action
));
391
drag
->
setMimeData
(
new
ActionRepositoryMimeData
(
action
,
dropAction
));
392
393
if
(
drag
->
exec
(
dropAction
) ==
Qt
::
IgnoreAction
) {
394
hideDragIndicator
();
395
if
(
dropAction
==
Qt
::
MoveAction
) {
396
const
ActionList
currentActions
=
m_toolBar
->
actions
();
397
QAction
*
previous
=
nullptr
;
398
if
(
index
>= 0 &&
index
<
currentActions
.
size
())
399
previous
=
currentActions
.
at
(
index
);
400
InsertActionIntoCommand
*
cmd
=
new
InsertActionIntoCommand
(
fw
);
401
cmd
->
init
(
m_toolBar
,
action
,
previous
);
402
fw
->
commandHistory
()->
push
(
cmd
);
403
}
404
}
405
return
true
;
406
}
407
408
QAction
*
ToolBarEventFilter
::
actionAt
(
const
QToolBar
*
tb
,
const
QPoint
&
pos
)
409
{
410
const
int
index
=
actionIndexAt
(
tb
,
pos
,
tb
->
orientation
());
411
if
(
index
== -1)
412
return
nullptr
;
413
return
tb
->
actions
().
at
(
index
);
414
}
415
416
//that's a trick to get access to the initStyleOption which is a protected member
417
class
FriendlyToolBar
:
public
QToolBar
{
418
public
:
419
friend
class
ToolBarEventFilter;
420
};
421
422
QRect
ToolBarEventFilter
::
handleArea
(
const
QToolBar
*
tb
)
423
{
424
QStyleOptionToolBar
opt
;
425
static_cast
<
const
FriendlyToolBar
*>(
tb
)->
initStyleOption
(&
opt
);
426
return
tb
->
style
()->
subElementRect
(
QStyle
::
SE_ToolBarHandle
, &
opt
,
tb
);
427
}
428
429
bool
ToolBarEventFilter
::
withinHandleArea
(
const
QToolBar
*
tb
,
const
QPoint
&
pos
)
430
{
431
return
handleArea
(
tb
).
contains
(
pos
);
432
}
433
434
// Determine the free area behind the last action.
435
QRect
ToolBarEventFilter
::
freeArea
(
const
QToolBar
*
tb
)
436
{
437
QRect
rc
=
QRect
(
QPoint
(0, 0),
tb
->
size
());
438
const
ActionList
actionList
=
tb
->
actions
();
439
QRect
exclusionRectangle
=
actionList
.
isEmpty
()
440
?
handleArea
(
tb
) :
tb
->
actionGeometry
(
actionList
.
constLast
());
441
switch
(
tb
->
orientation
()) {
442
case
Qt
::
Horizontal
:
443
switch
(
tb
->
layoutDirection
()) {
444
case
Qt
::
LayoutDirectionAuto
:
// Should never happen
445
case
Qt
::
LeftToRight
:
446
rc
.
setX
(
exclusionRectangle
.
right
() + 1);
447
break
;
448
case
Qt
::
RightToLeft
:
449
rc
.
setRight
(
exclusionRectangle
.
x
());
450
break
;
451
}
452
break
;
453
case
Qt
::
Vertical
:
454
rc
.
setY
(
exclusionRectangle
.
bottom
() + 1);
455
break
;
456
}
457
return
rc
;
458
}
459
460
}
461
462
QT_END_NAMESPACE
qdesigner_internal::FriendlyToolBar
Definition
qdesigner_toolbar.cpp:417
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qdesigner_internal
Auxiliary methods to store/retrieve settings.
Definition
buddyeditor.cpp:67
qttools
src
designer
src
lib
shared
qdesigner_toolbar.cpp
Generated on
for Qt by
1.16.1