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
stylesheeteditor.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
"stylesheeteditor_p.h"
6
#
include
"csshighlighter_p.h"
7
#
include
"iconloader_p.h"
8
#
include
"iconselector_p.h"
9
#
include
"qtgradientmanager_p.h"
10
#
include
"qtgradientviewdialog_p.h"
11
#
include
"qtgradientutils_p.h"
12
#
include
"qdesigner_utils_p.h"
13
14
#
include
<
QtDesigner
/
abstractformwindow
.
h
>
15
#
include
<
QtDesigner
/
abstractformwindowcursor
.
h
>
16
#
include
<
QtDesigner
/
abstractformeditor
.
h
>
17
#
include
<
QtDesigner
/
propertysheet
.
h
>
18
#
include
<
QtDesigner
/
abstractintegration
.
h
>
19
#
include
<
QtDesigner
/
abstractsettings
.
h
>
20
#
include
<
QtDesigner
/
qextensionmanager
.
h
>
21
22
#
include
<
texteditfindwidget_p
.
h
>
23
24
#
include
<
QtWidgets
/
qcolordialog
.
h
>
25
#
include
<
QtWidgets
/
qdialogbuttonbox
.
h
>
26
#
include
<
QtWidgets
/
qfontdialog
.
h
>
27
#
include
<
QtWidgets
/
qmenu
.
h
>
28
#
include
<
QtWidgets
/
qpushbutton
.
h
>
29
#
include
<
QtWidgets
/
qtoolbar
.
h
>
30
#
include
<
QtWidgets
/
qboxlayout
.
h
>
31
32
#
include
<
QtGui
/
qaction
.
h
>
33
#
include
<
QtGui
/
qevent
.
h
>
34
#
include
<
QtGui
/
qtextdocument
.
h
>
35
36
#
include
<
private
/
qcssparser_p
.
h
>
37
38
QT_BEGIN_NAMESPACE
39
40
using
namespace
Qt::StringLiterals;
41
42
static
constexpr
auto
styleSheetProperty
=
"styleSheet"_L1
;
43
static
constexpr
auto
StyleSheetDialogC
=
"StyleSheetDialog"_L1
;
44
static
constexpr
auto
seGeometry
=
"Geometry"_L1
;
45
46
namespace
qdesigner_internal
{
47
48
StyleSheetEditor
::
StyleSheetEditor
(
QWidget
*
parent
)
49
:
QTextEdit
(
parent
)
50
{
51
setTabStopDistance
(
fontMetrics
().
horizontalAdvance
(u' ') * 4);
52
setAcceptRichText
(
false
);
53
54
const
bool
darkMode
=
isDarkMode
();
55
56
CssHighlightColors
colors
;
57
colors
.
selector
=
darkMode
?
QColor
(
Qt
::
red
).
lighter
() :
QColor
(
Qt
::
darkRed
);
58
const
QColor
blue
(
Qt
::
blue
);
59
colors
.
property
=
darkMode
?
blue
.
lighter
() :
blue
;
60
colors
.
pseudo1
=
colors
.
pseudo2
=
colors
.
value
=
palette
().
color
(
QPalette
::
WindowText
);
61
colors
.
quote
=
darkMode
?
Qt
::
magenta
:
Qt
::
darkMagenta
;
62
colors
.
comment
=
darkMode
?
Qt
::
green
:
Qt
::
darkGreen
;
63
64
new
CssHighlighter
(
colors
,
document
());
65
}
66
67
// --- StyleSheetEditorDialog
68
StyleSheetEditorDialog
::
StyleSheetEditorDialog
(
QDesignerFormEditorInterface
*
core
,
QWidget
*
parent
,
Mode
mode
):
69
QDialog
(
parent
),
70
m_buttonBox
(
new
QDialogButtonBox
(
QDialogButtonBox
::
Ok
|
QDialogButtonBox
::
Cancel
|
QDialogButtonBox
::
Help
)),
71
m_editor
(
new
StyleSheetEditor
),
72
m_findWidget
(
new
TextEditFindWidget
),
73
m_validityLabel
(
new
QLabel
(
tr
(
"Valid Style Sheet"
))),
74
m_core
(
core
),
75
m_addResourceAction
(
new
QAction
(
tr
(
"Add Resource..."
),
this
)),
76
m_addGradientAction
(
new
QAction
(
tr
(
"Add Gradient..."
),
this
)),
77
m_addColorAction
(
new
QAction
(
tr
(
"Add Color..."
),
this
)),
78
m_addFontAction
(
new
QAction
(
tr
(
"Add Font..."
),
this
))
79
{
80
setWindowTitle
(
tr
(
"Edit Style Sheet"
));
81
82
connect
(
m_buttonBox
, &
QDialogButtonBox
::
accepted
,
this
, &
QDialog
::
accept
);
83
connect
(
m_buttonBox
, &
QDialogButtonBox
::
rejected
,
this
, &
QDialog
::
reject
);
84
connect
(
m_buttonBox
, &
QDialogButtonBox
::
helpRequested
,
85
this
, &
StyleSheetEditorDialog
::
slotRequestHelp
);
86
m_buttonBox
->
button
(
QDialogButtonBox
::
Help
)->
setShortcut
(
QKeySequence
::
HelpContents
);
87
88
connect
(
m_editor
, &
QTextEdit
::
textChanged
,
this
, &
StyleSheetEditorDialog
::
validateStyleSheet
);
89
m_findWidget
->
setTextEdit
(
m_editor
);
90
91
QToolBar
*
toolBar
=
new
QToolBar
;
92
93
QGridLayout
*
layout
=
new
QGridLayout
;
94
layout
->
addWidget
(
toolBar
, 0, 0, 1, 2);
95
layout
->
addWidget
(
m_editor
, 1, 0, 1, 2);
96
layout
->
addWidget
(
m_findWidget
, 2, 0, 1, 2);
97
layout
->
addWidget
(
m_validityLabel
, 3, 0, 1, 1);
98
layout
->
addWidget
(
m_buttonBox
, 3, 1, 1, 1);
99
setLayout
(
layout
);
100
101
m_editor
->
setContextMenuPolicy
(
Qt
::
CustomContextMenu
);
102
connect
(
m_editor
, &
QWidget
::
customContextMenuRequested
,
103
this
, &
StyleSheetEditorDialog
::
slotContextMenuRequested
);
104
105
connect
(
m_addResourceAction
, &
QAction
::
triggered
,
106
this
, [
this
] {
this
->
slotAddResource
(
QString
()); });
107
connect
(
m_addGradientAction
, &
QAction
::
triggered
,
108
this
, [
this
] {
this
->
slotAddGradient
(
QString
()); });
109
connect
(
m_addColorAction
, &
QAction
::
triggered
,
110
this
, [
this
] {
this
->
slotAddColor
(
QString
()); });
111
connect
(
m_addFontAction
, &
QAction
::
triggered
,
this
, &
StyleSheetEditorDialog
::
slotAddFont
);
112
113
m_addResourceAction
->
setEnabled
(
mode
==
ModePerForm
);
114
115
const
char
*
const
resourceProperties
[] = {
116
"background-image"
,
117
"border-image"
,
118
"image"
,
119
nullptr
120
};
121
122
const
char
*
const
colorProperties
[] = {
123
"color"
,
124
"background-color"
,
125
"alternate-background-color"
,
126
"border-color"
,
127
"border-top-color"
,
128
"border-right-color"
,
129
"border-bottom-color"
,
130
"border-left-color"
,
131
"gridline-color"
,
132
"selection-color"
,
133
"selection-background-color"
,
134
nullptr
135
};
136
137
QMenu
*
resourceActionMenu
=
new
QMenu
(
this
);
138
QMenu
*
gradientActionMenu
=
new
QMenu
(
this
);
139
QMenu
*
colorActionMenu
=
new
QMenu
(
this
);
140
141
for
(
int
resourceProperty
= 0;
resourceProperties
[
resourceProperty
]; ++
resourceProperty
) {
142
const
QString
resourcePropertyName
=
QLatin1StringView
(
resourceProperties
[
resourceProperty
]);
143
resourceActionMenu
->
addAction
(
resourcePropertyName
,
144
this
, [
this
,
resourcePropertyName
] {
this
->
slotAddResource
(
resourcePropertyName
); });
145
}
146
147
for
(
int
colorProperty
= 0;
colorProperties
[
colorProperty
]; ++
colorProperty
) {
148
const
QString
colorPropertyName
=
QLatin1StringView
(
colorProperties
[
colorProperty
]);
149
colorActionMenu
->
addAction
(
colorPropertyName
,
150
this
, [
this
,
colorPropertyName
] {
this
->
slotAddColor
(
colorPropertyName
); });
151
gradientActionMenu
->
addAction
(
colorPropertyName
,
152
this
, [
this
,
colorPropertyName
] {
this
->
slotAddGradient
(
colorPropertyName
); } );
153
}
154
155
m_addResourceAction
->
setMenu
(
resourceActionMenu
);
156
m_addGradientAction
->
setMenu
(
gradientActionMenu
);
157
m_addColorAction
->
setMenu
(
colorActionMenu
);
158
159
160
toolBar
->
addAction
(
m_addResourceAction
);
161
toolBar
->
addAction
(
m_addGradientAction
);
162
toolBar
->
addAction
(
m_addColorAction
);
163
toolBar
->
addAction
(
m_addFontAction
);
164
m_findAction
=
m_findWidget
->
createFindAction
(
toolBar
);
165
toolBar
->
addAction
(
m_findAction
);
166
167
m_editor
->
setFocus
();
168
169
QDesignerSettingsInterface
*
settings
=
core
->
settingsManager
();
170
settings
->
beginGroup
(
StyleSheetDialogC
);
171
172
if
(
settings
->
contains
(
seGeometry
))
173
restoreGeometry
(
settings
->
value
(
seGeometry
).
toByteArray
());
174
175
settings
->
endGroup
();
176
}
177
178
StyleSheetEditorDialog
::~
StyleSheetEditorDialog
()
179
{
180
QDesignerSettingsInterface
*
settings
=
m_core
->
settingsManager
();
181
settings
->
beginGroup
(
StyleSheetDialogC
);
182
183
settings
->
setValue
(
seGeometry
,
saveGeometry
());
184
settings
->
endGroup
();
185
}
186
187
void
StyleSheetEditorDialog
::
setOkButtonEnabled
(
bool
v
)
188
{
189
m_buttonBox
->
button
(
QDialogButtonBox
::
Ok
)->
setEnabled
(
v
);
190
if
(
QPushButton
*
applyButton
=
m_buttonBox
->
button
(
QDialogButtonBox
::
Apply
))
191
applyButton
->
setEnabled
(
v
);
192
}
193
194
void
StyleSheetEditorDialog
::
slotContextMenuRequested
(
const
QPoint
&
pos
)
195
{
196
QMenu
*
menu
=
m_editor
->
createStandardContextMenu
();
197
menu
->
addSeparator
();
198
menu
->
addAction
(
m_findAction
);
199
menu
->
addSeparator
();
200
menu
->
addAction
(
m_addResourceAction
);
201
menu
->
addAction
(
m_addGradientAction
);
202
menu
->
exec
(
mapToGlobal
(
pos
));
203
delete
menu
;
204
}
205
206
void
StyleSheetEditorDialog
::
slotAddResource
(
const
QString
&
property
)
207
{
208
const
QString
path
=
IconSelector
::
choosePixmapResource
(
m_core
,
m_core
->
resourceModel
(),
QString
(),
this
);
209
if
(!
path
.
isEmpty
())
210
insertCssProperty
(
property
,
"url("_L1
+
path
+ u')');
211
}
212
213
void
StyleSheetEditorDialog
::
slotAddGradient
(
const
QString
&
property
)
214
{
215
bool
ok
;
216
const
QGradient
grad
=
QtGradientViewDialog
::
getGradient
(&
ok
,
m_core
->
gradientManager
(),
this
);
217
if
(
ok
)
218
insertCssProperty
(
property
,
QtGradientUtils
::
styleSheetCode
(
grad
));
219
}
220
221
void
StyleSheetEditorDialog
::
slotAddColor
(
const
QString
&
property
)
222
{
223
const
QColor
color
=
QColorDialog
::
getColor
(0xffffffff,
this
,
QString
(),
QColorDialog
::
ShowAlphaChannel
);
224
if
(!
color
.
isValid
())
225
return
;
226
227
QString
colorStr
;
228
229
if
(
color
.
alpha
() == 255) {
230
colorStr
=
QString
::
asprintf
(
"rgb(%d, %d, %d)"
,
231
color
.
red
(),
color
.
green
(),
color
.
blue
());
232
}
else
{
233
colorStr
=
QString
::
asprintf
(
"rgba(%d, %d, %d, %d)"
,
234
color
.
red
(),
color
.
green
(),
color
.
blue
(),
235
color
.
alpha
());
236
}
237
238
insertCssProperty
(
property
,
colorStr
);
239
}
240
241
void
StyleSheetEditorDialog
::
slotAddFont
()
242
{
243
bool
ok
;
244
QFont
font
=
QFontDialog
::
getFont
(&
ok
,
this
);
245
if
(
ok
) {
246
QString
fontStr
;
247
if
(
font
.
weight
() !=
QFont
::
Normal
)
248
fontStr
+=
QString
::
number
(
font
.
weight
()) + u' ';
249
250
switch
(
font
.
style
()) {
251
case
QFont
::
StyleItalic
:
252
fontStr
+=
"italic "_L1
;
253
break
;
254
case
QFont
::
StyleOblique
:
255
fontStr
+=
"oblique "_L1
;
256
break
;
257
default
:
258
break
;
259
}
260
fontStr
+=
QString
::
number
(
font
.
pointSize
());
261
fontStr
+=
"pt \""_L1
;
262
fontStr
+=
font
.
family
();
263
fontStr
+= u'"';
264
265
insertCssProperty
(u"font"_s,
fontStr
);
266
QString
decoration
;
267
if
(
font
.
underline
())
268
decoration
+=
"underline"_L1
;
269
if
(
font
.
strikeOut
()) {
270
if
(!
decoration
.
isEmpty
())
271
decoration
+= u' ';
272
decoration
+=
"line-through"_L1
;
273
}
274
insertCssProperty
(u"text-decoration"_s,
decoration
);
275
}
276
}
277
278
void
StyleSheetEditorDialog
::
insertCssProperty
(
const
QString
&
name
,
const
QString
&
value
)
279
{
280
if
(!
value
.
isEmpty
()) {
281
QTextCursor
cursor
=
m_editor
->
textCursor
();
282
if
(!
name
.
isEmpty
()) {
283
cursor
.
beginEditBlock
();
284
cursor
.
removeSelectedText
();
285
cursor
.
movePosition
(
QTextCursor
::
EndOfLine
);
286
287
// Simple check to see if we're in a selector scope
288
const
QTextDocument
*
doc
=
m_editor
->
document
();
289
const
QTextCursor
closing
=
doc
->
find
(u"}"_s,
cursor
,
QTextDocument
::
FindBackward
);
290
const
QTextCursor
opening
=
doc
->
find
(u"{"_s,
cursor
,
QTextDocument
::
FindBackward
);
291
const
bool
inSelector
= !
opening
.
isNull
() && (
closing
.
isNull
() ||
292
closing
.
position
() <
opening
.
position
());
293
QString
insertion
;
294
if
(
m_editor
->
textCursor
().
block
().
length
() != 1)
295
insertion
+= u'\n';
296
if
(
inSelector
)
297
insertion
+= u'\t';
298
insertion
+=
name
;
299
insertion
+=
": "_L1
;
300
insertion
+=
value
;
301
insertion
+= u';';
302
cursor
.
insertText
(
insertion
);
303
cursor
.
endEditBlock
();
304
}
else
{
305
cursor
.
insertText
(
value
);
306
}
307
}
308
}
309
310
void
StyleSheetEditorDialog
::
slotRequestHelp
()
311
{
312
m_core
->
integration
()->
emitHelpRequested
(u"qtwidgets"_s,
313
u"stylesheet-reference.html"_s);
314
}
315
316
// See QDialog::keyPressEvent()
317
static
inline
bool
isEnter
(
const
QKeyEvent *e)
318
{
319
const
bool
isEnter = e->key() == Qt::Key_Enter;
320
const
bool
isReturn = e->key() == Qt::Key_Return;
321
return
(e->modifiers() == Qt::KeyboardModifiers() && (isEnter || isReturn))
322
|| (e->modifiers().testFlag(Qt::KeypadModifier) && isEnter);
323
}
324
325
void
StyleSheetEditorDialog
::
keyPressEvent
(
QKeyEvent
*
e
)
326
{
327
// As long as the find widget is visible, suppress the default button
328
// behavior (close on Enter) of QDialog.
329
if
(!(
m_findWidget
->
isVisible
() &&
isEnter
(
e
)))
330
QDialog
::
keyPressEvent
(
e
);
331
}
332
333
QDialogButtonBox
*
StyleSheetEditorDialog
::
buttonBox
()
const
334
{
335
return
m_buttonBox
;
336
}
337
338
QString
StyleSheetEditorDialog
::
text
()
const
339
{
340
return
m_editor
->
toPlainText
();
341
}
342
343
void
StyleSheetEditorDialog
::
setText
(
const
QString
&
t
)
344
{
345
m_editor
->
setText
(
t
);
346
}
347
348
bool
StyleSheetEditorDialog
::
isStyleSheetValid
(
const
QString
&
styleSheet
)
349
{
350
QCss
::
Parser
parser
(
styleSheet
);
351
QCss
::
StyleSheet
sheet
;
352
if
(
parser
.
parse
(&
sheet
))
353
return
true
;
354
QCss
::
Parser
parser2
(
"* { "_L1
+
styleSheet
+
'}'_L1
);
355
return
parser2
.
parse
(&
sheet
);
356
}
357
358
void
StyleSheetEditorDialog
::
validateStyleSheet
()
359
{
360
const
bool
valid
=
isStyleSheetValid
(
m_editor
->
toPlainText
());
361
setOkButtonEnabled
(
valid
);
362
if
(
valid
) {
363
m_validityLabel
->
setText
(
tr
(
"Valid Style Sheet"
));
364
m_validityLabel
->
setStyleSheet
(u"color: green"_s);
365
}
else
{
366
m_validityLabel
->
setText
(
tr
(
"Invalid Style Sheet"
));
367
m_validityLabel
->
setStyleSheet
(u"color: red"_s);
368
}
369
}
370
371
// --- StyleSheetPropertyEditorDialog
372
StyleSheetPropertyEditorDialog
::
StyleSheetPropertyEditorDialog
(
QWidget
*
parent
,
373
QDesignerFormWindowInterface
*
fw
,
374
QWidget
*
widget
):
375
StyleSheetEditorDialog
(
fw
->
core
(),
parent
),
376
m_fw
(
fw
),
377
m_widget
(
widget
)
378
{
379
Q_ASSERT
(
m_fw
!=
nullptr
);
380
381
QPushButton
*
apply
=
buttonBox
()->
addButton
(
QDialogButtonBox
::
Apply
);
382
QObject
::
connect
(
apply
, &
QAbstractButton
::
clicked
,
383
this
, &
StyleSheetPropertyEditorDialog
::
applyStyleSheet
);
384
QObject
::
connect
(
buttonBox
(), &
QDialogButtonBox
::
accepted
,
385
this
, &
StyleSheetPropertyEditorDialog
::
applyStyleSheet
);
386
387
QDesignerPropertySheetExtension
*
sheet
=
388
qt_extension
<
QDesignerPropertySheetExtension
*>(
m_fw
->
core
()->
extensionManager
(),
m_widget
);
389
Q_ASSERT
(
sheet
!=
nullptr
);
390
const
int
index
=
sheet
->
indexOf
(
styleSheetProperty
);
391
const
PropertySheetStringValue
value
=
qvariant_cast
<
PropertySheetStringValue
>(
sheet
->
property
(
index
));
392
setText
(
value
.
value
());
393
}
394
395
void
StyleSheetPropertyEditorDialog
::
applyStyleSheet
()
396
{
397
const
PropertySheetStringValue
value
(
text
(),
false
);
398
m_fw
->
cursor
()->
setWidgetProperty
(
m_widget
,
styleSheetProperty
,
QVariant
::
fromValue
(
value
));
399
}
400
401
}
// namespace qdesigner_internal
402
403
QT_END_NAMESPACE
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
qdesigner_internal::isEnter
static bool isEnter(const QKeyEvent *e)
Definition
stylesheeteditor.cpp:317
styleSheetProperty
static constexpr auto styleSheetProperty
Definition
stylesheeteditor.cpp:42
seGeometry
static constexpr auto seGeometry
Definition
stylesheeteditor.cpp:44
StyleSheetDialogC
static constexpr auto StyleSheetDialogC
Definition
stylesheeteditor.cpp:43
qttools
src
designer
src
lib
shared
stylesheeteditor.cpp
Generated on
for Qt by
1.16.1