Merge lp:~unity-team/unity8/indicators-client into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Approved by: Michał Sawicz
Approved revision: 116
Merged at revision: 102
Proposed branch: lp:~unity-team/unity8/indicators-client
Merge into: lp:unity8
Diff against target: 8866 lines (+7025/-588)
156 files modified
CMakeLists.txt (+3/-1)
Panel/IndicatorItem.qml (+22/-35)
Panel/IndicatorRow.qml (+5/-3)
Panel/Indicators.qml (+3/-7)
Panel/Indicators/DatetimeIndicatorPage.qml (+97/-0)
Panel/Indicators/DatetimeIndicatorWidget.qml (+65/-0)
Panel/Indicators/DefaultIndicatorPage.qml (+25/-0)
Panel/Indicators/DefaultIndicatorWidget.qml (+80/-0)
Panel/Indicators/MessagingIndicatorPage.qml (+35/-0)
Panel/Indicators/MessagingIndicatorWidget.qml (+25/-0)
Panel/Indicators/NetworkIndicatorPage.qml (+80/-0)
Panel/Indicators/NetworkIndicatorWidget.qml (+109/-0)
Panel/Indicators/SoundIndicatorWidget.qml (+25/-0)
Panel/Indicators/client/IndicatorsClient.qml (+42/-0)
Panel/Indicators/client/IndicatorsList.qml (+62/-0)
Panel/Indicators/client/IndicatorsPage.qml (+49/-0)
Panel/IndicatorsDataModel.qml (+66/-0)
Panel/MenuContent.qml (+19/-22)
Panel/Menus/Overview/OverviewGrid.qml (+16/-25)
build (+1/-2)
cmake/modules/autopilot.cmake (+7/-4)
debian/control (+21/-7)
debian/indicators-client.install (+1/-0)
debian/unity8.install (+1/-0)
main.cpp (+1/-2)
paths.h.in (+15/-0)
plugins/Unity/CMakeLists.txt (+2/-0)
plugins/Unity/Indicators/CMakeLists.txt (+52/-0)
plugins/Unity/Indicators/Messaging/CMakeLists.txt (+1/-0)
plugins/Unity/Indicators/Messaging/qml/ActionButton.qml (+43/-0)
plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml (+66/-0)
plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt (+15/-0)
plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml (+96/-0)
plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml (+120/-0)
plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml (+161/-0)
plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml (+96/-0)
plugins/Unity/Indicators/Messaging/qml/QuickReply.qml (+160/-0)
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml (+97/-0)
plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml (+142/-0)
plugins/Unity/Indicators/Messaging/qml/TextMessage.qml (+35/-0)
plugins/Unity/Indicators/Messaging/qml/qmldir (+12/-0)
plugins/Unity/Indicators/Messaging/qml/utils.js (+27/-0)
plugins/Unity/Indicators/Network/CMakeLists.txt (+42/-0)
plugins/Unity/Indicators/Network/networkagent.cpp (+146/-0)
plugins/Unity/Indicators/Network/networkagent.h (+65/-0)
plugins/Unity/Indicators/Network/plugin.cpp (+31/-0)
plugins/Unity/Indicators/Network/plugin.h (+32/-0)
plugins/Unity/Indicators/Network/qml/AccessPoint.qml (+68/-0)
plugins/Unity/Indicators/Network/qml/CMakeLists.txt (+15/-0)
plugins/Unity/Indicators/Network/qml/PasswordPage.qml (+88/-0)
plugins/Unity/Indicators/Network/qml/PasswordTextField.qml (+68/-0)
plugins/Unity/Indicators/Network/qml/WifiSection.qml (+34/-0)
plugins/Unity/Indicators/Network/qml/qmldir (+8/-0)
plugins/Unity/Indicators/Network/secret-agent.c (+382/-0)
plugins/Unity/Indicators/Network/secret-agent.h (+102/-0)
plugins/Unity/Indicators/flatmenuproxymodel.cpp (+272/-0)
plugins/Unity/Indicators/flatmenuproxymodel.h (+91/-0)
plugins/Unity/Indicators/indicator.cpp (+88/-0)
plugins/Unity/Indicators/indicator.h (+57/-0)
plugins/Unity/Indicators/indicators.h (+103/-0)
plugins/Unity/Indicators/indicatorsmanager.cpp (+285/-0)
plugins/Unity/Indicators/indicatorsmanager.h (+73/-0)
plugins/Unity/Indicators/indicatorsmodel.cpp (+321/-0)
plugins/Unity/Indicators/indicatorsmodel.h (+81/-0)
plugins/Unity/Indicators/plugin.cpp (+44/-0)
plugins/Unity/Indicators/plugin.h (+32/-0)
plugins/Unity/Indicators/qml/BasicMenuItem.qml (+48/-0)
plugins/Unity/Indicators/qml/ButtonMenuItem.qml (+47/-0)
plugins/Unity/Indicators/qml/CMakeLists.txt (+14/-0)
plugins/Unity/Indicators/qml/DivMenuItem.qml (+26/-0)
plugins/Unity/Indicators/qml/HLine.qml (+29/-0)
plugins/Unity/Indicators/qml/IndicatorBase.qml (+59/-0)
plugins/Unity/Indicators/qml/IndicatorPage.qml (+197/-0)
plugins/Unity/Indicators/qml/IndicatorWidget.qml (+68/-0)
plugins/Unity/Indicators/qml/MenuAction.qml (+86/-0)
plugins/Unity/Indicators/qml/MenuActionBinding.qml (+106/-0)
plugins/Unity/Indicators/qml/MenuItem.qml (+40/-0)
plugins/Unity/Indicators/qml/MenuItemFactory.qml (+110/-0)
plugins/Unity/Indicators/qml/ProgressMenuItem.qml (+65/-0)
plugins/Unity/Indicators/qml/RemoveBackground.qml (+55/-0)
plugins/Unity/Indicators/qml/SectionMenuItem.qml (+57/-0)
plugins/Unity/Indicators/qml/SliderMenuItem.qml (+64/-0)
plugins/Unity/Indicators/qml/SwitchMenuItem.qml (+43/-0)
plugins/Unity/Indicators/qml/qmldir (+20/-0)
plugins/Unity/Indicators/resources/artwork/messaging/default_app.svg (+42/-0)
plugins/Unity/Indicators/resources/indicators.qrc (+7/-0)
plugins/Utils/CMakeLists.txt (+1/-0)
plugins/Utils/applicationpaths.h (+38/-0)
plugins/Utils/plugin.cpp (+8/-0)
run (+3/-3)
src/CMakeLists.txt (+1/-0)
src/Panel/CMakeLists.txt (+1/-0)
src/Panel/Indicators/CMakeLists.txt (+2/-0)
src/Panel/Indicators/client/CMakeLists.txt (+25/-0)
src/Panel/Indicators/client/indicatorsclient.cpp (+99/-0)
src/Panel/Indicators/client/indicatorsclient.h (+45/-0)
src/Panel/Indicators/client/main.cpp (+26/-0)
src/Panel/Indicators/servicefiles/CMakeLists.txt (+18/-0)
src/Panel/Indicators/servicefiles/com.canonical.indicator.battery (+9/-0)
src/Panel/Indicators/servicefiles/com.canonical.indicator.messages (+9/-0)
src/Panel/Indicators/servicefiles/com.canonical.indicator.time (+9/-0)
src/Panel/Indicators/servicefiles/com.canonical.settings.network (+9/-0)
src/Panel/Indicators/servicefiles/com.canonical.settings.sound (+9/-0)
tests/autopilot/unity8/__init__.py (+8/-0)
tests/autopilot/unity8/indicators_client/__init__.py (+8/-0)
tests/autopilot/unity8/indicators_client/emulators/__init__.py (+31/-0)
tests/autopilot/unity8/indicators_client/emulators/common.py (+14/-0)
tests/autopilot/unity8/indicators_client/emulators/main_window.py (+27/-0)
tests/autopilot/unity8/indicators_client/tests/__init__.py (+87/-0)
tests/autopilot/unity8/indicators_client/tests/test_battery.py (+99/-0)
tests/autopilot/unity8/shell/__init__.py (+1/-1)
tests/autopilot/unity8/shell/tests/__init__.py (+1/-1)
tests/autopilot/unity8/shell/tests/testbigscreen.py (+1/-1)
tests/autopilot/unity8/shell/tests/testhud.py (+2/-2)
tests/autopilot/unity8/shell/tests/testlockscreen.py (+2/-2)
tests/data/unity/indicators/com.canonical.indicator.fake1 (+9/-0)
tests/data/unity/indicators/com.canonical.indicator.fake2 (+9/-0)
tests/data/unity/indicators/com.canonical.indicator.fake3 (+9/-0)
tests/data/unity/indicators/com.canonical.indicator.fake4 (+9/-0)
tests/mocks/Ubuntu/CMakeLists.txt (+0/-1)
tests/mocks/Ubuntu/ChewieUI/CMakeLists.txt (+0/-33)
tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.cpp (+0/-30)
tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.h (+0/-31)
tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.cpp (+0/-206)
tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.h (+0/-94)
tests/mocks/Ubuntu/ChewieUI/qmldir (+0/-1)
tests/mocks/Unity/CMakeLists.txt (+2/-0)
tests/mocks/Unity/Indicators/CMakeLists.txt (+52/-0)
tests/mocks/Unity/Indicators/IndicatorsModel.qml (+104/-0)
tests/mocks/Unity/Indicators/fakeplugin.cpp (+37/-0)
tests/mocks/Unity/Indicators/fakeplugin.h (+32/-0)
tests/mocks/Unity/Indicators/indicators_fake.qrc (+14/-0)
tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml (+3/-2)
tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml (+3/-2)
tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml (+3/-2)
tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml (+3/-2)
tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml (+3/-2)
tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qml (+23/-0)
tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qml (+23/-0)
tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qml (+23/-0)
tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qml (+23/-0)
tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qml (+23/-0)
tests/mocks/Unity/Indicators/qmldir (+5/-0)
tests/plugins/Unity/CMakeLists.txt (+2/-0)
tests/plugins/Unity/Indicators/CMakeLists.txt (+27/-0)
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp (+138/-0)
tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp (+102/-0)
tests/qmltests/Panel/tst_IndicatorItem.qml (+16/-31)
tests/qmltests/Panel/tst_IndicatorRow.qml (+4/-3)
tests/qmltests/Panel/tst_Indicators.qml (+1/-2)
tests/qmltests/Panel/tst_MenuContent.qml (+11/-10)
tests/qmltests/Panel/tst_Overview.qml (+5/-17)
tests/qmltests/Panel/tst_Panel.qml (+0/-1)
tests/qmltests/modules/CMakeLists.txt (+1/-0)
tests/qmltests/modules/Unity/CMakeLists.txt (+1/-0)
unity8.qmlproject (+1/-0)
To merge this branch: bzr merge lp:~unity-team/unity8/indicators-client
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michał Sawicz Approve
Nicolas d'Offay (community) Approve
Review via email: mp+172582@code.launchpad.net

Commit message

Moved indicators-client code into unity8.

Description of the change

Moved indicator-client code into unityNext.
indicator-client uses .indicator files to source indicator model.

To post a comment you must log in.
Revision history for this message
Michał Sawicz (saviq) wrote :

Yeah, and the hit to our code coverage with this is bad :/ We need to improve that soon after this is merged.

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
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :
Download full text (4.4 KiB)

    5652 + \qmltype MenuItemActionValue
    5653 + \inqmlmodule Indicators 0.1
    5654 + \brief Helper class to connect dbus action state with qml components property

    5656 + Exampiles:

    5672 +Item {

    It's "MenuItemAction" here, should be "MenuAction", even? And the \brief is copied from MenuItemActionValue, should say something different?

    Exampiles ← typo.

    Could it be a QtObject instead?

    =====

    5695 + // internal
    5696 + property QtObject __actionObject: null

    5707 + Item {
    5708 + id: priv
    5709 + property var actionObject: null
    5710 +
    5711 + Connections {

    Seems like priv.actionObject was supposed to replace __actionObject? Please complete that, and use "id: d" for the private object. There should be no need for the wrapping Item, either. Please use the Connections object as the private one.

    Now I see it's used in MenuItemActionValue, so I wonder if just exposing actionObject as public API of MenuItemAction wouldn't be cleaner...

Made a public property.

    =====

    5750 + \qmltype MenuItemActionValue

    Should this maybe be "MenuActionBinding"?

Renamed

    =====

    5783 + property string property: propertyBinding.property

    Couldn't this be an alias, too?

I has some issues with this. Apparently you dont get notifications for changes to binding properties, so I needed to make them root properties in order to update the connections. I've updated the target to be a property rather than an alias for the same reason.

    =====

    5795 + Item {
    5796 + id: priv
    5797 + property alias actionObject : dbusActionState.__actionObject
    5798 +
    5799 + property var currentTarget: undefined
    5800 + property string currentSignal
    5801 +
    5802 +
    5803 + Binding {

    Could be flattened to just Binding { }.

Removed the actionObject. The currentTarget/Signal is used to disconnect old property updates in connectViewChanges. Will be removed one we fix up the on%1Changed part.

    =====

    5821 + var signal = "on%1Changed".arg(property.charAt(0).toUpperCase() + property.slice(1));

    I wonder if this could be cleaner - I'd maybe even move this to C++ to mimic Binding { } more. Please add a TODO to re-evaluate at some point.

It's a bit of a mess. Added TODO

    =====

    5867 + id: __menuFactory

    5914 + id: __loader

    5980 + id: _progressMenu

    6047 + id: __backgroundItem

    6052 + id: __backgroundText

    6115 + id: __sectionMenu

    No need to prefix those with _.

    =====

    5995 + color: "#00000000"

    color: "transparent"

    =====

    6069 + anchors.rightMargin: __backgroundText.slidingMargin
    6070 + anchors.leftMargin: 0

    6079 + anchors.rightMargin: 0
    6080 + anchors.leftMargin: __backgroundText.slidingMargin

    These could just be static margins, no?

yep.

    =====

    6122 + anchors {
    6123 + left: parent ? parent.left : undefined
    6124 + right: parent ? parent.right : undefined
    6125 + }

    Didn't you say that no menu items have that? ;)

I may have said that :). removed.

    =====

    Do we have a use for SectionMenuItem yet?

It's used by the WifiSection. Shows the spinner while waiting f...

Read more...

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

 6304 + id: _textMenu

 6334 + id: _showPassword

 Remove prefixes.

removed

 =====

 6307 + property alias password: _showPassword.visible

 I wonder if we should instead have a separate password entry MenuItem... Right now you couldn't use it as a password entry from the MenuItemFactory. OTOH not sure it's meant to be supported, either.

I've changed it to just an Item and moved it into Network/PasswordTextField, and wrapped in a parent MenuItem in the Password page.

 =====

 6309 + implicitHeight: password ? units.gu(10) : units.gu(7)

 Should probably use contentColumn.height?

Yep. +units.gu(1) on the menu border.

 =====

 6488 + }
 6489 + else {

 Single line please.

Done.

 =====

 6572 + qmlRegisterType<ApplicationPaths>(uri, 0, 1, "ApplicationPaths");

 This should probably be a singleton instead.

Yep. Done.

 =====

 Hmm something weird, po/is.po got added as a new file?

Icelandic? Dont know why it isnt in try but was added in mine.
Should i remove?

 =====

 7046 +# copy indicators file into build directory for shadow builds
 7047 +file(COPY ${INDICATOR_FILES}
 7048 + DESTINATION ${CMAKE_BINARY_DIR}/share/unity/indicators
 7049 +)

 Same as before - use a custom command to make sure new versions are copied.

Done.

 =====

 7932 + wait(1000)

 Could we get rid of that?

Removed.

 =====

 8131 + ${GOBJECT_LDFLAGS}
 8132 + ${QMENUMODEL_LDFLAGS}

 Shouldn't the test also pkg_check_modules for those, if it's requiring them?

Links not needed.
Removed and fixed up some other cmake deps.

 =====

 DONE!

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Hey, I installed the packages from above, and I only get the date/time indicator content. Is that expected?

review: Needs Information
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> Hey, I installed the packages from above, and I only get the date/time
> indicator content. Is that expected?

Shouldn't do, but confirmed.
Was missing the install target for the Network indicators, causing the MenuFactory to fail to load.
Should be fixed now. Will confirm when jenkins pops arm build out.

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
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

W dniu 03.07.2013 19:36, Nick Dedekind pisze:
> 5783 + property string property: propertyBinding.property
>
> Couldn't this be an alias, too?
>
> I has some issues with this. Apparently you dont get notifications for changes to binding properties, so I needed to make them root properties in order to update the connections. I've updated the target to be a property rather than an alias for the same reason.

Can you confirm that's the case and find / file a bug with Qt?

> 5795 + Item {
> 5796 + id: priv
> 5797 + property alias actionObject : dbusActionState.__actionObject
> 5798 +
> 5799 + property var currentTarget: undefined
> 5800 + property string currentSignal
> 5801 +
> 5802 +
> 5803 + Binding {
>
> Could be flattened to just Binding { }.
>
> Removed the actionObject. The currentTarget/Signal is used to disconnect old property updates in connectViewChanges. Will be removed one we fix up the on%1Changed part.

Yeah, but we can move the currentTarget/Signal props to the Binding, or
is it the same issue as above?

> Do we have a use for SectionMenuItem yet?
>
> It's used by the WifiSection. Shows the spinner while waiting for wifi access points.

Not sure I like the spinner there, let's revisit.

> 6191 + width: _sliderMenu.text ? units.gu(20) : _sliderMenu.width - units.gu(4)
>
> Is that desired? I.e. do we want only 20GU-wide slider in that case? Do we have a usecase?
>
> It's used by the volume menu in the sound indicator. Possibly should be using the width of text, but we don't have access to that.
> May have to speak with SDK. This control will may be replaced with the ubuntu-settings-components control.

Right, we could arguably add a ListItem.Slider to the SDK.

> 6307 + property alias password: _showPassword.visible
>
> I wonder if we should instead have a separate password entry MenuItem... Right now you couldn't use it as a password entry from the MenuItemFactory. OTOH not sure it's meant to be supported, either.
>
> I've changed it to just an Item and moved it into Network/PasswordTextField, and wrapped in a parent MenuItem in the Password page.

Cool, this whole thing with the custom Network page... We'll have to see
if we can make it more generic.

> Icelandic? Dont know why it isnt in try but was added in mine.
> Should i remove?

It might've resulted from the lp:unity/8.0lp:unity8 move. Yes, please
remove, Launchpad will take care of it.

--
Michał (Saviq) Sawicz <email address hidden>
Canonical Services Ltd.

Revision history for this message
Michał Sawicz (saviq) wrote :

Last functional issue: "Show password" logic is reversed.

review: Needs Fixing
Revision history for this message
Nicolas d'Offay (nicolas-doffay) wrote :

Tried for a while to break something in the indicators to no avail.

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

The indicators_client AP tests failed with:

file:///usr/share/unity8/Panel/Indicators/client/IndicatorsList.qml:23 module "Unity.Indicators" is not installed

review: Needs Fixing
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
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Two tests in the indicators_client AP suite failed with:

  File "/usr/lib/python2.7/dist-packages/indicators_client/tests/test_power.py", line 30, in setUp
    self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
AttributeError: 'NoneType' object has no attribute 'progress'

review: Needs Fixing
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
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
Michał Sawicz (saviq) wrote :

1145 + libnm-glib-dev \
1146 + libnm-util-dev \
1147 + libqmenumodel-dev \

These shouldn't be here, mk-build-deps handles build deps.

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote :

qmenumodel-qml should be added to ./build, though, as we can't install runtime deps otherwise

review: Needs Fixing
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
Michał Sawicz (saviq) wrote :

I wonder if we should move indicators_client under the unity8 suite - even if they're not run with "autopilot run unity8", I think referencing them with "autopilot run unity8.indicators_client" would be better. What do you think?

review: Needs Information
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> I wonder if we should move indicators_client under the unity8 suite - even if
> they're not run with "autopilot run unity8", I think referencing them with
> "autopilot run unity8.indicators_client" would be better. What do you think?

While it would be cool to have them under the unity8 folder, mzanetti says no :) We want multiple suites, and putting indicators_client in the unity8 folder will import all the tests.
Perhaps we can move to unity8/shell & unity8/indicators_client

I've added split autopilot build targets. we now have:
autopilot - runs all tests
autopilot-unity8 - just the shell tests
autopilot-inidcators_client - just the indicators_client tests

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (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
Michał Sawicz (saviq) wrote :

We don't need the imports in the new __init__.py file, do we?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> We don't need the imports in the new __init__.py file, do we?

Apparently not.

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

Fixed debian/control conflict

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (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: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) :
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) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-07-10 17:13:28 +0000
3+++ CMakeLists.txt 2013-07-11 14:53:26 +0000
4@@ -91,7 +91,8 @@
5
6 # Autopilot tests
7 include(autopilot)
8-declare_autopilot_test(unity8 ${CMAKE_SOURCE_DIR}/tests/autopilot/)
9+declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
10+declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
11
12 set(SHELL_APP unity8)
13
14@@ -132,6 +133,7 @@
15 # add subdirectories to build
16 add_subdirectory(tests)
17 add_subdirectory(plugins)
18+add_subdirectory(src)
19
20 # install subdirectories
21 set(QML_DIRS
22
23=== modified file 'Panel/IndicatorItem.qml'
24--- Panel/IndicatorItem.qml 2013-06-05 22:03:08 +0000
25+++ Panel/IndicatorItem.qml 2013-07-11 14:53:26 +0000
26@@ -16,55 +16,42 @@
27
28 import QtQuick 2.0
29 import Ubuntu.Components 0.1
30+import Unity.Indicators 0.1 as Indicators
31
32 Item {
33 id: indicatorItem
34
35- property alias iconSource: itemImage.source
36- property alias label: itemLabel.text
37+ property alias widgetSource: loader.source
38 property bool highlighted: false
39 property bool dimmed: false
40+ property var indicatorProperties: undefined
41+
42+ opacity: dimmed ? 0.4 : 1
43
44 // only visible when non-empty
45- visible: label != "" || iconSource != ""
46- width: itemRow.width + units.gu(1)
47+ visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
48+ width: visible ? loader.item.width : 0
49+
50+ Loader {
51+ id: loader
52+
53+ onLoaded: {
54+ item.height = Qt.binding(function() { return indicatorItem.height; });
55+
56+ for(var pName in indicatorProperties) {
57+ if (item.hasOwnProperty(pName)) {
58+ item[pName] = indicatorProperties[pName];
59+ }
60+ }
61+ }
62+ }
63
64 Rectangle {
65 color: "#dd4814"
66+ objectName: "highlight"
67 height: units.dp(2)
68 width: parent.width
69 anchors.top: parent.bottom
70 visible: highlighted
71 }
72-
73- Row {
74- id: itemRow
75- objectName: "itemRow"
76- anchors {
77- top: parent.top
78- bottom: parent.bottom
79- horizontalCenter: parent.horizontalCenter
80- }
81- spacing: units.gu(0.5)
82- opacity: dimmed ? 0.4 : 1
83-
84- Image {
85- id: itemImage
86- objectName: "itemImage"
87- visible: source != ""
88- height: units.gu(2.5)
89- width: units.gu(2.5)
90- anchors.verticalCenter: parent.verticalCenter
91- }
92-
93- Label {
94- id: itemLabel
95- objectName: "itemLabel"
96- color: "#f3f3e7"
97- opacity: 0.8
98- font.family: "Ubuntu"
99- fontSize: "medium"
100- anchors.verticalCenter: parent.verticalCenter
101- }
102- }
103 }
104
105=== modified file 'Panel/IndicatorRow.qml'
106--- Panel/IndicatorRow.qml 2013-06-05 22:03:08 +0000
107+++ Panel/IndicatorRow.qml 2013-07-11 14:53:26 +0000
108@@ -21,7 +21,7 @@
109 id: indicatorRow
110
111 property QtObject currentItem : null
112- property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
113+ readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
114 property alias row: row
115 property QtObject indicatorsModel: null
116 property bool overviewActive: false // "state of the menu"
117@@ -54,13 +54,15 @@
118 id: rowRepeater
119 objectName: "rowRepeater"
120 model: indicatorsModel ? indicatorsModel : undefined
121+
122 IndicatorItem {
123 id: indicatorItem
124
125 property int ownIndex: index
126
127- label: model.label
128- iconSource: model.iconSource
129+ widgetSource: model.widgetSource
130+
131+ indicatorProperties : model.indicatorProperties
132 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
133 dimmed: { //See FIXME in Indicators regarding the "states" change
134 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
135
136=== added directory 'Panel/Indicators'
137=== modified file 'Panel/Indicators.qml'
138--- Panel/Indicators.qml 2013-07-02 21:22:50 +0000
139+++ Panel/Indicators.qml 2013-07-11 14:53:26 +0000
140@@ -17,7 +17,6 @@
141 import QtQuick 2.0
142 import Ubuntu.Components 0.1
143 import Ubuntu.Gestures 0.1
144-import Ubuntu.ChewieUI 0.1 as ChewieUI
145
146 import "../Components"
147 import "../Components/ListItems"
148@@ -70,8 +69,7 @@
149 // we dont want to switch to a indicator menu until we hit reveal state.
150 if (menuContent.overviewActive) {
151 menuContent.showOverview()
152- }
153- else {
154+ } else {
155 menuContent.showMenu()
156 }
157 indicators.state = "locked"
158@@ -272,9 +270,8 @@
159
160 }
161
162- ChewieUI.PluginModel {
163+ IndicatorsDataModel {
164 id: indicatorsModel
165- Component.onCompleted: load()
166 }
167
168 Connections {
169@@ -294,8 +291,7 @@
170 if (showAnimation.running) {
171 if (indicators.state == "initial") {
172 openOverview()
173- }
174- else {
175+ } else {
176 indicators.calculateCurrentItem(dragHandle.touchX, false)
177 menuContent.showMenu()
178 }
179
180=== added file 'Panel/Indicators/DatetimeIndicatorPage.qml'
181--- Panel/Indicators/DatetimeIndicatorPage.qml 1970-01-01 00:00:00 +0000
182+++ Panel/Indicators/DatetimeIndicatorPage.qml 2013-07-11 14:53:26 +0000
183@@ -0,0 +1,97 @@
184+/*
185+ * Copyright 2013 Canonical Ltd.
186+ *
187+ * This program is free software; you can redistribute it and/or modify
188+ * it under the terms of the GNU Lesser General Public License as published by
189+ * the Free Software Foundation; version 3.
190+ *
191+ * This program is distributed in the hope that it will be useful,
192+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
193+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
194+ * GNU Lesser General Public License for more details.
195+ *
196+ * You should have received a copy of the GNU Lesser General Public License
197+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
198+ *
199+ * Authors:
200+ * Renato Araujo Oliveira Filho <renato@canonical.com>
201+ * Ubo Riboni <ugo.riboni@canonical.com>
202+ */
203+
204+import QtQuick 2.0
205+import Ubuntu.Components 0.1
206+
207+Flickable {
208+ id: page
209+
210+ contentHeight: image.height
211+
212+ Image {
213+ id: image
214+ anchors {
215+ left: parent.left
216+ right: parent.right
217+ }
218+ source: "../graphics/time_and_date@18.png"
219+ fillMode: Image.PreserveAspectFit
220+ }
221+
222+ Item {
223+ anchors {
224+ top: parent.top
225+ topMargin: units.gu(5)
226+ left: parent.left
227+ right: parent.right
228+ }
229+
230+ height: units.gu(30)
231+
232+ Label {
233+ id: timeLabel
234+ anchors {
235+ horizontalCenter: parent.horizontalCenter
236+ verticalCenter: parent.verticalCenter
237+ }
238+
239+ text: ""
240+ color: "#f3f3e7"
241+ font.weight: Font.Light
242+ font.pixelSize: units.gu(6)
243+ }
244+
245+ Label {
246+ id: dateLabel
247+
248+ anchors {
249+ left: parent.left
250+ leftMargin: units.gu(2)
251+ bottom: parent.bottom
252+ bottomMargin: units.gu(1.5)
253+ }
254+ text: ""
255+ color: "#f3f3e7"
256+ fontSize: "small"
257+ }
258+ }
259+
260+ Timer {
261+ interval: 1000 * 10 // 10 seconds
262+ running: true
263+ repeat: true
264+ triggeredOnStart: true
265+ onTriggered: updateTime();
266+ }
267+
268+ function updateTime() {
269+ var dt = new Date();
270+ var time = Qt.formatTime(dt);
271+ var space = time.indexOf(" ");
272+ timeLabel.text = time.substr(0, space > 0 ? space : 5);
273+ dateLabel.text = Qt.formatDateTime(dt, "dddd,\ndd MMMM");
274+ }
275+
276+ // Make it compatible with the PluginItem interface
277+ function start() {}
278+ function stop() {}
279+ function reset() {}
280+}
281
282=== added file 'Panel/Indicators/DatetimeIndicatorWidget.qml'
283--- Panel/Indicators/DatetimeIndicatorWidget.qml 1970-01-01 00:00:00 +0000
284+++ Panel/Indicators/DatetimeIndicatorWidget.qml 2013-07-11 14:53:26 +0000
285@@ -0,0 +1,65 @@
286+/*
287+ * Copyright 2013 Canonical Ltd.
288+ *
289+ * This program is free software; you can redistribute it and/or modify
290+ * it under the terms of the GNU Lesser General Public License as published by
291+ * the Free Software Foundation; version 3.
292+ *
293+ * This program is distributed in the hope that it will be useful,
294+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
295+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
296+ * GNU Lesser General Public License for more details.
297+ *
298+ * You should have received a copy of the GNU Lesser General Public License
299+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
300+ *
301+ * Authors:
302+ * Nick Dedekind <nick.dedekind@canonical.com>
303+ */
304+
305+import QtQuick 2.0
306+import Ubuntu.Components 0.1
307+import Unity.Indicators 0.1 as Indicators
308+
309+Indicators.IndicatorWidget {
310+ id: indicatorWidget
311+
312+ width: timeLabel.width + units.gu(1)
313+
314+ property alias label: timeLabel.text
315+
316+ Label {
317+ id: timeLabel
318+ objectName: "timeLabel"
319+ color: "#f3f3e7"
320+ opacity: 0.8
321+ font.family: "Ubuntu"
322+ fontSize: "medium"
323+ anchors.centerIn: parent
324+ text: Qt.formatTime(timer.dateNow)
325+ }
326+
327+ Timer {
328+ id: timer
329+ interval: 1000 * 10
330+ running: indicatorWidget.visible
331+ repeat: true
332+ triggeredOnStart: true
333+ property date dateNow
334+
335+ onTriggered: dateNow = new Date
336+ }
337+
338+ onActionStateChanged: {
339+ if (action == undefined || !action.valid) {
340+ return;
341+ }
342+
343+ if (action.state == undefined) {
344+ visible = false;
345+ return;
346+ }
347+
348+ indicatorWidget.visible = action.state[3];
349+ }
350+}
351
352=== added file 'Panel/Indicators/DefaultIndicatorPage.qml'
353--- Panel/Indicators/DefaultIndicatorPage.qml 1970-01-01 00:00:00 +0000
354+++ Panel/Indicators/DefaultIndicatorPage.qml 2013-07-11 14:53:26 +0000
355@@ -0,0 +1,25 @@
356+/*
357+ * Copyright 2013 Canonical Ltd.
358+ *
359+ * This program is free software; you can redistribute it and/or modify
360+ * it under the terms of the GNU Lesser General Public License as published by
361+ * the Free Software Foundation; version 3.
362+ *
363+ * This program is distributed in the hope that it will be useful,
364+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
365+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
366+ * GNU Lesser General Public License for more details.
367+ *
368+ * You should have received a copy of the GNU Lesser General Public License
369+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
370+ *
371+ * Authors:
372+ * Nick Dedekind <nick.dedekind@canonical.com>
373+ */
374+
375+import QtQuick 2.0
376+import Unity.Indicators 0.1 as Indicators
377+
378+Indicators.IndicatorPage {
379+ anchors.fill: parent
380+}
381
382=== added file 'Panel/Indicators/DefaultIndicatorWidget.qml'
383--- Panel/Indicators/DefaultIndicatorWidget.qml 1970-01-01 00:00:00 +0000
384+++ Panel/Indicators/DefaultIndicatorWidget.qml 2013-07-11 14:53:26 +0000
385@@ -0,0 +1,80 @@
386+/*
387+ * Copyright 2013 Canonical Ltd.
388+ *
389+ * This program is free software; you can redistribute it and/or modify
390+ * it under the terms of the GNU Lesser General Public License as published by
391+ * the Free Software Foundation; version 3.
392+ *
393+ * This program is distributed in the hope that it will be useful,
394+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
395+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
396+ * GNU Lesser General Public License for more details.
397+ *
398+ * You should have received a copy of the GNU Lesser General Public License
399+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
400+ *
401+ * Authors:
402+ * Nick Dedekind <nick.dedekind@canonical.com>
403+ */
404+
405+import QtQuick 2.0
406+import Ubuntu.Components 0.1
407+import Unity.Indicators 0.1 as Indicators
408+
409+Indicators.IndicatorWidget {
410+ id: indicatorWidget
411+
412+ width: itemRow.width + units.gu(1)
413+
414+ property alias label: itemLabel.text
415+ property alias iconSource: itemImage.source
416+
417+ Row {
418+ id: itemRow
419+ objectName: "itemRow"
420+ anchors {
421+ top: parent.top
422+ bottom: parent.bottom
423+ horizontalCenter: parent.horizontalCenter
424+ }
425+ spacing: units.gu(0.5)
426+
427+ // FIXME : Should us Ubuntu.Icon . results in low res images
428+ Image {
429+ id: itemImage
430+ objectName: "itemImage"
431+ visible: source != ""
432+ height: indicatorWidget.iconSize
433+ width: indicatorWidget.iconSize
434+ anchors.verticalCenter: parent.verticalCenter
435+ }
436+
437+ Label {
438+ id: itemLabel
439+ objectName: "itemLabel"
440+ color: "#f3f3e7"
441+ opacity: 0.8
442+ font.family: "Ubuntu"
443+ fontSize: "medium"
444+ anchors.verticalCenter: parent.verticalCenter
445+ visible: text != ""
446+ }
447+ }
448+
449+ onActionStateChanged: {
450+ if (action == undefined || !action.valid) {
451+ return;
452+ }
453+
454+ if (action.state == undefined) {
455+ label = "";
456+ iconSource = "";
457+ enabled = false;
458+ return;
459+ }
460+
461+ label = action.state[Indicators.ActionState.Label];
462+ iconSource = "image://gicon/" + action.state[Indicators.ActionState.IconSource];
463+ enabled = action.state[Indicators.ActionState.Visible];
464+ }
465+}
466
467=== added file 'Panel/Indicators/MessagingIndicatorPage.qml'
468--- Panel/Indicators/MessagingIndicatorPage.qml 1970-01-01 00:00:00 +0000
469+++ Panel/Indicators/MessagingIndicatorPage.qml 2013-07-11 14:53:26 +0000
470@@ -0,0 +1,35 @@
471+/*
472+ * Copyright 2013 Canonical Ltd.
473+ *
474+ * This program is free software; you can redistribute it and/or modify
475+ * it under the terms of the GNU Lesser General Public License as published by
476+ * the Free Software Foundation; version 3.
477+ *
478+ * This program is distributed in the hope that it will be useful,
479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
481+ * GNU Lesser General Public License for more details.
482+ *
483+ * You should have received a copy of the GNU Lesser General Public License
484+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
485+ *
486+ * Authors:
487+ * Nick Dedekind <nick.dedekind@canonical.com>
488+ */
489+
490+import QtQuick 2.0
491+import Ubuntu.Components 0.1
492+import Unity.Indicators 0.1 as Indicators
493+
494+Indicators.IndicatorPage {
495+ anchors.fill: parent
496+
497+ highlightFollowsCurrentItem: false
498+ emptyText: "You have no more outstanding messages."
499+
500+ function stop() {
501+ // never stops the service
502+ // this will keep all objects in memory, consume more memory
503+ // but will optimize the menu contruction on the screen
504+ }
505+}
506
507=== added file 'Panel/Indicators/MessagingIndicatorWidget.qml'
508--- Panel/Indicators/MessagingIndicatorWidget.qml 1970-01-01 00:00:00 +0000
509+++ Panel/Indicators/MessagingIndicatorWidget.qml 2013-07-11 14:53:26 +0000
510@@ -0,0 +1,25 @@
511+/*
512+ * Copyright 2013 Canonical Ltd.
513+ *
514+ * This program is free software; you can redistribute it and/or modify
515+ * it under the terms of the GNU Lesser General Public License as published by
516+ * the Free Software Foundation; version 3.
517+ *
518+ * This program is distributed in the hope that it will be useful,
519+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
520+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
521+ * GNU Lesser General Public License for more details.
522+ *
523+ * You should have received a copy of the GNU Lesser General Public License
524+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
525+ *
526+ * Authors:
527+ * Nick Dedekind <nick.dedekind@canonical.com>
528+ */
529+
530+import QtQuick 2.0
531+
532+DefaultIndicatorWidget {
533+ // default the icon so we have something to show when we don't have the bus.
534+ iconSource: "image://gicon/indicator-messages"
535+}
536
537=== added file 'Panel/Indicators/NetworkIndicatorPage.qml'
538--- Panel/Indicators/NetworkIndicatorPage.qml 1970-01-01 00:00:00 +0000
539+++ Panel/Indicators/NetworkIndicatorPage.qml 2013-07-11 14:53:26 +0000
540@@ -0,0 +1,80 @@
541+/*
542+ * Copyright 2013 Canonical Ltd.
543+ *
544+ * This program is free software; you can redistribute it and/or modify
545+ * it under the terms of the GNU Lesser General Public License as published by
546+ * the Free Software Foundation; version 3.
547+ *
548+ * This program is distributed in the hope that it will be useful,
549+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
550+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
551+ * GNU Lesser General Public License for more details.
552+ *
553+ * You should have received a copy of the GNU Lesser General Public License
554+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
555+ *
556+ * Authors:
557+ * Renato Araujo Oliveira Filho <renato@canonical.com>
558+ */
559+
560+import QtQuick 2.0
561+import Unity.Indicators 0.1 as Indicators
562+import Unity.Indicators.Network 0.1 as ICNetwork
563+import Ubuntu.Components 0.1
564+
565+PageStack {
566+ id: _network
567+
568+ property alias title: _mainPage.title
569+ property alias emptyText: _pluginItem.emptyText
570+ property alias busType: _pluginItem.busType
571+ property alias busName: _pluginItem.busName
572+ property alias actionsObjectPath : _pluginItem.actionsObjectPath
573+ property alias menuObjectPaths : _pluginItem.menuObjectPaths
574+
575+ __showHeader: false
576+ anchors.fill: parent
577+
578+ Page {
579+ id: _mainPage
580+
581+ Indicators.IndicatorPage {
582+ id: _pluginItem
583+ anchors.fill: parent
584+ }
585+ }
586+
587+ Component {
588+ id: passwordPageComponent
589+
590+ ICNetwork.PasswordPage {
591+ agent: networkAgent
592+ token: token
593+ }
594+ }
595+
596+ ICNetwork.NetworkAgent {
597+ id: networkAgent
598+
599+ onSecretRequested: {
600+ _network.push(passwordPageComponent);
601+ }
602+ }
603+
604+ function start()
605+ {
606+ push(_mainPage);
607+ _pluginItem.start();
608+ }
609+
610+ function stop()
611+ {
612+ clear();
613+ _pluginItem.stop();
614+ }
615+
616+ function reset()
617+ {
618+ _pluginItem.reset();
619+ }
620+}
621
622=== added file 'Panel/Indicators/NetworkIndicatorWidget.qml'
623--- Panel/Indicators/NetworkIndicatorWidget.qml 1970-01-01 00:00:00 +0000
624+++ Panel/Indicators/NetworkIndicatorWidget.qml 2013-07-11 14:53:26 +0000
625@@ -0,0 +1,109 @@
626+/*
627+ * Copyright 2013 Canonical Ltd.
628+ *
629+ * This program is free software; you can redistribute it and/or modify
630+ * it under the terms of the GNU Lesser General Public License as published by
631+ * the Free Software Foundation; version 3.
632+ *
633+ * This program is distributed in the hope that it will be useful,
634+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
635+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
636+ * GNU Lesser General Public License for more details.
637+ *
638+ * You should have received a copy of the GNU Lesser General Public License
639+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
640+ *
641+ * Authors:
642+ * Nick Dedekind <nick.dedekind@canonical.com>
643+ */
644+
645+import QtQuick 2.0
646+import Ubuntu.Components 0.1
647+import Unity.Indicators 0.1 as Indicators
648+
649+Indicators.IndicatorWidget {
650+ id: indicatorWidget
651+
652+ width: networkIcon.width + units.gu(1)
653+
654+ property int signalStrength: 0
655+ property int connectionState: Indicators.NetworkConnection.Initial
656+ rootMenuType: "com.canonical.indicator.root.network"
657+
658+ // FIXME : Should us Ubuntu.Icon . results in low res images
659+ Image {
660+ id: networkIcon
661+ objectName: "itemImage"
662+ source: get_icon_for_signal(connectionState, signalStrength)
663+ visible: source != ""
664+ height: indicatorWidget.iconSize
665+ width: indicatorWidget.iconSize
666+ anchors.centerIn: parent
667+ }
668+
669+ onActionStateChanged: {
670+ if (action == undefined || !action.valid) {
671+ return;
672+ }
673+
674+ if (action.state == undefined) {
675+ connectionState = 0;
676+ return;
677+ }
678+
679+ connectionState = action.state[Indicators.NetworkActionState.Connection];
680+ if (connectionState == Indicators.NetworkConnection.Activated) {
681+ signalStrength = action.state[Indicators.NetworkActionState.SignalStrength];
682+ }
683+ }
684+
685+ NumberAnimation {
686+ id: activation_animation
687+ target: indicatorWidget
688+ property: "signalStrength"
689+ from: 0
690+ to: 100
691+ duration: 2500 // 5 states in 2.5 seconds
692+ loops: Animation.Infinite
693+ }
694+
695+ states: [
696+ State {
697+ name: "unknown"
698+ when: connectionState < Indicators.NetworkConnection.Activating || connectionState > Indicators.NetworkConnection.Deactivating
699+ PropertyChanges { target: activation_animation; running: false }
700+ },
701+ State {
702+ name: "activating"
703+ when: connectionState == Indicators.NetworkConnection.Activating
704+ PropertyChanges { target: activation_animation; running: true }
705+ },
706+ State {
707+ name: "activated"
708+ when: connectionState == Indicators.NetworkConnection.Activated
709+ PropertyChanges { target: activation_animation; running: false }
710+ },
711+ State {
712+ name: "deactivating"
713+ when: connectionState == Indicators.NetworkConnection.Deactivating
714+ PropertyChanges { target: activation_animation; running: true }
715+ }
716+ ]
717+
718+
719+ function get_icon_for_signal(con_state, value) {
720+ if (con_state >= Indicators.NetworkConnection.Activating && con_state <= Indicators.NetworkConnection.Deactivating) {
721+ if (value == 0) {
722+ return "image://gicon/nm-signal-00";
723+ } else if (value <= 25) {
724+ return "image://gicon/nm-signal-25";
725+ } else if (value <= 50) {
726+ return "image://gicon/nm-signal-50";
727+ } else if (value <= 75) {
728+ return "image://gicon/nm-signal-75";
729+ }
730+ return "image://gicon/nm-signal-100";
731+ }
732+ return "image://gicon/wifi-none";
733+ }
734+}
735
736=== added file 'Panel/Indicators/SoundIndicatorWidget.qml'
737--- Panel/Indicators/SoundIndicatorWidget.qml 1970-01-01 00:00:00 +0000
738+++ Panel/Indicators/SoundIndicatorWidget.qml 2013-07-11 14:53:26 +0000
739@@ -0,0 +1,25 @@
740+/*
741+ * Copyright 2013 Canonical Ltd.
742+ *
743+ * This program is free software; you can redistribute it and/or modify
744+ * it under the terms of the GNU Lesser General Public License as published by
745+ * the Free Software Foundation; version 3.
746+ *
747+ * This program is distributed in the hope that it will be useful,
748+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
749+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
750+ * GNU Lesser General Public License for more details.
751+ *
752+ * You should have received a copy of the GNU Lesser General Public License
753+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
754+ *
755+ * Authors:
756+ * Nick Dedekind <nick.dedekind@canonical.com>
757+ */
758+
759+import QtQuick 2.0
760+
761+DefaultIndicatorWidget {
762+ // default the icon so we have something to show when we don't have the bus.
763+ iconSource: "image://gicon/audio-volume-high"
764+}
765
766=== added directory 'Panel/Indicators/client'
767=== added file 'Panel/Indicators/client/IndicatorsClient.qml'
768--- Panel/Indicators/client/IndicatorsClient.qml 1970-01-01 00:00:00 +0000
769+++ Panel/Indicators/client/IndicatorsClient.qml 2013-07-11 14:53:26 +0000
770@@ -0,0 +1,42 @@
771+/*
772+ * Copyright 2013 Canonical Ltd.
773+ *
774+ * This program is free software; you can redistribute it and/or modify
775+ * it under the terms of the GNU Lesser General Public License as published by
776+ * the Free Software Foundation; version 3.
777+ *
778+ * This program is distributed in the hope that it will be useful,
779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
781+ * GNU Lesser General Public License for more details.
782+ *
783+ * You should have received a copy of the GNU Lesser General Public License
784+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
785+ *
786+ * Authors:
787+ * Renato Araujo Oliveira Filho <renato@canonical.com>
788+ */
789+
790+import QtQuick 2.0
791+import Ubuntu.Components 0.1
792+import Ubuntu.Components.ListItems 0.1 as ListItem
793+
794+Rectangle {
795+ color: "black"
796+ id: root
797+
798+ PageStack {
799+ id: pages
800+
801+ anchors.fill: parent
802+ Component.onCompleted: root.reset()
803+ }
804+
805+ function reset() {
806+ pages.clear();
807+ var component = Qt.createComponent("IndicatorsList.qml");
808+ var page = component.createObject(pages);
809+ console.log(component.errorString());
810+ pages.push(page);
811+ }
812+}
813
814=== added file 'Panel/Indicators/client/IndicatorsList.qml'
815--- Panel/Indicators/client/IndicatorsList.qml 1970-01-01 00:00:00 +0000
816+++ Panel/Indicators/client/IndicatorsList.qml 2013-07-11 14:53:26 +0000
817@@ -0,0 +1,62 @@
818+/*
819+ * Copyright 2013 Canonical Ltd.
820+ *
821+ * This program is free software; you can redistribute it and/or modify
822+ * it under the terms of the GNU Lesser General Public License as published by
823+ * the Free Software Foundation; version 3.
824+ *
825+ * This program is distributed in the hope that it will be useful,
826+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
827+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
828+ * GNU Lesser General Public License for more details.
829+ *
830+ * You should have received a copy of the GNU Lesser General Public License
831+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
832+ *
833+ * Authors:
834+ * Renato Araujo Oliveira Filho <renato@canonical.com>
835+ */
836+
837+import QtQuick 2.0
838+import Ubuntu.Components 0.1
839+import Ubuntu.Components.ListItems 0.1 as ListItem
840+import Unity.Indicators 0.1 as Indicators
841+import "../.."
842+
843+Page {
844+ id: page
845+ anchors.fill: parent
846+ title: "Plugin list"
847+
848+ IndicatorsDataModel {
849+ id: indicatorsModel
850+ }
851+
852+ ListView {
853+ id: mainMenu
854+ objectName: "mainMenu"
855+ anchors.fill: parent
856+ model: indicatorsModel
857+
858+ delegate: Indicators.MenuItem {
859+ anchors.left: parent.left
860+ anchors.right: parent.right
861+ progression: isValid
862+ objectName: identifier
863+
864+ Label {
865+ anchors.left: parent.left
866+ anchors.leftMargin: units.gu(0.5)
867+ anchors.verticalCenter: parent.verticalCenter
868+ text: title
869+ }
870+
871+ onClicked: {
872+ if (progression) {
873+ var new_page = Qt.createComponent("IndicatorsPage.qml");
874+ page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
875+ }
876+ }
877+ }
878+ }
879+}
880
881=== added file 'Panel/Indicators/client/IndicatorsPage.qml'
882--- Panel/Indicators/client/IndicatorsPage.qml 1970-01-01 00:00:00 +0000
883+++ Panel/Indicators/client/IndicatorsPage.qml 2013-07-11 14:53:26 +0000
884@@ -0,0 +1,49 @@
885+/*
886+ * Copyright 2013 Canonical Ltd.
887+ *
888+ * This program is free software; you can redistribute it and/or modify
889+ * it under the terms of the GNU Lesser General Public License as published by
890+ * the Free Software Foundation; version 3.
891+ *
892+ * This program is distributed in the hope that it will be useful,
893+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
894+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
895+ * GNU Lesser General Public License for more details.
896+ *
897+ * You should have received a copy of the GNU Lesser General Public License
898+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
899+ *
900+ * Authors:
901+ * Renato Araujo Oliveira Filho <renato@canonical.com>
902+ */
903+
904+import QtQuick 2.0
905+import Ubuntu.Components 0.1
906+
907+Page {
908+ id: _page
909+
910+ title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : ""
911+ property variant indicatorProperties
912+ property alias pageSource : page_loader.source
913+
914+ anchors.fill: parent
915+
916+ Loader {
917+ id: page_loader
918+ objectName: "page_loader"
919+
920+ anchors.fill: parent
921+
922+ onStatusChanged: {
923+ if (status == Loader.Ready) {
924+ for(var pName in indicatorProperties) {
925+ if (item.hasOwnProperty(pName)) {
926+ item[pName] = indicatorProperties[pName];
927+ }
928+ }
929+ item.start();
930+ }
931+ }
932+ }
933+}
934
935=== added file 'Panel/IndicatorsDataModel.qml'
936--- Panel/IndicatorsDataModel.qml 1970-01-01 00:00:00 +0000
937+++ Panel/IndicatorsDataModel.qml 2013-07-11 14:53:26 +0000
938@@ -0,0 +1,66 @@
939+/*
940+ * Copyright 2013 Canonical Ltd.
941+ *
942+ * This program is free software; you can redistribute it and/or modify
943+ * it under the terms of the GNU Lesser General Public License as published by
944+ * the Free Software Foundation; version 3.
945+ *
946+ * This program is distributed in the hope that it will be useful,
947+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
948+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
949+ * GNU Lesser General Public License for more details.
950+ *
951+ * You should have received a copy of the GNU Lesser General Public License
952+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
953+ *
954+ * Authors:
955+ * Renato Araujo Oliveira Filho <renato@canonical.com>
956+ */
957+
958+import QtQuick 2.0
959+import Unity.Indicators 0.1 as Indicators
960+import Utils 0.1
961+
962+Indicators.IndicatorsModel {
963+ id: ic_model
964+
965+ Component.onCompleted: load()
966+
967+ indicatorData : {
968+ 'indicator-messaging' : {
969+ 'title': 'Messaging',
970+ 'description' : '',
971+ 'priority': 10,
972+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorWidget.qml',
973+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorPage.qml'
974+ },
975+ 'indicator-sound' : {
976+ 'title': 'Sound',
977+ 'description' : '',
978+ 'priority': 20,
979+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/SoundIndicatorWidget.qml',
980+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
981+ },
982+ 'indicator-network' : {
983+ 'title': 'Networks',
984+ 'description' : '',
985+ 'priority': 30,
986+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorWidget.qml',
987+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage.qml'
988+ },
989+ 'indicator-battery' : {
990+ 'title': 'Battery',
991+ 'description' : '',
992+ 'priority': 40,
993+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget.qml',
994+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
995+ },
996+ 'indicator-time' : {
997+ 'title': 'Date and Time',
998+ 'description' : '',
999+ 'priority': 100,
1000+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorWidget.qml',
1001+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorPage.qml'
1002+ }
1003+ }
1004+}
1005
1006=== modified file 'Panel/MenuContent.qml'
1007--- Panel/MenuContent.qml 2013-07-02 20:33:09 +0000
1008+++ Panel/MenuContent.qml 2013-07-11 14:53:26 +0000
1009@@ -16,6 +16,7 @@
1010
1011 import QtQuick 2.0
1012 import Ubuntu.Components 0.1
1013+import Unity.Indicators 0.1 as Indicators
1014 import "Menus"
1015 import "../Components"
1016
1017@@ -29,7 +30,7 @@
1018 property bool __contentActive: false
1019 property alias currentIndex : menus.currentIndex
1020 property color backgroundColor: "#221e1c"
1021- property int contentReleaseInterval: 5000
1022+ property int contentReleaseInterval: 20000
1023
1024 width: units.gu(40)
1025 height: units.gu(42)
1026@@ -94,7 +95,7 @@
1027
1028 width: menus.width
1029 height: menus.height
1030- sourceComponent: component
1031+ source: pageSource
1032 visible: content.__shown
1033 onVisibleChanged: {
1034 // Reset the indicator states
1035@@ -104,25 +105,15 @@
1036 }
1037 asynchronous: true
1038
1039- onStatusChanged: {
1040- if (status == Loader.Ready) {
1041- if (indicatorsModel.widgetsMap && item.hasOwnProperty("widgetsMap")) {
1042- item["widgetsMap"] = indicatorsModel.widgetsMap
1043- }
1044- for(var pName in initialProperties) {
1045- if (item.hasOwnProperty(pName)) {
1046- item[pName] = initialProperties[pName]
1047- }
1048- }
1049- if (contentActive && menus.visible) {
1050- item.start()
1051- }
1052- }
1053- }
1054-
1055- // FIXME: QTBUG-30632 - asynchronous loader crashes when changing index quickly.
1056- Component.onDestruction: {
1057- active = false;
1058+ onLoaded: {
1059+ for(var pName in indicatorProperties) {
1060+ if (item.hasOwnProperty(pName)) {
1061+ item[pName] = indicatorProperties[pName]
1062+ }
1063+ }
1064+ if (contentActive && menus.visible) {
1065+ item.start()
1066+ }
1067 }
1068
1069 // Need to use a binding because the handle height changes.
1070@@ -189,7 +180,13 @@
1071 left: parent.left
1072 right: parent.right
1073 }
1074- text: content.overviewActive ? i18n.tr("Device") : (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count) ? indicatorsModel.get(menus.currentIndex).title : ""
1075+ text: {
1076+ if (content.overviewActive)
1077+ return i18n.tr("Device");
1078+ if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
1079+ return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
1080+ return "";
1081+ }
1082 opacity: __shown ? 1 : 0
1083 Behavior on opacity {NumberAnimation{duration: 100}}
1084 }
1085
1086=== modified file 'Panel/Menus/Overview/OverviewGrid.qml'
1087--- Panel/Menus/Overview/OverviewGrid.qml 2013-06-05 22:03:08 +0000
1088+++ Panel/Menus/Overview/OverviewGrid.qml 2013-07-11 14:53:26 +0000
1089@@ -59,31 +59,22 @@
1090 objectName: "overviewGridButton" + index
1091 width: grid.cellWidth
1092 height: grid.cellHeight
1093- Image {
1094- id: imageIcon
1095- objectName: "overviewGridButtonImage"
1096- source: iconSource
1097- width: units.gu(4)
1098- height: units.gu(4)
1099- anchors {
1100- centerIn: parent
1101- verticalCenterOffset: -units.gu(1)
1102- }
1103- sourceSize.width: width
1104- sourceSize.height: height
1105- visible: labelIcon.text === ""
1106- }
1107-
1108- Label {
1109- id: labelIcon
1110- text: label
1111- color: "#f3f3e7"
1112- opacity: 0.8
1113- font.family: "Ubuntu"
1114- fontSize: "large"
1115- anchors {
1116- centerIn: parent
1117- verticalCenterOffset: -units.gu(1)
1118+
1119+ Loader {
1120+ id: loader
1121+ source: widgetSource
1122+
1123+ width: units.gu(5)
1124+ height: units.gu(5)
1125+ anchors.centerIn: parent
1126+ anchors.verticalCenterOffset: -units.gu(1)
1127+
1128+ onLoaded: {
1129+ for(var pName in indicatorProperties) {
1130+ if (item.hasOwnProperty(pName)) {
1131+ item[pName] = indicatorProperties[pName]
1132+ }
1133+ }
1134 }
1135 }
1136
1137
1138=== added file 'Panel/graphics/time_and_date@18.png'
1139Binary files Panel/graphics/time_and_date@18.png 1970-01-01 00:00:00 +0000 and Panel/graphics/time_and_date@18.png 2013-07-11 14:53:26 +0000 differ
1140=== modified file 'build'
1141--- build 2013-07-03 10:33:48 +0000
1142+++ build 2013-07-11 14:53:26 +0000
1143@@ -43,10 +43,9 @@
1144 echo "Installing Unity 8 dependencies.."
1145 sudo apt-get install devscripts \
1146 equivs \
1147+ qmenumodel-qml \
1148 qtdeclarative5-ubuntu-ui-toolkit-plugin \
1149 qtdeclarative5-dee-plugin \
1150- indicators-client \
1151- indicators-client-plugin-* \
1152 ubuntu-mobile-icons \
1153 unity-notifications-impl-1 \
1154 unity-scope-home \
1155
1156=== modified file 'cmake/modules/autopilot.cmake'
1157--- cmake/modules/autopilot.cmake 2013-06-05 22:03:08 +0000
1158+++ cmake/modules/autopilot.cmake 2013-07-11 14:53:26 +0000
1159@@ -1,7 +1,10 @@
1160 add_custom_target(autopilot)
1161
1162-function(declare_autopilot_test TEST_NAME WORKING_DIR)
1163- add_custom_command(TARGET autopilot
1164- COMMAND autopilot run ${TEST_NAME}
1165- WORKING_DIRECTORY ${WORKING_DIR})
1166+function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
1167+ add_custom_target(autopilot-${TEST_NAME}
1168+ COMMAND autopilot run ${TEST_SUITE}
1169+ WORKING_DIRECTORY ${WORKING_DIR}
1170+ )
1171+
1172+ add_dependencies(autopilot autopilot-${TEST_NAME})
1173 endfunction()
1174
1175=== modified file 'debian/control'
1176--- debian/control 2013-07-11 13:49:23 +0000
1177+++ debian/control 2013-07-11 14:53:26 +0000
1178@@ -10,7 +10,10 @@
1179 libgles2-mesa-dev[armhf],
1180 libhud-client2-dev,
1181 libjson-perl,
1182+ libnm-glib-dev,
1183+ libnm-util-dev,
1184 libpulse-dev,
1185+ libqmenumodel-dev,
1186 libqt5v8-5-private-dev,
1187 libunity-api-dev (>= 7.80.3),
1188 libunity-core-6.0-dev (<< 7.80),
1189@@ -41,9 +44,19 @@
1190 Vcs-Bzr: https://code.launchpad.net/unity8
1191 Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
1192
1193+Package: indicators-client
1194+Architecture: amd64 armhf i386
1195+Depends: qmenumodel-qml,
1196+ qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
1197+ unity8 (= ${binary:Version}),
1198+ ${misc:Depends},
1199+ ${shlibs:Depends},
1200+Description: Indicators client test application
1201+ This package contains the client application for indicators used by autopilot
1202+
1203 Package: unity8
1204 Architecture: any
1205-Depends: indicators-client (>= 0.6.1),
1206+Depends: qmenumodel-qml,
1207 qtdeclarative5-dee-plugin,
1208 qtdeclarative5-ubuntu-ui-toolkit-plugin,
1209 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
1210@@ -55,18 +68,19 @@
1211 unity8-private | unity-launcher-impl,
1212 ${misc:Depends},
1213 ${shlibs:Depends},
1214-Recommends: indicators-client-plugin-datetime (>= 0.6.1),
1215- indicators-client-plugin-messaging (>= 0.6.1),
1216- indicators-client-plugin-network (>= 0.6.1),
1217- indicators-client-plugin-power (>= 0.6.1),
1218- indicators-client-plugin-sound (>= 0.6.1),
1219+Recommends: indicator-battery,
1220+ indicator-messages,
1221+ indicator-network,
1222+ indicator-sound,
1223+ indicator-time,
1224 ${unity-default-masterscopes},
1225 Description: Unity 8 shell
1226 The Unity 8 shell is the primary user interface for Ubuntu devices.
1227
1228 Package: unity8-autopilot
1229 Architecture: all
1230-Depends: libautopilot-qt,
1231+Depends: indicators-client (>= ${source:Version}),
1232+ libautopilot-qt,
1233 libqt5test5,
1234 libqt5widgets5,
1235 python-evdev,
1236
1237=== added file 'debian/indicators-client.install'
1238--- debian/indicators-client.install 1970-01-01 00:00:00 +0000
1239+++ debian/indicators-client.install 2013-07-11 14:53:26 +0000
1240@@ -0,0 +1,1 @@
1241+/usr/bin/indicators-client
1242
1243=== modified file 'debian/unity8.install'
1244--- debian/unity8.install 2013-07-02 14:44:34 +0000
1245+++ debian/unity8.install 2013-07-11 14:53:26 +0000
1246@@ -13,3 +13,4 @@
1247 usr/share/unity8/Shell.qml
1248 usr/share/unity8/SideStage
1249 usr/share/unity8/graphics
1250+usr/share/unity8/unity/indicators/*
1251
1252=== modified file 'main.cpp'
1253--- main.cpp 2013-07-03 09:23:56 +0000
1254+++ main.cpp 2013-07-11 14:53:26 +0000
1255@@ -22,6 +22,7 @@
1256 #include <QtGui/QIcon>
1257 #include <QtGui/QGuiApplication>
1258 #include <QtQml/QQmlEngine>
1259+#include <QtQml/QQmlContext>
1260 #include <qpa/qplatformnativeinterface.h>
1261 #include <QLibrary>
1262 #include <libintl.h>
1263@@ -131,8 +132,6 @@
1264 nativeInterface->setProperty("ubuntuSessionType", 1);
1265 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
1266
1267- QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
1268-
1269 QUrl source("Shell.qml");
1270 prependImportPaths(view->engine(), ::overrideImportPaths());
1271 appendImportPaths(view->engine(), ::fallbackImportPaths());
1272
1273=== modified file 'paths.h.in'
1274--- paths.h.in 2013-06-28 13:14:29 +0000
1275+++ paths.h.in 2013-07-11 14:53:26 +0000
1276@@ -23,6 +23,7 @@
1277 // Qt
1278 #include <QtCore/QCoreApplication>
1279 #include <QtCore/QDir>
1280+#include <QStandardPaths>
1281
1282 inline bool isRunningInstalled() {
1283 static bool installed = (QCoreApplication::applicationDirPath() ==
1284@@ -65,6 +66,20 @@
1285 return paths;
1286 }
1287
1288+inline QStringList shellDataDirs() {
1289+ QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
1290+ if (!isRunningInstalled()) {
1291+ if (getenv("UNITY_TEST_ENV")==NULL) {
1292+ dirs.prepend("@CMAKE_BINARY_DIR@/share");
1293+ }
1294+ }
1295+ else {
1296+ // append so by default we use xdg files.
1297+ dirs.append(shellAppDirectory());
1298+ }
1299+ return dirs;
1300+}
1301+
1302 inline QString sourceDirectory() {
1303 return QString("@CMAKE_SOURCE_DIR@/");
1304 }
1305
1306=== modified file 'plugins/Unity/CMakeLists.txt'
1307--- plugins/Unity/CMakeLists.txt 2013-07-11 08:19:10 +0000
1308+++ plugins/Unity/CMakeLists.txt 2013-07-11 14:53:26 +0000
1309@@ -1,6 +1,8 @@
1310 # export_qmlplugin macro
1311 include(Plugins)
1312
1313+add_subdirectory(Indicators)
1314+
1315 # Dependencies
1316 include(FindPkgConfig)
1317 pkg_check_modules(QTDEE REQUIRED libdee-qt5)
1318
1319=== added directory 'plugins/Unity/Indicators'
1320=== added file 'plugins/Unity/Indicators/CMakeLists.txt'
1321--- plugins/Unity/Indicators/CMakeLists.txt 1970-01-01 00:00:00 +0000
1322+++ plugins/Unity/Indicators/CMakeLists.txt 2013-07-11 14:53:26 +0000
1323@@ -0,0 +1,52 @@
1324+project(IndicatorsQml)
1325+
1326+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
1327+find_package(Qt5Core REQUIRED)
1328+find_package(Qt5Quick REQUIRED)
1329+
1330+add_subdirectory(qml)
1331+add_subdirectory(Messaging)
1332+add_subdirectory(Network)
1333+
1334+include_directories(
1335+ ${CMAKE_CURRENT_SOURCE_DIR}
1336+ ${CMAKE_CURRENT_BINARY_DIR}
1337+ ${QMENUMODEL_INCLUDE_DIRS}
1338+)
1339+
1340+set(IndicatorsQML_SOURCES
1341+ flatmenuproxymodel.cpp
1342+ indicator.cpp
1343+ indicators.h
1344+ indicatorsmanager.cpp
1345+ indicatorsmodel.cpp
1346+ plugin.cpp
1347+)
1348+
1349+set(IndicatorsQML_RESOURCES
1350+ resources/indicators.qrc
1351+)
1352+
1353+qt5_add_resources(IndicatorsQML_RESOURCES_RCC
1354+ ${IndicatorsQML_RESOURCES}
1355+)
1356+
1357+add_library(IndicatorsQml SHARED
1358+ ${IndicatorsQML_RESOURCES_RCC}
1359+ ${IndicatorsQML_SOURCES}
1360+)
1361+# Because this is an internal support library, we want
1362+# to expose all symbols in it. Consider changing this
1363+# either to a static library or just using the
1364+# files directly in targets.
1365+set_target_properties(IndicatorsQml PROPERTIES COMPILE_FLAGS -fvisibility=default)
1366+
1367+target_link_libraries(IndicatorsQml
1368+ ${QMENUMODEL_LDFLAGS}
1369+)
1370+
1371+qt5_use_modules(IndicatorsQml Core Qml Quick)
1372+
1373+install(TARGETS IndicatorsQml
1374+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators
1375+ )
1376
1377=== added directory 'plugins/Unity/Indicators/Messaging'
1378=== added file 'plugins/Unity/Indicators/Messaging/CMakeLists.txt'
1379--- plugins/Unity/Indicators/Messaging/CMakeLists.txt 1970-01-01 00:00:00 +0000
1380+++ plugins/Unity/Indicators/Messaging/CMakeLists.txt 2013-07-11 14:53:26 +0000
1381@@ -0,0 +1,1 @@
1382+add_subdirectory(qml)
1383
1384=== added directory 'plugins/Unity/Indicators/Messaging/qml'
1385=== added file 'plugins/Unity/Indicators/Messaging/qml/ActionButton.qml'
1386--- plugins/Unity/Indicators/Messaging/qml/ActionButton.qml 1970-01-01 00:00:00 +0000
1387+++ plugins/Unity/Indicators/Messaging/qml/ActionButton.qml 2013-07-11 14:53:26 +0000
1388@@ -0,0 +1,43 @@
1389+/*
1390+ * Copyright 2013 Canonical Ltd.
1391+ *
1392+ * This program is free software; you can redistribute it and/or modify
1393+ * it under the terms of the GNU Lesser General Public License as published by
1394+ * the Free Software Foundation; version 3.
1395+ *
1396+ * This program is distributed in the hope that it will be useful,
1397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1399+ * GNU Lesser General Public License for more details.
1400+ *
1401+ * You should have received a copy of the GNU Lesser General Public License
1402+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1403+ *
1404+ * Authors:
1405+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1406+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1407+ */
1408+
1409+import QtQuick 2.0
1410+import Ubuntu.Components 0.1
1411+import Unity.Indicators 0.1 as Indicators
1412+
1413+Button {
1414+ id: button
1415+ property QtObject actionGroup: null
1416+ property string action
1417+
1418+ property var actionParameter: null
1419+
1420+ Indicators.MenuAction {
1421+ id: menuAction
1422+ actionGroup: button.actionGroup
1423+ action: button.action
1424+ }
1425+
1426+ onClicked: {
1427+ if (menuAction.valid) {
1428+ menuAction.activate(actionParameter);
1429+ }
1430+ }
1431+}
1432
1433=== added file 'plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml'
1434--- plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml 1970-01-01 00:00:00 +0000
1435+++ plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml 2013-07-11 14:53:26 +0000
1436@@ -0,0 +1,66 @@
1437+/*
1438+ * Copyright 2013 Canonical Ltd.
1439+ *
1440+ * This program is free software; you can redistribute it and/or modify
1441+ * it under the terms of the GNU Lesser General Public License as published by
1442+ * the Free Software Foundation; version 3.
1443+ *
1444+ * This program is distributed in the hope that it will be useful,
1445+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1446+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1447+ * GNU Lesser General Public License for more details.
1448+ *
1449+ * You should have received a copy of the GNU Lesser General Public License
1450+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1451+ *
1452+ * Authors:
1453+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1454+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1455+ */
1456+
1457+import QtQuick 2.0
1458+import Ubuntu.Components 0.1
1459+
1460+Item {
1461+ property alias actionGroup: sendButton.actionGroup
1462+ property alias action: sendButton.action
1463+
1464+ property alias text: replyField.text
1465+ property alias buttonText: sendButton.text
1466+
1467+ TextField {
1468+ id: replyField
1469+
1470+ anchors {
1471+ top: parent.top
1472+ bottom: parent.bottom
1473+ left: parent.left
1474+ right: sendButton.left
1475+ rightMargin: units.gu(1)
1476+ }
1477+ placeholderText: "Reply"
1478+ hasClearButton: false
1479+
1480+ onEnabledChanged: {
1481+ //Make sure that the component lost focus when enabled = false,
1482+ //otherwise it will get focus again when enable = true
1483+ if (!enabled) {
1484+ focus = false;
1485+ }
1486+ }
1487+ }
1488+
1489+ ActionButton {
1490+ id: sendButton
1491+
1492+ actionParameter: replyField.text
1493+ anchors {
1494+ top: parent.top
1495+ bottom: parent.bottom
1496+ right: parent.right
1497+ }
1498+ width: units.gu(9)
1499+ enabled: replyField.text !== ""
1500+ color: enabled ? "#c94212" : "#bababa"
1501+ }
1502+}
1503
1504=== added file 'plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt'
1505--- plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt 1970-01-01 00:00:00 +0000
1506+++ plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt 2013-07-11 14:53:26 +0000
1507@@ -0,0 +1,15 @@
1508+file(GLOB IndicatorsMessaging_QMLFILES
1509+ *.qml
1510+ *.js
1511+ qmldir
1512+)
1513+
1514+# copy qml & qmldir files into build directory for shadow builds
1515+add_custom_target(UnityIndicatorsMessagingQmlFiles ALL
1516+ COMMAND cp ${IndicatorsMessaging_QMLFILES} ${CMAKE_BINARY_DIR}/plugins/Unity/Indicators/Messaging
1517+ DEPENDS ${IndicatorsMessaging_QMLFILES}
1518+)
1519+
1520+install(FILES ${IndicatorsMessaging_QMLFILES}
1521+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Messaging
1522+)
1523
1524=== added file 'plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml'
1525--- plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml 1970-01-01 00:00:00 +0000
1526+++ plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml 2013-07-11 14:53:26 +0000
1527@@ -0,0 +1,96 @@
1528+/*
1529+ * Copyright 2013 Canonical Ltd.
1530+ *
1531+ * This program is free software; you can redistribute it and/or modify
1532+ * it under the terms of the GNU Lesser General Public License as published by
1533+ * the Free Software Foundation; version 3.
1534+ *
1535+ * This program is distributed in the hope that it will be useful,
1536+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1537+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1538+ * GNU Lesser General Public License for more details.
1539+ *
1540+ * You should have received a copy of the GNU Lesser General Public License
1541+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1542+ *
1543+ * Authors:
1544+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1545+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1546+ */
1547+
1548+import QtQuick 2.0
1549+import Ubuntu.Components 0.1
1550+import Unity.Indicators 0.1 as Indicators
1551+
1552+Indicators.BasicMenuItem {
1553+ id: groupedMessage
1554+ property alias count: label.text
1555+
1556+ color: "#221e1b"
1557+ implicitHeight: units.gu(10)
1558+
1559+ Indicators.MenuAction {
1560+ id: menuAction
1561+ actionGroup: groupedMessage.actionGroup
1562+ action: menu ? menu.action : ""
1563+ }
1564+
1565+ Row {
1566+ anchors.fill: parent
1567+ anchors.margins: units.gu(2)
1568+ spacing: units.gu(4)
1569+
1570+ UbuntuShape {
1571+ height: units.gu(6)
1572+ width: units.gu(6)
1573+ image: Image {
1574+ source: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_app.svg"
1575+ fillMode: Image.PreserveAspectFit
1576+ }
1577+ }
1578+
1579+ Label {
1580+ anchors.verticalCenter: parent.verticalCenter
1581+ color: "#e8e1d0"
1582+ font.weight: Font.DemiBold
1583+ fontSize: "medium"
1584+ text: menu && menu.label ? menu.label : ""
1585+ }
1586+
1587+ Label {
1588+ id: label
1589+ anchors.verticalCenter: parent.verticalCenter
1590+ width: parent.width - x
1591+ horizontalAlignment: Text.AlignRight
1592+ color: "#e8e1d0"
1593+ font.weight: Font.DemiBold
1594+ fontSize: "medium"
1595+ text: menuAction.valid ? menuAction.state[0] : "0"
1596+ }
1597+ }
1598+
1599+ Indicators.HLine {
1600+ anchors.top: parent.top
1601+ color: "#403b37"
1602+ }
1603+
1604+ Indicators.HLine {
1605+ anchors.bottom: parent.bottom
1606+ color: "#060606"
1607+ }
1608+
1609+ MouseArea {
1610+ anchors.fill: parent
1611+ onClicked: {
1612+ if (menuAction.valid) {
1613+ menuAction.activate(true);
1614+ }
1615+ }
1616+ }
1617+
1618+ onItemRemoved: {
1619+ if (menuAction.valid) {
1620+ menuAction.activate(false);
1621+ }
1622+ }
1623+}
1624
1625=== added file 'plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml'
1626--- plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml 1970-01-01 00:00:00 +0000
1627+++ plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml 2013-07-11 14:53:26 +0000
1628@@ -0,0 +1,120 @@
1629+/*
1630+ * Copyright 2013 Canonical Ltd.
1631+ *
1632+ * This program is free software; you can redistribute it and/or modify
1633+ * it under the terms of the GNU Lesser General Public License as published by
1634+ * the Free Software Foundation; version 3.
1635+ *
1636+ * This program is distributed in the hope that it will be useful,
1637+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1638+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1639+ * GNU Lesser General Public License for more details.
1640+ *
1641+ * You should have received a copy of the GNU Lesser General Public License
1642+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1643+ *
1644+ * Authors:
1645+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1646+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1647+ */
1648+
1649+import QtQuick 2.0
1650+import Ubuntu.Components 0.1
1651+import Unity.Indicators 0.1 as Indicators
1652+
1653+Indicators.BasicMenuItem {
1654+ id: heroMessage
1655+
1656+ property variant actionsDescription: null
1657+ property alias heroMessageHeader: __heroMessageHeader
1658+ property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
1659+ property real expandedHeight: collapsedHeight
1660+
1661+ color: "#221e1c"
1662+
1663+ removable: state !== "expanded"
1664+ implicitHeight: collapsedHeight
1665+
1666+ Indicators.MenuAction {
1667+ id: menuAction
1668+ actionGroup: heroMessage.actionGroup
1669+ action: menu ? menu.action : ""
1670+ }
1671+
1672+ HeroMessageHeader {
1673+ id: __heroMessageHeader
1674+
1675+ anchors.top: parent.top
1676+ anchors.left: parent.left
1677+ anchors.right: parent.right
1678+
1679+ avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_contact.png"
1680+ icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_app_icon) : ""
1681+ appIcon: icon
1682+
1683+ state: heroMessage.state
1684+
1685+ onAppIconClicked: {
1686+ if (menuAction.valid) {
1687+ deactivateMenu();
1688+ action.activate(true);
1689+ }
1690+ }
1691+ }
1692+
1693+ onClicked: {
1694+ if (menuActivated) {
1695+ deactivateMenu();
1696+ } else {
1697+ activateMenu();
1698+ }
1699+ }
1700+
1701+ Indicators.HLine {
1702+ id: __topHLine
1703+ anchors.top: parent.top
1704+ color: "#403b37"
1705+ }
1706+
1707+ Indicators.HLine {
1708+ id: __bottomHLine
1709+ anchors.bottom: parent.bottom
1710+ color: "#060606"
1711+ }
1712+
1713+ states: State {
1714+ name: "expanded"
1715+ when: menuActivated
1716+
1717+ PropertyChanges {
1718+ target: heroMessage
1719+ color: "#333130"
1720+ implicitHeight: heroMessage.expandedHeight
1721+ }
1722+ PropertyChanges {
1723+ target: __topHLine
1724+ opacity: 0.0
1725+ }
1726+ PropertyChanges {
1727+ target: __bottomHLine
1728+ opacity: 0.0
1729+ }
1730+ }
1731+
1732+ transitions: Transition {
1733+ ParallelAnimation {
1734+ NumberAnimation {
1735+ properties: "opacity,implicitHeight"
1736+ duration: 200
1737+ easing.type: Easing.OutQuad
1738+ }
1739+ ColorAnimation {}
1740+ }
1741+ }
1742+
1743+ onItemRemoved: {
1744+ if (menuAction.valid) {
1745+ menuAction.activate(false);
1746+ }
1747+ }
1748+}
1749
1750=== added file 'plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml'
1751--- plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml 1970-01-01 00:00:00 +0000
1752+++ plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml 2013-07-11 14:53:26 +0000
1753@@ -0,0 +1,161 @@
1754+/*
1755+ * Copyright 2013 Canonical Ltd.
1756+ *
1757+ * This program is free software; you can redistribute it and/or modify
1758+ * it under the terms of the GNU Lesser General Public License as published by
1759+ * the Free Software Foundation; version 3.
1760+ *
1761+ * This program is distributed in the hope that it will be useful,
1762+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1763+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1764+ * GNU Lesser General Public License for more details.
1765+ *
1766+ * You should have received a copy of the GNU Lesser General Public License
1767+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1768+ *
1769+ * Authors:
1770+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1771+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1772+ */
1773+
1774+import QtQuick 2.0
1775+import Ubuntu.Components 0.1
1776+
1777+Item {
1778+ id: heroMessageHeader
1779+
1780+ property alias avatar: avatarImage.source
1781+ property alias icon: iconImage.source
1782+ property alias appIcon: appIconImage.source
1783+ property alias titleText: __titleText
1784+ property alias subtitleText: __subtitleText
1785+ property alias bodyText: __bodyText
1786+ property real bodyBottom: bodyText.y + bodyText.height
1787+
1788+ signal appIconClicked()
1789+
1790+ height: units.gu(9)
1791+
1792+ UbuntuShape {
1793+ id: avatarImageContainer
1794+ anchors {
1795+ top: parent.top
1796+ topMargin: units.gu(2)
1797+ left: parent.left
1798+ leftMargin: units.gu(2)
1799+ }
1800+ height: units.gu(6)
1801+ width: units.gu(6)
1802+ image: Image {
1803+ id: avatarImage
1804+ fillMode: Image.PreserveAspectFit
1805+ }
1806+ }
1807+
1808+ Image {
1809+ id: iconImage
1810+ anchors {
1811+ top: parent.top
1812+ topMargin: units.gu(2)
1813+ left: avatarImageContainer.right
1814+ leftMargin: units.gu(1)
1815+ }
1816+ height: units.gu(1.5)
1817+ width: units.gu(2)
1818+ horizontalAlignment: Image.AlignHCenter
1819+ verticalAlignment: Image.AlignBottom
1820+ fillMode: Image.PreserveAspectFit
1821+ }
1822+
1823+ Label {
1824+ id: __titleText
1825+ anchors {
1826+ baseline: iconImage.bottom
1827+ left: iconImage.right
1828+ leftMargin: units.gu(1)
1829+ right: __appIcon.left
1830+ rightMargin: units.gu(2)
1831+ }
1832+ elide: Text.ElideRight
1833+ color: "#e8e1d0"
1834+ font.weight: Font.DemiBold
1835+ fontSize: "medium"
1836+ }
1837+
1838+ Label {
1839+ id: __subtitleText
1840+ anchors {
1841+ baseline: __titleText.baseline
1842+ baselineOffset: units.gu(2.5)
1843+ left: __titleText.left
1844+ right: __titleText.right
1845+ }
1846+ elide: Text.ElideRight
1847+ color: "#8f8f88"
1848+ fontSize: "small"
1849+ }
1850+
1851+ Label {
1852+ id: __bodyText
1853+ anchors {
1854+ baseline: __subtitleText.baseline
1855+ baselineOffset: units.gu(2.5)
1856+ left: __titleText.left
1857+ right: parent.right
1858+ rightMargin: units.gu(2)
1859+ }
1860+ maximumLineCount: 2
1861+ wrapMode: Text.WordWrap
1862+ elide: Text.ElideRight
1863+ color: "#e8e1d0"
1864+ fontSize: "small"
1865+ }
1866+
1867+ Item {
1868+ id: __appIcon
1869+ width: units.gu(7)
1870+ height: units.gu(7)
1871+ anchors {
1872+ top: parent.top
1873+ right: parent.right
1874+ }
1875+ opacity: 0.0
1876+ enabled: heroMessageHeader.state === "expanded"
1877+
1878+ Image {
1879+ id: appIconImage
1880+ height: width
1881+ anchors {
1882+ left: parent.left
1883+ leftMargin: units.gu(2)
1884+ right: parent.right
1885+ rightMargin: units.gu(2)
1886+ topMargin: units.gu(1)
1887+ verticalCenter: parent.verticalCenter
1888+ }
1889+ fillMode: Image.PreserveAspectFit
1890+ }
1891+
1892+ MouseArea {
1893+ anchors.fill: parent
1894+ onClicked: heroMessageHeader.appIconClicked()
1895+ }
1896+ }
1897+
1898+ states: State {
1899+ name: "expanded"
1900+
1901+ PropertyChanges {
1902+ target: __appIcon
1903+ opacity: 1.0
1904+ }
1905+ }
1906+
1907+ transitions: Transition {
1908+ NumberAnimation {
1909+ property: "opacity"
1910+ duration: 200
1911+ easing.type: Easing.OutQuad
1912+ }
1913+ }
1914+}
1915
1916=== added file 'plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml'
1917--- plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml 1970-01-01 00:00:00 +0000
1918+++ plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml 2013-07-11 14:53:26 +0000
1919@@ -0,0 +1,96 @@
1920+/*
1921+ * Copyright 2013 Canonical Ltd.
1922+ *
1923+ * This program is free software; you can redistribute it and/or modify
1924+ * it under the terms of the GNU Lesser General Public License as published by
1925+ * the Free Software Foundation; version 3.
1926+ *
1927+ * This program is distributed in the hope that it will be useful,
1928+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1929+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1930+ * GNU Lesser General Public License for more details.
1931+ *
1932+ * You should have received a copy of the GNU Lesser General Public License
1933+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1934+ *
1935+ * Authors:
1936+ * Renato Araujo Oliveira Filho <renato@canonical.com>
1937+ * Olivier Tilloy <olivier.tilloy@canonical.com>
1938+ */
1939+
1940+import QtQuick 2.0
1941+import Ubuntu.Components 0.1
1942+import Unity.Indicators 0.1 as Indicators
1943+
1944+Indicators.BasicMenuItem {
1945+ property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
1946+
1947+ onActionGroupChanged: loadItem()
1948+ onActionsDescriptionChanged: loadItem()
1949+ implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
1950+
1951+ Loader {
1952+ id: contents
1953+
1954+ anchors.fill: parent
1955+ // Binding all properties for the item, to make sure that any change in the
1956+ // property will be propagated to the contents.item at any time
1957+ Binding {
1958+ target: contents.item
1959+ property: "menuActivated"
1960+ value: menuActivated
1961+ when: (contents.status == Loader.Ready)
1962+ }
1963+
1964+ Binding {
1965+ target: contents.item
1966+ property: "actionGroup"
1967+ value: actionGroup
1968+ when: (contents.status == Loader.Ready)
1969+ }
1970+
1971+ Binding {
1972+ target: contents.item
1973+ property: "menu"
1974+ value: menu
1975+ when: (contents.status == Loader.Ready)
1976+ }
1977+
1978+ Binding {
1979+ target: contents.item
1980+ property: "actionsDescription"
1981+ value: actionsDescription
1982+ when: (contents.status == Loader.Ready)
1983+ }
1984+
1985+ Connections {
1986+ target: contents.item ? contents.item : null
1987+ onActivateMenu: activateMenu()
1988+ onDeactivateMenu: deactivateMenu()
1989+ }
1990+ }
1991+
1992+
1993+ function loadItem()
1994+ {
1995+ var parameterType = ""
1996+ for (var actIndex in actionsDescription) {
1997+ var desc = actionsDescription[actIndex];
1998+ if (desc["parameter-type"] !== undefined) {
1999+ parameterType += desc["parameter-type"];
2000+ } else {
2001+ parameterType += "_";
2002+ }
2003+ }
2004+
2005+ if (parameterType === "") {
2006+ contents.source = "SimpleTextMessage.qml";
2007+ } else if (parameterType === "s") {
2008+ contents.source = "TextMessage.qml";
2009+ } else if (parameterType === "_s") {
2010+ contents.source = "SnapDecision.qml";
2011+ } else {
2012+ console.debug("Unknown paramater type: " + parameterType);
2013+ }
2014+ }
2015+}
2016
2017=== added file 'plugins/Unity/Indicators/Messaging/qml/QuickReply.qml'
2018--- plugins/Unity/Indicators/Messaging/qml/QuickReply.qml 1970-01-01 00:00:00 +0000
2019+++ plugins/Unity/Indicators/Messaging/qml/QuickReply.qml 2013-07-11 14:53:26 +0000
2020@@ -0,0 +1,160 @@
2021+/*
2022+ * Copyright 2013 Canonical Ltd.
2023+ *
2024+ * This program is free software; you can redistribute it and/or modify
2025+ * it under the terms of the GNU Lesser General Public License as published by
2026+ * the Free Software Foundation; version 3.
2027+ *
2028+ * This program is distributed in the hope that it will be useful,
2029+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2030+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2031+ * GNU Lesser General Public License for more details.
2032+ *
2033+ * You should have received a copy of the GNU Lesser General Public License
2034+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2035+ *
2036+ * Authors:
2037+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2038+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2039+ */
2040+
2041+import QtQuick 2.0
2042+import Ubuntu.Components 0.1
2043+import Unity.Indicators 0.1 as Indicators
2044+
2045+Item {
2046+ property alias actionGroup: actionTextField.actionGroup
2047+ property alias action: actionTextField.action
2048+
2049+ property alias buttonText: actionTextField.buttonText
2050+ property real expandedHeight: childrenRect.height
2051+ property alias messages : messagelistRepeater.model
2052+
2053+ Item {
2054+ id: header
2055+ anchors.top: parent.top
2056+ anchors.left: parent.left
2057+ anchors.right: parent.right
2058+ height: units.gu(4)
2059+
2060+ Row {
2061+ anchors {
2062+ fill: parent
2063+ leftMargin: units.gu(2)
2064+ rightMargin: units.gu(2)
2065+ topMargin: units.gu(1)
2066+ bottomMargin: units.gu(1)
2067+ }
2068+ spacing: units.gu(1)
2069+
2070+ Image {
2071+ width: units.gu(2)
2072+ height: width
2073+ fillMode: Image.PreserveAspectFit
2074+ source: "qrc:/indicators/artwork/messaging/message_sms01_54px.png"
2075+ }
2076+
2077+ Label {
2078+ height: parent.height
2079+ verticalAlignment: Text.AlignVCenter
2080+ fontSize: "small"
2081+ color: "#8f8f88"
2082+ text: "Quick reply with:"
2083+ }
2084+ }
2085+
2086+ Indicators.HLine {
2087+ anchors.bottom: parent.bottom
2088+ color: "#20201F"
2089+ }
2090+ }
2091+
2092+ Column {
2093+ id: messagelist
2094+ anchors {
2095+ left: parent.left
2096+ right: parent.right
2097+ top: header.bottom
2098+ }
2099+ height: childrenRect.height
2100+
2101+ Repeater {
2102+ id: messagelistRepeater
2103+
2104+ height: childrenRect.height
2105+
2106+ Rectangle {
2107+ width: messagelist.width
2108+ height: units.gu(5)
2109+ color: "#333230"
2110+
2111+ Label {
2112+ id: __label
2113+
2114+ anchors {
2115+ fill: parent
2116+ leftMargin: units.gu(2)
2117+ rightMargin: units.gu(2)
2118+ }
2119+ verticalAlignment: Text.AlignVCenter
2120+ fontSize: "medium"
2121+ color: "#e8e1d0"
2122+ text: modelData
2123+ }
2124+
2125+ Indicators.HLine {
2126+ anchors.top: parent.top
2127+ color: "#464543"
2128+ }
2129+
2130+ Indicators.HLine {
2131+ anchors.bottom: parent.bottom
2132+ color: "#20201F"
2133+ }
2134+
2135+ MouseArea {
2136+ id: __mouseArea
2137+
2138+ anchors.fill: parent
2139+ onClicked: {
2140+ actionTextField.text = modelData;
2141+ }
2142+ }
2143+
2144+ Rectangle {
2145+ id: __mask
2146+
2147+ anchors.fill: parent
2148+ color: "black"
2149+ opacity: __mouseArea.pressed ? 0.3 : 0.0
2150+ Behavior on opacity {
2151+ NumberAnimation {
2152+ duration: 200
2153+ easing.type: Easing.OutQuad
2154+ }
2155+ }
2156+ }
2157+ }
2158+
2159+ }
2160+ }
2161+
2162+ Item {
2163+ anchors.top: messagelist.bottom
2164+ anchors.left: parent.left
2165+ anchors.right: parent.right
2166+ height: units.gu(6)
2167+
2168+ ActionTextField {
2169+ id: actionTextField
2170+
2171+ anchors.fill: parent
2172+ anchors.margins: units.gu(1)
2173+ }
2174+
2175+ Indicators.HLine {
2176+ anchors.top: parent.top
2177+ color: "#464543"
2178+ }
2179+ }
2180+}
2181
2182=== added file 'plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml'
2183--- plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml 1970-01-01 00:00:00 +0000
2184+++ plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml 2013-07-11 14:53:26 +0000
2185@@ -0,0 +1,97 @@
2186+/*
2187+ * Copyright 2013 Canonical Ltd.
2188+ *
2189+ * This program is free software; you can redistribute it and/or modify
2190+ * it under the terms of the GNU Lesser General Public License as published by
2191+ * the Free Software Foundation; version 3.
2192+ *
2193+ * This program is distributed in the hope that it will be useful,
2194+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2195+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2196+ * GNU Lesser General Public License for more details.
2197+ *
2198+ * You should have received a copy of the GNU Lesser General Public License
2199+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2200+ *
2201+ * Authors:
2202+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2203+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2204+ */
2205+
2206+import QtQuick 2.0
2207+import Ubuntu.Components 0.1
2208+import "utils.js" as Utils
2209+
2210+HeroMessage {
2211+ id: __heroMessage
2212+
2213+ property alias footer: footerLoader.sourceComponent
2214+
2215+ expandedHeight: fullMessage.y + fullMessage.height + units.gu(2)
2216+ heroMessageHeader.titleText.text: menu ? menu.label : ""
2217+ heroMessageHeader.subtitleText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
2218+ heroMessageHeader.bodyText.text: menu ? menu.extra.canonical_text : ""
2219+
2220+ Item {
2221+ id: fullMessage
2222+
2223+ anchors {
2224+ left: parent.left
2225+ leftMargin: units.gu(2)
2226+ right: parent.right
2227+ rightMargin: units.gu(2)
2228+ top: heroMessageHeader.bottom
2229+ }
2230+ height: childrenRect.height
2231+ opacity: 0.0
2232+ enabled: false
2233+
2234+ Label {
2235+ id: bodyText
2236+ anchors {
2237+ top: parent.top
2238+ left: parent.left
2239+ right: parent.right
2240+ }
2241+ wrapMode: Text.WordWrap
2242+ elide: Text.ElideRight
2243+ color: "#e8e1d0"
2244+ fontSize: "medium"
2245+ text: heroMessageHeader.bodyText.text
2246+ }
2247+
2248+ Loader {
2249+ id: footerLoader
2250+
2251+ anchors {
2252+ top: bodyText.bottom
2253+ topMargin: units.gu(2)
2254+ left: parent.left
2255+ right: parent.right
2256+ }
2257+ height: item != undefined ? units.gu(4) : 0
2258+ }
2259+
2260+ states: State {
2261+ name: "expanded"
2262+ when: __heroMessage.state === "expanded"
2263+
2264+ PropertyChanges {
2265+ target: heroMessageHeader.bodyText
2266+ opacity: 0.0
2267+ }
2268+
2269+ PropertyChanges {
2270+ target: fullMessage
2271+ opacity: 1.0
2272+ enabled: true
2273+ }
2274+ }
2275+ transitions: Transition {
2276+ NumberAnimation {
2277+ property: "opacity"
2278+ duration: 200
2279+ }
2280+ }
2281+ }
2282+}
2283
2284=== added file 'plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml'
2285--- plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml 1970-01-01 00:00:00 +0000
2286+++ plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml 2013-07-11 14:53:26 +0000
2287@@ -0,0 +1,142 @@
2288+/*
2289+ * Copyright 2013 Canonical Ltd.
2290+ *
2291+ * This program is free software; you can redistribute it and/or modify
2292+ * it under the terms of the GNU Lesser General Public License as published by
2293+ * the Free Software Foundation; version 3.
2294+ *
2295+ * This program is distributed in the hope that it will be useful,
2296+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2297+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2298+ * GNU Lesser General Public License for more details.
2299+ *
2300+ * You should have received a copy of the GNU Lesser General Public License
2301+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2302+ *
2303+ * Authors:
2304+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2305+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2306+ */
2307+
2308+import QtQuick 2.0
2309+import Ubuntu.Components 0.1
2310+import Unity.Indicators 0.1 as Indicators
2311+import "utils.js" as Utils
2312+
2313+HeroMessage {
2314+ id: snapDecision
2315+
2316+ expandedHeight: buttons.y + buttons.height + quickreply.height + units.gu(2)
2317+ heroMessageHeader.titleText.text: menu ? menu.label : ""
2318+ heroMessageHeader.subtitleText.text: menu ? menu.extra.canonical_text : ""
2319+ heroMessageHeader.subtitleText.color: "#e8e1d0"
2320+ heroMessageHeader.bodyText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
2321+ heroMessageHeader.bodyText.color: "#8f8f88"
2322+
2323+ Item {
2324+ id: buttons
2325+
2326+ anchors.left: parent.left
2327+ anchors.leftMargin: units.gu(2)
2328+ anchors.right: parent.right
2329+ anchors.rightMargin: units.gu(2)
2330+ anchors.top: heroMessageHeader.bottom
2331+ anchors.topMargin: units.gu(1)
2332+ height: units.gu(4)
2333+ opacity: 0.0
2334+
2335+ Button {
2336+ text: "Message"
2337+ color: "#bababa"
2338+ anchors.left: parent.left
2339+ anchors.top: parent.top
2340+ anchors.bottom: parent.bottom
2341+ width: (parent.width - units.gu(1)) / 2
2342+
2343+ onClicked: {
2344+ if (quickreply.state === "") {
2345+ quickreply.state = "expanded";
2346+ } else {
2347+ quickreply.state = "";
2348+ }
2349+ }
2350+ }
2351+
2352+ ActionButton {
2353+ actionGroup: snapDecision.actionGroup
2354+ action: actionsDescription[0].name
2355+
2356+ text: actionsDescription ? actionsDescription[0].label : "Call back"
2357+ color: "#c94212"
2358+ anchors.right: parent.right
2359+ anchors.top: parent.top
2360+ anchors.bottom: parent.bottom
2361+ width: (parent.width - units.gu(1)) / 2
2362+ }
2363+
2364+ states: State {
2365+ name: "expanded"
2366+ when: snapDecision.state === "expanded"
2367+
2368+ PropertyChanges {
2369+ target: buttons
2370+ opacity: 1.0
2371+ }
2372+ }
2373+ transitions: Transition {
2374+ NumberAnimation {
2375+ property: "opacity"
2376+ duration: 200
2377+ easing.type: Easing.OutQuad
2378+ }
2379+ }
2380+ }
2381+
2382+ QuickReply {
2383+ id: quickreply
2384+
2385+ actionGroup: snapDecision.actionGroup
2386+ action: actionsDescription[1].name
2387+
2388+ messages: actionsDescription ? actionsDescription[1]["parameter-hint"] : ""
2389+ buttonText: actionsDescription ? actionsDescription[1].label : "send"
2390+ anchors {
2391+ top: buttons.bottom
2392+ topMargin: units.gu(2)
2393+ left: parent.left
2394+ right: parent.right
2395+ }
2396+ height: 0
2397+ opacity: 0.0
2398+ enabled: false
2399+
2400+ states: State {
2401+ name: "expanded"
2402+
2403+ PropertyChanges {
2404+ target: quickreply
2405+ height: expandedHeight
2406+ opacity: 1.0
2407+ }
2408+
2409+ PropertyChanges {
2410+ target: quickreply
2411+ enabled: true
2412+ }
2413+ }
2414+
2415+ transitions: Transition {
2416+ NumberAnimation {
2417+ properties: "opacity,height"
2418+ duration: 200
2419+ easing.type: Easing.OutQuad
2420+ }
2421+ }
2422+ }
2423+
2424+ onStateChanged: {
2425+ if (state === "") {
2426+ quickreply.state = "";
2427+ }
2428+ }
2429+}
2430
2431=== added file 'plugins/Unity/Indicators/Messaging/qml/TextMessage.qml'
2432--- plugins/Unity/Indicators/Messaging/qml/TextMessage.qml 1970-01-01 00:00:00 +0000
2433+++ plugins/Unity/Indicators/Messaging/qml/TextMessage.qml 2013-07-11 14:53:26 +0000
2434@@ -0,0 +1,35 @@
2435+/*
2436+ * Copyright 2013 Canonical Ltd.
2437+ *
2438+ * This program is free software; you can redistribute it and/or modify
2439+ * it under the terms of the GNU Lesser General Public License as published by
2440+ * the Free Software Foundation; version 3.
2441+ *
2442+ * This program is distributed in the hope that it will be useful,
2443+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2444+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2445+ * GNU Lesser General Public License for more details.
2446+ *
2447+ * You should have received a copy of the GNU Lesser General Public License
2448+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2449+ *
2450+ * Authors:
2451+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2452+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2453+ */
2454+
2455+import QtQuick 2.0
2456+import Ubuntu.Components 0.1
2457+import Unity.Indicators 0.1 as Indicators
2458+
2459+SimpleTextMessage {
2460+ id: simpleMessage
2461+
2462+ footer: ActionTextField {
2463+ anchors.fill: parent
2464+ actionGroup: simpleMessage.actionGroup
2465+ action: actionsDescription[0].name
2466+
2467+ buttonText: actionsDescription ? actionsDescription[0].label : "Send"
2468+ }
2469+}
2470
2471=== added file 'plugins/Unity/Indicators/Messaging/qml/qmldir'
2472--- plugins/Unity/Indicators/Messaging/qml/qmldir 1970-01-01 00:00:00 +0000
2473+++ plugins/Unity/Indicators/Messaging/qml/qmldir 2013-07-11 14:53:26 +0000
2474@@ -0,0 +1,12 @@
2475+module Unity.Indicators.Messaging
2476+
2477+ActionButton 0.1 ActionButton.qml
2478+ActionTextField 0.1 ActionTextField.qml
2479+GroupedMessage 0.1 GroupedMessage.qml
2480+HeroMessage 0.1 HeroMessage.qml
2481+HeroMessageHeader 0.1 HeroMessageHeader.qml
2482+MessageMenuItem 0.1 MessageMenuItem.qml
2483+QuickReply 0.1 QuickReply.qml
2484+SimpleTextMessage 0.1 SimpleTextMessage.qml
2485+SnapDecision 0.1 SnapDecision.qml
2486+TextMessage 0.1 TextMessage.qml
2487\ No newline at end of file
2488
2489=== added file 'plugins/Unity/Indicators/Messaging/qml/utils.js'
2490--- plugins/Unity/Indicators/Messaging/qml/utils.js 1970-01-01 00:00:00 +0000
2491+++ plugins/Unity/Indicators/Messaging/qml/utils.js 2013-07-11 14:53:26 +0000
2492@@ -0,0 +1,27 @@
2493+/*
2494+ * Copyright 2013 Canonical Ltd.
2495+ *
2496+ * This program is free software; you can redistribute it and/or modify
2497+ * it under the terms of the GNU Lesser General Public License as published by
2498+ * the Free Software Foundation; version 3.
2499+ *
2500+ * This program is distributed in the hope that it will be useful,
2501+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2502+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2503+ * GNU Lesser General Public License for more details.
2504+ *
2505+ * You should have received a copy of the GNU Lesser General Public License
2506+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2507+ *
2508+ * Authors:
2509+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2510+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2511+ */
2512+
2513+.pragma library
2514+
2515+function formatDate(timestamp) {
2516+ // timestamp is in microseconds since epoch
2517+ var date = new Date(timestamp / 1000);
2518+ return Qt.formatDateTime(date, "hh:mm - MMM dd");
2519+}
2520
2521=== added directory 'plugins/Unity/Indicators/Network'
2522=== added file 'plugins/Unity/Indicators/Network/CMakeLists.txt'
2523--- plugins/Unity/Indicators/Network/CMakeLists.txt 1970-01-01 00:00:00 +0000
2524+++ plugins/Unity/Indicators/Network/CMakeLists.txt 2013-07-11 14:53:26 +0000
2525@@ -0,0 +1,42 @@
2526+project(IndicatorsNetworkQml)
2527+
2528+pkg_check_modules(GLIB glib-2.0>=2.32)
2529+pkg_check_modules(LIBNM_GLIB libnm-glib>=0.9.6)
2530+pkg_check_modules(LIBNM_UTIL libnm-util>=0.9.6)
2531+
2532+if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
2533+ set(INDICATORS_NETWORK_SRC
2534+ networkagent.cpp
2535+ plugin.cpp
2536+ secret-agent.c
2537+ )
2538+
2539+ add_library(IndicatorsNetworkQml MODULE
2540+ ${INDICATORS_NETWORK_SRC}
2541+ )
2542+
2543+ qt5_use_modules(IndicatorsNetworkQml Core Qml Widgets)
2544+
2545+ set_target_properties(IndicatorsNetworkQml PROPERTIES COMPILE_FLAGS -fPIC)
2546+
2547+ include_directories(
2548+ ${CMAKE_CURRENT_SOURCE_DIR}
2549+ ${GLIB_INCLUDE_DIRS}
2550+ ${LIBNM_GLIB_INCLUDE_DIRS}
2551+ ${LIBNM_UTIL_INCLUDE_DIRS}
2552+ )
2553+
2554+ target_link_libraries(IndicatorsNetworkQml
2555+ ${GLIB_LIBRARIES}
2556+ ${LIBNM_GLIB_LIBRARIES}
2557+ ${LIBNM_UTIL_LIBRARIES}
2558+ )
2559+
2560+ install(TARGETS IndicatorsNetworkQml
2561+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Network
2562+ )
2563+else()
2564+ message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
2565+endif()
2566+
2567+add_subdirectory(qml)
2568
2569=== added file 'plugins/Unity/Indicators/Network/networkagent.cpp'
2570--- plugins/Unity/Indicators/Network/networkagent.cpp 1970-01-01 00:00:00 +0000
2571+++ plugins/Unity/Indicators/Network/networkagent.cpp 2013-07-11 14:53:26 +0000
2572@@ -0,0 +1,146 @@
2573+/*
2574+ * Copyright 2013 Canonical Ltd.
2575+ *
2576+ * This program is free software; you can redistribute it and/or modify
2577+ * it under the terms of the GNU Lesser General Public License as published by
2578+ * the Free Software Foundation; version 3.
2579+ *
2580+ * This program is distributed in the hope that it will be useful,
2581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2583+ * GNU Lesser General Public License for more details.
2584+ *
2585+ * You should have received a copy of the GNU Lesser General Public License
2586+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2587+ *
2588+ * Authors:
2589+ * Alberto Ruiz <alberto.ruiz@canonical.com>
2590+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2591+ */
2592+
2593+#include "networkagent.h"
2594+
2595+#include <QVariant>
2596+#include <QApplication>
2597+#include <QDebug>
2598+
2599+class NetworkAgentToken
2600+{
2601+public:
2602+ NMConnection *connection;
2603+ NMSettingWirelessSecurity *wisec;
2604+ guint id;
2605+ QByteArray keyMgmt;
2606+
2607+ NetworkAgentToken(NMConnection *connection,
2608+ NMSettingWirelessSecurity *wisec,
2609+ guint id,
2610+ QByteArray keyMgmt)
2611+ : connection(connection),
2612+ wisec(wisec),
2613+ id(id),
2614+ keyMgmt(keyMgmt)
2615+ {
2616+ if (connection) {
2617+ g_object_ref(connection);
2618+ } else {
2619+ qWarning() << "invalid connection object";
2620+ }
2621+ }
2622+
2623+ ~NetworkAgentToken()
2624+ {
2625+ if (connection) {
2626+ g_object_unref(connection);
2627+ }
2628+ }
2629+};
2630+
2631+NetworkAgent::NetworkAgent(QObject *parent)
2632+ : QObject(parent)
2633+{
2634+ m_agent = unity_settings_secret_agent_new();
2635+ g_signal_connect(G_OBJECT(m_agent),
2636+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
2637+ G_CALLBACK(onSecretRequested),
2638+ this);
2639+
2640+ g_signal_connect(G_OBJECT(m_agent),
2641+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
2642+ G_CALLBACK(onSecretRequestCancelled),
2643+ this);
2644+}
2645+
2646+NetworkAgent::~NetworkAgent()
2647+{
2648+ nm_secret_agent_unregister(NM_SECRET_AGENT(m_agent));
2649+ g_object_unref(m_agent);
2650+}
2651+
2652+void NetworkAgent::authenticate(const QVariant &token, const QString &key)
2653+{
2654+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
2655+ if (pToken == NULL) {
2656+ return;
2657+ }
2658+
2659+ if ((pToken->keyMgmt == "wpa-none") || (pToken->keyMgmt == "wpa-psk")) {
2660+ g_object_set(G_OBJECT(pToken->wisec),
2661+ NM_SETTING_WIRELESS_SECURITY_PSK, qPrintable(key),
2662+ NULL);
2663+ } else if (pToken->keyMgmt == "none") {
2664+ g_object_set(G_OBJECT(pToken->wisec),
2665+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, qPrintable(key),
2666+ NULL);
2667+ }
2668+
2669+ GHashTable *settings = nm_connection_to_hash(pToken->connection,
2670+ NM_SETTING_HASH_FLAG_ALL);
2671+
2672+ unity_settings_secret_agent_provide_secret(m_agent,
2673+ pToken->id, settings);
2674+ g_hash_table_unref(settings);
2675+ delete pToken;
2676+}
2677+
2678+void NetworkAgent::cancel(const QVariant &token)
2679+{
2680+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
2681+ if (pToken != NULL) {
2682+ unity_settings_secret_agent_cancel_request(m_agent, pToken->id);
2683+ delete pToken;
2684+ }
2685+}
2686+
2687+void NetworkAgent::onSecretRequested(UnitySettingsSecretAgent* /*agent*/,
2688+ guint id,
2689+ NMConnection* connection,
2690+ const char* /*setting_name*/,
2691+ const char** /*hints*/,
2692+ NMSecretAgentGetSecretsFlags /*flags*/,
2693+ NetworkAgent* self)
2694+{
2695+ NetworkAgentToken *token = new NetworkAgentToken(connection,
2696+ NULL,
2697+ id,
2698+ NULL);
2699+
2700+ token->wisec = nm_connection_get_setting_wireless_security(connection);
2701+ if (token->wisec) {
2702+ token->keyMgmt = nm_setting_wireless_security_get_key_mgmt(token->wisec);
2703+ }
2704+
2705+ QVariant varToken = qVariantFromValue((void *) token);
2706+ Q_EMIT self->secretRequested(varToken);
2707+}
2708+
2709+void NetworkAgent::onSecretRequestCancelled(UnitySettingsSecretAgent* /*agent*/,
2710+ guint /*id*/,
2711+ NMConnection* /*connection*/,
2712+ const char* /*setting_name*/,
2713+ const char** /*hints*/,
2714+ NMSecretAgentGetSecretsFlags /*flags*/,
2715+ NetworkAgent* /*self*/)
2716+{
2717+ //Do nothing for now
2718+}
2719
2720=== added file 'plugins/Unity/Indicators/Network/networkagent.h'
2721--- plugins/Unity/Indicators/Network/networkagent.h 1970-01-01 00:00:00 +0000
2722+++ plugins/Unity/Indicators/Network/networkagent.h 2013-07-11 14:53:26 +0000
2723@@ -0,0 +1,65 @@
2724+/*
2725+ * Copyright 2013 Canonical Ltd.
2726+ *
2727+ * This program is free software; you can redistribute it and/or modify
2728+ * it under the terms of the GNU Lesser General Public License as published by
2729+ * the Free Software Foundation; version 3.
2730+ *
2731+ * This program is distributed in the hope that it will be useful,
2732+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2733+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2734+ * GNU Lesser General Public License for more details.
2735+ *
2736+ * You should have received a copy of the GNU Lesser General Public License
2737+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2738+ *
2739+ * Authors:
2740+ * Alberto Ruiz <alberto.ruiz@canonical.com>
2741+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2742+ */
2743+
2744+#ifndef NETWORKAGENT_H
2745+#define NETWORKAGENT_H
2746+
2747+#include "secret-agent.h"
2748+
2749+#include <QObject>
2750+
2751+class NetworkAgentToken;
2752+
2753+class NetworkAgent : public QObject
2754+{
2755+ Q_OBJECT
2756+public:
2757+ NetworkAgent(QObject *parent=0);
2758+ ~NetworkAgent();
2759+
2760+ Q_INVOKABLE void authenticate(const QVariant &token, const QString &key);
2761+ Q_INVOKABLE void cancel(const QVariant &token);
2762+
2763+Q_SIGNALS:
2764+ void secretRequested(const QVariant &token);
2765+ void secretRequestCancelled();
2766+
2767+private:
2768+ UnitySettingsSecretAgent *m_agent;
2769+
2770+ static void onSecretRequested(UnitySettingsSecretAgent *agent,
2771+ guint id,
2772+ NMConnection *connection,
2773+ const char *setting_name,
2774+ const char **hints,
2775+ NMSecretAgentGetSecretsFlags flags,
2776+ NetworkAgent *self);
2777+
2778+ static void onSecretRequestCancelled(UnitySettingsSecretAgent *agent,
2779+ guint id,
2780+ NMConnection *connection,
2781+ const char *setting_name,
2782+ const char **hints,
2783+ NMSecretAgentGetSecretsFlags flags,
2784+ NetworkAgent *self);
2785+
2786+};
2787+
2788+#endif
2789
2790=== added file 'plugins/Unity/Indicators/Network/plugin.cpp'
2791--- plugins/Unity/Indicators/Network/plugin.cpp 1970-01-01 00:00:00 +0000
2792+++ plugins/Unity/Indicators/Network/plugin.cpp 2013-07-11 14:53:26 +0000
2793@@ -0,0 +1,31 @@
2794+/*
2795+ * Copyright (C) 2012 Canonical, Ltd.
2796+ *
2797+ * This program is free software; you can redistribute it and/or modify
2798+ * it under the terms of the GNU General Public License as published by
2799+ * the Free Software Foundation; version 3.
2800+ *
2801+ * This program is distributed in the hope that it will be useful,
2802+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2803+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2804+ * GNU General Public License for more details.
2805+ *
2806+ * You should have received a copy of the GNU General Public License
2807+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2808+ *
2809+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
2810+ */
2811+
2812+// Qt
2813+#include <QtQml>
2814+
2815+// self
2816+#include "plugin.h"
2817+
2818+// local
2819+#include "networkagent.h"
2820+
2821+void IndicatorsNetworkPlugin::registerTypes(const char *uri)
2822+{
2823+ qmlRegisterType<NetworkAgent>(uri, 0, 1, "NetworkAgent");
2824+}
2825
2826=== added file 'plugins/Unity/Indicators/Network/plugin.h'
2827--- plugins/Unity/Indicators/Network/plugin.h 1970-01-01 00:00:00 +0000
2828+++ plugins/Unity/Indicators/Network/plugin.h 2013-07-11 14:53:26 +0000
2829@@ -0,0 +1,32 @@
2830+/*
2831+ * Copyright (C) 2012 Canonical, Ltd.
2832+ *
2833+ * This program is free software; you can redistribute it and/or modify
2834+ * it under the terms of the GNU General Public License as published by
2835+ * the Free Software Foundation; version 3.
2836+ *
2837+ * This program is distributed in the hope that it will be useful,
2838+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2839+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2840+ * GNU General Public License for more details.
2841+ *
2842+ * You should have received a copy of the GNU General Public License
2843+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2844+ *
2845+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
2846+ */
2847+
2848+#ifndef INDICATORS_NETWORK_PLUGIN_H
2849+#define INDICATORS_NETWORK_PLUGIN_H
2850+
2851+#include <QtQml/QQmlExtensionPlugin>
2852+
2853+class IndicatorsNetworkPlugin : public QQmlExtensionPlugin
2854+{
2855+ Q_OBJECT
2856+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
2857+public:
2858+ void registerTypes(const char *uri);
2859+};
2860+
2861+#endif // INDICATORS_NETWORK_PLUGIN_H
2862
2863=== added directory 'plugins/Unity/Indicators/Network/qml'
2864=== added file 'plugins/Unity/Indicators/Network/qml/AccessPoint.qml'
2865--- plugins/Unity/Indicators/Network/qml/AccessPoint.qml 1970-01-01 00:00:00 +0000
2866+++ plugins/Unity/Indicators/Network/qml/AccessPoint.qml 2013-07-11 14:53:26 +0000
2867@@ -0,0 +1,68 @@
2868+/*
2869+ * Copyright 2013 Canonical Ltd.
2870+ *
2871+ * This program is free software; you can redistribute it and/or modify
2872+ * it under the terms of the GNU Lesser General Public License as published by
2873+ * the Free Software Foundation; version 3.
2874+ *
2875+ * This program is distributed in the hope that it will be useful,
2876+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2877+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2878+ * GNU Lesser General Public License for more details.
2879+ *
2880+ * You should have received a copy of the GNU Lesser General Public License
2881+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2882+ *
2883+ * Authors:
2884+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2885+ */
2886+
2887+import QtQuick 2.0
2888+import Ubuntu.Components 0.1
2889+import Ubuntu.Components.ListItems 0.1 as ListItem
2890+import Unity.Indicators 0.1 as Indicators
2891+
2892+Indicators.MenuItem {
2893+ id: accessPoint
2894+ property variant actionWifiApStrength : menu && actionGroup ? actionGroup.action(menu.extra.canonical_wifi_ap_strength_action) : null
2895+ property variant wifiApStrength : actionWifiApStrength && actionWifiApStrength.valid ? actionWifiApStrength.state : "0"
2896+
2897+ function getNetworkIcon(data) {
2898+ var imageName = "nm-signal-100"
2899+ var signalStrength = parseInt(wifiApStrength)
2900+
2901+ if (data.extra.canonical_wifi_ap_is_adhoc) {
2902+ imageName = "nm-adhoc";
2903+ } else if (signalStrength == 0) {
2904+ imageName = "nm-signal-00";
2905+ } else if (signalStrength <= 25) {
2906+ imageName = "nm-signal-25";
2907+ } else if (signalStrength <= 50) {
2908+ imageName = "nm-signal-50";
2909+ } else if (signalStrength <= 75) {
2910+ imageName = "nm-signal-75";
2911+ }
2912+
2913+ if (data.extra.canonical_wifi_ap_is_secure) {
2914+ imageName += "-secure";
2915+ }
2916+
2917+ return "image://gicon/" + imageName;
2918+ }
2919+
2920+ icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/wifi-none"
2921+ iconFrame: false
2922+ control: CheckBox {
2923+ id: checkBoxActive
2924+ height: units.gu(4)
2925+ width: units.gu(4)
2926+ anchors.centerIn: parent
2927+ }
2928+
2929+ Indicators.MenuActionBinding {
2930+ actionGroup: accessPoint.actionGroup
2931+ action: menu ? menu.action : ""
2932+ target: checkBoxActive
2933+ property: "checked"
2934+ }
2935+}
2936
2937=== added file 'plugins/Unity/Indicators/Network/qml/CMakeLists.txt'
2938--- plugins/Unity/Indicators/Network/qml/CMakeLists.txt 1970-01-01 00:00:00 +0000
2939+++ plugins/Unity/Indicators/Network/qml/CMakeLists.txt 2013-07-11 14:53:26 +0000
2940@@ -0,0 +1,15 @@
2941+file(GLOB IndicatorsNetwork_QMLFILES
2942+ *.qml
2943+ *.js
2944+ qmldir
2945+)
2946+
2947+# copy qml & qmldir files into build directory for shadow builds
2948+add_custom_target(UnityIndicatorsNetworkQmlFiles ALL
2949+ COMMAND cp ${IndicatorsNetwork_QMLFILES} ${CMAKE_BINARY_DIR}/plugins/Unity/Indicators/Network
2950+ DEPENDS ${IndicatorsNetwork_QMLFILES}
2951+)
2952+
2953+install(FILES ${IndicatorsNetwork_QMLFILES}
2954+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Network
2955+)
2956
2957=== added file 'plugins/Unity/Indicators/Network/qml/PasswordPage.qml'
2958--- plugins/Unity/Indicators/Network/qml/PasswordPage.qml 1970-01-01 00:00:00 +0000
2959+++ plugins/Unity/Indicators/Network/qml/PasswordPage.qml 2013-07-11 14:53:26 +0000
2960@@ -0,0 +1,88 @@
2961+/*
2962+ * Copyright 2013 Canonical Ltd.
2963+ *
2964+ * This program is free software; you can redistribute it and/or modify
2965+ * it under the terms of the GNU Lesser General Public License as published by
2966+ * the Free Software Foundation; version 3.
2967+ *
2968+ * This program is distributed in the hope that it will be useful,
2969+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2970+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2971+ * GNU Lesser General Public License for more details.
2972+ *
2973+ * You should have received a copy of the GNU Lesser General Public License
2974+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2975+ *
2976+ * Authors:
2977+ * Renato Araujo Oliveira Filho <renato@canonical.com>
2978+ */
2979+
2980+import QtQuick 2.0
2981+import Ubuntu.Components 0.1
2982+import Ubuntu.Components.ListItems 0.1 as ListItem
2983+import Unity.Indicators 0.1 as Indicators
2984+
2985+Page {
2986+ id: pagePassword
2987+
2988+ property variant agent
2989+ property variant token
2990+
2991+ anchors.fill: parent
2992+ title: "Network Authentication"
2993+
2994+ Column {
2995+ anchors {
2996+ left: parent.left
2997+ right: parent.right
2998+ }
2999+
3000+ Indicators.SectionMenuItem {
3001+ label: "Authentication"
3002+ }
3003+
3004+ Indicators.MenuItem {
3005+ implicitHeight: password.height + units.gu(1)
3006+
3007+ PasswordTextField {
3008+ id: password
3009+ anchors {
3010+ left: parent.left
3011+ right: parent.right
3012+ margins: units.gu(3)
3013+ verticalCenter: parent.verticalCenter
3014+ }
3015+ }
3016+ }
3017+
3018+ Indicators.MenuItem {
3019+ Row {
3020+ anchors {
3021+ right: parent.right
3022+ verticalCenter: parent.verticalCenter
3023+ margins: units.gu(3)
3024+ }
3025+
3026+ spacing: units.gu(1)
3027+
3028+ Button {
3029+ text: "Cancel"
3030+ width: units.gu(10)
3031+ onClicked: {
3032+ agent.cancel(token);
3033+ pageStack.pop();
3034+ }
3035+ }
3036+
3037+ Button {
3038+ text: "Ok"
3039+ width: units.gu(10)
3040+ onClicked: {
3041+ agent.authenticate(token, password.text);
3042+ pageStack.pop();
3043+ }
3044+ }
3045+ }
3046+ }
3047+ }
3048+}
3049
3050=== added file 'plugins/Unity/Indicators/Network/qml/PasswordTextField.qml'
3051--- plugins/Unity/Indicators/Network/qml/PasswordTextField.qml 1970-01-01 00:00:00 +0000
3052+++ plugins/Unity/Indicators/Network/qml/PasswordTextField.qml 2013-07-11 14:53:26 +0000
3053@@ -0,0 +1,68 @@
3054+/*
3055+ * Copyright 2013 Canonical Ltd.
3056+ *
3057+ * This program is free software; you can redistribute it and/or modify
3058+ * it under the terms of the GNU Lesser General Public License as published by
3059+ * the Free Software Foundation; version 3.
3060+ *
3061+ * This program is distributed in the hope that it will be useful,
3062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3064+ * GNU Lesser General Public License for more details.
3065+ *
3066+ * You should have received a copy of the GNU Lesser General Public License
3067+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3068+ *
3069+ * Authors:
3070+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3071+ */
3072+
3073+import QtQuick 2.0
3074+import Ubuntu.Components 0.1
3075+
3076+Item {
3077+ id: textMenu
3078+
3079+ property alias text: textField.text
3080+
3081+ height: contentColumn.height
3082+
3083+ Column {
3084+ id: contentColumn
3085+ spacing: units.gu(0.5)
3086+ anchors {
3087+ left: parent.left
3088+ right: parent.right
3089+ }
3090+
3091+ TextField {
3092+ id: textField
3093+
3094+ anchors {
3095+ left: parent.left
3096+ right: parent.right
3097+ }
3098+
3099+ placeholderText: "Password"
3100+ echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password
3101+ }
3102+
3103+ Row {
3104+ anchors {
3105+ left: parent.left
3106+ right: parent.right
3107+ }
3108+
3109+ spacing: units.gu(1)
3110+
3111+ CheckBox {
3112+ id: showPassword
3113+ }
3114+
3115+ Label {
3116+ text: "Show password"
3117+ anchors.verticalCenter: showPassword.verticalCenter
3118+ }
3119+ }
3120+ }
3121+}
3122
3123=== added file 'plugins/Unity/Indicators/Network/qml/WifiSection.qml'
3124--- plugins/Unity/Indicators/Network/qml/WifiSection.qml 1970-01-01 00:00:00 +0000
3125+++ plugins/Unity/Indicators/Network/qml/WifiSection.qml 2013-07-11 14:53:26 +0000
3126@@ -0,0 +1,34 @@
3127+/*
3128+ * Copyright 2013 Canonical Ltd.
3129+ *
3130+ * This program is free software; you can redistribute it and/or modify
3131+ * it under the terms of the GNU Lesser General Public License as published by
3132+ * the Free Software Foundation; version 3.
3133+ *
3134+ * This program is distributed in the hope that it will be useful,
3135+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3136+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3137+ * GNU Lesser General Public License for more details.
3138+ *
3139+ * You should have received a copy of the GNU Lesser General Public License
3140+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3141+ *
3142+ * Authors:
3143+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3144+ */
3145+
3146+import QtQuick 2.0
3147+import Ubuntu.Components 0.1
3148+import Unity.Indicators 0.1 as Indicators
3149+
3150+Indicators.SectionMenuItem {
3151+ id: wifiSectionMenu
3152+
3153+ Indicators.MenuAction {
3154+ id: busyAction
3155+ actionGroup: wifiSectionMenu.actionGroup
3156+ action: menu ? menu.extra.canonical_busy_action : ""
3157+ }
3158+
3159+ busy: busyAction.valid ? busyAction.state : false
3160+}
3161
3162=== added file 'plugins/Unity/Indicators/Network/qml/qmldir'
3163--- plugins/Unity/Indicators/Network/qml/qmldir 1970-01-01 00:00:00 +0000
3164+++ plugins/Unity/Indicators/Network/qml/qmldir 2013-07-11 14:53:26 +0000
3165@@ -0,0 +1,8 @@
3166+module Unity.Indicators.Network
3167+plugin IndicatorsNetworkQml
3168+
3169+NetworkPage 0.1 NetworkPage.qml
3170+AccessPoint 0.1 AccessPoint.qml
3171+PasswordPage 0.1 PasswordPage.qml
3172+PasswordTextField 0.1 PasswordTextField.qml
3173+WifiSection 0.1 WifiSection.qml
3174\ No newline at end of file
3175
3176=== added file 'plugins/Unity/Indicators/Network/secret-agent.c'
3177--- plugins/Unity/Indicators/Network/secret-agent.c 1970-01-01 00:00:00 +0000
3178+++ plugins/Unity/Indicators/Network/secret-agent.c 2013-07-11 14:53:26 +0000
3179@@ -0,0 +1,382 @@
3180+/*
3181+ * Copyright 2013 Canonical Ltd.
3182+ *
3183+ * This program is free software; you can redistribute it and/or modify
3184+ * it under the terms of the GNU Lesser General Public License as published by
3185+ * the Free Software Foundation; version 3.
3186+ *
3187+ * This program is distributed in the hope that it will be useful,
3188+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3189+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3190+ * GNU Lesser General Public License for more details.
3191+ *
3192+ * You should have received a copy of the GNU Lesser General Public License
3193+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3194+ *
3195+ * Authors:
3196+ * Alberto Ruiz <alberto.ruiz@canonical.com>
3197+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3198+ */
3199+
3200+
3201+#include <glib.h>
3202+#include <glib-object.h>
3203+#include <nm-secret-agent.h>
3204+#include "secret-agent.h"
3205+
3206+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
3207+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
3208+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
3209+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
3210+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
3211+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
3212+#define UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentPrivate))
3213+
3214+#define AGENT_ID "com.canonical.settings.network.nm-agent"
3215+
3216+static gpointer unity_settings_secret_agent_parent_class = NULL;
3217+
3218+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
3219+
3220+struct _UnitySettingsSecretAgentPrivate {
3221+ GQueue *requests;
3222+};
3223+
3224+typedef struct _SecretRequest {
3225+ gint id;
3226+ NMSecretAgent *agent;
3227+ NMConnection *connection;
3228+ const char *connection_path;
3229+ const char *setting_name;
3230+ const char **hints;
3231+ NMSecretAgentGetSecretsFlags flags;
3232+ NMSecretAgentGetSecretsFunc callback;
3233+ gpointer callback_data;
3234+} SecretRequest;
3235+
3236+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
3237+enum {
3238+ UNITY_SETTINGS_SECRET_AGENT_DUMMY_PROPERTY
3239+};
3240+
3241+enum {
3242+ SECRET_REQUESTED,
3243+ REQUEST_CANCELLED,
3244+ LAST_SIGNAL
3245+};
3246+
3247+static guint signals[LAST_SIGNAL] = { 0 };
3248+
3249+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
3250+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
3251+
3252+int
3253+secret_request_find (SecretRequest *req,
3254+ guint *id)
3255+{
3256+ if (req->id > *id)
3257+ return -1;
3258+
3259+ if (req->id < *id)
3260+ return 1;
3261+
3262+ return 0;
3263+}
3264+
3265+void
3266+unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
3267+ guint request,
3268+ GHashTable *secrets)
3269+{
3270+ GList *iter;
3271+ SecretRequest *req;
3272+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
3273+
3274+ iter = g_queue_find_custom (priv->requests,
3275+ &request,
3276+ (GCompareFunc)secret_request_find);
3277+
3278+ if (iter == NULL || iter->data == NULL)
3279+ {
3280+ g_warning ("Secret request with id <%d> was not found", (int)request);
3281+ return;
3282+ }
3283+
3284+ req = iter->data;
3285+
3286+ req->callback (NM_SECRET_AGENT (agent),
3287+ req->connection,
3288+ secrets,
3289+ NULL,
3290+ req->callback_data);
3291+
3292+ g_queue_remove_all (priv->requests, req);
3293+ g_free (req);
3294+ return;
3295+}
3296+
3297+void
3298+free_request (SecretRequest *req)
3299+{
3300+ g_object_unref (req->connection);
3301+ g_free (req);
3302+}
3303+
3304+void
3305+unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
3306+ guint request)
3307+{
3308+ GList *iter;
3309+ SecretRequest *req;
3310+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
3311+ GError *error;
3312+
3313+ iter = g_queue_find_custom (priv->requests,
3314+ &request,
3315+ (GCompareFunc)secret_request_find);
3316+
3317+ if (iter == NULL || iter->data == NULL)
3318+ {
3319+ g_warning ("Secret request with id <%d> was not found", (int)request);
3320+ return;
3321+ }
3322+
3323+ req = iter->data;
3324+ error = g_error_new (NM_SECRET_AGENT_ERROR,
3325+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
3326+ "This secret request was canceled by the user.");
3327+
3328+ req->callback (NM_SECRET_AGENT (agent),
3329+ req->connection,
3330+ NULL,
3331+ error,
3332+ req->callback_data);
3333+
3334+ g_queue_remove_all (priv->requests, req);
3335+ free_request (req);
3336+ return;
3337+}
3338+
3339+static void
3340+delete_secrets (NMSecretAgent *agent,
3341+ NMConnection *connection,
3342+ const char *connection_path,
3343+ NMSecretAgentDeleteSecretsFunc callback,
3344+ gpointer callback_data)
3345+{
3346+ g_debug ("delete secrets");
3347+}
3348+
3349+/* If it returns G_MAXUINT it's considered an error */
3350+static guint
3351+find_available_id (UnitySettingsSecretAgentPrivate *priv)
3352+{
3353+ guint i = 0;
3354+ guint candidate = 0;
3355+
3356+ if (g_queue_get_length (priv->requests) == G_MAXUINT)
3357+ return G_MAXUINT;
3358+
3359+ while (i < g_queue_get_length (priv->requests))
3360+ {
3361+ SecretRequest *req = (SecretRequest*)g_queue_peek_nth (priv->requests, i);
3362+
3363+ if (req->id == candidate)
3364+ {
3365+ candidate++;
3366+ i = 0;
3367+ }
3368+ else
3369+ {
3370+ i++;
3371+ }
3372+ }
3373+
3374+ return i;
3375+}
3376+
3377+static void
3378+get_secrets (NMSecretAgent *agent,
3379+ NMConnection *connection,
3380+ const char *connection_path,
3381+ const char *setting_name,
3382+ const char **hints,
3383+ NMSecretAgentGetSecretsFlags flags,
3384+ NMSecretAgentGetSecretsFunc callback,
3385+ gpointer callback_data)
3386+{
3387+ guint id;
3388+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
3389+ SecretRequest *req = NULL;
3390+
3391+ if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
3392+ {
3393+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
3394+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
3395+ "No password found for this connection.");
3396+ callback (agent, connection, NULL, error, callback_data);
3397+ g_error_free (error);
3398+ return;
3399+ }
3400+
3401+ id = find_available_id (priv);
3402+ if (id == G_MAXUINT)
3403+ {
3404+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
3405+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
3406+ "Reached maximum number of requests.");
3407+ callback (agent, connection, NULL, error, callback_data);
3408+ g_error_free (error);
3409+ return;
3410+ }
3411+
3412+ /* Adding a request */
3413+ req = (SecretRequest*) g_malloc0 (sizeof (SecretRequest));
3414+ *req = ((SecretRequest)
3415+ { id,
3416+ agent,
3417+ connection,
3418+ connection_path,
3419+ setting_name,
3420+ hints,
3421+ flags,
3422+ callback,
3423+ callback_data });
3424+
3425+ g_object_ref (connection);
3426+
3427+ g_queue_push_tail (priv->requests, req);
3428+
3429+ g_signal_emit_by_name (agent,
3430+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
3431+ id,
3432+ connection,
3433+ setting_name,
3434+ hints,
3435+ flags);
3436+}
3437+
3438+static void
3439+save_secrets (NMSecretAgent *agent,
3440+ NMConnection *connection,
3441+ const char *connection_path,
3442+ NMSecretAgentSaveSecretsFunc callback,
3443+ gpointer callback_data)
3444+{
3445+ g_debug ("save secrets");
3446+}
3447+
3448+static void
3449+cancel_get_secrets (NMSecretAgent *agent,
3450+ const char *connection_path,
3451+ const char *setting_name)
3452+{
3453+ g_debug ("cancel get secrets");
3454+}
3455+
3456+UnitySettingsSecretAgent*
3457+unity_settings_secret_agent_construct (GType object_type)
3458+{
3459+ UnitySettingsSecretAgent * self = NULL;
3460+ self = (UnitySettingsSecretAgent*) g_object_new (object_type,
3461+ NM_SECRET_AGENT_IDENTIFIER, AGENT_ID,
3462+ NULL);
3463+ return self;
3464+}
3465+
3466+
3467+UnitySettingsSecretAgent*
3468+unity_settings_secret_agent_new (void)
3469+{
3470+ return unity_settings_secret_agent_construct (UNITY_SETTINGS_TYPE_SECRET_AGENT);
3471+}
3472+
3473+static void
3474+destroy_pending_request (gpointer data)
3475+{
3476+ SecretRequest* req = (SecretRequest*)data;
3477+ /* Reporting the cancellation of all pending requests */
3478+ g_signal_emit_by_name (req->agent,
3479+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
3480+ req->id);
3481+
3482+ free_request (req);
3483+}
3484+
3485+static void
3486+unity_settings_secret_agent_finalize (GObject *agent)
3487+{
3488+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
3489+
3490+ g_queue_free_full (priv->requests, destroy_pending_request);
3491+}
3492+
3493+static void
3494+unity_settings_secret_agent_class_init (UnitySettingsSecretAgentClass *klass)
3495+{
3496+ unity_settings_secret_agent_parent_class = g_type_class_peek_parent (klass);
3497+ NMSecretAgentClass *parent_class = NM_SECRET_AGENT_CLASS (klass);
3498+ parent_class->get_secrets = get_secrets;
3499+ parent_class->save_secrets = save_secrets;
3500+ parent_class->delete_secrets = delete_secrets;
3501+ parent_class->cancel_get_secrets = cancel_get_secrets;
3502+
3503+ g_type_class_add_private (klass, sizeof(UnitySettingsSecretAgentPrivate));
3504+ G_OBJECT_CLASS (klass)->finalize = unity_settings_secret_agent_finalize;
3505+
3506+
3507+ signals[SECRET_REQUESTED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
3508+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
3509+ G_SIGNAL_RUN_FIRST,
3510+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, secret_requested),
3511+ NULL, NULL, NULL,
3512+ G_TYPE_NONE, 5,
3513+ G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT);
3514+
3515+ signals[REQUEST_CANCELLED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
3516+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
3517+ G_SIGNAL_RUN_FIRST,
3518+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, request_cancelled),
3519+ NULL, NULL, NULL,
3520+ G_TYPE_NONE, 1,
3521+ G_TYPE_UINT);
3522+}
3523+
3524+
3525+static void
3526+unity_settings_secret_agent_instance_init (UnitySettingsSecretAgent *self)
3527+{
3528+ self->priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (self);
3529+ self->priv->requests = g_queue_new ();
3530+}
3531+
3532+GType
3533+unity_settings_secret_agent_get_type (void)
3534+{
3535+ static volatile gsize unity_settings_secret_agent_type_id__volatile = 0;
3536+ if (g_once_init_enter (&unity_settings_secret_agent_type_id__volatile))
3537+ {
3538+ static const GTypeInfo g_define_type_info =
3539+ {
3540+ sizeof (UnitySettingsSecretAgentClass),
3541+ (GBaseInitFunc) NULL,
3542+ (GBaseFinalizeFunc) NULL,
3543+ (GClassInitFunc) unity_settings_secret_agent_class_init,
3544+ (GClassFinalizeFunc) NULL,
3545+ NULL,
3546+ sizeof (UnitySettingsSecretAgent),
3547+ 0,
3548+ (GInstanceInitFunc) unity_settings_secret_agent_instance_init,
3549+ NULL
3550+ };
3551+ GType unity_settings_secret_agent_type_id;
3552+ unity_settings_secret_agent_type_id = g_type_register_static (NM_TYPE_SECRET_AGENT,
3553+ "UnitySettingsSecretAgent",
3554+ &g_define_type_info,
3555+ 0);
3556+ g_once_init_leave (&unity_settings_secret_agent_type_id__volatile,
3557+ unity_settings_secret_agent_type_id);
3558+ }
3559+
3560+ return unity_settings_secret_agent_type_id__volatile;
3561+}
3562
3563=== added file 'plugins/Unity/Indicators/Network/secret-agent.h'
3564--- plugins/Unity/Indicators/Network/secret-agent.h 1970-01-01 00:00:00 +0000
3565+++ plugins/Unity/Indicators/Network/secret-agent.h 2013-07-11 14:53:26 +0000
3566@@ -0,0 +1,102 @@
3567+/*
3568+ * Copyright 2013 Canonical Ltd.
3569+ *
3570+ * This program is free software; you can redistribute it and/or modify
3571+ * it under the terms of the GNU Lesser General Public License as published by
3572+ * the Free Software Foundation; version 3.
3573+ *
3574+ * This program is distributed in the hope that it will be useful,
3575+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3576+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3577+ * GNU Lesser General Public License for more details.
3578+ *
3579+ * You should have received a copy of the GNU Lesser General Public License
3580+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3581+ *
3582+ * Authors:
3583+ * Alberto Ruiz <alberto.ruiz@canonical.com>
3584+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3585+ */
3586+
3587+#ifndef __SECRET_AGENT_H__
3588+#define __SECRET_AGENT_H__
3589+
3590+#include <glib.h>
3591+#include <glib-object.h>
3592+#include <nm-secret-agent.h>
3593+
3594+/*
3595+ * This class is a basic implementation of the NetworkManager SecretAgent base class.
3596+ *
3597+ * The purpose of this class is to handle credential requests from the network,
3598+ * for example, from a WiFi hotspot or a VPN network.
3599+ *
3600+ * It queues requests objects (SecretRequest) on a GQueue in the private struct
3601+ * of the class. And notifies the consumer of the class through the "secret-request"
3602+ * and the "request-cancelled" signals with the following callback prototypes:
3603+ *
3604+ * void (*secret_requested) (UnitySettingsSecretAgent *self,
3605+ * guint id,
3606+ * NMConnection *connection,
3607+ * const char *setting_name,
3608+ * const char **hints,
3609+ * NMSecretAgentGetSecretsFlags flags,
3610+ * gpointer user_data);
3611+ *
3612+ * void (*request_cancelled) (UnitySettingsSecretAgent *self,
3613+ * guint id,
3614+ * gpointer user_data);
3615+ *
3616+ */
3617+
3618+
3619+G_BEGIN_DECLS
3620+
3621+
3622+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
3623+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
3624+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
3625+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
3626+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
3627+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
3628+
3629+#define UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED "secret-requested"
3630+#define UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED "request-cancelled"
3631+
3632+typedef struct _UnitySettingsSecretAgent UnitySettingsSecretAgent;
3633+typedef struct _UnitySettingsSecretAgentClass UnitySettingsSecretAgentClass;
3634+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
3635+
3636+struct _UnitySettingsSecretAgent {
3637+ NMSecretAgent parent_instance;
3638+ UnitySettingsSecretAgentPrivate * priv;
3639+};
3640+
3641+struct _UnitySettingsSecretAgentClass {
3642+ NMSecretAgentClass parent_class;
3643+
3644+ void (*secret_requested) (UnitySettingsSecretAgent *self,
3645+ guint id,
3646+ NMConnection *connection,
3647+ const char *setting_name,
3648+ const char **hints,
3649+ NMSecretAgentGetSecretsFlags flags);
3650+
3651+ void (*request_cancelled) (UnitySettingsSecretAgent *self,
3652+ guint id);
3653+};
3654+
3655+
3656+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
3657+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
3658+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
3659+
3660+void unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
3661+ guint request,
3662+ GHashTable *secrets);
3663+void unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
3664+ guint request);
3665+
3666+G_END_DECLS
3667+
3668+#endif
3669
3670=== added file 'plugins/Unity/Indicators/flatmenuproxymodel.cpp'
3671--- plugins/Unity/Indicators/flatmenuproxymodel.cpp 1970-01-01 00:00:00 +0000
3672+++ plugins/Unity/Indicators/flatmenuproxymodel.cpp 2013-07-11 14:53:26 +0000
3673@@ -0,0 +1,272 @@
3674+/*
3675+ * Copyright 2012 Canonical Ltd.
3676+ *
3677+ * This program is free software; you can redistribute it and/or modify
3678+ * it under the terms of the GNU Lesser General Public License as published by
3679+ * the Free Software Foundation; version 3.
3680+ *
3681+ * This program is distributed in the hope that it will be useful,
3682+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3683+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3684+ * GNU Lesser General Public License for more details.
3685+ *
3686+ * You should have received a copy of the GNU Lesser General Public License
3687+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3688+ *
3689+ * Authors:
3690+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3691+ */
3692+
3693+extern "C" {
3694+#include <gio/gio.h>
3695+}
3696+
3697+#include "flatmenuproxymodel.h"
3698+#include <QString>
3699+#include <QStringList>
3700+
3701+FlatMenuProxyModel::FlatMenuProxyModel(QAbstractItemModel *source)
3702+ : QAbstractProxyModel(source),
3703+ m_rowCount(0)
3704+{
3705+ m_model = new QDBusMenuModel;
3706+ setSourceModel(m_model);
3707+}
3708+
3709+/*! \internal */
3710+FlatMenuProxyModel::~FlatMenuProxyModel()
3711+{
3712+ delete m_model;
3713+}
3714+
3715+void FlatMenuProxyModel::setSourceModel(QAbstractItemModel *source)
3716+{
3717+ if (sourceModel()) {
3718+ QAbstractItemModel *oldSource = sourceModel();
3719+ if (oldSource == source) {
3720+ return;
3721+ }
3722+
3723+ oldSource->disconnect(this);
3724+ }
3725+
3726+ QAbstractProxyModel::setSourceModel(source);
3727+
3728+ if (source) {
3729+
3730+ // FIXME - not working correctly with dynamic inserts/removes
3731+
3732+ connect(source,
3733+ SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
3734+ SLOT(onModelAboutToBeReset()));
3735+ connect(source,
3736+ SIGNAL(rowsInserted(QModelIndex,int,int)),
3737+ SLOT(onModelReset()));
3738+
3739+ connect(source,
3740+ SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
3741+ SLOT(onModelAboutToBeReset()));
3742+ connect(source,
3743+ SIGNAL(rowsRemoved(QModelIndex,int,int)),
3744+ SLOT(onModelReset()));
3745+
3746+ connect(source,
3747+ SIGNAL(modelAboutToBeReset()),
3748+ SLOT(onModelAboutToBeReset()));
3749+ connect(source,
3750+ SIGNAL(modelReset()),
3751+ SLOT(onModelReset()));
3752+
3753+ connect(source,
3754+ SIGNAL(statusChanged(DBusEnums::ConnectionStatus)),
3755+ SIGNAL(statusChanged()));
3756+
3757+ // initiliaze rowCount
3758+ QModelIndex lastItem = source->index(source->rowCount() - 1, 0);
3759+ m_rowCount = recursiveRowCount(lastItem);
3760+ } else {
3761+ m_rowCount = 0;
3762+ }
3763+
3764+ Q_EMIT countChanged();
3765+}
3766+
3767+void FlatMenuProxyModel::setBusName(const QString &busName)
3768+{
3769+ m_model->setBusName(busName);
3770+}
3771+
3772+QString FlatMenuProxyModel::busName() const
3773+{
3774+ return m_model->busName();
3775+}
3776+
3777+void FlatMenuProxyModel::setObjectPath(const QString &busPath)
3778+{
3779+ m_model->setObjectPath(busPath);
3780+}
3781+
3782+QString FlatMenuProxyModel::objectPath() const
3783+{
3784+ return m_model->objectPath();
3785+}
3786+
3787+int FlatMenuProxyModel::status() const
3788+{
3789+ return m_model->status();
3790+}
3791+
3792+DBusEnums::BusType FlatMenuProxyModel::busType() const
3793+{
3794+ return m_model->busType();
3795+}
3796+
3797+void FlatMenuProxyModel::setIntBusType(int type)
3798+{
3799+ m_model->setBusType((DBusEnums::BusType) type);
3800+}
3801+
3802+void FlatMenuProxyModel::start()
3803+{
3804+ m_model->start();
3805+}
3806+
3807+void FlatMenuProxyModel::stop()
3808+{
3809+ m_model->stop();
3810+}
3811+
3812+QModelIndex FlatMenuProxyModel::mapFromSource(const QModelIndex &index) const
3813+{
3814+ if (!index.isValid()) {
3815+ return QModelIndex();
3816+ }
3817+
3818+ QModelIndex result = createIndex(rowOffsetOf(index, index.row()), 0);
3819+ return result;
3820+}
3821+
3822+QModelIndex FlatMenuProxyModel::mapToSource(const QModelIndex &index) const
3823+{
3824+ if (sourceModel() && m_indexCache.contains(index.row())) {
3825+ QString key = m_indexCache.value(index.row());
3826+ QStringList sections = key.split('.', QString::SkipEmptyParts);
3827+ QModelIndex sourceIndex = QModelIndex();
3828+ for(int i=0; i < sections.size(); i++) {
3829+ sourceIndex = sourceModel()->index(sections.at(i).toInt(), 9, sourceIndex);
3830+ }
3831+ return sourceIndex;
3832+ } else {
3833+ return QModelIndex();
3834+ }
3835+}
3836+
3837+QModelIndex FlatMenuProxyModel::index(int row, int sectionRow, const QModelIndex &parent, const QString &key) const
3838+{
3839+ for (int i = 0, count = 0; i < sourceModel()->rowCount(parent); i++) {
3840+ QModelIndex sourceIndex = sourceModel()->index(i, 0, parent);
3841+ int indexCount = recursiveRowCount(sourceIndex);
3842+
3843+ if (count == sectionRow) {
3844+ QString sectionKey = key + "." + QString::number(i);
3845+ m_indexCache.insert(row, sectionKey);
3846+ return createIndex(row, 0);
3847+ } else if ((count + indexCount) >= sectionRow) {
3848+ count++;
3849+ return index(row, sectionRow - count, sourceIndex, key + "." + QString::number(i));
3850+ }
3851+
3852+ count += indexCount + 1;
3853+ }
3854+ return QModelIndex();
3855+}
3856+
3857+QModelIndex FlatMenuProxyModel::index(int row, int, const QModelIndex &) const
3858+{
3859+ return index(row, row, QModelIndex(), "");
3860+}
3861+
3862+QModelIndex FlatMenuProxyModel::parent(const QModelIndex &) const
3863+{
3864+ return QModelIndex();
3865+}
3866+
3867+int FlatMenuProxyModel::columnCount(const QModelIndex &) const
3868+{
3869+ return 1;
3870+}
3871+
3872+int FlatMenuProxyModel::rowCount(const QModelIndex &) const
3873+{
3874+ return m_rowCount;
3875+}
3876+
3877+int FlatMenuProxyModel::count() const
3878+{
3879+ return rowCount(QModelIndex());
3880+}
3881+
3882+void FlatMenuProxyModel::onModelAboutToBeReset()
3883+{
3884+ beginResetModel();
3885+}
3886+
3887+void FlatMenuProxyModel::onModelReset()
3888+{
3889+ // initiliaze rowCount
3890+ m_rowCount = 0;
3891+ for (int i = 0, iMax = sourceModel()->rowCount(); i < iMax; i++) {
3892+ QModelIndex index = sourceModel()->index(i, 0);
3893+ m_rowCount += recursiveRowCount(index) + 1;
3894+ }
3895+ m_indexCache.clear();
3896+ endResetModel();
3897+ Q_EMIT countChanged();
3898+}
3899+
3900+int FlatMenuProxyModel::recursiveRowCount(const QModelIndex &index) const
3901+{
3902+ int size = sourceModel()->rowCount(index);
3903+ for (int i=0, iMax=size; i < iMax; i++) {
3904+ QModelIndex currentIndex = sourceModel()->index(i, 0, index);
3905+ size += recursiveRowCount(currentIndex);
3906+ }
3907+
3908+ return size;
3909+}
3910+
3911+int FlatMenuProxyModel::rowOffsetOf(const QModelIndex &index, int row, bool inclusive) const
3912+{
3913+ int offset = 0;
3914+
3915+ QModelIndex parent = index.parent();
3916+
3917+ // Check row 0 offset
3918+ while(parent.isValid()) {
3919+ offset += 1;
3920+ for (int i = 0; i < parent.row(); i++) {
3921+ QModelIndex currentIndex = sourceModel()->index(i, 0, parent);
3922+ offset += recursiveRowCount(currentIndex) + 1;
3923+ }
3924+ parent = parent.parent();
3925+ }
3926+
3927+ // Check index.row() offset
3928+ for(int i = 0; i < row; i++) {
3929+ QModelIndex currentIndex = sourceModel()->index(i, 0, index.parent());
3930+ offset += recursiveRowCount(currentIndex) + 1;
3931+ }
3932+
3933+ if (inclusive) {
3934+ // itself
3935+ QModelIndex currentIndex = sourceModel()->index(row, 0, index.parent());
3936+ offset += recursiveRowCount(currentIndex);
3937+ }
3938+
3939+ return offset;
3940+}
3941+
3942+QVariant FlatMenuProxyModel::data(int row, int role) const
3943+{
3944+ return QAbstractProxyModel::data(index(row, 0), role);
3945+}
3946\ No newline at end of file
3947
3948=== added file 'plugins/Unity/Indicators/flatmenuproxymodel.h'
3949--- plugins/Unity/Indicators/flatmenuproxymodel.h 1970-01-01 00:00:00 +0000
3950+++ plugins/Unity/Indicators/flatmenuproxymodel.h 2013-07-11 14:53:26 +0000
3951@@ -0,0 +1,91 @@
3952+/*
3953+ * Copyright 2012 Canonical Ltd.
3954+ *
3955+ * This program is free software; you can redistribute it and/or modify
3956+ * it under the terms of the GNU Lesser General Public License as published by
3957+ * the Free Software Foundation; version 3.
3958+ *
3959+ * This program is distributed in the hope that it will be useful,
3960+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3961+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3962+ * GNU Lesser General Public License for more details.
3963+ *
3964+ * You should have received a copy of the GNU Lesser General Public License
3965+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3966+ *
3967+ * Authors:
3968+ * Renato Araujo Oliveira Filho <renato@canonical.com>
3969+ */
3970+
3971+#ifndef FLATMENUPROXYMODEL_H
3972+#define FLATMENUPROXYMODEL_H
3973+
3974+#include <QAbstractProxyModel>
3975+#include <qdbusmenumodel.h>
3976+
3977+class SectionInfo;
3978+
3979+class FlatMenuProxyModel : public QAbstractProxyModel
3980+{
3981+ Q_OBJECT
3982+ Q_PROPERTY(int count READ count NOTIFY countChanged)
3983+ Q_PROPERTY(int busType READ busType WRITE setIntBusType NOTIFY busTypeChanged)
3984+ Q_PROPERTY(QString busName READ busName WRITE setBusName NOTIFY busNameChanged)
3985+ Q_PROPERTY(QString objectPath READ objectPath WRITE setObjectPath NOTIFY objectPathChanged)
3986+ Q_PROPERTY(int status READ status NOTIFY statusChanged)
3987+
3988+ Q_ENUMS(Roles)
3989+public:
3990+ FlatMenuProxyModel(QAbstractItemModel *source=0);
3991+ ~FlatMenuProxyModel();
3992+
3993+ void setSourceModel(QAbstractItemModel * sourceModel);
3994+
3995+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
3996+
3997+ QModelIndex mapFromSource(const QModelIndex &index) const;
3998+ QModelIndex mapToSource(const QModelIndex &index) const;
3999+
4000+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
4001+ QModelIndex parent(const QModelIndex &index) const;
4002+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
4003+ int count() const;
4004+ int columnCount(const QModelIndex &parent) const;
4005+
4006+ void setBusName(const QString &busName);
4007+ QString busName() const;
4008+
4009+ void setObjectPath(const QString &busName);
4010+ QString objectPath() const;
4011+
4012+ DBusEnums::BusType busType() const;
4013+ void setIntBusType(int type);
4014+
4015+ int status() const;
4016+
4017+public Q_SLOTS:
4018+ void onModelAboutToBeReset();
4019+ void onModelReset();
4020+
4021+ void start();
4022+ void stop();
4023+
4024+Q_SIGNALS:
4025+ void countChanged();
4026+
4027+ void busTypeChanged();
4028+ void busNameChanged();
4029+ void objectPathChanged();
4030+ void statusChanged();
4031+
4032+private:
4033+ QDBusMenuModel *m_model;
4034+ mutable QMap<int, QString> m_indexCache;
4035+ int m_rowCount;
4036+
4037+ int rowOffsetOf(const QModelIndex &index, int row, bool inclusive = false) const;
4038+ int recursiveRowCount(const QModelIndex &index) const;
4039+ QModelIndex index(int row, int rowCount, const QModelIndex &parent, const QString &key) const;
4040+};
4041+
4042+#endif
4043
4044=== added file 'plugins/Unity/Indicators/indicator.cpp'
4045--- plugins/Unity/Indicators/indicator.cpp 1970-01-01 00:00:00 +0000
4046+++ plugins/Unity/Indicators/indicator.cpp 2013-07-11 14:53:26 +0000
4047@@ -0,0 +1,88 @@
4048+/*
4049+ * Copyright 2013 Canonical Ltd.
4050+ *
4051+ * This program is free software; you can redistribute it and/or modify
4052+ * it under the terms of the GNU Lesser General Public License as published by
4053+ * the Free Software Foundation; version 3.
4054+ *
4055+ * This program is distributed in the hope that it will be useful,
4056+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4057+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4058+ * GNU Lesser General Public License for more details.
4059+ *
4060+ * You should have received a copy of the GNU Lesser General Public License
4061+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4062+ *
4063+ * Authors:
4064+ * Renato Araujo Oliveira Filho <renato@canonical.com>
4065+ */
4066+
4067+#include "indicator.h"
4068+
4069+#include <QStringList>
4070+
4071+Indicator::Indicator(QObject *parent)
4072+ : QObject(parent)
4073+{
4074+}
4075+
4076+Indicator::~Indicator()
4077+{
4078+}
4079+
4080+void Indicator::init(const QString& busName, const QSettings& settings)
4081+{
4082+ setId(settings.value("Indicator Service/Name").toString());
4083+
4084+ QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
4085+
4086+ QVariantMap mapMenuObjectPaths;
4087+ Q_FOREACH(const QString& childGroup, settings.childGroups())
4088+ {
4089+ if (childGroup == "Indicator Service")
4090+ continue;
4091+
4092+ QString menuPath = childGroup+"/ObjectPath";
4093+ if (settings.contains(menuPath))
4094+ {
4095+ mapMenuObjectPaths[childGroup] = settings.value(menuPath).toString();
4096+ }
4097+ }
4098+
4099+
4100+ QVariantMap properties;
4101+ properties.clear();
4102+ properties.insert("busType", 1);
4103+ properties.insert("busName", busName);
4104+ properties.insert("actionsObjectPath", actionObjectPath);
4105+ properties.insert("menuObjectPaths", mapMenuObjectPaths);
4106+ setIndicatorProperties(properties);
4107+}
4108+
4109+QString Indicator::identifier() const
4110+{
4111+ return m_identifier;
4112+}
4113+
4114+void Indicator::setId(const QString &identifier)
4115+{
4116+ if (identifier != m_identifier) {
4117+ m_identifier = identifier;
4118+ Q_EMIT identifierChanged(m_identifier);
4119+ }
4120+}
4121+
4122+
4123+QVariant Indicator::indicatorProperties() const
4124+{
4125+ return m_properties;
4126+}
4127+
4128+void Indicator::setIndicatorProperties(const QVariant &properties)
4129+{
4130+ if (m_properties != properties)
4131+ {
4132+ m_properties = properties;
4133+ Q_EMIT indicatorPropertiesChanged(m_properties);
4134+ }
4135+}
4136
4137=== added file 'plugins/Unity/Indicators/indicator.h'
4138--- plugins/Unity/Indicators/indicator.h 1970-01-01 00:00:00 +0000
4139+++ plugins/Unity/Indicators/indicator.h 2013-07-11 14:53:26 +0000
4140@@ -0,0 +1,57 @@
4141+/*
4142+ * Copyright 2013 Canonical Ltd.
4143+ *
4144+ * This program is free software; you can redistribute it and/or modify
4145+ * it under the terms of the GNU Lesser General Public License as published by
4146+ * the Free Software Foundation; version 3.
4147+ *
4148+ * This program is distributed in the hope that it will be useful,
4149+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4150+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4151+ * GNU Lesser General Public License for more details.
4152+ *
4153+ * You should have received a copy of the GNU Lesser General Public License
4154+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4155+ *
4156+ * Authors:
4157+ * Renato Araujo Oliveira Filho <renato@canonical.com>
4158+ * Nick Dedekind <nick.dedekind@canonical.com>
4159+ */
4160+
4161+#ifndef INDICATOR_H
4162+#define INDICATOR_H
4163+
4164+#include <QObject>
4165+#include <QSettings>
4166+
4167+class Indicator : public QObject
4168+{
4169+ Q_OBJECT
4170+ Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
4171+ Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
4172+
4173+public:
4174+ typedef QSharedPointer<Indicator> Ptr;
4175+
4176+ Indicator(QObject *parent = 0);
4177+ virtual ~Indicator();
4178+
4179+ void init(const QString& busName, const QSettings& settings);
4180+
4181+ QString identifier() const;
4182+ QVariant indicatorProperties() const;
4183+
4184+Q_SIGNALS:
4185+ void identifierChanged(const QString &identifier);
4186+ void indicatorPropertiesChanged(const QVariant &properties);
4187+
4188+protected:
4189+ void setId(const QString &id);
4190+ void setIndicatorProperties(const QVariant &properties);
4191+
4192+private:
4193+ QString m_identifier;
4194+ QVariant m_properties;
4195+};
4196+
4197+#endif // INDICATOR_H
4198
4199=== added file 'plugins/Unity/Indicators/indicators.h'
4200--- plugins/Unity/Indicators/indicators.h 1970-01-01 00:00:00 +0000
4201+++ plugins/Unity/Indicators/indicators.h 2013-07-11 14:53:26 +0000
4202@@ -0,0 +1,103 @@
4203+/*
4204+ * Copyright (C) 2012 Canonical, Ltd.
4205+ *
4206+ * This program is free software; you can redistribute it and/or modify
4207+ * it under the terms of the GNU General Public License as published by
4208+ * the Free Software Foundation; version 3.
4209+ *
4210+ * This program is distributed in the hope that it will be useful,
4211+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4213+ * GNU General Public License for more details.
4214+ *
4215+ * You should have received a copy of the GNU General Public License
4216+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4217+ *
4218+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
4219+ */
4220+
4221+#ifndef INDICATORS_H
4222+#define INDICATORS_H
4223+
4224+#include <QObject>
4225+
4226+class ActionState : public QObject
4227+{
4228+ Q_OBJECT
4229+public:
4230+ Q_ENUMS(ActionStates)
4231+ enum ActionStates {
4232+ Label = 0x00,
4233+ IconSource = 0x01,
4234+ AccessableName = 0x02,
4235+ Visible = 0x03,
4236+ };
4237+
4238+ ActionState(QObject*parent=0):QObject(parent) {}
4239+};
4240+
4241+class NetworkActionState : public QObject
4242+{
4243+ Q_OBJECT
4244+public:
4245+ Q_ENUMS(NetworkActionStates)
4246+ enum NetworkActionStates {
4247+ Connection = 0x01,
4248+ SignalStrength = 0x02,
4249+ };
4250+
4251+ NetworkActionState(QObject*parent=0):QObject(parent) {}
4252+};
4253+
4254+class NetworkConnection : public QObject
4255+{
4256+ Q_OBJECT
4257+public:
4258+ Q_ENUMS(NetworkConnectionStates)
4259+ enum NetworkConnectionStates {
4260+ Initial = 0x00,
4261+ Activating = 0x01,
4262+ Activated = 0x02,
4263+ Deactivating = 0x03,
4264+ };
4265+
4266+ NetworkConnection(QObject*parent=0):QObject(parent) {}
4267+};
4268+
4269+class IndicatorsModelRole : public QObject
4270+{
4271+ Q_OBJECT
4272+public:
4273+ Q_ENUMS(Roles)
4274+ enum Roles {
4275+ Identifier = 0,
4276+ Priority,
4277+ Title,
4278+ Description,
4279+ WidgetSource,
4280+ PageSource,
4281+ IndicatorProperties,
4282+ IsValid
4283+ };
4284+
4285+ IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
4286+};
4287+
4288+class FlatMenuProxyModelRole : public QObject
4289+{
4290+ Q_OBJECT
4291+public:
4292+ Q_ENUMS(Roles)
4293+ enum Roles {
4294+ Action = Qt::DisplayRole + 1,
4295+ Label,
4296+ Extra,
4297+ Depth,
4298+ hasSection,
4299+ hasSubMenu
4300+ };
4301+
4302+ FlatMenuProxyModelRole(QObject*parent=0):QObject(parent) {}
4303+};
4304+
4305+#endif // INDICATORS_H
4306
4307=== added file 'plugins/Unity/Indicators/indicatorsmanager.cpp'
4308--- plugins/Unity/Indicators/indicatorsmanager.cpp 1970-01-01 00:00:00 +0000
4309+++ plugins/Unity/Indicators/indicatorsmanager.cpp 2013-07-11 14:53:26 +0000
4310@@ -0,0 +1,285 @@
4311+/*
4312+ * Copyright (C) 2013 Canonical, Ltd.
4313+ *
4314+ * This program is free software; you can redistribute it and/or modify
4315+ * it under the terms of the GNU General Public License as published by
4316+ * the Free Software Foundation; version 3.
4317+ *
4318+ * This program is distributed in the hope that it will be useful,
4319+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4320+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4321+ * GNU General Public License for more details.
4322+ *
4323+ * You should have received a copy of the GNU General Public License
4324+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4325+ *
4326+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
4327+ */
4328+
4329+#include "indicatorsmanager.h"
4330+
4331+#include <QSettings>
4332+#include <QDebug>
4333+
4334+#include "paths.h"
4335+
4336+
4337+class IndicatorsManager::IndicatorData
4338+{
4339+public:
4340+ IndicatorData(const QString& name, const QFileInfo& fileInfo)
4341+ : m_name(name)
4342+ , m_fileInfo(fileInfo)
4343+ , m_verified (true)
4344+ {}
4345+
4346+ QString m_name;
4347+ QFileInfo m_fileInfo;
4348+
4349+ bool m_verified;
4350+ Indicator::Ptr m_indicator;
4351+};
4352+
4353+IndicatorsManager::IndicatorsManager(QObject* parent)
4354+ : QObject(parent)
4355+ , m_loaded(false)
4356+{
4357+}
4358+
4359+IndicatorsManager::~IndicatorsManager()
4360+{
4361+ unload();
4362+}
4363+
4364+void IndicatorsManager::load()
4365+{
4366+ unload();
4367+ QStringList xdgLocations = shellDataDirs();//QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
4368+
4369+ m_fsWatcher.reset(new QFileSystemWatcher(this));
4370+
4371+ Q_FOREACH(const QString& xdgLocation, xdgLocations)
4372+ {
4373+ QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
4374+ QDir indicator_dir(indicator_path);
4375+ if (indicator_dir.exists())
4376+ {
4377+ // watch folder for changes.
4378+ m_fsWatcher->addPath(indicator_path);
4379+
4380+ loadDir(indicator_dir);
4381+ }
4382+ }
4383+
4384+ QObject::connect(m_fsWatcher.data(), SIGNAL(directoryChanged(const QString&)), this, SLOT(onDirectoryChanged(const QString&)));
4385+ QObject::connect(m_fsWatcher.data(), SIGNAL(fileChanged(const QString&)), this, SLOT(onFileChanged(const QString&)));
4386+ setLoaded(true);
4387+}
4388+
4389+void IndicatorsManager::onDirectoryChanged(const QString& directory)
4390+{
4391+ loadDir(QDir(directory));
4392+}
4393+
4394+void IndicatorsManager::onFileChanged(const QString& file)
4395+{
4396+ QFileInfo file_info(file);
4397+ if (!file_info.exists())
4398+ {
4399+ unloadFile(file_info);
4400+ return;
4401+ }
4402+ else
4403+ {
4404+ loadFile(QFileInfo(file));
4405+ }
4406+}
4407+
4408+void IndicatorsManager::loadDir(const QDir& dir)
4409+{
4410+ startVerify(dir.canonicalPath());
4411+
4412+ QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
4413+ Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
4414+ {
4415+ loadFile(indicator_file);
4416+ }
4417+
4418+ endVerify(dir.canonicalPath());
4419+}
4420+
4421+void IndicatorsManager::loadFile(const QFileInfo& file_info)
4422+{
4423+ QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
4424+ QString name = indicator_settings.value("Indicator Service/Name").toString();
4425+
4426+ auto iter = m_indicatorsData.find(name);
4427+ if (iter != m_indicatorsData.end())
4428+ {
4429+ QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
4430+ IndicatorData* currentData = (*iter);
4431+ currentData->m_verified = true;
4432+
4433+ int file_info_location = -1;
4434+ int current_data_location = -1;
4435+
4436+ QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
4437+
4438+ // if we've already got this indicator, we need to make sure we're not overwriting data which is
4439+ // from a lower priority standard path
4440+ QStringList xdgLocations = shellDataDirs();
4441+ for (int i = 0; i < xdgLocations.size(); i++)
4442+ {
4443+ QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
4444+
4445+ if (newFileInfoDir == indicatorDir)
4446+ {
4447+ file_info_location = i;
4448+ }
4449+ if (currentDataDir == indicatorDir)
4450+ {
4451+ current_data_location = i;
4452+ }
4453+
4454+ if (file_info_location != -1 && current_data_location != -1)
4455+ {
4456+ break;
4457+ }
4458+ }
4459+
4460+ // file location is higher (or of equal) priority. overwrite.
4461+ if (file_info_location <= current_data_location &&
4462+ file_info != currentData->m_fileInfo)
4463+ {
4464+ currentData->m_fileInfo = file_info;
4465+ Q_EMIT indicatorLoaded(name);
4466+ }
4467+ }
4468+ else
4469+ {
4470+ IndicatorData* data = new IndicatorData(name, file_info);
4471+ data->m_verified = true;
4472+ m_indicatorsData[name]= data;
4473+ Q_EMIT indicatorLoaded(name);
4474+ }
4475+}
4476+
4477+void IndicatorsManager::unload()
4478+{
4479+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
4480+ while(iter.hasNext())
4481+ {
4482+ iter.next();
4483+ Q_EMIT indicatorAboutToBeUnloaded(iter.key());
4484+ }
4485+
4486+ qDeleteAll(m_indicatorsData);
4487+ m_indicatorsData.clear();
4488+
4489+ setLoaded(false);
4490+}
4491+
4492+void IndicatorsManager::unloadFile(const QFileInfo& file)
4493+{
4494+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
4495+ while(iter.hasNext())
4496+ {
4497+ iter.next();
4498+ IndicatorData* data = iter.value();
4499+ if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
4500+ {
4501+ if (!data->m_verified)
4502+ {
4503+ QString name = data->m_name;
4504+ Q_EMIT indicatorAboutToBeUnloaded(name);
4505+
4506+ delete data;
4507+ iter.remove();
4508+ }
4509+ }
4510+ }
4511+
4512+ setLoaded(m_indicatorsData.size() > 0);
4513+}
4514+
4515+void IndicatorsManager::setLoaded(bool loaded)
4516+{
4517+ if (loaded != m_loaded)
4518+ {
4519+ m_loaded = loaded;
4520+ Q_EMIT loadedChanged(m_loaded);
4521+ }
4522+}
4523+
4524+void IndicatorsManager::startVerify(const QString& path)
4525+{
4526+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
4527+ while(iter.hasNext())
4528+ {
4529+ iter.next();
4530+ IndicatorData* data = iter.value();
4531+ if (data->m_fileInfo.canonicalPath() == path)
4532+ {
4533+ data->m_verified = false;
4534+ }
4535+ }
4536+}
4537+
4538+void IndicatorsManager::endVerify(const QString& path)
4539+{
4540+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
4541+ while(iter.hasNext())
4542+ {
4543+ iter.next();
4544+ IndicatorData* data = iter.value();
4545+ if (data->m_fileInfo.canonicalPath() == path)
4546+ {
4547+ if (!data->m_verified)
4548+ {
4549+ QString name = data->m_name;
4550+ Q_EMIT indicatorAboutToBeUnloaded(name);
4551+
4552+ delete data;
4553+ iter.remove();
4554+ }
4555+ }
4556+ }
4557+}
4558+
4559+Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
4560+{
4561+ if (!m_indicatorsData.contains(indicator_name))
4562+ {
4563+ qWarning() << Q_FUNC_INFO << "Invalid indicator name: " << indicator_name;
4564+ return Indicator::Ptr();
4565+ }
4566+
4567+ IndicatorData *data = m_indicatorsData[indicator_name];
4568+ if (data->m_indicator)
4569+ {
4570+ return data->m_indicator;
4571+ }
4572+
4573+ Indicator::Ptr new_indicator(new Indicator(this));
4574+ data->m_indicator = new_indicator;
4575+ QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
4576+ new_indicator->init(data->m_fileInfo.fileName(), settings);
4577+ return new_indicator;
4578+}
4579+
4580+QList<Indicator::Ptr> IndicatorsManager::indicators()
4581+{
4582+ QList<Indicator::Ptr> list;
4583+ Q_FOREACH(IndicatorData* data, m_indicatorsData)
4584+ {
4585+ Indicator::Ptr ret = indicator(data->m_name);
4586+ if (ret)
4587+ list.append(ret);
4588+ }
4589+ return list;
4590+}
4591+
4592+bool IndicatorsManager::isLoaded() const
4593+{
4594+ return m_loaded;
4595+}
4596
4597=== added file 'plugins/Unity/Indicators/indicatorsmanager.h'
4598--- plugins/Unity/Indicators/indicatorsmanager.h 1970-01-01 00:00:00 +0000
4599+++ plugins/Unity/Indicators/indicatorsmanager.h 2013-07-11 14:53:26 +0000
4600@@ -0,0 +1,73 @@
4601+/*
4602+ * Copyright (C) 2013 Canonical, Ltd.
4603+ *
4604+ * This program is free software; you can redistribute it and/or modify
4605+ * it under the terms of the GNU General Public License as published by
4606+ * the Free Software Foundation; version 3.
4607+ *
4608+ * This program is distributed in the hope that it will be useful,
4609+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4610+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4611+ * GNU General Public License for more details.
4612+ *
4613+ * You should have received a copy of the GNU General Public License
4614+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4615+ *
4616+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
4617+ */
4618+
4619+#ifndef INDICATORS_MANAGER_H
4620+#define INDICATORS_MANAGER_H
4621+
4622+#include <QObject>
4623+#include <QFileSystemWatcher>
4624+#include <QDir>
4625+#include <QHash>
4626+#include <QSharedPointer>
4627+
4628+#include "indicator.h"
4629+
4630+class IndicatorsManager : public QObject
4631+{
4632+ Q_OBJECT
4633+ Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
4634+public:
4635+ explicit IndicatorsManager(QObject* parent = 0);
4636+ ~IndicatorsManager();
4637+
4638+ Q_INVOKABLE void load();
4639+ Q_INVOKABLE void unload();
4640+
4641+ Indicator::Ptr indicator(const QString& indicator_name);
4642+
4643+ QList<Indicator::Ptr> indicators();
4644+
4645+ bool isLoaded() const;
4646+
4647+Q_SIGNALS:
4648+ void loadedChanged(bool);
4649+
4650+ void indicatorLoaded(const QString& indicator_name);
4651+ void indicatorAboutToBeUnloaded(const QString& indicator_name);
4652+
4653+private Q_SLOTS:
4654+ void onDirectoryChanged(const QString& directory);
4655+ void onFileChanged(const QString& file);
4656+
4657+private:
4658+ void loadDir(const QDir& dir);
4659+ void loadFile(const QFileInfo& file);
4660+ void unloadFile(const QFileInfo& dir);
4661+
4662+ void startVerify(const QString& path);
4663+ void endVerify(const QString& path);
4664+
4665+ void setLoaded(bool);
4666+
4667+ class IndicatorData;
4668+ QHash<QString, IndicatorData*> m_indicatorsData;
4669+ QSharedPointer<QFileSystemWatcher> m_fsWatcher;
4670+ bool m_loaded;
4671+};
4672+
4673+#endif // INDICATORS_MANAGER_H
4674
4675=== added file 'plugins/Unity/Indicators/indicatorsmodel.cpp'
4676--- plugins/Unity/Indicators/indicatorsmodel.cpp 1970-01-01 00:00:00 +0000
4677+++ plugins/Unity/Indicators/indicatorsmodel.cpp 2013-07-11 14:53:26 +0000
4678@@ -0,0 +1,321 @@
4679+/*
4680+ * Copyright 2012 Canonical Ltd.
4681+ *
4682+ * This program is free software; you can redistribute it and/or modify
4683+ * it under the terms of the GNU Lesser General Public License as published by
4684+ * the Free Software Foundation; version 3.
4685+ *
4686+ * This program is distributed in the hope that it will be useful,
4687+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4688+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4689+ * GNU Lesser General Public License for more details.
4690+ *
4691+ * You should have received a copy of the GNU Lesser General Public License
4692+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4693+ *
4694+ * Authors:
4695+ * Renato Araujo Oliveira Filho <renato@canonical.com>
4696+ */
4697+
4698+#include "indicatorsmodel.h"
4699+#include "indicatorsmanager.h"
4700+#include "indicator.h"
4701+#include "indicators.h"
4702+#include "paths.h"
4703+
4704+#include <QQmlContext>
4705+#include <QQmlEngine>
4706+#include <QDebug>
4707+
4708+/*!
4709+ \qmltype IndicatorsModel
4710+ \inherits QAbstractListModel
4711+
4712+ \brief The IndicatorsModel class defines the list model for indicators
4713+
4714+ \b {This component is under heavy development.}
4715+
4716+ This class expose the available indicators.
4717+
4718+ \code
4719+ IndicatorsModel {
4720+ id: menuModel
4721+ }
4722+
4723+ ListView {
4724+ id: view
4725+ model: menuModel
4726+ Component.onCompleted: menuModel.load()
4727+ }
4728+ \endcode
4729+*/
4730+IndicatorsModel::IndicatorsModel(QObject *parent)
4731+ : QAbstractListModel(parent)
4732+{
4733+ m_manager = new IndicatorsManager(this);
4734+ QObject::connect(m_manager, SIGNAL(indicatorLoaded(const QString&)), this, SLOT(onIndicatorLoaded(const QString&)));
4735+ QObject::connect(m_manager, SIGNAL(indicatorAboutToBeUnloaded(const QString&)), this, SLOT(onIndicatorAboutToBeUnloaded(const QString&)));
4736+
4737+ QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
4738+ QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
4739+ QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
4740+}
4741+
4742+/*! \internal */
4743+IndicatorsModel::~IndicatorsModel()
4744+{
4745+ disconnect(m_manager, 0, 0, 0);
4746+ m_manager->deleteLater();
4747+}
4748+
4749+/*!
4750+ \qmlproperty IndicatorsModel::count
4751+ The number of data entries in the model.
4752+
4753+ \b Note: methods should only be called after the Component has completed.
4754+*/
4755+int IndicatorsModel::count() const
4756+{
4757+ return rowCount();
4758+}
4759+
4760+/*!
4761+ \qmlmethod IndicatorsModel::unload()
4762+
4763+ Load all indicators.
4764+*/
4765+void IndicatorsModel::load()
4766+{
4767+ m_indicators.clear();
4768+ m_manager->load();
4769+}
4770+
4771+/*!
4772+ \qmlmethod IndicatorsModel::unload()
4773+
4774+ Unload all indicators.
4775+*/
4776+void IndicatorsModel::unload()
4777+{
4778+ m_manager->unload();
4779+}
4780+
4781+/*! \internal */
4782+void IndicatorsModel::onIndicatorLoaded(const QString& indicator_name)
4783+{
4784+ Indicator::Ptr indicator = m_manager->indicator(indicator_name);
4785+ if (!indicator)
4786+ {
4787+ return;
4788+ }
4789+
4790+ if (m_indicators.indexOf(indicator) >= 0)
4791+ {
4792+ return;
4793+ }
4794+
4795+ // find the insert position
4796+ int pos = 0;
4797+ while (pos < count())
4798+ {
4799+ // keep going while the existing priority is less.
4800+ if (indicatorData(indicator, IndicatorsModelRole::Priority).toInt() < data(index(pos), IndicatorsModelRole::Priority).toInt())
4801+ break;
4802+ pos++;
4803+ }
4804+
4805+ QObject::connect(indicator.data(), SIGNAL(identifierChanged(const QString&)), this, SLOT(onIdentifierChanged()));
4806+ QObject::connect(indicator.data(), SIGNAL(indicatorPropertiesChanged(const QVariant&)), this, SLOT(onIndicatorPropertiesChanged()));
4807+
4808+ beginInsertRows(QModelIndex(), pos, pos);
4809+
4810+ m_indicators.insert(pos, indicator);
4811+ endInsertRows();
4812+}
4813+
4814+/*! \internal */
4815+void IndicatorsModel::onIndicatorAboutToBeUnloaded(const QString& indicator_name)
4816+{
4817+ Indicator::Ptr indicator = m_manager->indicator(indicator_name);
4818+ if (!indicator)
4819+ {
4820+ return;
4821+ }
4822+
4823+ int i = 0;
4824+ QMutableListIterator<Indicator::Ptr> iter(m_indicators);
4825+ while(iter.hasNext())
4826+ {
4827+ if (indicator == iter.next())
4828+ {
4829+ beginRemoveRows(QModelIndex(), i, i);
4830+ iter.remove();
4831+ endRemoveRows();
4832+ break;
4833+ }
4834+ i++;
4835+ }
4836+
4837+}
4838+
4839+/*! \internal */
4840+void IndicatorsModel::onIdentifierChanged()
4841+{
4842+ notifyDataChanged(QObject::sender(), IndicatorsModelRole::Identifier);
4843+}
4844+
4845+/*! \internal */
4846+void IndicatorsModel::onIndicatorPropertiesChanged()
4847+{
4848+ notifyDataChanged(QObject::sender(), IndicatorsModelRole::IndicatorProperties);
4849+}
4850+
4851+/*! \internal */
4852+void IndicatorsModel::notifyDataChanged(QObject *sender, int role)
4853+{
4854+ Indicator* indicator = qobject_cast<Indicator*>(sender);
4855+ if (!indicator)
4856+ {
4857+ return;
4858+ }
4859+
4860+ int index = 0;
4861+ QMutableListIterator<Indicator::Ptr> iter(m_indicators);
4862+ while(iter.hasNext())
4863+ {
4864+ if (indicator == iter.next())
4865+ {
4866+ QModelIndex changedIndex = this->index(index);
4867+ dataChanged(changedIndex, changedIndex, QVector<int>() << role);
4868+ break;
4869+ }
4870+ index++;
4871+ }
4872+}
4873+
4874+/*! \internal */
4875+QHash<int, QByteArray> IndicatorsModel::roleNames() const
4876+{
4877+ static QHash<int, QByteArray> roles;
4878+ if (roles.isEmpty())
4879+ {
4880+ roles[IndicatorsModelRole::Identifier] = "identifier";
4881+ roles[IndicatorsModelRole::Priority] = "priority";
4882+ roles[IndicatorsModelRole::Title] = "title";
4883+ roles[IndicatorsModelRole::Description] = "description";
4884+ roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
4885+ roles[IndicatorsModelRole::PageSource] = "pageSource";
4886+ roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties";
4887+ roles[IndicatorsModelRole::IsValid] = "isValid";
4888+ }
4889+ return roles;
4890+}
4891+
4892+/*! \internal */
4893+int IndicatorsModel::columnCount(const QModelIndex &) const
4894+{
4895+ return 1;
4896+}
4897+
4898+/*! \internal */
4899+QVariant IndicatorsModel::defaultData(Indicator::Ptr indicator, int role)
4900+{
4901+ switch (role)
4902+ {
4903+ case IndicatorsModelRole::Priority:
4904+ return 0;
4905+ case IndicatorsModelRole::Title:
4906+ return indicator ? indicator->identifier() : "Unknown";
4907+ case IndicatorsModelRole::Description:
4908+ return "";
4909+ case IndicatorsModelRole::WidgetSource:
4910+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml";
4911+ case IndicatorsModelRole::PageSource:
4912+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml";
4913+ }
4914+ return QVariant();
4915+}
4916+
4917+Q_INVOKABLE QVariant IndicatorsModel::data(int row, int role) const
4918+{
4919+ return data(index(row, 0), role);
4920+}
4921+
4922+/*! \internal */
4923+QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
4924+{
4925+ if (!index.isValid() || index.row() >= m_indicators.size())
4926+ return QVariant();
4927+
4928+ Indicator::Ptr indicator = m_indicators[index.row()];
4929+
4930+ switch (role)
4931+ {
4932+ case IndicatorsModelRole::Identifier:
4933+ if (indicator)
4934+ {
4935+ return QVariant(indicator->identifier());
4936+ }
4937+ break;
4938+ case IndicatorsModelRole::IndicatorProperties:
4939+ if (indicator)
4940+ {
4941+ return QVariant(indicator->indicatorProperties());
4942+ }
4943+ break;
4944+ case IndicatorsModelRole::IsValid:
4945+ return (indicator ? true : false);
4946+ case IndicatorsModelRole::Priority:
4947+ case IndicatorsModelRole::Title:
4948+ case IndicatorsModelRole::Description:
4949+ case IndicatorsModelRole::WidgetSource:
4950+ case IndicatorsModelRole::PageSource:
4951+ return indicatorData(indicator, role);
4952+ default:
4953+ break;
4954+ }
4955+ return QVariant();
4956+}
4957+
4958+QVariant IndicatorsModel::indicatorData(const Indicator::Ptr& indicator, int role) const
4959+{
4960+ if (indicator && m_parsed_indicator_data.contains(indicator->identifier()))
4961+ {
4962+ QVariantMap data = m_parsed_indicator_data[indicator->identifier()];
4963+ return data.value(roleNames()[role], QVariant());
4964+ }
4965+ return defaultData(indicator, role);
4966+}
4967+
4968+/*! \internal */
4969+QModelIndex IndicatorsModel::parent(const QModelIndex&) const
4970+{
4971+ return QModelIndex();
4972+}
4973+
4974+/*! \internal */
4975+int IndicatorsModel::rowCount(const QModelIndex&) const
4976+{
4977+ return m_indicators.count();
4978+}
4979+
4980+void IndicatorsModel::setIndicatorData(const QVariant& data)
4981+{
4982+ m_indicator_data = data;
4983+
4984+ m_parsed_indicator_data.clear();
4985+ QMap<QString, QVariant> map = data.toMap();
4986+ QMapIterator<QString, QVariant> iter(map);
4987+ while(iter.hasNext())
4988+ {
4989+ iter.next();
4990+ m_parsed_indicator_data[iter.key()] = iter.value().toMap();
4991+ }
4992+
4993+ Q_EMIT indicatorDataChanged(m_indicator_data);
4994+}
4995+
4996+QVariant IndicatorsModel::indicatorData() const
4997+{
4998+ return m_indicator_data;
4999+}
5000
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches