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 <hello@camila.codes>
This commit is contained in:
Camila San 2018-04-21 01:24:31 +02:00 committed by Roeland Jago Douma
parent 9ad01f0819
commit ef4a30fcb9
No known key found for this signature in database
GPG key ID: F941078878347C0C
4 changed files with 86 additions and 57 deletions

View file

@ -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,63 +137,23 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
messageTextBox.setWidth(0);
}
// Action buttons
int buttonsWidth = 0;
QList<QStyleOptionButton> buttons;
QStyleOptionButton optionsButton;
if(activityType == Activity::Type::NotificationType){
QList<QVariant> customList = index.data(ActionsLinksRole).toList();
QList<ActivityLink> actionLinks;
foreach(QVariant customItem, customList){
actionLinks << qvariant_cast<ActivityLink>(customItem);
}
QUrl link = qvariant_cast<QString>(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 === */
@ -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<Activity::Type>(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);
}

View file

@ -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

View file

@ -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<QVariant> customList = index.data(ActivityItemDelegate::ActionsLinksRole).toList();
QList<ActivityLink> actionLinks;
foreach(QVariant customItem, customList){
actionLinks << qvariant_cast<ActivityLink>(customItem);
}
QMenu menu;
QUrl link = qvariant_cast<QString>(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<QString>(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();

View file

@ -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();