Fixed behavior of locked items:

- locked items is not editable now.
- toolbar for text item hides when item is locked

Fixed behavior of toolbar:
toolbar of media items hides after 5s of idle.
preferencesAboutTextFull
Aleksei Kanash 13 years ago
parent a3a24b7465
commit 714e185564
  1. 106
      src/board/UBBoardView.cpp
  2. 4
      src/board/UBBoardView.h
  3. 8
      src/domain/UBGraphicsDelegateFrame.cpp
  4. 19
      src/domain/UBGraphicsItemDelegate.cpp
  5. 9
      src/domain/UBGraphicsItemDelegate.h
  6. 14
      src/domain/UBGraphicsMediaItem.cpp
  7. 4
      src/domain/UBGraphicsMediaItem.h
  8. 28
      src/domain/UBGraphicsMediaItemDelegate.cpp
  9. 6
      src/domain/UBGraphicsMediaItemDelegate.h
  10. 11
      src/domain/UBGraphicsTextItemDelegate.cpp

@ -375,6 +375,45 @@ void UBBoardView::tabletEvent (QTabletEvent * event)
} }
bool UBBoardView::hasToolBarAsParent(QGraphicsItem *item)
{
if (!item)
return false;
if (!item->parentItem())
return hasToolBarAsParent(0);
if (UBGraphicsToolBarItem::Type == item->parentItem()->type())
return true;
else
return hasToolBarAsParent(item->parentItem());
}
bool UBBoardView::itemIsLocked(QGraphicsItem *item)
{
if (!item)
return false;
if (item->data(UBGraphicsItemData::ItemLocked).toBool())
return true;
return itemIsLocked(item->parentItem());
}
bool UBBoardView::itemHaveType(QGraphicsItem *item, int type)
{
if (!item)
return false;
if (type == item->type())
return true;
return itemHaveType(item->parentItem(), type);
}
void UBBoardView::mousePressEvent (QMouseEvent *event) void UBBoardView::mousePressEvent (QMouseEvent *event)
{ {
if (isAbsurdPoint (event->pos ())) if (isAbsurdPoint (event->pos ()))
@ -438,10 +477,14 @@ void UBBoardView::mousePressEvent (QMouseEvent *event)
|| movingItem == this->scene()->backgroundObject() || movingItem == this->scene()->backgroundObject()
|| (movingItem->parentItem() && movingItem->parentItem()->type() == UBGraphicsGroupContainerItem::Type)) || (movingItem->parentItem() && movingItem->parentItem()->type() == UBGraphicsGroupContainerItem::Type))
{ {
movingItem = NULL; if (!itemIsLocked(movingItem)
QGraphicsView::mousePressEvent (event); || itemHaveType(movingItem, UBGraphicsMediaItem::Type))
{
QGraphicsView::mousePressEvent (event);
} }
movingItem = NULL;
}
else else
{ {
mLastPressedMousePos = mapToScene(event->pos()); mLastPressedMousePos = mapToScene(event->pos());
@ -452,12 +495,29 @@ void UBBoardView::mousePressEvent (QMouseEvent *event)
suspendedMousePressEvent = new QMouseEvent(event->type(), event->pos(), event->button(), event->buttons(), event->modifiers()); // удалить suspendedMousePressEvent = new QMouseEvent(event->type(), event->pos(), event->button(), event->buttons(), event->modifiers()); // удалить
} }
event->accept(); event->accept();
} }
else if (currentTool == UBStylusTool::Play) else if (currentTool == UBStylusTool::Play)
{ {
QGraphicsView::mousePressEvent (event);
movingItem = scene()->itemAt(this->mapToScene(event->posF().toPoint()));
mLastPressedMousePos = mapToScene(event->pos());
if (movingItem
&& (UBGraphicsGroupContainerItem::Type == movingItem->type()
|| UBGraphicsMediaItem::Type == movingItem->type()
|| hasToolBarAsParent(movingItem)))
{
movingItem = NULL;
QGraphicsView::mousePressEvent (event);
return;
}
if(movingItem && movingItem->parentItem() && movingItem->parentItem()->type() == UBGraphicsGroupContainerItem::Type)
{
movingItem = movingItem->parentItem();
}
event->accept(); event->accept();
} }
@ -579,7 +639,8 @@ UBBoardView::mouseMoveEvent (QMouseEvent *event)
} }
} }
if (movingItem && (mMouseButtonIsPressed || mTabletStylusIsPressed)) if (movingItem && (mMouseButtonIsPressed || mTabletStylusIsPressed) &&
!movingItem->data(UBGraphicsItemData::ItemLocked).toBool())
{ {
QPointF scenePos = mapToScene(event->pos()); QPointF scenePos = mapToScene(event->pos());
QPointF newPos = movingItem->pos() + scenePos - mLastPressedMousePos; QPointF newPos = movingItem->pos() + scenePos - mLastPressedMousePos;
@ -592,7 +653,18 @@ UBBoardView::mouseMoveEvent (QMouseEvent *event)
} }
else if (currentTool == UBStylusTool::Play) else if (currentTool == UBStylusTool::Play)
{ {
QGraphicsView::mouseMoveEvent (event); if (movingItem && (mMouseButtonIsPressed || mTabletStylusIsPressed) &&
!movingItem->data(UBGraphicsItemData::ItemLocked).toBool())
{
QPointF scenePos = mapToScene(event->pos());
QPointF newPos = movingItem->pos() + scenePos - mLastPressedMousePos;
movingItem->setPos(newPos);
mLastPressedMousePos = scenePos;
mWidgetMoved = true;
event->accept();
}
else
QGraphicsView::mouseMoveEvent (event);
} }
else if ((UBDrawingController::drawingController()->isDrawingTool()) else if ((UBDrawingController::drawingController()->isDrawingTool())
&& !mMouseButtonIsPressed) && !mMouseButtonIsPressed)
@ -638,13 +710,21 @@ UBBoardView::mouseReleaseEvent (QMouseEvent *event)
mWidgetMoved = false; mWidgetMoved = false;
movingItem = NULL; movingItem = NULL;
} }
else if (movingItem && suspendedMousePressEvent) else
{ if (movingItem)
QGraphicsView::mousePressEvent(suspendedMousePressEvent); // suspendedMousePressEvent is deleted by old Qt event loop {
movingItem = NULL; if (suspendedMousePressEvent && !movingItem->data(UBGraphicsItemData::ItemLocked).toBool())
delete suspendedMousePressEvent; {
suspendedMousePressEvent = NULL; QGraphicsView::mousePressEvent(suspendedMousePressEvent); // suspendedMousePressEvent is deleted by old Qt event loop
} movingItem = NULL;
delete suspendedMousePressEvent;
suspendedMousePressEvent = NULL;
}
else
{
movingItem->setSelected(true);
}
}
if (mUBRubberBand && mUBRubberBand->isVisible()) { if (mUBRubberBand && mUBRubberBand->isVisible()) {
mUBRubberBand->hide(); mUBRubberBand->hide();

@ -51,6 +51,10 @@ class UBBoardView : public QGraphicsView
protected: protected:
bool hasToolBarAsParent(QGraphicsItem *item);
bool itemIsLocked(QGraphicsItem *item);
bool itemHaveType(QGraphicsItem *item, int type);
virtual bool event (QEvent * e); virtual bool event (QEvent * e);
virtual void keyPressEvent(QKeyEvent *event); virtual void keyPressEvent(QKeyEvent *event);

@ -249,8 +249,8 @@ bool UBGraphicsDelegateFrame::canResizeBottomRight(qreal width, qreal height, qr
void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ {
if (mDelegate->delegated()->data(UBGraphicsItemData::ItemLocked).toBool()) if (None == mCurrentTool)
return; return;
QLineF move(mStartingPoint, event->scenePos()); QLineF move(mStartingPoint, event->scenePos());
qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180);
@ -713,8 +713,8 @@ QGraphicsItem* UBGraphicsDelegateFrame::delegated()
UBGraphicsDelegateFrame::FrameTool UBGraphicsDelegateFrame::toolFromPos(QPointF pos) UBGraphicsDelegateFrame::FrameTool UBGraphicsDelegateFrame::toolFromPos(QPointF pos)
{ {
if(mDelegate->isLocked()) if(mDelegate->isLocked())
return None; return None;
else if (bottomRightResizeGripRect().contains(pos)) else if (bottomRightResizeGripRect().contains(pos))
return ResizeBottomRight; return ResizeBottomRight;
else if (bottomResizeGripRect().contains(pos)){ else if (bottomResizeGripRect().contains(pos)){

@ -328,7 +328,7 @@ void UBGraphicsItemDelegate::positionHandles()
if (mDelegated->isSelected()) { if (mDelegated->isSelected()) {
bool shownOnDisplay = mDelegated->data(UBGraphicsItemData::ItemLayerType).toInt() != UBItemLayerType::Control; bool shownOnDisplay = mDelegated->data(UBGraphicsItemData::ItemLayerType).toInt() != UBItemLayerType::Control;
showHide(shownOnDisplay); showHide(shownOnDisplay);
lock(isLocked()); mDelegated->setData(UBGraphicsItemData::ItemLocked, QVariant(isLocked()));
updateFrame(); updateFrame();
if (UBStylusTool::Play != UBDrawingController::drawingController()->stylusTool()) if (UBStylusTool::Play != UBDrawingController::drawingController()->stylusTool())
@ -453,6 +453,7 @@ void UBGraphicsItemDelegate::lock(bool locked)
} }
mDelegated->update(); mDelegated->update();
positionHandles();
mFrame->positionHandles(); mFrame->positionHandles();
} }
@ -678,7 +679,7 @@ UBGraphicsToolBarItem::UBGraphicsToolBarItem(QGraphicsItem * parent) :
rect.setWidth(parent->boundingRect().width()); rect.setWidth(parent->boundingRect().width());
this->setRect(rect); this->setRect(rect);
setBrush(QColor(UBSettings::paletteColor)); // setBrush(QColor(UBSettings::paletteColor));
setPen(Qt::NoPen); setPen(Qt::NoPen);
hide(); hide();
@ -710,6 +711,17 @@ void UBGraphicsToolBarItem::paint(QPainter *painter, const QStyleOptionGraphicsI
QPainterPath path; QPainterPath path;
path.addRoundedRect(rect(), 10, 10); path.addRoundedRect(rect(), 10, 10);
if (parentItem() && parentItem()->data(UBGraphicsItemData::ItemLocked).toBool())
{
QColor baseColor = UBSettings::paletteColor;
baseColor.setAlphaF(baseColor.alphaF() / 3);
setBrush(QBrush(baseColor));
}
else
{
setBrush(QBrush(UBSettings::paletteColor));
}
painter->fillPath(path, brush()); painter->fillPath(path, brush());
} }
@ -1217,6 +1229,7 @@ void DelegateMediaControl::mousePressEvent(QGraphicsSceneMouseEvent *event)
seekToMousePos(event->pos()); seekToMousePos(event->pos());
this->update(); this->update();
event->accept(); event->accept();
emit used();
} }
} }
@ -1229,6 +1242,7 @@ void DelegateMediaControl::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
seekToMousePos(event->pos()); seekToMousePos(event->pos());
this->update(); this->update();
event->accept(); event->accept();
emit used();
} }
} }
@ -1253,6 +1267,7 @@ void DelegateMediaControl::seekToMousePos(QPointF mousePos)
//OSX is a bit lazy //OSX is a bit lazy
updateTicker(tickPos); updateTicker(tickPos);
} }
emit used();
} }
void DelegateMediaControl::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void DelegateMediaControl::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)

@ -102,8 +102,10 @@ uint smallPoint : 1;
}; };
class DelegateMediaControl: public QGraphicsRectItem class DelegateMediaControl: public QObject, public QGraphicsRectItem
{ {
Q_OBJECT
public: public:
DelegateMediaControl(UBGraphicsMediaItem* pDelegated, QGraphicsItem * parent = 0); DelegateMediaControl(UBGraphicsMediaItem* pDelegated, QGraphicsItem * parent = 0);
@ -127,7 +129,10 @@ class DelegateMediaControl: public QGraphicsRectItem
void updateTicker(qint64 time); void updateTicker(qint64 time);
void totalTimeChanged(qint64 newTotalTime); void totalTimeChanged(qint64 newTotalTime);
protected: signals:
void used();
protected:
void seekToMousePos(QPointF mousePos); void seekToMousePos(QPointF mousePos);
UBGraphicsMediaItem* mDelegate; UBGraphicsMediaItem* mDelegate;

@ -34,8 +34,8 @@ UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsIte
, mInitialPos(0) , mInitialPos(0)
, mVideoWidget(NULL) , mVideoWidget(NULL)
, mAudioWidget(NULL) , mAudioWidget(NULL)
, mLinkedImage(NULL)
{ {
update(); update();
QString s = pMediaFileUrl.toLocalFile(); QString s = pMediaFileUrl.toLocalFile();
@ -60,6 +60,7 @@ UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsIte
mVideoWidget->resize(320,240); mVideoWidget->resize(320,240);
} }
setWidget(mVideoWidget); setWidget(mVideoWidget);
haveLinkedImage = true;
} }
else else
if (pMediaFileUrl.toLocalFile().contains("audios")) if (pMediaFileUrl.toLocalFile().contains("audios"))
@ -71,6 +72,7 @@ UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsIte
mAudioWidget = new QWidget(); mAudioWidget = new QWidget();
mAudioWidget->resize(320,26); mAudioWidget->resize(320,26);
setWidget(mAudioWidget); setWidget(mAudioWidget);
haveLinkedImage = false;
} }
Phonon::createPath(mMediaObject, mAudioOutput); Phonon::createPath(mMediaObject, mAudioOutput);
@ -226,7 +228,7 @@ void UBGraphicsMediaItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (mDelegate) if (mDelegate)
{ {
mDelegate->mousePressEvent(event); mDelegate->mousePressEvent(event);
if (mDelegate && parentItem() && UBGraphicsGroupContainerItem::Type == parentItem()->type()) if (parentItem() && UBGraphicsGroupContainerItem::Type == parentItem()->type())
{ {
UBGraphicsGroupContainerItem *group = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(parentItem()); UBGraphicsGroupContainerItem *group = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(parentItem());
if (group) if (group)
@ -242,11 +244,6 @@ void UBGraphicsMediaItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
} }
} }
else
{
mDelegate->getToolBarItem()->show();
}
} }
if (parentItem() && parentItem()->type() == UBGraphicsGroupContainerItem::Type) if (parentItem() && parentItem()->type() == UBGraphicsGroupContainerItem::Type)
@ -271,9 +268,6 @@ void UBGraphicsMediaItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
void UBGraphicsMediaItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void UBGraphicsMediaItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ {
if (data(UBGraphicsItemData::ItemLocked).toBool())
return;
if(mShouldMove && (event->buttons() & Qt::LeftButton)) if(mShouldMove && (event->buttons() & Qt::LeftButton))
{ {
QPointF offset = event->scenePos() - mMousePressPos; QPointF offset = event->scenePos() - mMousePressPos;

@ -73,6 +73,8 @@ public:
return mVideoWidget; return mVideoWidget;
} }
bool hasLinkedImage(){return haveLinkedImage;}
mediaType getMediaType() { return mMediaType; } mediaType getMediaType() { return mMediaType; }
virtual UBGraphicsScene* scene(); virtual UBGraphicsScene* scene();
@ -115,6 +117,8 @@ private:
QPointF mMousePressPos; QPointF mMousePressPos;
QPointF mMouseMovePos; QPointF mMouseMovePos;
bool haveLinkedImage;
QGraphicsPixmapItem *mLinkedImage;
}; };

@ -33,6 +33,8 @@
UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, Phonon::MediaObject* pMedia, QObject * parent) UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, Phonon::MediaObject* pMedia, QObject * parent)
: UBGraphicsItemDelegate(pDelegated, parent, true, false) : UBGraphicsItemDelegate(pDelegated, parent, true, false)
, mMedia(pMedia) , mMedia(pMedia)
, mToolBarShowTimer(NULL)
, m_iToolBarShowingInterval(5000)
{ {
QPalette palette; QPalette palette;
palette.setBrush ( QPalette::Light, Qt::darkGray ); palette.setBrush ( QPalette::Light, Qt::darkGray );
@ -42,27 +44,47 @@ UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pD
connect(mMedia, SIGNAL(finished()), this, SLOT(updatePlayPauseState())); connect(mMedia, SIGNAL(finished()), this, SLOT(updatePlayPauseState()));
connect(mMedia, SIGNAL(tick(qint64)), this, SLOT(updateTicker(qint64))); connect(mMedia, SIGNAL(tick(qint64)), this, SLOT(updateTicker(qint64)));
connect(mMedia, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64))); connect(mMedia, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
if (delegated()->hasLinkedImage())
{
mToolBarShowTimer = new QTimer();
connect(mToolBarShowTimer, SIGNAL(timeout()), this, SLOT(hideToolBar()));
mToolBarShowTimer->setInterval(m_iToolBarShowingInterval);
}
} }
bool UBGraphicsMediaItemDelegate::mousePressEvent(QGraphicsSceneMouseEvent *event) bool UBGraphicsMediaItemDelegate::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
mToolBarItem->show(); mToolBarItem->show();
if (mToolBarShowTimer)
mToolBarShowTimer->start();
return UBGraphicsItemDelegate::mousePressEvent(event); return UBGraphicsItemDelegate::mousePressEvent(event);
} }
void UBGraphicsMediaItemDelegate::hideToolBar()
{
mToolBarItem->hide();
}
void UBGraphicsMediaItemDelegate::buildButtons() void UBGraphicsMediaItemDelegate::buildButtons()
{ {
mPlayPauseButton = new DelegateButton(":/images/play.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); mPlayPauseButton = new DelegateButton(":/images/play.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
connect(mPlayPauseButton, SIGNAL(clicked(bool)), this, SLOT(togglePlayPause())); connect(mPlayPauseButton, SIGNAL(clicked(bool)), this, SLOT(togglePlayPause()));
connect(mPlayPauseButton, SIGNAL(clicked(bool)), mToolBarShowTimer, SLOT(start()));
mStopButton = new DelegateButton(":/images/stop.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); mStopButton = new DelegateButton(":/images/stop.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
connect(mStopButton, SIGNAL(clicked(bool)), mMedia, SLOT(stop())); connect(mStopButton, SIGNAL(clicked(bool)), mMedia, SLOT(stop()));
connect(mStopButton, SIGNAL(clicked(bool)), mToolBarShowTimer, SLOT(start()));
mMediaControl = new DelegateMediaControl(delegated(), mToolBarItem); mMediaControl = new DelegateMediaControl(delegated(), mToolBarItem);
mMediaControl->setFlag(QGraphicsItem::ItemIsSelectable, true); mMediaControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
UBGraphicsItem::assignZValue(mMediaControl, delegated()->zValue()); UBGraphicsItem::assignZValue(mMediaControl, delegated()->zValue());
connect(mMediaControl, SIGNAL(used()), mToolBarShowTimer, SLOT(start()));
if (delegated()->isMuted()) if (delegated()->isMuted())
mMuteButton = new DelegateButton(":/images/soundOff.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); mMuteButton = new DelegateButton(":/images/soundOff.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
else else
@ -70,6 +92,7 @@ void UBGraphicsMediaItemDelegate::buildButtons()
connect(mMuteButton, SIGNAL(clicked(bool)), delegated(), SLOT(toggleMute())); connect(mMuteButton, SIGNAL(clicked(bool)), delegated(), SLOT(toggleMute()));
connect(mMuteButton, SIGNAL(clicked(bool)), this, SLOT(toggleMute())); // for changing button image connect(mMuteButton, SIGNAL(clicked(bool)), this, SLOT(toggleMute())); // for changing button image
connect(mMuteButton, SIGNAL(clicked(bool)), mToolBarShowTimer, SLOT(start()));
mButtons << mPlayPauseButton << mStopButton << mMuteButton; mButtons << mPlayPauseButton << mStopButton << mMuteButton;
@ -89,7 +112,8 @@ void UBGraphicsMediaItemDelegate::buildButtons()
UBGraphicsMediaItemDelegate::~UBGraphicsMediaItemDelegate() UBGraphicsMediaItemDelegate::~UBGraphicsMediaItemDelegate()
{ {
//NOOP if (mToolBarShowTimer)
delete mToolBarShowTimer;
} }
void UBGraphicsMediaItemDelegate::positionHandles() void UBGraphicsMediaItemDelegate::positionHandles()

@ -18,6 +18,7 @@
#include <QtGui> #include <QtGui>
#include <phonon/MediaObject> #include <phonon/MediaObject>
#include <QTimer>
#include "core/UB.h" #include "core/UB.h"
#include "UBGraphicsItemDelegate.h" #include "UBGraphicsItemDelegate.h"
@ -54,6 +55,8 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate
void totalTimeChanged(qint64 newTotalTime); void totalTimeChanged(qint64 newTotalTime);
void hideToolBar();
protected: protected:
virtual void buildButtons(); virtual void buildButtons();
@ -65,6 +68,9 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate
DelegateMediaControl *mMediaControl; DelegateMediaControl *mMediaControl;
Phonon::MediaObject* mMedia; Phonon::MediaObject* mMedia;
QTimer *mToolBarShowTimer;
int m_iToolBarShowingInterval;
}; };
#endif /* UBGRAPHICSMEDIAITEMDELEGATE_H_ */ #endif /* UBGRAPHICSMEDIAITEMDELEGATE_H_ */

@ -303,11 +303,14 @@ void UBGraphicsTextItemDelegate::positionHandles()
UBGraphicsGroupContainerItem *group = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(mDelegated->parentItem()); UBGraphicsGroupContainerItem *group = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(mDelegated->parentItem());
mToolBarItem->hide(); mToolBarItem->hide();
if (group && group->getCurrentItem() == mDelegated && group->isSelected()) if (mToolBarItem->parentItem() && !mToolBarItem->parentItem()->data(UBGraphicsItemData::ItemLocked).toBool())
mToolBarItem->show(); {
if (group && group->getCurrentItem() == mDelegated && group->isSelected())
mToolBarItem->show();
if (!group) if (!group)
mToolBarItem->show(); mToolBarItem->show();
}
} }
} }

Loading…
Cancel
Save