Merge lp:~flscogna/ubuntu-terminal-app/profile-selection into lp:~ubuntu-terminal-dev/ubuntu-terminal-app/reboot

Proposed by Filippo Scognamiglio
Status: Merged
Approved by: Alan Pope 🍺🐧🐱 πŸ¦„
Approved revision: 77
Merged at revision: 80
Proposed branch: lp:~flscogna/ubuntu-terminal-app/profile-selection
Merge into: lp:~ubuntu-terminal-dev/ubuntu-terminal-app/reboot
Diff against target: 434 lines (+207/-59)
8 files modified
po/com.ubuntu.terminal.pot (+13/-8)
src/app/fileio.cpp (+2/-4)
src/app/qml/KeyboardBar.qml (+31/-9)
src/app/qml/KeyboardRows/KeyboardLayout.qml (+2/-2)
src/app/qml/LayoutsPage.qml (+47/-0)
src/app/qml/SettingsPage.qml (+38/-31)
src/app/qml/TerminalSettings.qml (+69/-5)
src/app/qml/ubuntu-terminal-app.qml (+5/-0)
To merge this branch: bzr merge lp:~flscogna/ubuntu-terminal-app/profile-selection
Reviewer Review Type Date Requested Status
Alan Pope 🍺🐧🐱 πŸ¦„ (community) Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+255077@code.launchpad.net

Commit message

Custom profile visibility in settings

Description of the change

Custom profile visibility in settings. It is possible to show only a subset of the installed layouts.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

I set no profiles active, but still see the keyboard button. Can we hide that when all keyboard layouts are disabled?

http://people.canonical.com/~alan/screenshots/device-2015-04-13-120147.png

Other than that, looks great.

review: Needs Fixing
Revision history for this message
Filippo Scognamiglio (flscogna) wrote :

Alan, we can theoretically hide the keyboard button, but what about the row? If we hide only the button, we would basically have a black useless rectangle at the bottom.
Let's discuss some options:

1) Leave the current situation, with a useless bar and a useless button. (quite bad but predictable)
2) Hide the keyboard bar when no profiles are selected. (might be confusing?)
3) Force at least one profiles to be active (e.g. your ubuntu layout).

What do you think?

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

I prefer 2).

If someone doesn't want to 'waste' the screen real-estate used by the layout, so switches them all off, they'll be disappointed that they don't gain space IMO.

If we force a profile to be active, we're forcing that 'waste' of space for users who don't need it.

I would default to having the layouts enabled by default, but if the user actively has chosen to disable them _all_ then they should expect the consequence that they're gone from the main UI. They've already discovered how to disable them, re-enabling them shouldn't be a stretch for them.

What do you think?

Revision history for this message
Filippo Scognamiglio (flscogna) wrote :

We already have a setting to completely disable the keyboard bar (in the main page).
The state which might be confusing here is: "Show Keyboard Bar" is turned on, but all profiles are disabled.

I'd personally not mix profiles selection with bar visibility. I'm thinking some day we'll have a keyboard shortcut to show/hide the bar, and we need to preserve the state (read the profiles enabled).

I'm inclined to think the best solution is to always show the additional bar (provided "Show Keyboard Bar" is enabled), but grey out the button when no profile is selected.
If the users wants to recover the screen real-estate (temporarily or permanently) it is just a tick away, without the need to change anything about its favourites profiles.

I perfectly agree with the default choices.

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Ok, you make a good argument. Let's go with your plan.

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Are you planning to add the grey icon in this merge? If so, when can we expect that?

Revision history for this message
Filippo Scognamiglio (flscogna) wrote :

Sorry, I completely forgot about this merge proposal. I'll work on it in
the next two days.

2015-05-19 11:22 GMT+02:00 Alan Pope ξƒΏ <email address hidden>:

> Are you planning to add the grey icon in this merge? If so, when can we
> expect that?
> --
>
> https://code.launchpad.net/~flscogna/ubuntu-terminal-app/profile-selection/+merge/255077
> You are the owner of lp:~flscogna/ubuntu-terminal-app/profile-selection.
>

74. By Filippo Scognamiglio

Set the button colour to grey when no profiles are selected.

75. By Filippo Scognamiglio

Merge the latest changes from trunk.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Filippo Scognamiglio (flscogna) wrote :

Alan, when you have some time give this a go. The colour might be tweaked a bit, but I think the result is decent.

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

There seems to be a breakage in some use cases.

Add a few layouts
Go back to the main terminal screen
Select one as the current one
Go back to layout settings, de-select the one set as current

Expected behaviour:- Switch to another layout (next in list for example), or un-set a layout

Actual behaviour can sometimes be:-

* No layout set, choosing a layout has no effect:-
http://people.canonical.com/~alan/screenshots/device-2015-05-27-155914.png
http://people.canonical.com/~alan/screenshots/device-2015-05-27-155920.png

review: Needs Fixing
76. By Filippo Scognamiglio

Fix unexpected behaviour when unselecting the last profile in the list.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Filippo Scognamiglio (flscogna) wrote :

Ok, there was an issue when the last profile was active and unselected from the settings. This should work fine now.

77. By Filippo Scognamiglio

Import the latest changes from trunk.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

That fixed it!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'po/com.ubuntu.terminal.pot'
--- po/com.ubuntu.terminal.pot 2015-03-23 11:12:46 +0000
+++ po/com.ubuntu.terminal.pot 2015-06-02 19:52:04 +0000
@@ -8,7 +8,8 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: \n"9"Project-Id-Version: \n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2015-03-21 13:11+0100\n"11
12"POT-Creation-Date: 2015-04-02 14:49+0200\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"13"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"14"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"15"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -53,23 +54,27 @@
53msgid "Authentication failed"54msgid "Authentication failed"
54msgstr ""55msgstr ""
5556
56#: ../src/app/qml/KeyboardBar.qml:15757#: ../src/app/qml/KeyboardBar.qml:163
57msgid "Change Keyboard"58msgid "Change Keyboard"
58msgstr ""59msgstr ""
5960
61#: ../src/app/qml/LayoutsPage.qml:27 ../src/app/qml/SettingsPage.qml:36
62msgid "Layouts"
63msgstr ""
64
60#: ../src/app/qml/SettingsPage.qml:2765#: ../src/app/qml/SettingsPage.qml:27
61msgid "Settings"66msgid "Settings"
62msgstr ""67msgstr ""
6368
64#: ../src/app/qml/SettingsPage.qml:3669#: ../src/app/qml/SettingsPage.qml:42
70msgid "Show Keyboard Bar"
71msgstr ""
72
73#: ../src/app/qml/SettingsPage.qml:52
65msgid "Font Size:"74msgid "Font Size:"
66msgstr ""75msgstr ""
6776
68#: ../src/app/qml/SettingsPage.qml:5977#: ../src/app/qml/SettingsPage.qml:78
69msgid "Show Keyboard Bar"
70msgstr ""
71
72#: ../src/app/qml/SettingsPage.qml:73
73msgid "Color Scheme"78msgid "Color Scheme"
74msgstr ""79msgstr ""
7580
7681
=== modified file 'src/app/fileio.cpp'
--- src/app/fileio.cpp 2015-02-03 21:43:38 +0000
+++ src/app/fileio.cpp 2015-06-02 19:52:04 +0000
@@ -8,8 +8,7 @@
8 if (sourceUrl.isEmpty())8 if (sourceUrl.isEmpty())
9 return false;9 return false;
1010
11 QUrl url(sourceUrl);11 QFile file(sourceUrl);
12 QFile file(url.toLocalFile());
13 if (!file.open(QFile::WriteOnly | QFile::Truncate))12 if (!file.open(QFile::WriteOnly | QFile::Truncate))
14 return false;13 return false;
1514
@@ -23,8 +22,7 @@
23 if (sourceUrl.isEmpty())22 if (sourceUrl.isEmpty())
24 return "";23 return "";
2524
26 QUrl url(sourceUrl);25 QFile file(sourceUrl);
27 QFile file(url.toLocalFile());
28 if (!file.open(QFile::ReadOnly))26 if (!file.open(QFile::ReadOnly))
29 return "";27 return "";
3028
3129
=== modified file 'src/app/qml/KeyboardBar.qml'
--- src/app/qml/KeyboardBar.qml 2015-02-14 10:33:32 +0000
+++ src/app/qml/KeyboardBar.qml 2015-06-02 19:52:04 +0000
@@ -40,13 +40,16 @@
40 }40 }
41 }41 }
4242
43 function createLayoutObject(profileUrl) {43 function createLayoutObject(profileObject) {
44 var object = layoutComponent.createObject(keyboardContainer);44 var object = layoutComponent.createObject(keyboardContainer);
45 object.loadProfile(fileIO.read(profileUrl));45 object.loadProfile(profileObject);
46 return object;46 return object;
47 }47 }
4848
49 function disableLayout(index) {49 function disableLayout(index) {
50 if (!isIndexLayoutValid(index))
51 return;
52
50 var layoutObject = layoutsList.get(index).layout;53 var layoutObject = layoutsList.get(index).layout;
51 layoutObject.visible = false;54 layoutObject.visible = false;
52 layoutObject.enabled = false;55 layoutObject.enabled = false;
@@ -56,6 +59,9 @@
56 }59 }
5760
58 function enableLayout(index) {61 function enableLayout(index) {
62 if (!isIndexLayoutValid(index))
63 return;
64
59 var layoutObject = layoutsList.get(index).layout;65 var layoutObject = layoutsList.get(index).layout;
60 layoutObject.visible = true;66 layoutObject.visible = true;
61 layoutObject.enabled = true;67 layoutObject.enabled = true;
@@ -64,10 +70,13 @@
64 layoutObject.simulateCommand.connect(simulateCommand);70 layoutObject.simulateCommand.connect(simulateCommand);
65 }71 }
6672
73 function isIndexLayoutValid(index) {
74 return (index >= 0 && index < layoutsList.count);
75 }
76
67 function selectLayout(index) {77 function selectLayout(index) {
68 if (index < 0 || index >= layoutsList.count)78 if (!isIndexLayoutValid(index))
69 return;79 return;
70
71 disableLayout(selectedLayoutIndex);80 disableLayout(selectedLayoutIndex);
72 enableLayout(index);81 enableLayout(index);
73 selectedLayoutIndex = index;82 selectedLayoutIndex = index;
@@ -97,13 +106,19 @@
97 }106 }
98107
99 function loadProfiles() {108 function loadProfiles() {
100 for (var i = 0; i < keyboardLayouts.length; i++) {109 dropProfiles();
110
111 for (var i = 0; i < settings.profilesList.count; i++) {
112 var profile = settings.profilesList.get(i);
113 if (!profile.profileVisible)
114 continue;
115
101 try {116 try {
102 console.log("Loading Layout:", Qt.resolvedUrl(keyboardLayouts[i]));117 console.log("Loading Layout:", Qt.resolvedUrl(profile.file));
103 var layoutObject = createLayoutObject(Qt.resolvedUrl(keyboardLayouts[i]));118 var layoutObject = createLayoutObject(profile.object);
104 layoutsList.append({layout: layoutObject});119 layoutsList.append({layout: layoutObject});
105 } catch (e) {120 } catch (e) {
106 console.error("Error in profile " + keyboardLayouts[i]);121 console.error("Error in profile " + profile.file);
107 console.error(e);122 console.error(e);
108 }123 }
109 }124 }
@@ -129,9 +144,11 @@
129 }144 }
130 }145 }
131146
147 enabled: layoutsList.count != 0
148
132 Rectangle {149 Rectangle {
133 anchors.fill: parent150 anchors.fill: parent
134 color: UbuntuColors.orange151 color: parent.enabled ? UbuntuColors.orange : UbuntuColors.warmGrey
135152
136 Icon {153 Icon {
137 scale: 0.5154 scale: 0.5
@@ -187,6 +204,11 @@
187 }204 }
188 }205 }
189206
207 Connections {
208 target: settings
209 onProfilesChanged: rootItem.loadProfiles();
210 }
211
190 Component.onDestruction: dropProfiles();212 Component.onDestruction: dropProfiles();
191 Component.onCompleted: loadProfiles();213 Component.onCompleted: loadProfiles();
192}214}
193215
=== modified file 'src/app/qml/KeyboardRows/KeyboardLayout.qml'
--- src/app/qml/KeyboardRows/KeyboardLayout.qml 2015-02-14 10:56:28 +0000
+++ src/app/qml/KeyboardRows/KeyboardLayout.qml 2015-06-02 19:52:04 +0000
@@ -68,13 +68,13 @@
68 return objectString;68 return objectString;
69 }69 }
7070
71 function loadProfile(profileString) {71 function loadProfile(profileObject) {
72 dropProfile();72 dropProfile();
7373
74 var maxWidth = 0;74 var maxWidth = 0;
7575
76 // This function might raise exceptions which are handled in KeyboardBar.qml76 // This function might raise exceptions which are handled in KeyboardBar.qml
77 var profile = profile = Parser.parseJson(profileString);77 var profile = profileObject;
7878
79 name = profile.name;79 name = profile.name;
80 short_name = profile.short_name;80 short_name = profile.short_name;
8181
=== added file 'src/app/qml/LayoutsPage.qml'
--- src/app/qml/LayoutsPage.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/LayoutsPage.qml 2015-06-02 19:52:04 +0000
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2013, 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
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 General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Filippo Scognamiglio <flscogna@gmail.com>
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 1.1
21import Ubuntu.Components.ListItems 1.0 as ListItem
22
23Page {
24 id: rootItem
25 objectName: "layoutsPage"
26
27 title: i18n.tr("Layouts")
28
29 onVisibleChanged: {
30 if (visible === false)
31 settings.profilesChanged();
32 }
33
34 ListView {
35 anchors.fill: parent
36 model: settings.profilesList
37 delegate: ListItem.Standard {
38 control: Switch {
39 checked: profileVisible
40 onCheckedChanged: {
41 settings.profilesList.setProperty(index, "profileVisible", checked);
42 }
43 }
44 text: name
45 }
46 }
47}
048
=== modified file 'src/app/qml/SettingsPage.qml'
--- src/app/qml/SettingsPage.qml 2015-01-17 02:02:04 +0000
+++ src/app/qml/SettingsPage.qml 2015-06-02 19:52:04 +0000
@@ -30,50 +30,57 @@
30 id: mainColumn30 id: mainColumn
3131
32 spacing: units.gu(1)32 spacing: units.gu(1)
33 anchors { margins: units.gu(2); fill: parent }33 anchors.fill: parent
3434
35 Label {35 ListItem.Standard {
36 text: i18n.tr("Font Size:")36 text: i18n.tr("Layouts")
37 }37 progression: true
3838 onClicked: pageStack.push(layoutsPage);
39 Slider {39 }
40 id: slFont40
41 objectName: "slFont"41 ListItem.Standard {
42 anchors { left: parent.left; right: parent.right }42 text: i18n.tr("Show Keyboard Bar")
43 minimumValue: 8;43 control: Switch {
44 maximumValue: 32;44 onCheckedChanged: settings.showKeyboardBar = checked;
45 onValueChanged: {45 Component.onCompleted: checked = settings.showKeyboardBar;
46 settings.fontSize = value;46 }
47 }47 }
48 Component.onCompleted: {
49 value = settings.fontSize;
50 }
51 }
52
53 ListItem.ThinDivider { }
5448
55 ListItem.Empty {49 ListItem.Empty {
56 showDivider: false50 height: units.gu(10)
57 Label {51 Label {
58 anchors { left: parent.left; verticalCenter: parent.verticalCenter }52 text: i18n.tr("Font Size:")
59 text: i18n.tr("Show Keyboard Bar")53 x: units.gu(2)
60 }54 }
61 Switch {55 Slider {
62 anchors { right: parent.right; verticalCenter: parent.verticalCenter }56 id: slFont
63 onCheckedChanged: settings.showKeyboardBar = checked;57 objectName: "slFont"
64 Component.onCompleted: checked = settings.showKeyboardBar;58 anchors {
59 left: parent.left
60 right: parent.right
61 bottom: parent.bottom
62 margins: units.gu(2)
63 }
64 minimumValue: 8;
65 maximumValue: 32;
66 onValueChanged: {
67 settings.fontSize = value;
68 }
69 Component.onCompleted: {
70 value = settings.fontSize;
71 }
65 }72 }
66 }73 }
6774
68 ListItem.ThinDivider { }
69
70 OptionSelector {75 OptionSelector {
71 id: colorsSchemeSelector76 id: colorsSchemeSelector
72 objectName: "colorsSchemeSelector"77 objectName: "colorsSchemeSelector"
73 text: i18n.tr("Color Scheme")78 text: i18n.tr("Color Scheme")
79 width: parent.width - units.gu(4)
80 x: units.gu(2)
7481
75 // TODO Hackish, but works quite well.82 // TODO Hackish, but works quite well.
76 containerHeight: parent.height - y - units.gu(4)83 containerHeight: parent.height - y - units.gu(6)
7784
78 // TODO This is a workaround at the moment.85 // TODO This is a workaround at the moment.
79 // The application should get them from the c++.86 // The application should get them from the c++.
8087
=== modified file 'src/app/qml/TerminalSettings.qml'
--- src/app/qml/TerminalSettings.qml 2015-01-17 02:02:04 +0000
+++ src/app/qml/TerminalSettings.qml 2015-06-02 19:52:04 +0000
@@ -1,9 +1,73 @@
1import QtQuick 2.01import QtQuick 2.0
2import Qt.labs.settings 1.02import Qt.labs.settings 1.0
33
4Settings {4import "KeyboardRows/jsonParser.js" as Parser
5 property int fontSize: 145
6 property string fontStyle: "Ubuntu Mono"6Item {
7 property string colorScheme: "Ubuntu"7 id: rootItem
8 property bool showKeyboardBar: true8 property alias fontSize: innerSettings.fontSize
9 property alias fontStyle: innerSettings.fontStyle
10 property alias colorScheme: innerSettings.colorScheme
11 property alias showKeyboardBar: innerSettings.showKeyboardBar
12
13 property alias jsonVisibleProfiles: innerSettings.jsonVisibleProfiles
14
15 property ListModel profilesList: ListModel {}
16
17 signal profilesChanged();
18
19 onProfilesChanged: saveProfileVisibleStrings();
20
21 function saveProfileVisibleStrings() {
22 var result = {};
23
24 for (var i = 0; i < profilesList.count; i++) {
25 var profileObject = profilesList.get(i);
26 result[profileObject.file] = profileObject.profileVisible;
27 }
28
29 jsonVisibleProfiles = JSON.stringify(result);
30 }
31
32 Settings {
33 id: innerSettings
34 property int fontSize: 14
35 property string fontStyle: "Ubuntu Mono"
36 property string colorScheme: "Ubuntu"
37 property bool showKeyboardBar: true
38 property string jsonVisibleProfiles: "[]"
39 }
40
41 // Load the keyboard profiles.
42 Component.onCompleted: {
43 var visibleProfiles = undefined;
44 try {
45 visibleProfiles = JSON.parse(innerSettings.jsonVisibleProfiles);
46 } catch (e) {}
47
48 function isProfileVisible(profilePath) {
49 return !(visibleProfiles[profilePath] == false);
50 }
51
52 for (var i = 0; i < keyboardLayouts.length; i++) {
53 var filePath = keyboardLayouts[i];
54 var isVisible = isProfileVisible(filePath);
55
56 try {
57 var profileObject = Parser.parseJson(fileIO.read(filePath));
58
59 profilesList.append(
60 {
61 file: filePath,
62 profileVisible: isVisible,
63 object: profileObject,
64 name: profileObject.name
65 });
66 } catch (e) {
67 console.error("Error in profile", filePath);
68 console.error(e);
69 }
70 }
71 profilesChanged();
72 }
9}73}
1074
=== modified file 'src/app/qml/ubuntu-terminal-app.qml'
--- src/app/qml/ubuntu-terminal-app.qml 2014-12-05 22:52:26 +0000
+++ src/app/qml/ubuntu-terminal-app.qml 2015-06-02 19:52:04 +0000
@@ -106,6 +106,11 @@
106 id: settingsPage106 id: settingsPage
107 visible: false107 visible: false
108 }108 }
109
110 LayoutsPage {
111 id: layoutsPage
112 visible: false
113 }
109 }114 }
110115
111 Component.onCompleted: {116 Component.onCompleted: {

Subscribers

People subscribed via source and target branches