Merge lp:~kalikiana/ubuntu-ui-toolkit/appname into lp:ubuntu-ui-toolkit

Proposed by Cris Dywan
Status: Merged
Approved by: Zoltan Balogh
Approved revision: 713
Merged at revision: 752
Proposed branch: lp:~kalikiana/ubuntu-ui-toolkit/appname
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 376 lines (+286/-0)
9 files modified
modules/Ubuntu/Components/MainView.qml (+5/-0)
modules/Ubuntu/Components/plugin/plugin.cpp (+7/-0)
modules/Ubuntu/Components/plugin/plugin.pro (+2/-0)
modules/Ubuntu/Components/plugin/ucapplication.cpp (+57/-0)
modules/Ubuntu/Components/plugin/ucapplication.h (+53/-0)
tests/unit/tst_mainview/AppName.qml (+23/-0)
tests/unit/tst_mainview/tst_mainview.cpp (+132/-0)
tests/unit/tst_mainview/tst_mainview.pro (+6/-0)
tests/unit/unit.pro (+1/-0)
To merge this branch: bzr merge lp:~kalikiana/ubuntu-ui-toolkit/appname
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Zsombor Egri Approve
Tim Peeters Pending
Review via email: mp+180601@code.launchpad.net

Commit message

Set QCoreApplication::applicationName based on MainView

To post a comment you must log in.
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

Should this be ApplicationIdentifier in our API? AFAIK we are using $APP_ID and "Application Identifier" in our docs and discussion.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

why do you need applicationName in i18n? Is it really something different than domain, and can you not use only one variables that combines these two?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

why do you need organizationName?

Revision history for this message
Cris Dywan (kalikiana) wrote :

> why do you need organizationName?

As the code says: "// Unset organization to skip an extra folder component"

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

63 + qmlRegisterUncreatableType<UCApplication>(uri, 0, 1, "Application", "Singleton object");

This is not needed. Pls remove.

Revision history for this message
Zsombor Egri (zsombi) wrote :

35 + /* Set name and organization on Application which QStandardPaths
36 + honors to construct folders.
37 + This works across platforms. For confinement we rely on the fact
38 + that the folders are whitelisted based on the app name. Similar
39 + to how Unity uses it to distinguish running applications.
40 + */
41 + UbuntuApplication.applicationName = applicationName
42 + // Unset organization to skip an extra folder component
43 + UbuntuApplication.organizationName = ""

If we anyway set the organizationName to an empty string, shouldn't we do this in the UCApplication itself? Do we have to expose it? Or do you expect to use it at some point in QML?

Revision history for this message
Zsombor Egri (zsombi) wrote :

Nice one! Have you ran unit tests on the device?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

I'm not able to do anything with my device at the moment because it doesn't boot, so this is all tested on the desktop only, I'm still trying to figure out what the problem is.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

seems you have errors in documentation.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

Good to go!

review: Approve
Revision history for this message
Zsombor Egri (zsombi) wrote :

Hold on, if I create a QSettings() object right after the application name is set, the path the setting file will be located will look as follows: ~/.config/qt-project.org/AppName.conf.
If I create it with QSetting("", UCApplication::instance().applicationName()), the file path will be ~/.config/Unknown Organization/AppName.conf.

Seems the QCoreApplication::organizationName = "" wasn't good enough. If I set the organizationName to the same as applicationName, then the setting file will be in ~/.config/AppName/AppName.conf

review: Needs Fixing
Revision history for this message
Cris Dywan (kalikiana) wrote :

The problem is in QSettings using its own mechanism to build the path which diverges from the rest of Qt as far as I can say - so either we can find a way to override it or we need to patch it. All other APIs will add another folder level when setting an organizationName even if it's the app name.

Revision history for this message
Zsombor Egri (zsombi) wrote :

OK, then let's forget about this. We will use QSetting with custom
constructor.

On Wed, Sep 18, 2013 at 7:09 PM, Christian Dywan <email address hidden>wrote:

> The problem is in QSettings using its own mechanism to build the path
> which diverges from the rest of Qt as far as I can say - so either we can
> find a way to override it or we need to patch it. All other APIs will add
> another folder level when setting an organizationName even if it's the app
> name.
> --
>
> https://code.launchpad.net/~kalikiana/ubuntu-ui-toolkit/appname/+merge/180601
> You are reviewing the proposed merge of
> lp:~kalikiana/ubuntu-ui-toolkit/appname into lp:ubuntu-ui-toolkit.
>

Revision history for this message
Zsombor Egri (zsombi) :
review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Affected by bug 1229110

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'modules/Ubuntu/Components/MainView.qml'
--- modules/Ubuntu/Components/MainView.qml 2013-08-22 17:15:35 +0000
+++ modules/Ubuntu/Components/MainView.qml 2013-09-23 08:32:16 +0000
@@ -133,6 +133,10 @@
133 \preliminary133 \preliminary
134 The property holds the application's name, which must be the same as the134 The property holds the application's name, which must be the same as the
135 desktop file's name.135 desktop file's name.
136 The name also sets the name of the QCoreApplication and defaults for data
137 and cache folders that work on the desktop and under confinement.
138 C++ code that writes files may use QStandardPaths::writableLocation with
139 QStandardPaths::DataLocation or QStandardPaths::CacheLocation.
136 */140 */
137 property string applicationName: ""141 property string applicationName: ""
138142
@@ -334,6 +338,7 @@
334 onApplicationNameChanged: {338 onApplicationNameChanged: {
335 if (applicationName !== "") {339 if (applicationName !== "") {
336 i18n.domain = applicationName;340 i18n.domain = applicationName;
341 UbuntuApplication.applicationName = applicationName
337 }342 }
338 }343 }
339}344}
340345
=== modified file 'modules/Ubuntu/Components/plugin/plugin.cpp'
--- modules/Ubuntu/Components/plugin/plugin.cpp 2013-08-23 11:13:21 +0000
+++ modules/Ubuntu/Components/plugin/plugin.cpp 2013-09-23 08:32:16 +0000
@@ -42,6 +42,7 @@
42#include "ucfontutils.h"42#include "ucfontutils.h"
43#include "ucarguments.h"43#include "ucarguments.h"
44#include "ucargument.h"44#include "ucargument.h"
45#include "ucapplication.h"
45#include "ucalarm.h"46#include "ucalarm.h"
46#include "ucalarmmodel.h"47#include "ucalarmmodel.h"
47#include "unitythemeiconprovider.h"48#include "unitythemeiconprovider.h"
@@ -167,6 +168,12 @@
167 QObject::connect(&UbuntuI18n::instance(), SIGNAL(languageChanged()),168 QObject::connect(&UbuntuI18n::instance(), SIGNAL(languageChanged()),
168 &i18nChangeListener, SLOT(updateContextProperty()));169 &i18nChangeListener, SLOT(updateContextProperty()));
169170
171 // We can't use 'Application' because it exists (undocumented)
172 context->setContextProperty("UbuntuApplication", &UCApplication::instance());
173 static ContextPropertyChangeListener applicationChangeListener(context, "UbuntuApplication");
174 QObject::connect(&UCApplication::instance(), SIGNAL(applicationNameChanged()),
175 &applicationChangeListener, SLOT(updateContextProperty()));
176
170 context->setContextProperty("units", &UCUnits::instance());177 context->setContextProperty("units", &UCUnits::instance());
171 static ContextPropertyChangeListener unitsChangeListener(context, "units");178 static ContextPropertyChangeListener unitsChangeListener(context, "units");
172 QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()),179 QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()),
173180
=== modified file 'modules/Ubuntu/Components/plugin/plugin.pro'
--- modules/Ubuntu/Components/plugin/plugin.pro 2013-08-28 14:07:46 +0000
+++ modules/Ubuntu/Components/plugin/plugin.pro 2013-09-23 08:32:16 +0000
@@ -40,6 +40,7 @@
40 qquickclipboard_p.h \40 qquickclipboard_p.h \
41 ucubuntuanimation.h \41 ucubuntuanimation.h \
42 ucfontutils.h \42 ucfontutils.h \
43 ucapplication.h \
43 ucarguments.h \44 ucarguments.h \
44 ucargument.h \45 ucargument.h \
45 ucalarm.h \46 ucalarm.h \
@@ -68,6 +69,7 @@
68 qquickmimedata.cpp \69 qquickmimedata.cpp \
69 ucubuntuanimation.cpp \70 ucubuntuanimation.cpp \
70 ucfontutils.cpp \71 ucfontutils.cpp \
72 ucapplication.cpp \
71 ucarguments.cpp \73 ucarguments.cpp \
72 ucargument.cpp \74 ucargument.cpp \
73 ucalarm.cpp \75 ucalarm.cpp \
7476
=== added file 'modules/Ubuntu/Components/plugin/ucapplication.cpp'
--- modules/Ubuntu/Components/plugin/ucapplication.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/ucapplication.cpp 2013-09-23 08:32:16 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Christian Dywan <christian.dywan@canonical.om>
17 */
18
19#include "ucapplication.h"
20
21#include <QtCore/QCoreApplication>
22#include <QDebug>
23
24/*!
25 * \qmltype UbuntuApplication
26 * \instantiates UCApplication
27 * \inqmlmodule Ubuntu.Components 0.1
28 * \ingroup ubuntu
29 * \brief UbuntuApplication is a QML binding for a subset of QCoreApplication.
30 *
31 * UbuntuApplication is a context property in QML.
32 */
33UCApplication::UCApplication(QObject* parent) : QObject(parent)
34{
35}
36
37/*!
38 * \qmlproperty string Application::applicationName
39 * \internal
40 * The name of the application, see QCoreApplication::applicationName
41 */
42QString UCApplication::applicationName() {
43 return QCoreApplication::applicationName();
44}
45
46void UCApplication::setApplicationName(QString applicationName) {
47 /* QStandardPaths uses the name to build folder names.
48 This works across platforms. For confinement we rely on the fact
49 that the folders are whitelisted based on the app name. Similar
50 to how Unity uses it to distinguish running applications.
51 */
52 QCoreApplication::setApplicationName(applicationName);
53 // Unset organization to skip an extra folder component
54 QCoreApplication::setOrganizationName("");
55 Q_EMIT applicationNameChanged();
56}
57
058
=== added file 'modules/Ubuntu/Components/plugin/ucapplication.h'
--- modules/Ubuntu/Components/plugin/ucapplication.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/ucapplication.h 2013-09-23 08:32:16 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Christian Dywan <christian.dywan@canonical.om>
17 */
18
19#ifndef UBUNTU_COMPONENTS_APPLICATION_H
20#define UBUNTU_COMPONENTS_APPLICATION_H
21
22#include <QtCore/QObject>
23
24class QQmlContext;
25class QQmlEngine;
26
27class UCApplication : public QObject
28{
29 Q_OBJECT
30 Q_PROPERTY(QString applicationName READ applicationName WRITE setApplicationName NOTIFY applicationNameChanged)
31
32private:
33 Q_DISABLE_COPY(UCApplication)
34 explicit UCApplication(QObject* parent = 0);
35
36
37public:
38 static UCApplication& instance() {
39 static UCApplication instance;
40 return instance;
41 }
42
43 // getter
44 QString applicationName();
45
46 // setter
47 void setApplicationName(QString applicationName);
48
49Q_SIGNALS:
50 void applicationNameChanged();
51};
52
53#endif // UBUNTU_COMPONENTS_I18N_H
054
=== added directory 'tests/unit/tst_mainview'
=== added file 'tests/unit/tst_mainview/AppName.qml'
--- tests/unit/tst_mainview/AppName.qml 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_mainview/AppName.qml 2013-09-23 08:32:16 +0000
@@ -0,0 +1,23 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components 0.1
19
20MainView {
21 objectName: "appName"
22 applicationName: "org.gnu.wildebeest"
23}
024
=== added file 'tests/unit/tst_mainview/tst_mainview.cpp'
--- tests/unit/tst_mainview/tst_mainview.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_mainview/tst_mainview.cpp 2013-09-23 08:32:16 +0000
@@ -0,0 +1,132 @@
1/*
2 * Copyright 2012-2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Christian Dywan <christian.dywan@canonical.com>
17 */
18
19#include <QtCore/QString>
20#include <QtCore/QTextCodec>
21#include <QtCore/QStandardPaths>
22#include <QtCore/QProcessEnvironment>
23#include <QtCore/QDebug>
24#include <QtTest/QTest>
25#include <QtTest/QSignalSpy>
26#include <QtCore/QCoreApplication>
27#include <QtQml/QQmlEngine>
28#include <QtQuick/QQuickView>
29#include <QtQuick/QQuickItem>
30#include <QtCore/QThread>
31#include <QtCore/QFileInfo>
32#include <QtCore/QDir>
33
34#include "ucapplication.h"
35#include "ucunits.h"
36
37class tst_MainView : public QObject
38{
39 Q_OBJECT
40
41private:
42 QQuickView *view;
43
44public:
45 tst_MainView() :
46 view(0)
47 {
48 }
49
50 QQuickItem *loadTest(const QString &document)
51 {
52 // load the document
53 view->setSource(QUrl::fromLocalFile(document));
54 QTest::waitForEvents();
55
56 return view->rootObject();
57 }
58
59 QQuickItem *testItem(QQuickItem *that, const QString &identifier)
60 {
61 if (that->property(identifier.toLocal8Bit()).isValid())
62 return that->property(identifier.toLocal8Bit()).value<QQuickItem*>();
63
64 QList<QQuickItem*> children = that->findChildren<QQuickItem*>(identifier);
65 return (children.count() > 0) ? children[0] : 0;
66 }
67
68private Q_SLOTS:
69
70 void initTestCase()
71 {
72 QString modules("../../../modules");
73 QVERIFY(QDir(modules).exists());
74
75 view = new QQuickView;
76 QQmlEngine *quickEngine = view->engine();
77
78 view->setGeometry(0,0, UCUnits::instance().gu(40), UCUnits::instance().gu(30));
79 //add modules folder so we have access to the plugin from QML
80 QStringList imports = quickEngine->importPathList();
81 imports.prepend(QDir(modules).absolutePath());
82 quickEngine->setImportPathList(imports);
83 }
84
85 void cleanupTestCase()
86 {
87 delete view;
88 }
89
90 void testCase_AppName()
91 {
92 QQuickItem *root = loadTest("AppName.qml");
93 QVERIFY(root);
94 QQuickItem *mainView = root;
95 QString applicationName(mainView->property("applicationName").toString());
96 QCOMPARE(applicationName, QString("org.gnu.wildebeest"));
97 QCOMPARE(applicationName, QCoreApplication::applicationName());
98 QCOMPARE(QString(""), QCoreApplication::organizationName());
99 }
100
101 void testSetApplicationName() {
102 QString appName("com.ubuntu.foo");
103 UCApplication::instance().setApplicationName(appName);
104 QCOMPARE(UCApplication::instance().applicationName(), appName);
105 QCOMPARE(QCoreApplication::applicationName(), appName);
106 QCOMPARE(QString(""), QCoreApplication::organizationName());
107 }
108
109 void testExpectedDataFolder() {
110 QString appName("net.weight.gain");
111 UCApplication::instance().setApplicationName(appName);
112 QString dataFolder(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
113 QString xdgDataHome(QProcessEnvironment::systemEnvironment().value("XDG_DATA_HOME",
114 QProcessEnvironment::systemEnvironment().value("HOME") + "/.local/share"));
115 QString expectedDataFolder(xdgDataHome + "/" + appName);
116 QCOMPARE(dataFolder, expectedDataFolder);
117 }
118
119 void testExpectedCacheFolder() {
120 QString appName("cat.long.very");
121 UCApplication::instance().setApplicationName(appName);
122 QString cacheFolder(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
123 QString xdgCacheHome(QProcessEnvironment::systemEnvironment().value("XDG_CACHE_HOME",
124 QProcessEnvironment::systemEnvironment().value("HOME") + "/.cache"));
125 QString expectedCacheFolder(xdgCacheHome + "/" + appName);
126 QCOMPARE(cacheFolder, expectedCacheFolder);
127 }
128};
129
130QTEST_MAIN(tst_MainView)
131
132#include "tst_mainview.moc"
0133
=== added file 'tests/unit/tst_mainview/tst_mainview.pro'
--- tests/unit/tst_mainview/tst_mainview.pro 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_mainview/tst_mainview.pro 2013-09-23 08:32:16 +0000
@@ -0,0 +1,6 @@
1include(../test-include.pri)
2
3QT += gui
4SOURCES += tst_mainview.cpp
5
6OTHER_FILES += $$system(ls tst_*.qml)
07
=== modified file 'tests/unit/unit.pro'
--- tests/unit/unit.pro 2013-08-28 09:49:02 +0000
+++ tests/unit/unit.pro 2013-09-23 08:32:16 +0000
@@ -20,6 +20,7 @@
20 tst_qquick_image_extension \20 tst_qquick_image_extension \
21 tst_performance \21 tst_performance \
22 tst_ubuntu_shape \22 tst_ubuntu_shape \
23 tst_mainview \
23 tst_arguments \24 tst_arguments \
24 tst_argument \25 tst_argument \
25 tst_layouts \26 tst_layouts \

Subscribers

People subscribed via source and target branches

to status/vote changes: