From ef4a30fcb9c4bd0132349001bb9176f3ed171c40 Mon Sep 17 00:00:00 2001 From: Camila San Date: Sat, 21 Apr 2018 01:24:31 +0200 Subject: [PATCH] Displays a menu once the user clicks on the button in the notifications. - In activityitemdelegate the mouse events are filtered (ActivityItemDelegate::editorEvent) to check if the user clicked on a button in the list of activities/notifications. Then a signal is emitted to ActivityWidget that does the rest: show submenu when there are more options, open browser, open file manager, send request to server. Signed-off-by: Camila San --- src/gui/activityitemdelegate.cpp | 88 +++++++++++--------------------- src/gui/activityitemdelegate.h | 6 +++ src/gui/activitywidget.cpp | 46 +++++++++++++++++ src/gui/activitywidget.h | 3 ++ 4 files changed, 86 insertions(+), 57 deletions(-) diff --git a/src/gui/activityitemdelegate.cpp b/src/gui/activityitemdelegate.cpp index e48c1fc88..80f41b42c 100644 --- a/src/gui/activityitemdelegate.cpp +++ b/src/gui/activityitemdelegate.cpp @@ -30,6 +30,9 @@ namespace OCC { int ActivityItemDelegate::_iconHeight = 0; int ActivityItemDelegate::_margin = 0; +int ActivityItemDelegate::_buttonWidth = 0; +int ActivityItemDelegate::_timeWidth = 0; +int ActivityItemDelegate::_buttonHeight = 0; int ActivityItemDelegate::iconHeight() { @@ -116,6 +119,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & timeBox.setLeft(option.rect.right() - timeBoxWidth - margin); timeBox.setRight(option.rect.right() + margin); timeBox.setHeight(fm.height()); + _timeWidth = timeBox.width(); // subject text rect QRect actionTextBox = timeBox; @@ -133,64 +137,24 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & messageTextBox.setWidth(0); } - // Action buttons - int buttonsWidth = 0; - QList buttons; + QStyleOptionButton optionsButton; if(activityType == Activity::Type::NotificationType){ - QList customList = index.data(ActionsLinksRole).toList(); - QList actionLinks; - foreach(QVariant customItem, customList){ - actionLinks << qvariant_cast(customItem); - } - QUrl link = qvariant_cast(index.data(LinkRole)); - int rightMargin = margin * 2; int leftMargin = margin * 4; int right = timeBox.left() - rightMargin; int left = timeBox.left() - leftMargin; - - // dismiss button - draw buttons from right to left - foreach (ActivityLink actionLink, actionLinks) { - QStyleOptionButton button; - button.rect = option.rect; - - int size = buttons.size(); - int btnTextWidth = fm.width(actionLink._label.toAscii()); - - if(size > 0){ - right = buttons.at(size-1).rect.left() - rightMargin; - left = buttons.at(size-1).rect.left() - leftMargin; - } - - button.rect.setLeft(left - btnTextWidth); - button.rect.setRight(right); - button.text = actionLink._label; - buttons.append(button); - buttonsWidth += button.rect.width(); - } - - // More information button - - if(!link.isEmpty()){ - const QString buttonText = tr("More Information"); - QStyleOptionButton button; - button.rect = option.rect; - - int size = buttons.size(); - int btnTextWidth = fm.width(buttonText); - - if(size > 0){ - right = buttons.at(size-1).rect.left() - rightMargin; - left = buttons.at(size-1).rect.left() - leftMargin; - } - - button.rect.setLeft(left - btnTextWidth); - button.rect.setRight(right); - button.text = buttonText; - buttons.append(button); - buttonsWidth += button.rect.width(); - } - } + optionsButton.rect = option.rect; + optionsButton.text = "..."; + int btnTextWidth = fm.width(optionsButton.text.toAscii()); + optionsButton.rect.setLeft(left - btnTextWidth); + optionsButton.rect.setRight(right); + optionsButton.rect.setTop(option.rect.top() + 5); + optionsButton.rect.setHeight(option.rect.height() - 10); + optionsButton.features |= QStyleOptionButton::DefaultButton; + optionsButton.state |= QStyle::State_Raised; + _buttonWidth = optionsButton.rect.size().width(); + _buttonHeight = optionsButton.rect.height(); + } /* === start drawing === */ QPixmap pm = actionIcon.pixmap(iconWidth, iconHeight, QIcon::Normal); @@ -207,7 +171,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & painter->setPen(option.palette.color(cg, QPalette::Text)); } - int spaceLeftForText = (option.rect.width() - (actionIconRect.width() + buttonsWidth))/4; + int spaceLeftForText = (option.rect.width() - (actionIconRect.width() + _buttonWidth))/4; const QString elidedAction = fm.elidedText(actionText, Qt::ElideRight, spaceLeftForText); painter->drawText(actionTextBox, elidedAction); @@ -217,9 +181,8 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & painter->drawText(messageTextBox, elidedMessage); } - foreach (QStyleOptionButton button, buttons) { - QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter); - } + if(activityType == Activity::Type::NotificationType) + QApplication::style()->drawControl(QStyle::CE_PushButton, &optionsButton, painter); if (!accountOnline) { QPalette p = option.palette; @@ -234,6 +197,17 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & bool ActivityItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { + if(qvariant_cast(index.data(ActionRole)) == Activity::Type::NotificationType){ + if (event->type() == QEvent::MouseButtonRelease){ + QMouseEvent *mouseEvent = (QMouseEvent*)event; + int x = option.rect.left() + option.rect.width() - _buttonWidth - _timeWidth; + int y = option.rect.top(); + if (mouseEvent->x() > x && mouseEvent->x() < (x + _buttonWidth)){ + if(mouseEvent->y() > y && mouseEvent->y() < (y + _buttonHeight)) + emit buttonClickedOnItemView(index); + } + } + } return QStyledItemDelegate::editorEvent(event, model, option, index); } diff --git a/src/gui/activityitemdelegate.h b/src/gui/activityitemdelegate.h index 844a12d51..821969aeb 100644 --- a/src/gui/activityitemdelegate.h +++ b/src/gui/activityitemdelegate.h @@ -46,9 +46,15 @@ public: static int rowHeight(); static int iconHeight(); +signals: + void buttonClickedOnItemView(const QModelIndex &index); + private: static int _margin; static int _iconHeight; + static int _buttonWidth; + static int _timeWidth; + static int _buttonHeight; }; } // namespace OCC diff --git a/src/gui/activitywidget.cpp b/src/gui/activitywidget.cpp index 0d2b839b2..977d51c66 100644 --- a/src/gui/activitywidget.cpp +++ b/src/gui/activitywidget.cpp @@ -92,6 +92,9 @@ ActivityWidget::ActivityWidget(AccountState *accountState, QWidget *parent) connect(_model, &QAbstractItemModel::rowsInserted, this, &ActivityWidget::rowsInserted); + connect(delegate, &ActivityItemDelegate::buttonClickedOnItemView, this, &ActivityWidget::slotButtonClickedOnListView); + connect(this, &ActivityWidget::sendNotificationRequest, this, &ActivityWidget::slotSendNotificationRequest); + connect(_ui->_activityList, &QListView::activated, this, &ActivityWidget::slotOpenFile); connect(&_removeTimer, &QTimer::timeout, this, &ActivityWidget::slotCheckToCleanWidgets); @@ -103,6 +106,49 @@ ActivityWidget::~ActivityWidget() delete _ui; } +void ActivityWidget::slotButtonClickedOnListView(const QModelIndex &index){ + QList customList = index.data(ActivityItemDelegate::ActionsLinksRole).toList(); + QList actionLinks; + foreach(QVariant customItem, customList){ + actionLinks << qvariant_cast(customItem); + } + + QMenu menu; + QUrl link = qvariant_cast(index.data(ActivityItemDelegate::LinkRole)); + if(!link.isEmpty()){ + QAction *menuAction = new QAction(tr("More Information"), &menu); + connect(menuAction, &QAction::triggered, this, [link] { QDesktopServices::openUrl(link); }); + menu.addAction(menuAction); + } + + foreach (ActivityLink actionLink, actionLinks) { + QAction *menuAction = new QAction(actionLink._label, &menu); + connect(menuAction, &QAction::triggered, this, [this, index, actionLink] { + qCInfo(lcActivity) << "Notification Link: " << actionLink._verb << actionLink._link; + emit this->sendNotificationRequest(qvariant_cast(index.data(ActivityItemDelegate::AccountRole)), actionLink._link, actionLink._verb); + }); + menu.addAction(menuAction); + } + + menu.exec(QCursor::pos()); +} + +void ActivityWidget::slotNotificationRequestFinished(int statusCode) +{ + int i = 0; + QString doneText; + QLocale locale; + + QString timeStr = locale.toString(QTime::currentTime()); + + // the ocs API returns stat code 100 or 200 inside the xml if it succeeded. + if (statusCode != OCS_SUCCESS_STATUS_CODE && statusCode != OCS_SUCCESS_STATUS_CODE_V2) { + qCWarning(lcActivity) << "Notification Request to Server failed, leave button visible."; + } else { + qCWarning(lcActivity) << "Notification Request to Server successed, leave button visible."; + } +} + void ActivityWidget::slotRefreshActivities() { _model->slotRefreshActivity(); diff --git a/src/gui/activitywidget.h b/src/gui/activitywidget.h index 56cf66957..9006b4832 100644 --- a/src/gui/activitywidget.h +++ b/src/gui/activitywidget.h @@ -86,6 +86,7 @@ signals: void rowsInserted(); void hideActivityTab(bool); void newNotification(); + void sendNotificationRequest(const QString &, const QString &link, const QByteArray &verb); private slots: void slotBuildNotificationDisplay(const ActivityList &list); @@ -95,6 +96,8 @@ private slots: void endNotificationRequest(NotificationWidget *widget, int replyCode); void scheduleWidgetToRemove(NotificationWidget *widget, int milliseconds = 100); void slotCheckToCleanWidgets(); + void slotNotificationRequestFinished(int statusCode); + void slotButtonClickedOnListView(const QModelIndex &index); private: void showLabels();