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