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
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
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{
38 QQmlError error;
39 error.setUrl(translationBindingInformation.compilationUnit->url());
40 error.setLine(translationBindingInformation.line);
41 error.setColumn(translationBindingInformation.column);
42 error.setDescription(
43 QString(QLatin1String(
44 "QDebug translation binding"
45 )));
46 return debug << qPrintable(error.toString());
47}
48
49static QString translationIdString(const QQmlTranslation::QsTrData &data)
50{
51 return QString::fromUtf8(data.text());
52}
53
54static QString translationIdString(const QQmlTranslation::QsTrIdData &data)
55{
56 return QString::fromUtf8(data.id());
57}
58
59static QString translationIdString(const QQmlTranslation &translation)
60{
61 return translation.visit(
62 [](auto &&arg) -> QString {
63 using T = std::decay_t<decltype(arg)>;
64 if constexpr (!std::is_same_v<T, std::nullptr_t>)
65 return translationIdString(arg);
66 else {
67 Q_ASSERT_X(false, "QQmlTranslation", "Uninitialized Translation");
68 return {};
69 }
70 });
71}
72
74{
76public:
84
99
108
130
132 {
133 // TODO: for disabling we need to keep track which one were enabled
134 if (s == false)
135 qWarning() << "disable WatchTextElides is not implemented";
140 if (elideIndex >= 0) {
143 }
144 }
145 }
146
148 {
149 if (font.styleName() != "")
150 return font.styleName();
152 if (font.bold())
153 styleName.append("Bold ");
154 if (font.italic())
155 styleName.append("Italic " );
156 if (font.strikeOut())
157 styleName.append("StrikeThrough ");
158 if (font.underline())
159 styleName.append("Underline ");
160 return styleName.trimmed();
161 }
162
164 {
165
168
170
172
176
178 if (textIndex >= 0) {
179
181
183
189
196 scopeObject->property("horizontalAlignment").toInt();
197 qmlElement.verticalAlignment = scopeObject->property("verticalAlignment").toInt();
198
203
204 } else {
205 QString warningMessage = "(QQmlDebugTranslationService can not resolve %1 - %2:"
206 " this should never happen)";
209 }
210 }
211 std::sort(qmlElements.begin(), qmlElements.end(), [](const auto &l1, const auto &l2){
212 return l1.codeMarker < l2.codeMarker;
213 });
214
217 }
218
225
259
261
262 bool watchTextElides = false;
265 ProxyTranslator *proxyTranslator;
266
270
271 QQuickItem *currentRootItem()
272 {
273 if (QQmlPreviewServiceImpl *service = QQmlDebugConnector::service<QQmlPreviewServiceImpl>())
274 return service->currentRootItem();
275 if (currentQuickView)
276 return currentQuickView->rootObject();
277 return nullptr;
278 }
280
281private:
282 CodeMarker codeMarker(const TranslationBindingInformation &information)
283 {
284 CodeMarker c;
285 c.url = information.compilationUnit->url();
286 c.line = information.line;
287 c.column = information.column;
288 return c;
289 }
290 QString currentStateName;
291};
292
293QQmlDebugTranslationServiceImpl::QQmlDebugTranslationServiceImpl(QObject *parent)
294 : QQmlDebugTranslationService(1, parent)
295{
296 d = new QQmlDebugTranslationServicePrivate(this);
297
298 connect(this, &QQmlDebugTranslationServiceImpl::watchTextElides,
299 d, &QQmlDebugTranslationServicePrivate::setWatchTextElides,
300 Qt::QueuedConnection);
301
302 connect(this, &QQmlDebugTranslationServiceImpl::language,
303 d->proxyTranslator, &ProxyTranslator::setLanguage,
304 Qt::QueuedConnection);
305
306 connect(this, &QQmlDebugTranslationServiceImpl::state,
307 d, &QQmlDebugTranslationServicePrivate::setState,
308 Qt::QueuedConnection);
309
310 connect(this, &QQmlDebugTranslationServiceImpl::stateList,
311 d, &QQmlDebugTranslationServicePrivate::sendStateList,
312 Qt::QueuedConnection);
313
314 connect(d->proxyTranslator, &ProxyTranslator::languageChanged,
315 d, &QQmlDebugTranslationServicePrivate::sendLanguageChanged,
316 Qt::QueuedConnection);
317
318 connect(this, &QQmlDebugTranslationServiceImpl::translationIssues,
319 d, &QQmlDebugTranslationServicePrivate::sendTranslationIssues,
320 Qt::QueuedConnection);
321
322 connect(this, &QQmlDebugTranslationServiceImpl::sendTranslatableTextOccurrences,
323 d, &QQmlDebugTranslationServicePrivate::sendTranslatableTextOccurrences,
324 Qt::QueuedConnection);
325}
326
332
333void QQmlDebugTranslationServiceImpl::messageReceived(const QByteArray &message)
334{
335 QVersionedPacket<QQmlDebugConnector> packet(message);
336 QQmlDebugTranslation::Request command;
337
338 packet >> command;
339 switch (command) {
340 case QQmlDebugTranslation::Request::ChangeLanguage: {
341 QUrl context;
342 QString locale;
343 packet >> context >> locale;
344 emit language(context, QLocale(locale));
345 break;
346 }
347 case QQmlDebugTranslation::Request::ChangeState: {
348 QString stateName;
349 packet >> stateName;
350 emit state(stateName);
351 break;
352 }
353 case QQmlDebugTranslation::Request::StateList: {
354 emit stateList();
355 break;
356 }
357 case QQmlDebugTranslation::Request::TranslationIssues: {
358 emit translationIssues();
359 break;
360 }
361 case QQmlDebugTranslation::Request::TranslatableTextOccurrences: {
362 emit sendTranslatableTextOccurrences();
363 break;
364 }
365 case QQmlDebugTranslation::Request::WatchTextElides: {
366 emit watchTextElides(true);
367 break;
368 }
369 case QQmlDebugTranslation::Request::DisableWatchTextElides: {
370 emit watchTextElides(false);
371 break;
372 }
373 default: {
374 qWarning() << "DebugTranslationService: received unknown command: " << static_cast<int>(command);
375 break;
376 }
377 } // switch (command)
378}
379
381{
382 if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
383 d->proxyTranslator->addEngine(qmlEngine);
384
385 if (engine->parent())
386 d->currentQuickView = qobject_cast<QQuickView*>(engine->parent());
387
388 emit attachedToEngine(engine);
389}
390
392{
393 if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
394 d->proxyTranslator->removeEngine(qmlEngine);
395 emit detachedFromEngine(engine);
396}
397
398void QQmlDebugTranslationServiceImpl::foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation)
399{
400 QObject *scopeObject = translationBindingInformation.scopeObject;
401 connect(scopeObject, &QObject::destroyed, this, [this, scopeObject] () {
402 this->d->objectTranslationBindingMultiMap.remove(scopeObject);
403 });
404
405 d->objectTranslationBindingMultiMap.insert(scopeObject, translationBindingInformation);
406}
407
408QT_END_NAMESPACE
409
410#include "moc_qqmldebugtranslationservice.cpp"
411
412#include <qqmldebugtranslationservice.moc>
void messageReceived(const QByteArray &message) override
void foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation) override
void engineAboutToBeAdded(QJSEngine *engine) override
void engineAboutToBeRemoved(QJSEngine *engine) override
QMultiMap< QObject *, TranslationBindingInformation > objectTranslationBindingMultiMap
QList< QPointer< QQuickItem > > translatableTextOccurrences
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
static QString translationIdString(const QQmlTranslation::QsTrData &data)