mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 13:35:58 +03:00
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:
parent
9ad01f0819
commit
ef4a30fcb9
4 changed files with 86 additions and 57 deletions
|
@ -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<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 === */
|
||||
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<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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue