[Pkg-owncloud-commits] [owncloud-client] 201/470: Notifications: Handle Notifications without an action.

Sandro Knauß hefee-guest at moszumanska.debian.org
Thu May 12 16:25:03 UTC 2016


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit 1fe5d6bb0cfb6d556b8eb6bf7b35a668cdcff243
Author: Klaas Freitag <freitag at owncloud.com>
Date:   Wed Mar 23 16:59:03 2016 +0100

    Notifications: Handle Notifications without an action.
    
    The policy that was said is that if a notification has no action, the
    client can and should display a close-button. This patch does it.
    
    In additon to that, the client needs a blacklist of closed notifcations
    otherwise they would re-appear next time the server notifications are
    fetched again.
    
    Also, changed the cleanup of not-longer-used widgets to be more robust.
---
 src/gui/activitywidget.cpp     | 84 +++++++++++++++++++++++++++++++++---------
 src/gui/activitywidget.h       | 10 ++++-
 src/gui/notificationwidget.cpp | 44 +++++++++++++---------
 src/gui/notificationwidget.h   |  2 +-
 4 files changed, 103 insertions(+), 37 deletions(-)

diff --git a/src/gui/activitywidget.cpp b/src/gui/activitywidget.cpp
index 08b9195..9b7c7cd 100644
--- a/src/gui/activitywidget.cpp
+++ b/src/gui/activitywidget.cpp
@@ -94,6 +94,9 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
 
     connect( _ui->_activityList, SIGNAL(activated(QModelIndex)), this,
              SLOT(slotOpenFile(QModelIndex)));
+
+    connect( &_removeTimer, SIGNAL(timeout()), this, SLOT(slotCheckToCleanWidgets()) );
+    _removeTimer.setInterval(1000);
 }
 
 ActivityWidget::~ActivityWidget()
@@ -231,18 +234,26 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
     QString listAccountName;
 
     foreach( auto activity, list ) {
+        if( _blacklistedActivities.contains(activity)) {
+            qDebug() << Q_FUNC_INFO << "Activity in blacklist, skip";
+            continue;
+        }
+
         NotificationWidget *widget = 0;
 
-        if( _widgetForNotifId.contains(activity._id) ) {
-            widget = _widgetForNotifId[activity._id];
+        if( _widgetForNotifId.contains( activity.ident()) ) {
+            widget = _widgetForNotifId[activity.ident()];
         } else {
             widget = new NotificationWidget(this);
             connect(widget, SIGNAL(sendNotificationRequest(QString, QString, QString)),
                     this, SLOT(slotSendNotificationRequest(QString, QString, QString)));
+            connect(widget, SIGNAL(requestCleanupAndBlacklist(Activity)),
+                    this, SLOT(slotRequestCleanupAndBlacklist(Activity)));
+
             _notificationsLayout->addWidget(widget);
             // _ui->_notifyScroll->setMinimumHeight( widget->height());
             _ui->_notifyScroll->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
-            _widgetForNotifId[activity._id] = widget;
+            _widgetForNotifId[activity.ident()] = widget;
         }
 
         widget->setActivity( activity );
@@ -280,19 +291,20 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
         }
     }
 
-    // check if we have widgets that have no corresponding activity from
+    // check if there are widgets that have no corresponding activity from
     // the server any more. Collect them in a list
-    QList<int> strayCats;
+    QList< Activity::Identifier > strayCats;
     foreach( auto id, _widgetForNotifId.keys() ) {
-        bool found = false;
         NotificationWidget *widget = _widgetForNotifId[id];
 
+        bool found = false;
         // do not mark widgets of other accounts to delete.
-        if( widget->accountName() != listAccountName ) {
+        if( widget->activity()._accName != listAccountName ) {
             continue;
         }
+
         foreach( auto activity, list ) {
-            if( activity._id == id ) {
+            if( activity.ident() == id ) {
                 // found an activity
                 found = true;
                 break;
@@ -307,8 +319,7 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
     // .. and now delete all these stray cat widgets.
     foreach( auto strayCatId, strayCats ) {
         NotificationWidget *widgetToGo = _widgetForNotifId[strayCatId];
-        widgetToGo->deleteLater();
-        _widgetForNotifId.remove(strayCatId);
+        scheduleWidgetToRemove(widgetToGo, 0);
     }
 
     _ui->_notifyLabel->setHidden(  _widgetForNotifId.isEmpty() );
@@ -410,21 +421,60 @@ void ActivityWidget::slotNotifyServerFinished( const QString& reply, int replyCo
     // Add 200 millisecs to the predefined value to make sure that the timer in
     // widget's method readyToClose() has elapsed.
     if( replyCode == OCS_SUCCESS_STATUS_CODE ) {
-        QTimer::singleShot(NOTIFICATION_WIDGET_CLOSE_AFTER_MILLISECS+200, this, SLOT(slotCleanWidgetList()));
+        scheduleWidgetToRemove( job->widget() );
+    }
+}
+
+// blacklist the activity coming in here.
+void ActivityWidget::slotRequestCleanupAndBlacklist(const Activity& blacklistActivity)
+{
+    if ( ! _blacklistedActivities.contains(blacklistActivity) ) {
+        _blacklistedActivities.append(blacklistActivity);
     }
+
+    NotificationWidget *widget = _widgetForNotifId[ blacklistActivity.ident() ];
+    scheduleWidgetToRemove(widget);
 }
 
-void ActivityWidget::slotCleanWidgetList()
+void ActivityWidget::scheduleWidgetToRemove(NotificationWidget *widget, int milliseconds)
 {
-    foreach( int id, _widgetForNotifId.keys() ) {
-        Q_ASSERT(_widgetForNotifId[id]);
-        if( _widgetForNotifId[id]->readyToClose() ) {
-            auto *widget = _widgetForNotifId[id];
+    if( !widget ) {
+        return;
+    }
+    // in fife seconds from now, remove the widget.
+    QDateTime removeTime = QDateTime::currentDateTime().addMSecs(milliseconds);
+
+    QPair<QDateTime, NotificationWidget*> removeInfo = qMakePair(removeTime, widget);
+    if( !_widgetsToRemove.contains(removeInfo) ) {
+        _widgetsToRemove.insert( removeInfo );
+        if( !_removeTimer.isActive() ) {
+            _removeTimer.start();
+        }
+    }
+}
+
+// Called every second to see if widgets need to be removed.
+void ActivityWidget::slotCheckToCleanWidgets()
+{
+    // loop over all widgets in the to-remove queue
+    foreach( auto toRemove, _widgetsToRemove ) {
+        QDateTime t = toRemove.first;
+        NotificationWidget *widget = toRemove.second;
+
+        if( QDateTime::currentDateTime() > t ) {
+            // found one to remove!
+            Activity::Identifier id = widget->activity().ident();
             _widgetForNotifId.remove(id);
-            delete widget;
+            widget->deleteLater();
+            _widgetsToRemove.remove(toRemove);
         }
     }
 
+    if( _widgetsToRemove.isEmpty() ) {
+        _removeTimer.stop();
+    }
+
+    // check to see if the whole notification pane should be hidden
     if( _widgetForNotifId.isEmpty() ) {
         _ui->_notifyLabel->setHidden(true);
         _ui->_notifyScroll->setHidden(true);
diff --git a/src/gui/activitywidget.h b/src/gui/activitywidget.h
index cf6d732..a070a6f 100644
--- a/src/gui/activitywidget.h
+++ b/src/gui/activitywidget.h
@@ -66,6 +66,7 @@ public slots:
     void slotRefreshNotifications(AccountState *ptr);
     void slotRemoveAccount( AccountState *ptr );
     void slotAccountActivityStatus(AccountState *ast, int statusCode);
+    void slotRequestCleanupAndBlacklist(const Activity& blacklistActivity);
 
 signals:
     void guiLog(const QString&, const QString&);
@@ -80,7 +81,8 @@ private slots:
     void slotNotifyNetworkError( QNetworkReply* );
     void slotNotifyServerFinished( const QString& reply, int replyCode );
     void endNotificationRequest(NotificationWidget *widget , int replyCode);
-    void slotCleanWidgetList();
+    void scheduleWidgetToRemove(NotificationWidget *widget, int milliseconds = 4500);
+    void slotCheckToCleanWidgets();
 
 private:
     void showLabels();
@@ -89,9 +91,13 @@ private:
     QPushButton *_copyBtn;
 
     QSet<QString> _accountsWithoutActivities;
-    QMap<int, NotificationWidget*> _widgetForNotifId;
+    QMap<Activity::Identifier, NotificationWidget*> _widgetForNotifId;
     QElapsedTimer _guiLogTimer;
     QSet<int> _guiLoggedNotifications;
+    ActivityList _blacklistedActivities;
+
+    QSet< QPair<QDateTime, NotificationWidget*> > _widgetsToRemove;
+    QTimer _removeTimer;
 
     // number of currently running notification requests. If non zero,
     // no query for notifications is started.
diff --git a/src/gui/notificationwidget.cpp b/src/gui/notificationwidget.cpp
index 88217f1..15dd7fc 100644
--- a/src/gui/notificationwidget.cpp
+++ b/src/gui/notificationwidget.cpp
@@ -54,13 +54,22 @@ void NotificationWidget::setActivity(const Activity& activity)
     foreach( auto button, _ui._buttonBox->buttons() ) {
         _ui._buttonBox->removeButton(button);
     }
+    _buttons.clear();
 
     // display buttons for the links
-    foreach( auto link, activity._links ) {
-        QPushButton *b = _ui._buttonBox->addButton( link._label, QDialogButtonBox::AcceptRole);
-        b->setDefault(link._isPrimary);
+    if( activity._links.isEmpty() ) {
+        // in case there is no action defined, do a close button.
+        QPushButton *b = _ui._buttonBox->addButton( QDialogButtonBox::Close );
+        b->setDefault(true);
         connect(b, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
         _buttons.append(b);
+    } else {
+        foreach( auto link, activity._links ) {
+            QPushButton *b = _ui._buttonBox->addButton(link._label, QDialogButtonBox::AcceptRole);
+            b->setDefault(link._isPrimary);
+            connect(b, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
+            _buttons.append(b);
+        }
     }
 }
 
@@ -84,12 +93,24 @@ void NotificationWidget::slotButtonClicked()
         }
 
         // if the button was found, the link must be called
+        if( index > -1 && _myActivity._links.count() == 0 ) {
+            // no links, that means it was the close button
+            // empty link. Just close and remove the widget.
+            QString doneText = tr("Closing in a few seconds...");
+            _ui._timeLabel->setText(doneText);
+            emit requestCleanupAndBlacklist(_myActivity);
+            return;
+        }
+
         if( index > -1 && index < _myActivity._links.count() ) {
             ActivityLink triggeredLink = _myActivity._links.at(index);
             _actionLabel = triggeredLink._label;
-            qDebug() << Q_FUNC_INFO << "Notification Link: "<< triggeredLink._verb << triggeredLink._link;
-            _progressIndi->startAnimation();
-            emit sendNotificationRequest( _accountName, triggeredLink._link, triggeredLink._verb );
+
+            if( ! triggeredLink._link.isEmpty() ) {
+                qDebug() << Q_FUNC_INFO << "Notification Link: "<< triggeredLink._verb << triggeredLink._link;
+                _progressIndi->startAnimation();
+                emit sendNotificationRequest( _accountName, triggeredLink._link, triggeredLink._verb );
+            }
         }
     }
 }
@@ -116,12 +137,6 @@ void NotificationWidget::slotNotificationRequestFinished(int statusCode)
 
         //* The second parameter is a time, such as 'selected at 09:58pm'
         doneText = tr("'%1' selected at %2").arg(_actionLabel).arg(timeStr);
-
-        // start a timer, so that activity widget can remove this widget after a
-        // certain time. It needs to be done by ActivityWidget because it also
-        // needs to hide the scrollview if no widget is left any more.
-        // method readyToClose() checks for the timer value to see if it is expired
-        _closeTimer.start();
     }
     _ui._timeLabel->setText( doneText );
 
@@ -129,9 +144,4 @@ void NotificationWidget::slotNotificationRequestFinished(int statusCode)
 
 }
 
-bool NotificationWidget::readyToClose()
-{
-    return _closeTimer.isValid() && _closeTimer.elapsed() > NOTIFICATION_WIDGET_CLOSE_AFTER_MILLISECS;
-}
-
 }
diff --git a/src/gui/notificationwidget.h b/src/gui/notificationwidget.h
index c0b8755..6f19284 100644
--- a/src/gui/notificationwidget.h
+++ b/src/gui/notificationwidget.h
@@ -37,6 +37,7 @@ public:
 
 signals:
     void sendNotificationRequest( const QString&, const QString& link, const QString& verb);
+    void requestCleanupAndBlacklist( const Activity& activity );
 
 public slots:
      void setActivity(const Activity& activity);
@@ -52,7 +53,6 @@ private:
     QString _accountName;
     QProgressIndicator *_progressIndi;
     QString _actionLabel;
-    QElapsedTimer _closeTimer;
 };
 
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list