diff --git a/assets/images/settings_call_selected.svg b/assets/images/settings_call_selected.svg
index 2a517d0f5..5fbdda3ce 100644
--- a/assets/images/settings_call_selected.svg
+++ b/assets/images/settings_call_selected.svg
@@ -5,7 +5,7 @@
Created with Sketch.
-
+
diff --git a/src/app/App.cpp b/src/app/App.cpp
index 2620f89c4..164fa7b48 100644
--- a/src/app/App.cpp
+++ b/src/app/App.cpp
@@ -106,9 +106,7 @@ App::~App () {
// -----------------------------------------------------------------------------
-inline QQuickWindow *createSubWindow (App *app, const char *path) {
- QQmlEngine *engine = app->getEngine();
-
+inline QQuickWindow *createSubWindow (QQmlApplicationEngine *engine, const char *path) {
QQmlComponent component(engine, QUrl(path));
if (component.isError()) {
qWarning() << component.errors();
@@ -117,16 +115,16 @@ inline QQuickWindow *createSubWindow (App *app, const char *path) {
QObject *object = component.create();
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
- object->setParent(app->getEngine());
+ object->setParent(engine);
return qobject_cast(object);
}
// -----------------------------------------------------------------------------
-inline void activeSplashScreen (App *app) {
+inline void activeSplashScreen (QQmlApplicationEngine *engine) {
qInfo() << QStringLiteral("Open splash screen...");
- QQuickWindow *splashScreen = ::createSubWindow(app, QML_VIEW_SPLASH_SCREEN);
+ QQuickWindow *splashScreen = ::createSubWindow(engine, QML_VIEW_SPLASH_SCREEN);
QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::coreStarted, splashScreen, [splashScreen] {
splashScreen->close();
splashScreen->deleteLater();
@@ -176,17 +174,20 @@ void App::initContentApp () {
mEngine->addImageProvider(ImageProvider::PROVIDER_ID, new ImageProvider());
mEngine->addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider());
+ mColors = new Colors(this);
+
registerTypes();
registerSharedTypes();
registerToolTypes();
+ registerSharedToolTypes();
// Enable notifications.
- createNotifier();
+ mNotifier = new Notifier(mEngine);
// Load splashscreen.
bool selfTest = mParser->isSet("self-test");
if (!selfTest)
- ::activeSplashScreen(this);
+ ::activeSplashScreen(mEngine);
// Set a self test limit.
else
QTimer::singleShot(SELF_TEST_DELAY, this, [] {
@@ -224,7 +225,7 @@ void App::executeCommand (const QString &command) {
QQuickWindow *App::getCallsWindow () {
if (!mCallsWindow)
- mCallsWindow = ::createSubWindow(this, QML_VIEW_CALLS_WINDOW);
+ mCallsWindow = ::createSubWindow(mEngine, QML_VIEW_CALLS_WINDOW);
return mCallsWindow;
}
@@ -237,7 +238,7 @@ QQuickWindow *App::getMainWindow () const {
QQuickWindow *App::getSettingsWindow () {
if (!mSettingsWindow) {
- mSettingsWindow = ::createSubWindow(this, QML_VIEW_SETTINGS_WINDOW);
+ mSettingsWindow = ::createSubWindow(mEngine, QML_VIEW_SETTINGS_WINDOW);
QObject::connect(mSettingsWindow, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) {
if (visibility == QWindow::Hidden) {
qInfo() << QStringLiteral("Update nat policy.");
@@ -338,6 +339,15 @@ void registerToolType (const char *name) {
});
}
+#define registerSharedToolType(TYPE, NAME, METHOD) qmlRegisterSingletonType( \
+ NAME, 1, 0, NAME, \
+ [](QQmlEngine *, QJSEngine *) -> QObject *{ \
+ QObject *object = METHOD(); \
+ QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); \
+ return object; \
+ } \
+)
+
void App::registerTypes () {
qInfo() << QStringLiteral("Registering types...");
@@ -387,12 +397,18 @@ void App::registerToolTypes () {
qInfo() << QStringLiteral("Registering tool types...");
registerToolType("Clipboard");
- registerToolType("Colors");
registerToolType("TextToSpeech");
registerToolType("Units");
}
+void App::registerSharedToolTypes () {
+ qInfo() << QStringLiteral("Registering shared tool types...");
+
+ registerSharedToolType(Colors, "Colors", App::getInstance()->getColors);
+}
+
#undef registerUncreatableType
+#undef registerSharedToolType
#undef registerSharedSingletonType
// -----------------------------------------------------------------------------
@@ -436,13 +452,6 @@ void App::setTrayIcon () {
// -----------------------------------------------------------------------------
-void App::createNotifier () {
- if (!mNotifier)
- mNotifier = new Notifier(this);
-}
-
-// -----------------------------------------------------------------------------
-
void App::initLocale () {
// Try to use preferred locale.
QString locale;
diff --git a/src/app/App.hpp b/src/app/App.hpp
index 0f58825b6..ca93868f0 100644
--- a/src/app/App.hpp
+++ b/src/app/App.hpp
@@ -27,6 +27,7 @@
#include
#include "../components/notifier/Notifier.hpp"
+#include "../components/other/colors/Colors.hpp"
#include "../externals/single-application/SingleApplication.hpp"
#define APP_CODE_RESTART 1000
@@ -63,6 +64,10 @@ public:
return mNotifier;
}
+ Colors *getColors () const {
+ return mColors;
+ }
+
QQuickWindow *getMainWindow () const;
bool hasFocus () const;
@@ -92,6 +97,7 @@ private:
void registerTypes ();
void registerSharedTypes ();
void registerToolTypes ();
+ void registerSharedToolTypes ();
void setTrayIcon ();
void createNotifier ();
@@ -128,6 +134,8 @@ private:
QQuickWindow *mCallsWindow = nullptr;
QQuickWindow *mSettingsWindow = nullptr;
+ Colors *mColors = nullptr;
+
Cli *mCli = nullptr;
};
diff --git a/src/app/providers/ImageProvider.cpp b/src/app/providers/ImageProvider.cpp
index 2462810b9..d7fdd687b 100644
--- a/src/app/providers/ImageProvider.cpp
+++ b/src/app/providers/ImageProvider.cpp
@@ -28,6 +28,8 @@
#include
#include
+#include "../App.hpp"
+
#include "ImageProvider.hpp"
// Max image size in bytes. (100Kb)
@@ -35,28 +37,73 @@
// =============================================================================
-const QString ImageProvider::PROVIDER_ID = "internal";
+static QByteArray buildByteArrayAttribute (const QByteArray &name, const QByteArray &value) {
+ QByteArray attribute = name;
+ attribute.append("=\"");
+ attribute.append(value);
+ attribute.append("\" ");
+ return attribute;
+}
-ImageProvider::ImageProvider () : QQuickImageProvider(
- QQmlImageProviderBase::Image,
- QQmlImageProviderBase::ForceAsynchronousImageLoading
- ) {}
+static QByteArray fillFillAndStroke (QXmlStreamAttributes &readerAttributes, bool &fill, bool &stroke, const Colors &colors) {
+ static QRegExp regex("^color-([^-]+)-(fill|stroke)$");
-// -----------------------------------------------------------------------------
-
-static QByteArray parseAttributes (QXmlStreamReader &reader) {
QByteArray attributes;
- for (const auto &attribute : reader.attributes()) {
- const QByteArray prefix = attribute.prefix().toLatin1();
+ QByteArray value = readerAttributes.value("class").toLatin1();
+ if (!value.length())
+ return attributes;
+
+ for (const auto &subValue : value.split(' ')) {
+ regex.indexIn(subValue.trimmed());
+ const QStringList list = regex.capturedTexts();
+ if (list.length() != 3)
+ continue;
+
+ const QString colorName = list[1];
+ QVariant colorValue = colors.property(colorName.toStdString().c_str());
+ if (!colorValue.isValid()) {
+ qWarning() << QStringLiteral("Color name `%1` does not exist.").arg(colorName);
+ continue;
+ }
+
+ QByteArray property = list[2].toLatin1();
+ if (property == QStringLiteral("fill"))
+ fill = true;
+ else
+ stroke = true;
+
+ attributes.append(
+ buildByteArrayAttribute(
+ property,
+ colorValue.value().name().toLatin1()
+ )
+ );
+ }
+
+ return attributes;
+}
+
+static QByteArray parseAttributes (QXmlStreamReader &reader, const Colors &colors) {
+ QXmlStreamAttributes readerAttributes = reader.attributes();
+ bool fill = false, stroke = false;
+ QByteArray attributes = fillFillAndStroke(readerAttributes, fill, stroke, colors);
+
+ for (const auto &attribute : readerAttributes) {
+ QByteArray name = attribute.name().toLatin1();
+ if (fill && name == QStringLiteral("fill"))
+ continue;
+ if (stroke && name == QStringLiteral("stroke"))
+ continue;
+
+ QByteArray prefix = attribute.prefix().toLatin1();
+ QByteArray value = attribute.value().toLatin1();
+
if (prefix.length() > 0) {
attributes.append(prefix);
attributes.append(":");
}
- attributes.append(attribute.name().toLatin1());
- attributes.append("=\"");
- attributes.append(attribute.value().toLatin1());
- attributes.append("\" ");
+ attributes.append(buildByteArrayAttribute(name, value));
}
return attributes;
@@ -65,7 +112,7 @@ static QByteArray parseAttributes (QXmlStreamReader &reader) {
static QByteArray parseDeclarations (QXmlStreamReader &reader) {
QByteArray declarations;
for (const auto &declaration : reader.namespaceDeclarations()) {
- const QByteArray prefix = declaration.prefix().toLatin1();
+ QByteArray prefix = declaration.prefix().toLatin1();
if (prefix.length() > 0) {
declarations.append("xmlns:");
declarations.append(prefix);
@@ -89,11 +136,11 @@ static QByteArray parseStartDocument (QXmlStreamReader &reader) {
return startDocument;
}
-static QByteArray parseStartElement (QXmlStreamReader &reader) {
+static QByteArray parseStartElement (QXmlStreamReader &reader, const Colors &colors) {
QByteArray startElement = "<";
startElement.append(reader.name().toLatin1());
startElement.append(" ");
- startElement.append(parseAttributes(reader));
+ startElement.append(parseAttributes(reader, colors));
startElement.append(" ");
startElement.append(parseDeclarations(reader));
startElement.append(">");
@@ -110,6 +157,8 @@ static QByteArray parseEndElement (QXmlStreamReader &reader) {
// -----------------------------------------------------------------------------
static QByteArray computeContent (QFile &file) {
+ const Colors *colors = App::getInstance()->getColors();
+
QByteArray content;
QXmlStreamReader reader(&file);
while (!reader.atEnd())
@@ -127,7 +176,7 @@ static QByteArray computeContent (QFile &file) {
break;
case QXmlStreamReader::StartElement:
- content.append(parseStartElement(reader));
+ content.append(parseStartElement(reader, *colors));
break;
case QXmlStreamReader::EndElement:
@@ -148,6 +197,15 @@ static QByteArray computeContent (QFile &file) {
// -----------------------------------------------------------------------------
+const QString ImageProvider::PROVIDER_ID = "internal";
+
+ImageProvider::ImageProvider () : QQuickImageProvider(
+ QQmlImageProviderBase::Image,
+ QQmlImageProviderBase::ForceAsynchronousImageLoading
+ ) {}
+
+// -----------------------------------------------------------------------------
+
QImage ImageProvider::requestImage (const QString &id, QSize *, const QSize &) {
const QString path = QStringLiteral(":/assets/images/%1").arg(id);