I have made the following changes intended for : CE:UX:MTF / lipstick CE:UX:MTF / lipstick-colorful-home
Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below. https://build.pub.meego.com//request/show/7216 Thank You, Islam Amer [This message was auto-generated] --- Request # 7216: Messages from BOSS: State: review at 2012-10-31T11:25:03 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: Project:MTF:UX / lipstick -> CE:UX:MTF / lipstick changes files: -------------- --- lipstick.changes +++ lipstick.changes @@ -0,0 +1,7 @@ +* Wed Oct 31 2012 Robin Burchell <[email protected]> - 0.4.4 +- Improvements to the notification system & tool (from Vesa) +- Add properties or notification previews (from Vesa) +- make clean should not remove makefiles (from Vesa) +- Fix .pro file versioning (from Vesa) +- Fixes NEMO#338: Icon resolution is really slow - desktops should now do their own icon resolution + old: ---- lipstick-0.4.3.tar.bz2 new: ---- lipstick-0.4.4.tar.bz2 spec files: ----------- --- lipstick.spec +++ lipstick.spec @@ -9,7 +9,7 @@ # << macros Summary: QML toolkit for homescreen creation -Version: 0.4.3 +Version: 0.4.4 Release: 1 Group: System/Libraries License: LGPLv2.1 other changes: -------------- ++++++ lipstick-0.4.3.tar.bz2 -> lipstick-0.4.4.tar.bz2 --- .gitignore +++ .gitignore @@ -0,0 +1,18 @@ +Makefile +*.o +*gen_*.h +*gen_*.cpp +*gen_*.o +*moc_*.h +*moc_*.cpp +*moc_*.o +*~ +*.log +*.log.xml +*.gcno +*.gcda +*.pro.user +configure-stamp +build-stamp +.project +.cproject --- lipstick.pro +++ lipstick.pro @@ -5,8 +5,6 @@ tools.depends = src QMAKE_CLEAN += \ - Makefile \ - */Makefile \ build-stamp \ configure-stamp \ artifacts/*.deb \ --- plugin/.gitignore +++ plugin/.gitignore @@ -0,0 +1 @@ +liblipstickplugin.so --- plugin/lipstickplugin.cpp +++ plugin/lipstickplugin.cpp @@ -24,6 +24,7 @@ #include <components/windowmanager.h> #include <components/windowinfo.h> #include <notifications/notificationlistmodel.h> +#include <notifications/notification.h> LipstickPlugin::LipstickPlugin(QObject *parent) : QDeclarativeExtensionPlugin(parent) @@ -39,6 +40,7 @@ qmlRegisterType<SwitcherPixmapItem>("org.nemomobile.lipstick", 0, 1, "SwitcherPixmapItem"); qmlRegisterType<StatusBar>("org.nemomobile.lipstick", 0, 1, "StatusBar"); qmlRegisterType<NotificationListModel>("org.nemomobile.lipstick", 0, 1, "NotificationListModel"); + qmlRegisterType<Notification>("org.nemomobile.lipstick", 0, 1, "Notification"); qmlRegisterUncreatableType<WindowInfo>("org.nemomobile.lipstick", 0, 1, "WindowInfo", "This type is initialized by SwitcherModel"); qmlRegisterUncreatableType<LauncherItem>("org.nemomobile.lipstick", 0, 1, "LauncherItem", "This type is initialized by LauncherModel"); qmlRegisterUncreatableType<WindowManager>("org.nemomobile.lipstick", 0, 1, "WindowManager", "This type should be accessed through a context property."); --- src/.gitignore +++ src/.gitignore @@ -0,0 +1,2 @@ +liblipstick.* +pkgconfig --- src/components/launcheritem.cpp +++ src/components/launcheritem.cpp @@ -37,141 +37,6 @@ #define LAUNCHER_DEBUG(things) #endif -static bool iconNameSizeSortHelper(const QString &s1, const QString &s2) -{ - int x1 = s1.indexOf(QChar('x')); - int x2 = s2.indexOf(QChar('x')); - - if (x1 == -1) - return true; - if (x2 == -1) - return false; - - int ss1 = s1.left(x1).toInt(); - int ss2 = s2.left(x2).toInt(); - - if (!ss1) - return true; - if (!ss2) - return false; - - // The > is NOT a mistake, we need the higher res things before the lower res things - return ss1 > ss2; -} - -static QString findIconHelper(const QString &pathName, const QString &icon) -{ - QStringList extensions; - extensions << ""; - extensions << ".png"; - extensions << ".svg"; - // qDebug() << "Trying " << pathName << " for " << icon; - - foreach (const QString &extension, extensions) { - if (QFile::exists(pathName + QDir::separator() + icon + extension)) - return pathName + QDir::separator() + icon + extension; - } - - QStringList entryList = QDir(pathName).entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); - foreach (const QString &dir, entryList) { - QString retval = findIconHelper(QDir(pathName).absoluteFilePath(dir), icon); - if (!retval.isNull()) - return retval; - } - - // all else failed - return QString(); -} - -static QString getIconPath(const QString &name) -{ - if (QFile::exists(name)) { - // fast path: file given - return name; - } - - QSettings settings("MeeGo", "IconCache"); - QString cachedPath = settings.value(name).toString(); - - if (!QFile::exists(cachedPath)) - { - LAUNCHER_DEBUG("Negative cache hit for " << name << " to " << cachedPath); - } - else - { - return cachedPath; - } - - QString retval; - QStringList themes = QDir("/usr/share/themes").entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); - - if (!themes.isEmpty()) - { - // TODO: look up active theme in gconf and set it to the first search path, don't hardcode it. - // TODO: would be nice to investigate if our fallback behaviour is actually correct, too, but meh. - - if (themes.contains("n900de") && themes.at(0) != "n900de") - { - themes.removeAll("n900de"); - themes.insert(0, "n900de"); - } - - foreach (const QString &theme, themes) - { - retval = findIconHelper("/usr/share/themes/" + theme, name); - - if (!retval.isNull()) - { - if (QFile::exists(retval)) - { - settings.setValue(name, retval); - return retval; - } - } - } - } - - // they also seem to get plonked here - retval = findIconHelper("/usr/share/pixmaps/", name); - - if (!retval.isNull()) - { - if (QFile::exists(retval)) - { - settings.setValue(name, retval); - return retval; - } - } - - - // I hate all application developers - - // Going through all folders in here too - QStringList hiColorSizes = QDir("/usr/share/icons/hicolor").entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); - // Ordering them in a way that scalable comes first and then resolutions in descending order - qSort(hiColorSizes.begin(), hiColorSizes.end(), iconNameSizeSortHelper); - - if (!hiColorSizes.isEmpty()) - { - foreach (const QString &hiColorSize, hiColorSizes) - { - retval = findIconHelper("/usr/share/icons/hicolor/" + hiColorSize, name); - - if (!retval.isNull()) - { - if (QFile::exists(retval)) - { - settings.setValue(name, retval); - return retval; - } - } - } - } - - // If everything fails, return an empty string - return QString(); -} - LauncherItem::LauncherItem(const QString &path, QObject *parent) : QObject(parent) , _desktopEntry(new MDesktopEntry(path)) @@ -203,26 +68,9 @@ return _desktopEntry->type(); } -QString LauncherItem::iconFilePath() const +QString LauncherItem::iconId() const { - LAUNCHER_DEBUG("icon path is:" << _desktopEntry->icon()); - - if (_desktopEntry->icon().length() == 0) - { - LAUNCHER_DEBUG("desktop entry has empty icon setting:" << _desktopEntry->path()); - return QString(); - } - - QString path = getIconPath(_desktopEntry->icon()); - - if (path.length() == 0) - { - LAUNCHER_DEBUG("could not find icon for iconname:" << _desktopEntry->icon()); - return QString(); - } - - LAUNCHER_DEBUG("icon file found for iconname:" << _desktopEntry->icon() << path); - return "file://" + path; + return _desktopEntry->icon(); } QStringList LauncherItem::desktopCategories() const --- src/components/launcheritem.h +++ src/components/launcheritem.h @@ -34,7 +34,7 @@ Q_PROPERTY(QString filePath READ filePath NOTIFY itemChanged) Q_PROPERTY(QString title READ title NOTIFY itemChanged) Q_PROPERTY(QString entryType READ entryType NOTIFY itemChanged) - Q_PROPERTY(QString iconFilePath READ iconFilePath NOTIFY itemChanged) + Q_PROPERTY(QString iconId READ iconId NOTIFY itemChanged) Q_PROPERTY(QStringList desktopCategories READ desktopCategories NOTIFY itemChanged) Q_PROPERTY(bool shouldDisplay READ shouldDisplay NOTIFY itemChanged) Q_PROPERTY(bool isValid READ isValid NOTIFY itemChanged) @@ -53,7 +53,7 @@ QString filePath() const; QString title() const; QString entryType() const; - QString iconFilePath() const; + QString iconId() const; QStringList desktopCategories() const; bool shouldDisplay() const; bool isValid() const; --- src/notifications/.gitignore +++ src/notifications/.gitignore @@ -0,0 +1 @@ +notificationmanageradaptor.* --- src/notifications/notification.cpp +++ src/notifications/notification.cpp @@ -30,7 +30,8 @@ { } -Notification::Notification() : +Notification::Notification(QObject *parent) : + QObject(parent), replacesId_(0), expireTimeout_(-1) { @@ -119,6 +120,9 @@ { QString oldIcon = icon(); QDateTime oldTimestamp = timestamp(); + QString oldPreviewIcon = previewIcon(); + QString oldPreviewSummary = previewSummary(); + QString oldPreviewBody = previewBody(); hints_ = hints; @@ -129,6 +133,18 @@ if (oldTimestamp != timestamp()) { emit localizedTimestampChanged(); } + + if (oldPreviewIcon != previewIcon()) { + emit previewIconChanged(); + } + + if (oldPreviewSummary != previewSummary()) { + emit previewSummaryChanged(); + } + + if (oldPreviewBody != previewBody()) { + emit previewBodyChanged(); + } } int Notification::expireTimeout() const @@ -143,7 +159,7 @@ QString Notification::icon() const { - return hints_.value(NotificationManager::HINT_ICON).toString(); + return appIcon_.isEmpty() ? hints_.value(NotificationManager::HINT_ICON).toString() : appIcon_; } QDateTime Notification::timestamp() const @@ -156,6 +172,21 @@ return timestamp().toString("hh:mm:ss"); } +QString Notification::previewIcon() const +{ + return hints_.value(NotificationManager::HINT_PREVIEW_ICON).toString(); +} + +QString Notification::previewSummary() const +{ + return hints_.value(NotificationManager::HINT_PREVIEW_SUMMARY).toString(); +} + +QString Notification::previewBody() const +{ + return hints_.value(NotificationManager::HINT_PREVIEW_BODY).toString(); +} + QDBusArgument &operator<<(QDBusArgument &argument, const Notification ¬ification) { argument.beginStructure(); --- src/notifications/notification.h +++ src/notifications/notification.h @@ -39,6 +39,9 @@ Q_PROPERTY(QString icon READ icon NOTIFY iconChanged) Q_PROPERTY(QDateTime timestamp READ timestamp) Q_PROPERTY(QString localizedTimestamp READ localizedTimestamp NOTIFY localizedTimestampChanged) + Q_PROPERTY(QString previewIcon READ previewIcon NOTIFY previewIconChanged) + Q_PROPERTY(QString previewSummary READ previewSummary NOTIFY previewSummaryChanged) + Q_PROPERTY(QString previewBody READ previewBody NOTIFY previewBodyChanged) public: /*! @@ -56,6 +59,13 @@ */ Notification(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout, QObject *parent = 0); + /*! + * Creates a new uninitialized representation of a notification. + * + * \param parent the parent QObject + */ + Notification(QObject *parent = 0); + //! Returns the name of the application sending the notification QString appName() const; @@ -110,14 +120,16 @@ //! Returns the timestamp for the notification in localized text format QString localizedTimestamp() const; - //! \internal - /*! - * Creates a new uninitialized representation of a notification. This - * constructor should only be used for populating the notification list - * from D-Bus structures. - */ - Notification(); + //! Returns the icon ID for the preview of the notification + QString previewIcon() const; + + //! Returns the summary text for the preview of the notification + QString previewSummary() const; + //! Returns the body text for the preview of the notification + QString previewBody() const; + + //! \internal /*! * Creates a copy of an existing representation of a notification. * This constructor should only be used for populating the notification @@ -151,6 +163,15 @@ //! Sent when the localized timestamp has changed void localizedTimestampChanged(); + //! Sent when the preview icon has been modified + void previewIconChanged(); + + //! Sent when the preview summary has been modified + void previewSummaryChanged(); + + //! Sent when the preview body has been modified + void previewBodyChanged(); + private: //! Name of the application sending the notification QString appName_; --- src/notifications/notificationmanager.cpp +++ src/notifications/notificationmanager.cpp @@ -185,7 +185,8 @@ NOTIFICATIONS_DEBUG("REMOVE:" << id); emit notificationRemoved(id); - delete notifications.take(id); + // Mark the notification to be destroyed + removedNotifications.insert(notifications.take(id)); } } @@ -447,6 +448,9 @@ database->commit(); committed = true; } + + qDeleteAll(removedNotifications); + removedNotifications.clear(); } void NotificationManager::execSQL(const QString &command, const QVariantList &args) --- src/notifications/notificationmanager.h +++ src/notifications/notificationmanager.h @@ -20,6 +20,7 @@ #include "notification.h" #include <QObject> #include <QTimer> +#include <QSet> class CategoryDefinitionStore; class QSqlDatabase; @@ -241,7 +242,10 @@ */ void updateNotificationsWithCategory(const QString &category); - //! Commits the current database transaction, if any + /*! + * Commits the current database transaction, if any. + * Also destroys any removed notifications. + */ void commit(); /*! @@ -346,6 +350,9 @@ //! Hash of all notifications keyed by notification IDs QHash<uint, Notification*> notifications; + //! Notifications waiting to be destroyed + QSet<Notification *> removedNotifications; + //! Previous notification ID used uint previousNotificationID; --- src/src.pro +++ src/src.pro @@ -2,7 +2,7 @@ TEMPLATE = lib TARGET = lipstick -VERSION = 0.1 +VERSION = 0.4.4 DEFINES += LIPSTICK_BUILD_LIBRARY DEBUG_NOTIFICATIONS --- tests/stubs/notificationmanager_stub.h +++ tests/stubs/notificationmanager_stub.h @@ -132,6 +132,9 @@ // 4. CREATE A PROXY WHICH CALLS THE STUB const char *NotificationManager::HINT_ICON = "x-nemo-icon"; const char *NotificationManager::HINT_TIMESTAMP = "x-nemo-timestamp"; +const char *NotificationManager::HINT_PREVIEW_ICON = "x-nemo-preview-icon"; +const char *NotificationManager::HINT_PREVIEW_BODY = "x-nemo-preview-body"; +const char *NotificationManager::HINT_PREVIEW_SUMMARY = "x-nemo-preview-summary"; NotificationManager *NotificationManager::instance_ = 0; NotificationManager * NotificationManager::instance() { --- tests/ut_categorydefinitionstore/.gitignore +++ tests/ut_categorydefinitionstore/.gitignore @@ -0,0 +1 @@ +ut_categorydefinitionstore --- tests/ut_lipstickdbusinterface/.gitignore +++ tests/ut_lipstickdbusinterface/.gitignore @@ -0,0 +1 @@ +ut_lipstickdbusinterface --- tests/ut_lipsticksettings/.gitignore +++ tests/ut_lipsticksettings/.gitignore @@ -0,0 +1 @@ +ut_lipsticksettings --- tests/ut_notification/.gitignore +++ tests/ut_notification/.gitignore @@ -0,0 +1 @@ +ut_notification --- tests/ut_notification/ut_notification.cpp +++ tests/ut_notification/ut_notification.cpp @@ -26,12 +26,16 @@ QString appIcon = "appIcon1"; QString summary = "summary1"; QString body = "body1"; + QString previewIcon = "previewIcon1"; + QString previewSummary = "previewSummary1"; + QString previewBody = "previewBody1"; QStringList actions = QStringList() << "action1a" << "action1b"; - QString icon = "icon1"; QDateTime timestamp = QDateTime::currentDateTime(); QVariantHash hints; - hints.insert(NotificationManager::HINT_ICON, icon); hints.insert(NotificationManager::HINT_TIMESTAMP, timestamp); + hints.insert(NotificationManager::HINT_PREVIEW_ICON, previewIcon); + hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, previewSummary); + hints.insert(NotificationManager::HINT_PREVIEW_BODY, previewBody); int expireTimeout = 1; // Ensure that the constructor puts things in place @@ -43,19 +47,25 @@ QCOMPARE(notification.body(), body); QCOMPARE(notification.actions(), actions); QCOMPARE(notification.expireTimeout(), expireTimeout); - QCOMPARE(notification.icon(), icon); QCOMPARE(notification.timestamp(), timestamp); QCOMPARE(notification.localizedTimestamp(), timestamp.toString("hh:mm:ss")); + QCOMPARE(notification.previewIcon(), previewIcon); + QCOMPARE(notification.previewSummary(), previewSummary); + QCOMPARE(notification.previewBody(), previewBody); appName = "appName2"; appIcon = "appIcon2"; summary = "summary2"; body = "body2"; + previewIcon = "previewIcon2"; + previewSummary = "previewSummary2"; + previewBody = "previewBody2"; actions = QStringList() << "action2a" << "action2b" << "action2c"; - icon = "icon2"; timestamp = QDateTime::currentDateTime(); - hints.insert(NotificationManager::HINT_ICON, icon); hints.insert(NotificationManager::HINT_TIMESTAMP, timestamp); + hints.insert(NotificationManager::HINT_PREVIEW_ICON, previewIcon); + hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, previewSummary); + hints.insert(NotificationManager::HINT_PREVIEW_BODY, previewBody); expireTimeout = 2; notification.setAppName(appName); notification.setAppIcon(appIcon); @@ -70,9 +80,40 @@ QCOMPARE(notification.body(), body); QCOMPARE(notification.actions(), actions); QCOMPARE(notification.expireTimeout(), expireTimeout); - QCOMPARE(notification.icon(), icon); QCOMPARE(notification.timestamp(), timestamp); QCOMPARE(notification.localizedTimestamp(), timestamp.toString("hh:mm:ss")); + QCOMPARE(notification.previewIcon(), previewIcon); + QCOMPARE(notification.previewSummary(), previewSummary); + QCOMPARE(notification.previewBody(), previewBody); +} + +void Ut_Notification::testIcon_data() +{ + QTest::addColumn<QString>("appIcon"); + QTest::addColumn<QString>("hintIcon"); + QTest::addColumn<QString>("icon"); + + QTest::newRow("No app_icon, no hint") << QString() << QString() << QString(); + QTest::newRow("No app_icon, hint") << QString() << QString("hintIcon") << QString("hintIcon"); + QTest::newRow("app_icon, no hint") << QString("appIcon") << QString() << QString("appIcon"); + QTest::newRow("app_icon, hint") << QString("appIcon") << QString("hintIcon") << QString("appIcon"); +} + +void Ut_Notification::testIcon() +{ + QFETCH(QString, appIcon); + QFETCH(QString, hintIcon); + QFETCH(QString, icon); + + QVariantHash hints; + hints.insert(NotificationManager::HINT_ICON, hintIcon); + + Notification notification1(QString(), 0, appIcon, QString(), QString(), QStringList(), hints, 0); + QCOMPARE(notification1.icon(), icon); + Notification notification2(QString(), 0, QString(), QString(), QString(), QStringList(), QVariantHash(), 0); + notification2.setAppIcon(appIcon); + notification2.setHints(hints); + QCOMPARE(notification2.icon(), icon); } void Ut_Notification::testSignals() --- tests/ut_notification/ut_notification.h +++ tests/ut_notification/ut_notification.h @@ -23,6 +23,8 @@ private slots: void testGettersAndSetters(); + void testIcon_data(); + void testIcon(); void testSignals(); void testSerialization(); }; --- tests/ut_notificationlistmodel/.gitignore +++ tests/ut_notificationlistmodel/.gitignore @@ -0,0 +1 @@ +ut_notificationlistmodel --- tests/ut_notificationmanager/.gitignore +++ tests/ut_notificationmanager/.gitignore @@ -0,0 +1 @@ +ut_notificationmanager --- tools/notificationtool/.gitignore +++ tools/notificationtool/.gitignore @@ -0,0 +1,2 @@ +notificationmanagerproxy.* +notificationtool --- tools/notificationtool/notificationtool.cpp +++ tools/notificationtool/notificationtool.cpp @@ -33,16 +33,28 @@ // The notification ID to use uint id = 0; +// The icon of the notification +QString icon; + +// The category of the notification +QString category; + // The count of items represented by the notification -uint count = 1; +int count = -1; + +// Expire timeout for the notifcation +int expireTimeout = -1; // Timestamp for notification QString timestamp; +// Actions for the notification +QHash<QString, QStringList> actions; + // Prints usage information int usage(const char *program) { - std::cerr << std::setw(7) << "Usage: " << program << " [OPTION]... CATEGORY [SUMMARY BODY IMAGE ACTION...]" << std::endl; + std::cerr << std::setw(7) << "Usage: " << program << " [OPTION]... [SUMMARY BODY PREVIEWSUMMARY PREVIEWBODY]" << std::endl; std::cerr << std::setw(7) << "Manage notifications." << std::endl; std::cerr << std::setw(7) << std::endl; std::cerr << std::setw(7) << "Mandatory arguments to long options are mandatory for short options too." << std::endl; @@ -50,9 +62,13 @@ std::cerr << std::setw(7) << " add - Adds a new notification." << std::endl; std::cerr << std::setw(7) << " update - Updates an existing notification." << std::endl; std::cerr << std::setw(7) << " remove - Removes an existing notification." << std::endl; - std::cerr << std::setw(7) << " -i, --id=ID The notification ID to use." << std::endl; - std::cerr << std::setw(7) << " -c, --count=NUMBER The number of items represented by thenotification." << std::endl; - std::cerr << std::setw(7) << " -t, --timestamp Timestamp to use on a notification. Use ISO 8601 extended date format."<< std::endl; + std::cerr << std::setw(7) << " -i, --id=ID The notification ID to use when updating or removing a notification." << std::endl; + std::cerr << std::setw(7) << " -I, --icon=ICON Icon for the notification."<< std::endl; + std::cerr << std::setw(7) << " -c, --category=CATEGORY The category of the notification." << std::endl; + std::cerr << std::setw(7) << " -C, --count=NUMBER The number of items represented by the notification." << std::endl; + std::cerr << std::setw(7) << " -t, --timestamp=TIMESTAMP Timestamp to use on a notification. Use ISO 8601 extended date format."<< std::endl; + std::cerr << std::setw(7) << " -T, --timeout=MILLISECONDS Expire timeout for the notification in milliseconds or -1 to use server defaults."<< std::endl; + std::cerr << std::setw(7) << " -a, --action An action for the notification in \"ACTIONNAME DBUSSERVICE DBUSPATH DBUSINTERFACE METHOD ARGUMENTS\" format."<< std::endl; std::cerr << std::setw(7) << " --help display this help and exit" << std::endl; std::cerr << std::setw(7) << std::endl; std::cerr << std::setw(7) << "A notification ID is mandatory when the operation is 'update' or 'remove'." << std::endl; @@ -68,15 +84,20 @@ static struct option long_options[] = { { "operation", required_argument, NULL, 'o' }, { "id", required_argument, NULL, 'i' }, - { "count", required_argument, NULL, 'c' }, - { "help", no_argument, NULL, 'h' }, + { "icon", required_argument, NULL, 'I' }, + { "category", required_argument, NULL, 'c' }, + { "count", required_argument, NULL, 'C' }, { "timestamp", required_argument, NULL, 't'}, + { "timeout", required_argument, NULL, 'T' }, + { "action", required_argument, NULL, 'a'}, + { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } }; - int c = getopt_long(argc, argv, "o:i:c:t:", long_options, &option_index); - if (c == -1) + int c = getopt_long(argc, argv, "o:i:I:c:C:t:T:a:h", long_options, &option_index); + if (c == -1) { break; + } switch (c) { case 'o': @@ -91,7 +112,13 @@ case 'i': id = atoi(optarg); break; + case 'I': + icon = QString(optarg); + break; case 'c': + category = QString(optarg); + break; + case 'C': count = atoi(optarg); break; case 'h': @@ -100,15 +127,24 @@ case 't': timestamp = QString(optarg); break; + case 'T': + expireTimeout = atoi(optarg); + break; + case 'a': { + QStringList action = QString(optarg).split(' '); + QString name = action.takeFirst(); + actions.insert(name, action); + break; + } default: break; } } if (toolOperation == Undefined || - (toolOperation == Add && argc < optind + 1) || + (toolOperation == Add && argc < optind) || (toolOperation == Add && id != 0) || - (toolOperation == Update && argc < optind + 1) || + (toolOperation == Update && argc < optind) || (toolOperation == Update && id == 0)) { return usage(argv[0]); } @@ -132,30 +168,43 @@ case Add: case Update: { // Get the parameters for adding and updating notifications - QString category = QString(argv[optind]); - QString summary, body, image; - QStringList actions; + QString summary, body, previewSummary, previewBody; + if (argc >= optind) { + summary = QString(argv[optind]); + } if (argc >= optind + 1) { - summary = QString(argv[optind + 1]); + body = QString(argv[optind + 1]); } if (argc >= optind + 2) { - body = QString(argv[optind + 2]); + previewSummary = QString(argv[optind + 2]); } if (argc >= optind + 3) { - image = QString(argv[optind + 3]); - } - if (argc >= optind + 4) { - for (int action = optind + 4; action < argc; action++) { - actions.append(QString(argv[action])); - } + previewBody = QString(argv[optind + 3]); } // Add/update a notification QVariantHash hints; - hints.insert(NotificationManager::HINT_CATEGORY, category); - hints.insert(NotificationManager::HINT_ITEM_COUNT, count); - hints.insert(NotificationManager::HINT_TIMESTAMP, timestamp); - result = proxy.Notify(argv[0], id, image, summary, body, actions, hints, -1); + if (!category.isEmpty()) { + hints.insert(NotificationManager::HINT_CATEGORY, category); + } + if (count >= 0) { + hints.insert(NotificationManager::HINT_ITEM_COUNT, count); + } + if (!timestamp.isEmpty()) { + hints.insert(NotificationManager::HINT_TIMESTAMP, timestamp); + } + if (!actions.isEmpty()) { + foreach (const QString &name, actions.keys()) { + hints.insert(QString(NotificationManager::HINT_REMOTE_ACTION_PREFIX) + name, actions.value(name)); + } + } + if (!previewSummary.isEmpty()) { + hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, previewSummary); + } + if (!previewBody.isEmpty()) { + hints.insert(NotificationManager::HINT_PREVIEW_BODY, previewBody); + } + result = proxy.Notify(argv[0], id, icon, summary, body, QStringList(), hints, expireTimeout); break; } case Remove: ++++++ lipstick.yaml --- lipstick.yaml +++ lipstick.yaml @@ -1,6 +1,6 @@ Name: lipstick Summary: QML toolkit for homescreen creation -Version: 0.4.3 +Version: 0.4.4 Release: 1 Group: System/Libraries License: LGPLv2.1 submit: Project:MTF:UX / lipstick-colorful-home -> CE:UX:MTF / lipstick-colorful-home changes files: -------------- --- lipstick-colorful-home.changes +++ lipstick-colorful-home.changes @@ -0,0 +1,6 @@ +* Wed Oct 31 2012 Robin Burchell <[email protected]> - 0.0.9 +- Ensure systemd service restarts (from Robin) +- Remove unnecessary outer Flickable (from Robin) +- Remove wrapper Item from Pager (from Robin) +- Use mthemedaemon to do icon resolution for us (from Robin) + old: ---- lipstick-colorful-home-0.0.8.tar.bz2 new: ---- lipstick-colorful-home-0.0.9.tar.bz2 spec files: ----------- --- lipstick-colorful-home.spec +++ lipstick-colorful-home.spec @@ -9,7 +9,7 @@ # << macros Summary: A nice homescreen -Version: 0.0.8 +Version: 0.0.9 Release: 1 Group: System/GUI/Other License: BSD @@ -18,7 +18,7 @@ Source1: lipstick.desktop Source2: lipstick.service Source100: lipstick-colorful-home.yaml -Requires: lipstick >= 0.4.1 +Requires: lipstick >= 0.4.4 Requires: nemo-qml-plugins-configuration BuildRequires: pkgconfig(QtCore) BuildRequires: pkgconfig(QtDeclarative) other changes: -------------- ++++++ lipstick-colorful-home-0.0.8.tar.bz2 -> lipstick-colorful-home-0.0.9.tar.bz2 --- src/qml/MainScreen.qml +++ src/qml/MainScreen.qml @@ -140,7 +140,7 @@ right: parent.right bottom: parent.bottom } - pages: VisualItemModel { + model: VisualItemModel { /* Favorites { id: favorites @@ -155,7 +155,6 @@ */ AppLauncher { id: launcher - width: pager.width height: pager.height } AppSwitcher { --- src/qml/components/Pager.qml +++ src/qml/components/Pager.qml @@ -23,26 +23,20 @@ import QtQuick 1.1 -Item { - property alias pages: view.model - property alias currentIndex: view.currentIndex - - PathView { - id: view - highlightRangeMode: PathView.StrictlyEnforceRange - preferredHighlightBegin: 0.5 - preferredHighlightEnd: 0.5 - flickDeceleration: 10000 - highlightMoveDuration: 100 - clip: true - anchors.fill: parent - path: Path { - startX: - width * pages.count / 2 + width / 2 - startY: height / 2 - PathLine { - x: width * pages.count / 2 + width / 2 - y: height / 2 - } +PathView { + id: view + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + flickDeceleration: 10000 + highlightMoveDuration: 100 + clip: true + path: Path { + startX: - width * model.count / 2 + width / 2 + startY: height / 2 + PathLine { + x: width * model.count / 2 + width / 2 + y: height / 2 } } } --- src/qml/pages/AppLauncher.qml +++ src/qml/pages/AppLauncher.qml @@ -24,39 +24,37 @@ import QtQuick 1.1 import org.nemomobile.lipstick 0.1 +import com.nokia.meego 1.2 import "./AppLauncher" // App Launcher page // the place for browsing installed applications and launching them -Flickable { - id: launcherRoot +GridView { + id: gridview + cellWidth: 80 + 60 + cellHeight: cellWidth + width: Math.floor(parent.width / cellWidth) * cellWidth + cacheBuffer: gridview.contentHeight + x: (parent.width - width) / 2 // can't use an anchor because we need to animate our position + + // just for margin purposes + header: Item { + height: 30 + } + + footer: Item { + height: 20 + } - property alias cellWidth: gridview.cellWidth - contentHeight: gridview.height + 50 + model: LauncherModel { } - GridView { - id: gridview - cellWidth: 80 + 60 - cellHeight: cellWidth - width: Math.floor(parent.width / cellWidth) * cellWidth - height: gridview.contentHeight - interactive: false - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: 30 - } - - model: LauncherModel { } - - delegate: LauncherItem { - id: launcherItem - width: gridview.cellWidth - height: gridview.cellHeight - iconFilePath: model.object.iconFilePath === "" ? ":/images/icons/apps.png" : model.object.iconFilePath - iconCaption: model.object.title - onClicked: model.object.launchApplication(); - } + delegate: LauncherItem { + id: launcherItem + width: gridview.cellWidth + height: gridview.cellHeight + source: model.object.iconId == "" ? ":/images/icons/apps.png" : (model.object.iconId.indexOf("/") == 0 ? "file://" : "image://theme/") + model.object.iconId + iconCaption: model.object.title + onClicked: model.object.launchApplication(); } } --- src/qml/pages/AppLauncher/LauncherItem.qml +++ src/qml/pages/AppLauncher/LauncherItem.qml @@ -25,7 +25,7 @@ import QtQuick 1.1 MouseArea { - property alias iconFilePath: iconImage.source + property alias source: iconImage.source property alias iconCaption: iconText.text // Application icon for the launcher ++++++ lipstick-colorful-home.yaml --- lipstick-colorful-home.yaml +++ lipstick-colorful-home.yaml @@ -1,6 +1,6 @@ Name: lipstick-colorful-home Summary: A nice homescreen -Version: 0.0.8 +Version: 0.0.9 Release: 1 Group: System/GUI/Other License: BSD @@ -17,7 +17,7 @@ Description: A homescreen for Nemo Mobile Builder: qmake Requires: - - lipstick >= 0.4.1 + - lipstick >= 0.4.4 - nemo-qml-plugins-configuration PkgConfigBR: - QtCore ++++++ lipstick.service --- lipstick.service +++ lipstick.service @@ -5,4 +5,5 @@ [Service] ExecStart=/usr/bin/lipstick +Restart=always
