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