Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmldebugtranslationservice.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "proxytranslator.h"
7
8#include <QtCore/qtranslator.h>
9#include <QtCore/qdebug.h>
10#include <QtCore/qlibraryinfo.h>
11#include <QtCore/qdir.h>
12#include <QtCore/qfile.h>
13#include <QtCore/qtimer.h>
14#include <QtCore/qhash.h>
15#include <QtCore/qpointer.h>
16
17#include <private/qqmldebugtranslationprotocol_p.h>
18#include <private/qqmldebugconnector_p.h>
19#include <private/qversionedpacket_p.h>
20
21#include <private/qqmlbinding_p.h>
22#include <private/qqmlbinding_p.h>
23#include <private/qquickstategroup_p.h>
24#include <private/qquickitem_p.h>
25#include <private/qquicktext_p.h>
26#include <private/qdebug_p.h>
27
28#include <QtQuick/qquickitem.h>
29
30#include <qquickview.h>
31
33
34using namespace QQmlDebugTranslation;
35
36QDebug operator<<(QDebug debug, const TranslationBindingInformation &translationBindingInformation)
37{
39 error.setUrl(translationBindingInformation.compilationUnit->url());
40 error.setLine(translationBindingInformation.line);
41 error.setColumn(translationBindingInformation.column);
42 error.setDescription(
44 "QDebug translation binding"
45 )));
46 return debug << qPrintable(error.toString());
47}
48
50{
52public:
60
61 void setState(const QString &stateName)
62 {
64 QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states();
65 if (stateGroup->findState(stateName)) {
69 stateGroup->setState(stateName);
70 }
71 else
72 qWarning() << "Could not switch the state" << stateName << "at" << rootItem;
73 }
74 }
75
77 {
78 if (QQuickStateGroup *stateGroup = qobject_cast<QQuickStateGroup*>(sender()))
79 currentStateName = stateGroup->state();
80 QVersionedPacket<QQmlDebugConnector> packet;
81 packet << Reply::StateChanged << currentStateName;
82 emit q->messageToClient(q->name(), packet.data());
83 }
84
86 {
87 QVersionedPacket<QQmlDebugConnector> packet;
88 packet << Reply::StateList;
89 QVector<QmlState> qmlStates;
90
92 QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states();
93
94 QList<QQuickState *> states = stateGroup->states();
95
96 for (QQuickState *state : states) {
97 QmlState qmlState;
98 qmlState.name = state->name();
99 qmlStates.append(qmlState);
100 }
101 }
102
103 packet << qmlStates;
104 emit q->messageToClient(q->name(), packet.data());
105 }
106
108 {
109 // TODO: for disabling we need to keep track which one were enabled
110 if (s == false)
111 qWarning() << "disable WatchTextElides is not implemented";
113 for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
114 QObject *scopeObject = information.scopeObject;
115 int elideIndex = scopeObject->metaObject()->indexOfProperty("elide");
116 if (elideIndex >= 0) {
117 auto elideProperty = scopeObject->metaObject()->property(elideIndex);
118 elideProperty.write(scopeObject, Qt::ElideRight);
119 }
120 }
121 }
122
124 {
125 if (font.styleName() != "")
126 return font.styleName();
127 QString styleName;
128 if (font.bold())
129 styleName.append("Bold ");
130 if (font.italic())
131 styleName.append("Italic " );
132 if (font.strikeOut())
133 styleName.append("StrikeThrough ");
134 if (font.underline())
135 styleName.append("Underline ");
136 return styleName.trimmed();
137 }
138
140 {
141
142 QVersionedPacket<QQmlDebugConnector> packet;
143 packet << Reply::TranslatableTextOccurrences;
144
145 QVector<QmlElement> qmlElements;
146
147 for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
148
149 QObject *scopeObject = information.scopeObject;
150 auto compilationUnit = information.compilationUnit;
151 auto metaObject = scopeObject->metaObject();
152
153 int textIndex = metaObject->indexOfProperty(information.propertyName.toLatin1());
154 if (textIndex >= 0) {
155
156 QmlElement qmlElement;
157
158 qmlElement.codeMarker = codeMarker(information);
159
160 auto textProperty = scopeObject->metaObject()->property(textIndex);
161 qmlElement.propertyName = textProperty.name();
162 qmlElement.translationId = information.translation.idForQmlDebug();
163 qmlElement.translatedText = textProperty.read(scopeObject).toString();
164 qmlElement.elementId = qmlContext(scopeObject)->nameForObject(scopeObject);
165
166 QFont font = scopeObject->property("font").value<QFont>();
167 qmlElement.fontFamily = font.family();
168 qmlElement.fontPointSize = font.pointSize();
169 qmlElement.fontPixelSize = font.pixelSize();
170 qmlElement.fontStyleName = getStyleNameForFont(font);
171 qmlElement.horizontalAlignment =
172 scopeObject->property("horizontalAlignment").toInt();
173 qmlElement.verticalAlignment = scopeObject->property("verticalAlignment").toInt();
174
176 qmlElement.elementType = qmlType.qmlTypeName() + "/" + qmlType.typeName();
177 qmlElement.stateName = currentStateName;
178 qmlElements.append(qmlElement);
179
180 } else {
181 QString warningMessage = "(QQmlDebugTranslationService can not resolve %1 - %2:"\
182 " this should never happen)";
183 const QString id = qmlContext(scopeObject)->nameForObject(scopeObject);
184 qWarning().noquote() << warningMessage.arg(id, information.propertyName);
185 }
186 }
187 std::sort(qmlElements.begin(), qmlElements.end(), [](const auto &l1, const auto &l2){
188 return l1.codeMarker < l2.codeMarker;
189 });
190
191 packet << qmlElements;
192 emit q->messageToClient(q->name(), packet.data());
193 }
194
196 {
197 QVersionedPacket<QQmlDebugConnector> packet;
198 packet << Reply::LanguageChanged;
199 emit q->messageToClient(q->name(), packet.data());
200 }
201
203 {
204 QVersionedPacket<QQmlDebugConnector> packet;
205 packet << Reply::TranslationIssues;
206
207 QVector<TranslationIssue> issues;
208 for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
209 if (!proxyTranslator->hasTranslation(information)) {
210 TranslationIssue issue;
211 issue.type = TranslationIssue::Type::Missing;
212 issue.codeMarker = codeMarker(information);
213 issue.language = proxyTranslator->currentUILanguages();
214 issues.append(issue);
215 }
216
217 QObject *scopeObject = information.scopeObject;
218 QQuickText *quickText = static_cast<QQuickText*>(scopeObject);
219 if (quickText) {
220 if (quickText->truncated()) {
221 TranslationIssue issue;
222 issue.type = TranslationIssue::Type::Elided;
223 issue.codeMarker = codeMarker(information);
224 issue.language = proxyTranslator->currentUILanguages();
225 issues.append(issue);
226 }
227 }
228 }
229 std::sort(issues.begin(), issues.end(), [](const auto &l1, const auto &l2){
230 return l1.codeMarker < l2.codeMarker;
231 });
232 packet << issues;
233 emit q->messageToClient(q->name(), packet.data());
234 }
235
237
238 bool watchTextElides = false;
239 QMultiMap<QObject*, TranslationBindingInformation> objectTranslationBindingMultiMap;
240 QHash<QObject*, QVector<QMetaObject::Connection>> elideConnections;
242
245 QList<QPointer<QQuickItem>> translatableTextOccurrences;
246
248 {
249 if (QQmlPreviewServiceImpl *service = QQmlDebugConnector::service<QQmlPreviewServiceImpl>())
250 return service->currentRootItem();
253 return nullptr;
254 }
256
257private:
258 CodeMarker codeMarker(const TranslationBindingInformation &information)
259 {
261 c.url = information.compilationUnit->url();
262 c.line = information.line;
263 c.column = information.column;
264 return c;
265 }
266 QString currentStateName;
267};
268
302
308
310{
311 QVersionedPacket<QQmlDebugConnector> packet(message);
313
314 packet >> command;
315 switch (command) {
318 QString locale;
319 packet >> context >> locale;
320 emit language(context, QLocale(locale));
321 break;
322 }
324 QString stateName;
325 packet >> stateName;
326 emit state(stateName);
327 break;
328 }
330 emit stateList();
331 break;
332 }
335 break;
336 }
339 break;
340 }
342 emit watchTextElides(true);
343 break;
344 }
346 emit watchTextElides(false);
347 break;
348 }
349 default: {
350 qWarning() << "DebugTranslationService: received unknown command: " << static_cast<int>(command);
351 break;
352 }
353 } // switch (command)
354}
355
357{
358 if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
360
361 if (engine->parent())
362 d->currentQuickView = qobject_cast<QQuickView*>(engine->parent());
363
364 emit attachedToEngine(engine);
365}
366
368{
369 if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
371 emit detachedFromEngine(engine);
372}
373
374void QQmlDebugTranslationServiceImpl::foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation)
375{
376 QObject *scopeObject = translationBindingInformation.scopeObject;
377 connect(scopeObject, &QObject::destroyed, this, [this, scopeObject] () {
378 this->d->objectTranslationBindingMultiMap.remove(scopeObject);
379 });
380
381 d->objectTranslationBindingMultiMap.insert(scopeObject, translationBindingInformation);
382}
383
385
386#include "moc_qqmldebugtranslationservice.cpp"
387
388#include <qqmldebugtranslationservice.moc>
void removeEngine(QQmlEngine *engine)
void languageChanged(const QLocale &locale)
bool hasTranslation(const TranslationBindingInformation &translationBindingInformation) const
void addEngine(QQmlEngine *engine)
void setLanguage(const QUrl &context, const QLocale &locale)
QString currentUILanguages() const
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
\reentrant
Definition qfont.h:22
QString family() const
Returns the requested font family name.
Definition qfont.cpp:817
QString styleName() const
Definition qfont.cpp:849
int pixelSize() const
Returns the pixel size of the font if it was set with setPixelSize().
Definition qfont.cpp:1074
bool italic() const
Returns true if the style() of the font is not QFont::StyleNormal.
Definition qfont.h:376
bool strikeOut() const
Returns true if strikeout has been set; otherwise returns false.
Definition qfont.cpp:1304
bool underline() const
Returns true if underline has been set; otherwise returns false.
Definition qfont.cpp:1251
int pointSize() const
Returns the point size of the font.
Definition qfont.cpp:884
bool bold() const
Returns true if weight() is a value greater than \l{Weight}{QFont::Medium}; otherwise returns false.
Definition qfont.h:369
The QJSEngine class provides an environment for evaluating JavaScript code.
Definition qjsengine.h:26
iterator insert(const Key &key, const T &value)
Definition qmap.h:1452
size_type remove(const Key &key)
Definition qmap.h:971
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition qobject.cpp:2658
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4323
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QString nameForObject(const QObject *) const
Returns the name of object in this context, or an empty string if object is not named in the context.
QQmlDebugTranslationServiceImpl(QObject *parent=nullptr)
void messageReceived(const QByteArray &message) override
void foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation) override
void engineAboutToBeAdded(QJSEngine *engine) override
void state(const QString &stateName)
void engineAboutToBeRemoved(QJSEngine *engine) override
void language(const QUrl &context, const QLocale &locale)
QHash< QObject *, QVector< QMetaObject::Connection > > elideConnections
QQmlDebugTranslationServicePrivate(QQmlDebugTranslationServiceImpl *parent)
QMultiMap< QObject *, TranslationBindingInformation > objectTranslationBindingMultiMap
QList< QPointer< QQuickItem > > translatableTextOccurrences
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version)
Returns the type (if any) of URI-qualified named qualifiedName and version specified by version_major...
QString qmlTypeName() const
Definition qqmltype.cpp:469
QByteArray typeName() const
Definition qqmltype.cpp:451
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQuickState * findState(const QString &name) const
QQmlListProperty< QQuickState > states
void setState(const QString &)
void stateChanged(const QString &)
The QQuickView class provides a window for displaying a Qt Quick user interface.
Definition qquickview.h:20
QQuickItem * rootObject() const
Returns the view's root \l {QQuickItem} {item}.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8870
QString & append(QChar c)
Definition qstring.cpp:3252
QString trimmed() const &
Definition qstring.h:447
\inmodule QtCore
Definition qtimer.h:20
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
\inmodule QtCore
Definition qurl.h:94
T value() const &
Definition qvariant.h:516
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
else opt state
[0]
Combined button and popup list for selecting options.
ConnectionType
@ QueuedConnection
@ UniqueConnection
@ ElideRight
Definition qnamespace.h:190
static void * context
DBusConnection const char DBusError * error
#define qWarning
Definition qlogging.h:166
GLuint GLsizei const GLchar * message
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint * states
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
QDebug operator<<(QDebug debug, const TranslationBindingInformation &translationBindingInformation)
const QQuickItem * rootItem(const I &item)
#define qPrintable(string)
Definition qstring.h:1531
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define Q_OBJECT
#define emit
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
obj metaObject() -> className()
QJSEngine engine
[0]