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