новые иконки в OpenBoard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
OpenBoard/src/gui/UBThumbnailWidget.cpp

925 lines
31 KiB

/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QString>
#include <QCursor>
#include "UBThumbnailWidget.h"
#include "UBRubberBand.h"
#include "board/UBBoardController.h"
#include "core/UBSettings.h"
#include "core/UBApplication.h"
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
#include "core/memcheck.h"
UBThumbnailWidget::UBThumbnailWidget(QWidget* parent)
: QGraphicsView(parent)
, mThumbnailWidth(UBSettings::defaultThumbnailWidth)
, mSpacing(UBSettings::thumbnailSpacing)
, mLastSelectedThumbnail(0)
, mSelectionSpan(0)
, mPrevLassoRect(QRect())
, mLassoRectItem(0)
{
// By default, the drag is possible
bCanDrag = true;
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
setFrameShape(QFrame::NoFrame);
setScene(&mThumbnailsScene);
setAlignment(Qt::AlignLeft | Qt::AlignTop);
connect(&mThumbnailsScene, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged()));
}
UBThumbnailWidget::~UBThumbnailWidget()
{
disconnect(&mThumbnailsScene, SIGNAL(selectionChanged()));
}
void UBThumbnailWidget::setThumbnailWidth(qreal pThumbnailWidth)
{
mThumbnailWidth = pThumbnailWidth;
refreshScene();
}
void UBThumbnailWidget::setSpacing(qreal pSpacing)
{
mSpacing = pSpacing;
refreshScene();
}
void UBThumbnailWidget::setGraphicsItems(const QList<QGraphicsItem*>& pGraphicsItems
, const QList<QUrl>& pItemsPaths
, const QStringList pLabels
, const QString& pMimeType)
{
mGraphicItems = pGraphicsItems;
mItemsPaths = pItemsPaths;
mMimeType = pMimeType;
mLabels = pLabels;
foreach(QGraphicsItem* it, mThumbnailsScene.items())
{
mThumbnailsScene.removeItem(it, true);
}
// set lasso to 0 as it has been cleared as well
mLassoRectItem = 0;
foreach (QGraphicsItem* item, pGraphicsItems)
{
if (item->scene() != &mThumbnailsScene)
{
mThumbnailsScene.addItem(item);
}
}
mLabelsItems.clear();
foreach (const QString label, pLabels)
{
QFontMetrics fm(font());
UBThumbnailTextItem *labelItem =
new UBThumbnailTextItem(label); // deleted while replace or by the scene destruction
mThumbnailsScene.addItem(labelItem);
mLabelsItems << labelItem;
}
refreshScene();
mLastSelectedThumbnail = 0;
}
void UBThumbnailWidget::refreshScene()
{
int nbColumns = (geometry().width() - mSpacing) / (mThumbnailWidth + mSpacing);
int labelSpacing = 0;
if (mLabelsItems.size() > 0)
{
QFontMetrics fm(mLabelsItems.at(0)->font());
labelSpacing = UBSettings::thumbnailSpacing + fm.height(); // TODO UB 4.x where is 20 from ??? configure ?? compute based on mSpacing ?? JBA Is it the font height?
}
nbColumns = qMax(nbColumns, 1);
qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio;
for (int i = 0; i < mGraphicItems.size(); i++)
{
QGraphicsItem* item = mGraphicItems.at(i);
qreal scaleWidth = mThumbnailWidth / item->boundingRect().width();
qreal scaleHeight = thumbnailHeight / item->boundingRect().height();
qreal scaleFactor = qMin(scaleWidth, scaleHeight);
//bitmap should not be stretched
UBThumbnail* pix = dynamic_cast<UBThumbnail*>(item);
if (pix)
scaleFactor = qMin(scaleFactor, 1.0);
QTransform transform;
transform.scale(scaleFactor, scaleFactor);
item->setTransform(transform);
item->setFlag(QGraphicsItem::ItemIsSelectable, true);
int columnIndex = i % nbColumns;
int rowIndex = i / nbColumns;
if (pix)
{
pix->setColumn(columnIndex);
pix->setRow(rowIndex);
}
int w = item->boundingRect().width();
int h = item->boundingRect().height();
QPointF pos(
mSpacing + (mThumbnailWidth - w * scaleFactor) / 2 + columnIndex * (mThumbnailWidth + mSpacing),
mSpacing + rowIndex * (thumbnailHeight + mSpacing + labelSpacing) + (thumbnailHeight - h * scaleFactor) / 2);
item->setPos(pos);
if (mLabelsItems.size() > i)
{
QFontMetrics fm(mLabelsItems.at(i)->font(), this);
QString elidedText = fm.elidedText(mLabels.at(i), Qt::ElideRight, mThumbnailWidth);
mLabelsItems.at(i)->setPlainText(elidedText);
mLabelsItems.at(i)->setWidth(fm.width(elidedText) + 2 * mLabelsItems.at(i)->document()->documentMargin());
pos.setY(pos.y() + (thumbnailHeight + h * scaleFactor) / 2 + 5);
qreal labelWidth = fm.width(elidedText);
pos.setX(mSpacing + (mThumbnailWidth - labelWidth) / 2 + columnIndex * (mThumbnailWidth + mSpacing));
mLabelsItems.at(i)->setPos(pos);
}
}
QScrollBar *vertScrollBar = verticalScrollBar();
int scrollBarThickness = 0;
if (vertScrollBar && vertScrollBar->isVisible())
scrollBarThickness = vertScrollBar->width();
setSceneRect(0, 0,
geometry().width() - scrollBarThickness,
mSpacing + ((((mGraphicItems.size() - 1) / nbColumns) + 1) * (thumbnailHeight + mSpacing + labelSpacing)));
}
QList<QGraphicsItem*> UBThumbnailWidget::selectedItems()
{
QList<QGraphicsItem*> sortedSelectedItems = mThumbnailsScene.selectedItems();
qSort(sortedSelectedItems.begin(), sortedSelectedItems.end(), thumbnailLessThan);
return sortedSelectedItems;
}
void UBThumbnailWidget::mousePressEvent(QMouseEvent *event)
{
mClickTime = QTime::currentTime();
mMousePressPos = event->pos();
UBSceneThumbnailPixmap* sceneItem = dynamic_cast<UBSceneThumbnailPixmap*>(itemAt(mMousePressPos));
if(sceneItem){
int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex());
if(pageIndex == 0){
event->ignore();
return;
}
}
mMousePressScenePos = mapToScene(mMousePressPos);
QGraphicsItem* underlyingItem = itemAt(mMousePressPos);
UBThumbnail *previousSelectedThumbnail = mLastSelectedThumbnail;
if (!dynamic_cast<UBThumbnail*>(underlyingItem))
{
deleteLasso();
UBRubberBand rubberBand(QRubberBand::Rectangle);
QStyleOption option;
option.initFrom(&rubberBand);
mPrevLassoRect = QRect();
mLassoRectItem = new QGraphicsRectItem(0, scene());
#ifdef Q_WS_MAC
// The following code must stay in synch with <Qt installation folder>\src\gui\styles\qmacstyle_mac.mm
QColor strokeColor;
strokeColor.setHsvF(0, 0, 0.86, 1.0);
mLassoRectItem->setPen(QPen(strokeColor));
QColor fillColor(option.palette.color(QPalette::Disabled, QPalette::Highlight));
fillColor.setHsvF(0, 0, 0.53, 0.25);
mLassoRectItem->setBrush(fillColor);
#else
// The following code must stay in synch with <Qt installation folder>\src\gui\styles\qwindowsxpstyle.cpp
QColor highlight = option.palette.color(QPalette::Active, QPalette::Highlight);
mLassoRectItem->setPen(highlight.darker(120));
QColor dimHighlight(qMin(highlight.red() / 2 + 110, 255),
qMin(highlight.green() / 2 + 110, 255),
qMin(highlight.blue() / 2 + 110, 255),
127);
mLassoRectItem->setBrush(dimHighlight);
#endif
mLassoRectItem->setZValue(10000);
mLassoRectItem->setRect(QRectF(mMousePressScenePos, QSizeF()));
if (Qt::ControlModifier & event->modifiers() || Qt::ShiftModifier & event->modifiers())
{
// mSelectedThumbnailItems = selectedItems().toSet();
return;
}
mSelectedThumbnailItems.clear();
mPreviouslyIncrementalSelectedItemsX.clear();
mPreviouslyIncrementalSelectedItemsY.clear();
QGraphicsView::mousePressEvent(event);
}
else if (Qt::ShiftModifier & event->modifiers())
{
if (previousSelectedThumbnail)
{
QGraphicsItem* previousSelectedItem = dynamic_cast<QGraphicsItem*>(previousSelectedThumbnail);
if (previousSelectedItem)
{
int index1 = mGraphicItems.indexOf(previousSelectedItem);
int index2 = mGraphicItems.indexOf(underlyingItem);
if (-1 == index2)
{
mSelectedThumbnailItems = selectedItems().toSet();
return;
}
mSelectionSpan = index2 - index1;
selectItems(qMin(index1, index2), mSelectionSpan < 0 ? - mSelectionSpan + 1 : mSelectionSpan + 1);
return;
}
}
}
else
{
mLastSelectedThumbnail = dynamic_cast<UBThumbnail*>(underlyingItem);
if (!underlyingItem->isSelected())
{
int index = mGraphicItems.indexOf(underlyingItem);
selectItemAt(index, Qt::ControlModifier & event->modifiers());
}
else
{
QGraphicsView::mousePressEvent(event);
}
if (!mLastSelectedThumbnail && mGraphicItems.count() > 0)
mLastSelectedThumbnail = dynamic_cast<UBThumbnail*>(mGraphicItems.at(0));
mSelectionSpan = 0;
return;
}
}
void UBThumbnailWidget::mouseMoveEvent(QMouseEvent *event)
{
int distance = (mMousePressPos - event->pos()).manhattanLength();
if (0 == (event->buttons() & Qt::LeftButton) || distance < QApplication::startDragDistance())
return;
if (mLassoRectItem)
{
bSelectionInProgress = true;
int incrementLassoMinWidth = 2;
QPointF currentScenePos = mapToScene(event->pos());
QRectF lassoRect(
qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()),
qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(mMousePressScenePos.y() - currentScenePos.y()));
if (QPoint() == prevMoveMousePos)
prevMoveMousePos = currentScenePos;
QRectF incrementXSelection(
qMin(prevMoveMousePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()),
qAbs(prevMoveMousePos.x() - currentScenePos.x())+incrementLassoMinWidth, qAbs(mMousePressScenePos.y() - currentScenePos.y()));
QRectF incrementYSelection(
qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(prevMoveMousePos.y(), currentScenePos.y()),
qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(prevMoveMousePos.y() - currentScenePos.y())+incrementLassoMinWidth);
prevMoveMousePos = currentScenePos;
mLassoRectItem->setRect(lassoRect);
QSet<QGraphicsItem*> lassoSelectedThumbnailItems;
QSet<QGraphicsItem*> toUnset;
QSet<QGraphicsItem*> toSet;
// for horizontal moving
QSet<QGraphicsItem*> incSelectedItemsX = scene()->items(incrementXSelection, Qt::IntersectsItemBoundingRect).toSet();
foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsX)
{
if (lassoSelectedItem)
{
UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast<UBSceneThumbnailPixmap*>(lassoSelectedItem);
if (thumbnailItem)
lassoSelectedThumbnailItems += lassoSelectedItem;
}
}
if(lassoRect.width() < mPrevLassoRect.width())
{
if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsX))
toUnset += mPreviouslyIncrementalSelectedItemsX - lassoSelectedThumbnailItems;
}
mPreviouslyIncrementalSelectedItemsX = lassoSelectedThumbnailItems;
toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsX;
lassoSelectedThumbnailItems.clear();
// for vertical moving
QSet<QGraphicsItem*> incSelectedItemsY = scene()->items(incrementYSelection, Qt::IntersectsItemBoundingRect).toSet();
foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsY)
{
if (lassoSelectedItem)
{
UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast<UBSceneThumbnailPixmap*>(lassoSelectedItem);
if (thumbnailItem)
lassoSelectedThumbnailItems += lassoSelectedItem;
}
}
if(lassoRect.height() < mPrevLassoRect.height())
{
if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsY))
toUnset += mPreviouslyIncrementalSelectedItemsY - lassoSelectedThumbnailItems;
}
mPreviouslyIncrementalSelectedItemsY = lassoSelectedThumbnailItems;
toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsY;
toSet -= toUnset;
foreach (QGraphicsItem *item, toSet)
{
item->setSelected(true);
}
foreach (QGraphicsItem *item, toUnset)
{
item->setSelected(false);
}
mSelectedThumbnailItems += lassoSelectedThumbnailItems;
mPrevLassoRect = lassoRect;
if (Qt::ControlModifier & event->modifiers())
{
for (int i = 0; i < mSelectedThumbnailItems.count()-1; i++)
{
mSelectedThumbnailItems.values().at(i)->setSelected(true);
}
}
}
else
{
bSelectionInProgress = false;
if (0 == selectedItems().size())
return;
if(bCanDrag)
{
QDrag *drag = new QDrag(this);
QMimeData *mime = new QMimeData();
if (mMimeType.length() > 0)
mime->setData(mMimeType, QByteArray()); // trick the d&d system to register our own mime type
drag->setMimeData(mime);
QList<QUrl> qlElements;
foreach (QGraphicsItem* item, selectedItems())
{
if (mGraphicItems.contains(item))
{
if (mGraphicItems.indexOf(item) <= mItemsPaths.size()){
qlElements << mItemsPaths.at(mGraphicItems.indexOf(item));
}
}
}
if (qlElements.size() > 0){
mime->setUrls(qlElements);
drag->setMimeData(mime);
drag->exec(Qt::CopyAction);
}
}
}
QGraphicsView::mouseMoveEvent(event);
}
void UBThumbnailWidget::mouseReleaseEvent(QMouseEvent *event)
{
int elapsedTimeSincePress = mClickTime.elapsed();
prevMoveMousePos = QPoint();
deleteLasso();
QGraphicsView::mouseReleaseEvent(event);
if(elapsedTimeSincePress < STARTDRAGTIME) {
emit mouseClick(itemAt(event->pos()), 0);
}
}
void UBThumbnailWidget::keyPressEvent(QKeyEvent *event)
{
if (mLastSelectedThumbnail)
{
QGraphicsItem *lastSelectedGraphicsItem = dynamic_cast<QGraphicsItem*>(mLastSelectedThumbnail);
if (!lastSelectedGraphicsItem) return;
int startSelectionIndex = mGraphicItems.indexOf(lastSelectedGraphicsItem);
int previousSelectedThumbnailIndex = startSelectionIndex + mSelectionSpan;
switch (event->key())
{
case Qt::Key_Down:
case Qt::Key_Up:
{
if (rowCount() <= 1) break;
if (Qt::ShiftModifier & event->modifiers())
{
int endSelectionIndex;
if (Qt::Key_Down == event->key())
{
endSelectionIndex = previousSelectedThumbnailIndex + columnCount();
if (endSelectionIndex >= mGraphicItems.count()) break;
}
else
{
endSelectionIndex = previousSelectedThumbnailIndex - columnCount();
if (endSelectionIndex < 0) break;
}
int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex;
int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1;
mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1);
selectItems(startIndex, count);
}
else
{
int toSelectIndex;
if (Qt::Key_Down == event->key())
{
toSelectIndex = previousSelectedThumbnailIndex + columnCount();
if (toSelectIndex >= mGraphicItems.count()) break;
}
else
{
toSelectIndex = previousSelectedThumbnailIndex - columnCount();
if (toSelectIndex < 0) break;
}
selectItemAt(toSelectIndex, Qt::ControlModifier & event->modifiers());
mSelectionSpan = 0;
}
}
break;
case Qt::Key_Left:
case Qt::Key_Right:
{
QGraphicsItem *previousSelectedItem = mGraphicItems.at(previousSelectedThumbnailIndex);
UBThumbnail *previousSelectedThumbnail = dynamic_cast<UBThumbnail*>(previousSelectedItem);
if (!previousSelectedThumbnail) break;
if (Qt::Key_Left == event->key())
{
if (0 == previousSelectedThumbnail->column()) break;
}
else
{
if (previousSelectedThumbnail->column() == columnCount() - 1 ||
previousSelectedThumbnailIndex == mGraphicItems.count() - 1) break;
}
if (Qt::ShiftModifier & event->modifiers())
{
int endSelectionIndex;
if (Qt::Key_Left == event->key())
{
endSelectionIndex = previousSelectedThumbnailIndex - 1;
if (endSelectionIndex < 0) break;
}
else
{
endSelectionIndex = previousSelectedThumbnailIndex + 1;
if (endSelectionIndex >= mGraphicItems.count()) break;
}
int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex;
int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1;
mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1);
selectItems(startIndex, count);
}
else
{
if (Qt::Key_Left == event->key())
selectItemAt(previousSelectedThumbnailIndex - 1, Qt::ControlModifier & event->modifiers());
else
selectItemAt(previousSelectedThumbnailIndex + 1, Qt::ControlModifier & event->modifiers());
mSelectionSpan = 0;
}
}
break;
case Qt::Key_Home:
{
if (Qt::ShiftModifier & event->modifiers())
{
mSelectionSpan = - startSelectionIndex;
selectItems(0, startSelectionIndex + 1);
}
else
{
selectItemAt(0, Qt::ControlModifier & event->modifiers());
mSelectionSpan = 0;
}
}
break;
case Qt::Key_End:
{
if (Qt::ShiftModifier & event->modifiers())
{
mSelectionSpan = mGraphicItems.count() - startSelectionIndex - 1;
selectItems(startSelectionIndex, mSelectionSpan + 1);
}
else
{
selectItemAt(mGraphicItems.count() - 1, Qt::ControlModifier & event->modifiers());
mSelectionSpan = 0;
}
}
break;
case Qt::Key_A:
{
if (Qt::ControlModifier & event->modifiers())
selectAll();
}
break;
}
}
QGraphicsView::keyPressEvent(event);
}
void UBThumbnailWidget::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event);
if (0 == selectedItems().count() && mGraphicItems.count() > 0 && Qt::TabFocusReason == event->reason())
{
selectItemAt(0);
mSelectionSpan = 0;
}
}
void UBThumbnailWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
refreshScene();
emit resized();
}
void UBThumbnailWidget::sceneSelectionChanged()
{
emit selectionChanged();
}
void UBThumbnailWidget::selectItemAt(int pIndex, bool extend)
{
QGraphicsItem* itemToSelect = 0;
if (pIndex >= 0 && pIndex < mGraphicItems.size())
itemToSelect = mGraphicItems.at(pIndex);
foreach (QGraphicsItem* item, items())
{
if (item == itemToSelect)
{
mLastSelectedThumbnail = dynamic_cast<UBThumbnail*>(item);
item->setSelected(true);
ensureVisible(item);
}
else if (!extend)
{
item->setSelected(false);
}
}
}
void UBThumbnailWidget::unselectItemAt(int pIndex)
{
if (pIndex >= 0 && pIndex < mGraphicItems.size())
{
QGraphicsItem *itemToUnselect = mGraphicItems.at(pIndex);
itemToUnselect->setSelected(false);
}
}
void UBThumbnailWidget::selectItems(int startIndex, int count)
{
for (int i = 0; i < mGraphicItems.count(); i++)
{
mGraphicItems.at(i)->setSelected(i >= startIndex && i < startIndex + count);
}
}
void UBThumbnailWidget::selectAll()
{
foreach (QGraphicsItem* item, mGraphicItems)
{
item->setSelected(true);
}
}
int UBThumbnailWidget::rowCount() const
{
UBThumbnail *lastThumbnail = dynamic_cast<UBThumbnail*>(mGraphicItems.last());
return lastThumbnail ? lastThumbnail->row() + 1 : 0;
}
int UBThumbnailWidget::columnCount() const
{
UBThumbnail *lastThumbnail = dynamic_cast<UBThumbnail*>(mGraphicItems.last());
if (!lastThumbnail) return 0;
int lastRow = lastThumbnail->row();
int lastColumn = lastThumbnail->column();
return lastRow > 0 ? (mGraphicItems.count() - lastColumn - 1) / lastRow : mGraphicItems.count();
}
void UBThumbnailWidget::mouseDoubleClickEvent(QMouseEvent * event)
{
QGraphicsItem* item = itemAt(event->pos());
if (item)
{
int index = mGraphicItems.indexOf(item);
emit mouseDoubleClick(item, index);
}
}
bool UBThumbnailWidget::thumbnailLessThan(QGraphicsItem* item1, QGraphicsItem* item2)
{
UBThumbnail *thumbnail1 = dynamic_cast<UBThumbnail*>(item1);
UBThumbnail *thumbnail2 = dynamic_cast<UBThumbnail*>(item2);
if (thumbnail1 && thumbnail2)
{
if (thumbnail1->row() != thumbnail2->row())
return thumbnail1->row() < thumbnail2->row();
else
return thumbnail1->column() < thumbnail2->column();
}
return false;
}
void UBThumbnailWidget::deleteLasso()
{
if (mLassoRectItem && scene())
{
scene()->removeItem(mLassoRectItem);
delete mLassoRectItem;
mLassoRectItem = 0;
}
}
UBThumbnail::UBThumbnail()
: mAddedToScene(false)
{
mSelectionItem = new QGraphicsRectItem(0, 0, 0, 0);
mSelectionItem->setPen(QPen(UBSettings::treeViewBackgroundColor, 8));
// TODO UB 4.x fix nasty dependencies : 8 is a bit less than half of UBThumbnailWidget.mSpacing
}
UBThumbnail::~UBThumbnail()
{
if (mSelectionItem && !mAddedToScene)
delete mSelectionItem;
}
UBSceneThumbnailNavigPixmap::UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex)
: UBSceneThumbnailPixmap(pix, proxy, pSceneIndex)
, bButtonsVisible(false)
, bCanDelete(false)
, bCanMoveUp(false)
, bCanMoveDown(false)
, bCanDuplicate(false)
{
if(0 <= UBDocumentContainer::pageFromSceneIndex(pSceneIndex)){
setAcceptsHoverEvents(true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
}
}
UBSceneThumbnailNavigPixmap::~UBSceneThumbnailNavigPixmap()
{
}
void UBSceneThumbnailNavigPixmap::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
updateButtonsState();
update();
}
void UBSceneThumbnailNavigPixmap::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
bButtonsVisible = false;
update();
}
void UBSceneThumbnailNavigPixmap::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
UBSceneThumbnailPixmap::paint(painter, option, widget);
if(bButtonsVisible)
{
if(bCanDelete)
painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/close.svg"));
else
painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/closeDisabled.svg"));
if(bCanDuplicate)
painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicate.svg"));
else
painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicateDisabled.svg"));
if(bCanMoveUp)
painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUp.svg"));
else
painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUpDisabled.svg"));
if(bCanMoveDown)
painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menu.svg"));
else
painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menuDisabled.svg"));
}
}
void UBSceneThumbnailNavigPixmap::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QPointF p = event->pos();
// Here we check the position of the click and verify if it has to trig an action or not.
if(bCanDelete && p.x() >= 0 && p.x() <= BUTTONSIZE && p.y() >= 0 && p.y() <= BUTTONSIZE)
deletePage();
if(bCanDuplicate && p.x() >= BUTTONSIZE + BUTTONSPACING && p.x() <= 2*BUTTONSIZE + BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE)
duplicatePage();
if(bCanMoveUp && p.x() >= 2*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 3*BUTTONSIZE + 2*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE)
moveUpPage();
if(bCanMoveDown && p.x() >= 3*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 4*BUTTONSIZE + 3*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE)
moveDownPage();
event->accept();
}
void UBSceneThumbnailNavigPixmap::updateButtonsState()
{
bCanDelete = false;
bCanMoveUp = false;
bCanMoveDown = false;
bCanDuplicate = false;
if(proxy()){
int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneIndex());
UBDocumentController* documentController = UBApplication::documentController;
bCanDelete = documentController->pageCanBeDeleted(pageIndex);
bCanMoveUp = documentController->pageCanBeMovedUp(pageIndex);
bCanMoveDown = documentController->pageCanBeMovedDown(pageIndex);
bCanDuplicate = documentController->pageCanBeDuplicated(pageIndex);
}
if(bCanDelete || bCanMoveUp || bCanMoveDown || bCanDuplicate)
bButtonsVisible = true;
}
void UBSceneThumbnailNavigPixmap::deletePage()
{
UBApplication::boardController->deleteScene(sceneIndex());
}
void UBSceneThumbnailNavigPixmap::duplicatePage()
{
UBApplication::boardController->duplicateScene(sceneIndex());
}
void UBSceneThumbnailNavigPixmap::moveUpPage()
{
if (sceneIndex()!=0)
UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() - 1);
}
void UBSceneThumbnailNavigPixmap::moveDownPage()
{
if (sceneIndex() < UBApplication::boardController->selectedDocument()->pageCount()-1)
UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() + 1);
}
void UBImgTextThumbnailElement::Place(int row, int col, qreal width, qreal height)
{
int labelSpacing = 0;
if(this->caption)
{
QFontMetrics fm(this->caption->font());
labelSpacing = UBSettings::thumbnailSpacing + fm.height();
}
if(this->thumbnail)
{
int w = this->thumbnail->boundingRect().width();
int h = this->thumbnail->boundingRect().height();
qreal scaleWidth = width / w;
qreal scaleHeight = height / h;
qreal scaleFactor = qMin(scaleWidth, scaleHeight);
UBThumbnail* pix = dynamic_cast<UBThumbnail*>(this->thumbnail);
QTransform transform;
transform.scale(scaleFactor, scaleFactor);
// Apply the scaling
this->thumbnail->setTransform(transform);
this->thumbnail->setFlag(QGraphicsItem::ItemIsSelectable, true);
if(pix)
{
pix->setColumn(col);
pix->setRow(row);
}
QPointF pos(border + (width - w * scaleFactor) / 2 + col * (width + border),
border + row * (height + border + labelSpacing) + (height - h * scaleFactor) / 2);
this->thumbnail->setPos(pos);
if(this->caption)
{
QFontMetrics fm(this->caption->font());
QString elidedText = fm.elidedText(this->caption->toPlainText(), Qt::ElideRight, width);
this->caption->setPlainText(elidedText);
this->caption->setWidth(fm.width(elidedText) + 2 * this->caption->document()->documentMargin());
pos.setY(pos.y() + (height + h * scaleFactor) / 2 + 5); // What is this 5 ??
qreal labelWidth = fm.width(elidedText);
pos.setX(border + (width - labelWidth) / 2 + col * (width + border));
this->caption->setPos(pos);
}
}
}