merge 1.4-dev + thumbnail views & fixes

preferencesAboutTextFull
Clément Fauconnier 7 years ago
parent f1f96fd3ac
commit 7b1f64eabf
  1. 7
      OpenBoard.pro
  2. 2
      resources/OpenBoard.qrc
  3. 5
      resources/etc/OpenBoard.config
  4. 75
      resources/forms/brushProperties.ui
  5. 8
      resources/images/moveDown.svg
  6. 64
      resources/images/moveDownDisabled.svg
  7. 2
      resources/style.qss
  8. 34
      src/board/UBBoardController.cpp
  9. 2
      src/board/UBBoardPaletteManager.cpp
  10. 7
      src/board/UBBoardView.cpp
  11. 3
      src/core/UBApplication.cpp
  12. 1
      src/core/UBPersistenceManager.cpp
  13. 12
      src/core/UBPreferencesController.cpp
  14. 1
      src/core/UBPreferencesController.h
  15. 17
      src/core/UBSettings.cpp
  16. 10
      src/core/UBSettings.h
  17. 20
      src/document/UBDocumentContainer.cpp
  18. 7
      src/document/UBDocumentContainer.h
  19. 29
      src/document/UBDocumentController.cpp
  20. 128
      src/domain/UBDragableThumbnail.cpp
  21. 31
      src/domain/UBDragableThumbnail.h
  22. 2
      src/domain/UBGraphicsPolygonItem.cpp
  23. 2
      src/domain/UBGraphicsPolygonItem.h
  24. 87
      src/domain/UBGraphicsScene.cpp
  25. 5
      src/domain/UBGraphicsScene.h
  26. 4
      src/domain/UBGraphicsStroke.cpp
  27. 5
      src/domain/UBGraphicsTextItem.cpp
  28. 2
      src/domain/UBGraphicsTextItem.h
  29. 10
      src/domain/UBGraphicsTextItemDelegate.cpp
  30. 301
      src/gui/UBBoardThumbnailsView.cpp
  31. 72
      src/gui/UBBoardThumbnailsView.h
  32. 311
      src/gui/UBDocumentNavigator.cpp
  33. 16
      src/gui/UBDocumentThumbnailWidget.cpp
  34. 2
      src/gui/UBDocumentThumbnailWidget.h
  35. 2
      src/gui/UBPageNavigationWidget.cpp
  36. 4
      src/gui/UBPageNavigationWidget.h
  37. 41
      src/gui/UBThumbnailView.cpp
  38. 17
      src/gui/UBThumbnailView.h
  39. 283
      src/gui/UBThumbnailWidget.cpp
  40. 354
      src/gui/UBThumbnailWidget.h
  41. 8
      src/gui/gui.pri
  42. 1
      src/tools/UBGraphicsCompass.cpp

@ -11,9 +11,10 @@ CONFIG += debug_and_release \
VERSION_MAJ = 1
VERSION_MIN = 4
VERSION_PATCH = 0
VERSION_TYPE = a # a = alpha, b = beta, rc = release candidate, r = release, other => error
VERSION_TYPE = b # a = alpha, b = beta, rc = release candidate, r = release, other => error
VERSION_BUILD = 1
VERSION = "$${VERSION_MAJ}.$${VERSION_MIN}.$${VERSION_PATCH}-$${VERSION_TYPE}.$${VERSION_BUILD}"
equals(VERSION_TYPE, r) {
@ -454,3 +455,7 @@ INSTALLS = UB_ETC \
UB_LIBRARY \
UB_THIRDPARTY_INTERACTIVE
DISTFILES += \
resources/images/moveDown.svg \
resources/images/moveDownDisabled.svg

@ -339,6 +339,8 @@
<file>images/left_arrow.png</file>
<file>images/right_arrow.png</file>
<file>images/moveUp.svg</file>
<file>images/moveDown.svg</file>
<file>images/moveDownDisabled.svg</file>
<file>images/closeDisabled.svg</file>
<file>images/menuDisabled.svg</file>
<file>images/moveUpDisabled.svg</file>

@ -65,9 +65,10 @@ RightLibPaletteDesktopModeWidth=270
ShowEraserPreviewCircle=true
ShowMarkerPreviewCircle=true
ShowPenPreviewCircle=true
PenPreviewFromSize=5
ShowToolsPalette=false
SimplifyMarkerStrokes=true
SimplifyPenStrokes=true
SimplifyMarkerStrokes=false
SimplifyPenStrokes=false
SimplifyPenStrokesThresholdAngle=3
SimplifyPenStrokesThresholdWidthDifference=2
StartupKeyboardLocale=0

@ -497,7 +497,80 @@
</property>
</spacer>
</item>
</layout>
<item>
<widget class="QFrame" name="circleFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="cspacerleft">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="circleCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show preview circle from</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="circleSpinBox"/>
</item>
<item>
<widget class="QLabel" name="pxlabel">
<property name="text">
<string>px</string>
</property>
</widget>
</item>
<item>
<spacer name="cspacerright">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>198</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="26px" height="26px" viewBox="0 0 26 26" xml:space="preserve">
<circle fill="#CCCCCC" cx="13" cy="13" r="13"/>
<circle fill="#999999" cx="13" cy="13" r="11"/>
<polygon fill="#FFFFFF" points="5,11 21,11 13,19 "/>
</svg>

After

Width:  |  Height:  |  Size: 518 B

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.2"
id="Layer_1"
x="0px"
y="0px"
width="26px"
height="26px"
viewBox="0 0 26 26"
xml:space="preserve"
inkscape:version="0.48.1 r9760"
sodipodi:docname="menu.svg"><metadata
id="metadata13"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs11" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1089"
inkscape:window-height="706"
id="namedview9"
showgrid="false"
inkscape:zoom="11.076923"
inkscape:cx="13"
inkscape:cy="13"
inkscape:window-x="7"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<circle
fill="#CCCCCC"
cx="13"
cy="13"
r="13"
id="circle3"
style="opacity:0.3" />
<circle
fill="#999999"
cx="13"
cy="13"
r="11"
id="circle5"
style="opacity:0.3" />
<polygon
fill="#FFFFFF"
points="5,11 21,11 13,19 "
id="polygon7"
style="opacity:0.3" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -1,5 +1,5 @@
QWidget#DockPaletteWidgetBox,
QWidget#documentNavigator,
QWidget#UBBoardThumbnailsView,
QWidget#UBLibPathViewer,
QWidget#UBLibNavigatorWidget,
QWidget#UBLibItemProperties,

@ -583,6 +583,7 @@ void UBBoardController::duplicateScene(int nIndex)
duplicatePages(scIndexes);
insertThumbPage(nIndex);
emit documentThumbnailsUpdated(this);
emit addThumbnailRequired(this, nIndex + 1);
selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
setActiveDocumentScene(nIndex + 1);
@ -1399,7 +1400,6 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl
if (result){
selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
reloadThumbnails();
}
}
else if (UBMimeType::OpenboardTool == itemMimeType)
@ -1542,11 +1542,11 @@ void UBBoardController::setActiveDocumentScene(UBDocumentProxy* pDocumentProxy,
mActiveSceneIndex = index;
setDocument(pDocumentProxy, forceReload);
emit initThumbnailsRequired(this);
updateSystemScaleFactor();
mControlView->setScene(mActiveScene);
disconnect(mControlView, SIGNAL(mouseReleased()), mActiveScene, SLOT(updateSelectionFrame()));
connect(mControlView, SIGNAL(mouseReleased()), mActiveScene, SLOT(updateSelectionFrame()));
mDisplayView->setScene(mActiveScene);
mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11());
pDocumentProxy->setDefaultDocumentSize(mActiveScene->nominalSize());
@ -1584,9 +1584,11 @@ void UBBoardController::moveSceneToIndex(int source, int target)
selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
UBPersistenceManager::persistenceManager()->persistDocumentMetadata(selectedDocument());
mMovingSceneIndex = source;
mActiveSceneIndex = target;
setActiveDocumentScene(target);
mMovingSceneIndex = -1;
emit activeSceneChanged();
}
}
@ -1636,6 +1638,23 @@ void UBBoardController::ClearUndoStack()
findUniquesItems(UBApplication::undoStack->command(i), uniqueItems);
}
// Get items from clipboard in order not to delete an item that was cut
// (using source URL of graphics items as a surrogate for equality testing)
// This ensures that we can cut and paste a media item, widget, etc. from one page to the next.
QClipboard *clipboard = QApplication::clipboard();
const QMimeData* data = clipboard->mimeData();
QList<QUrl> sourceURLs;
if (data && data->hasFormat(UBApplication::mimeTypeUniboardPageItem)) {
const UBMimeDataGraphicsItem* mimeDataGI = qobject_cast <const UBMimeDataGraphicsItem*>(data);
if (mimeDataGI) {
foreach (UBItem* sourceItem, mimeDataGI->items()) {
sourceURLs << sourceItem->sourceUrl();
}
}
}
// go through all unique items, and check, if they are on scene, or not.
// if not on scene, than item can be deleted
QSetIterator<QGraphicsItem*> itUniq(uniqueItems);
@ -1647,7 +1666,12 @@ void UBBoardController::ClearUndoStack()
scene = dynamic_cast<UBGraphicsScene*>(item->scene());
}
if(!scene)
bool inClipboard = false;
UBItem* ubi = dynamic_cast<UBItem*>(item);
if (ubi && sourceURLs.contains(ubi->sourceUrl()))
inClipboard = true;
if(!scene && !inClipboard)
{
if (!mActiveScene->deleteItem(item)){
delete item;
@ -1798,6 +1822,7 @@ void UBBoardController::documentSceneChanged(UBDocumentProxy* pDocumentProxy, in
if(selectedDocument() == pDocumentProxy)
{
setActiveDocumentScene(mActiveSceneIndex);
updatePage(pIndex);
}
}
@ -1941,7 +1966,6 @@ void UBBoardController::persistCurrentScene(bool isAnAutomaticBackup, bool force
&& (mActiveScene->isModified()))
{
UBPersistenceManager::persistenceManager()->persistDocumentScene(selectedDocument(), mActiveScene, mActiveSceneIndex, isAnAutomaticBackup,forceImmediateSave);
updatePage(mActiveSceneIndex);
}
}

@ -135,7 +135,6 @@ void UBBoardPaletteManager::setupDockPaletteWidgets()
//------------------------------------------------//
// Create the widgets for the dock palettes
mpPageNavigWidget = new UBPageNavigationWidget();
mpCachePropWidget = new UBCachePropertiesWidget();
@ -146,7 +145,6 @@ void UBBoardPaletteManager::setupDockPaletteWidgets()
mLeftPalette = new UBLeftPalette(mContainer);
// LEFT palette widgets
mpPageNavigWidget = new UBPageNavigationWidget();
mLeftPalette->registerWidget(mpPageNavigWidget);
mLeftPalette->addTab(mpPageNavigWidget);

@ -1719,7 +1719,12 @@ void UBBoardView::setToolCursor (int tool)
switch (tool)
{
case UBStylusTool::Pen:
controlViewport->setCursor (UBResources::resources ()->penCursor);
if (UBSettings::settings()->showPenPreviewCircle->get().toBool() &&
UBSettings::settings()->currentPenWidth() >= UBSettings::settings()->penPreviewFromSize->get().toInt()) {
controlViewport->setCursor (QCursor (Qt::BlankCursor));
} else {
controlViewport->setCursor (UBResources::resources ()->penCursor);
}
break;
case UBStylusTool::Eraser:
controlViewport->setCursor (UBResources::resources ()->eraserCursor);

@ -58,6 +58,7 @@
#include "gui/UBMainWindow.h"
#include "gui/UBResources.h"
#include "gui/UBThumbnailWidget.h"
#include "adaptors/publishing/UBSvgSubsetRasterizer.h"
@ -286,6 +287,8 @@ int UBApplication::exec(const QString& pFileToImport)
mainWindow->actionPaste->setShortcuts(QKeySequence::Paste);
mainWindow->actionCut->setShortcuts(QKeySequence::Cut);
UBThumbnailUI::_private::initCatalog();
connect(mainWindow->actionBoard, SIGNAL(triggered()), this, SLOT(showBoard()));
connect(mainWindow->actionWeb, SIGNAL(triggered()), this, SLOT(showInternet()));
connect(mainWindow->actionWeb, SIGNAL(triggered()), this, SLOT(stopScript()));

@ -744,7 +744,6 @@ UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy,
if (scene)
mSceneCache.insert(proxy, sceneIndex, scene);
}
if (cacheNeighboringScenes) {
if(sceneIndex + 1 < proxy->pageCount() && !mSceneCache.contains(proxy, sceneIndex + 1))
mWorker->readScene(proxy,sceneIndex+1);

@ -165,6 +165,8 @@ void UBPreferencesController::wire()
connect(mPenProperties->mediumSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mPenProperties->strongSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mPenProperties->pressureSensitiveCheckBox, SIGNAL(clicked(bool)), settings, SLOT(setPenPressureSensitive(bool)));
connect(mPenProperties->circleCheckBox, SIGNAL(clicked(bool)), settings, SLOT(setPenPreviewCircle(bool)));
connect(mPenProperties->circleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(penPreviewFromSizeChanged(int)));
// marker
QList<QColor> markerLightBackgroundColors = settings->boardMarkerLightBackgroundColors->colors();
@ -178,6 +180,8 @@ void UBPreferencesController::wire()
mMarkerProperties->pressureSensitiveCheckBox->setText(tr("Marker is pressure sensitive"));
mMarkerProperties->circleFrame->hide();
connect(mMarkerProperties->fineSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mMarkerProperties->mediumSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mMarkerProperties->strongSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
@ -229,6 +233,8 @@ void UBPreferencesController::init()
mPenProperties->mediumSlider->setValue(settings->boardPenMediumWidth->get().toDouble() * sSliderRatio);
mPenProperties->strongSlider->setValue(settings->boardPenStrongWidth->get().toDouble() * sSliderRatio);
mPenProperties->pressureSensitiveCheckBox->setChecked(settings->boardPenPressureSensitive->get().toBool());
mPenProperties->circleCheckBox->setChecked(settings->showPenPreviewCircle->get().toBool());
mPenProperties->circleSpinBox->setValue(settings->penPreviewFromSize->get().toInt());
// marker tab
mMarkerProperties->fineSlider->setValue(settings->boardMarkerFineWidth->get().toDouble() * sSliderRatio);
@ -278,6 +284,8 @@ void UBPreferencesController::defaultSettings()
mPenProperties->mediumSlider->setValue(settings->boardPenMediumWidth->reset().toDouble() * sSliderRatio);
mPenProperties->strongSlider->setValue(settings->boardPenStrongWidth->reset().toDouble() * sSliderRatio);
mPenProperties->pressureSensitiveCheckBox->setChecked(settings->boardPenPressureSensitive->reset().toBool());
mPenProperties->circleCheckBox->setChecked(settings->showPenPreviewCircle->reset().toBool());
mPenProperties->circleSpinBox->setValue(settings->penPreviewFromSize->reset().toInt());
settings->boardPenLightBackgroundSelectedColors->reset();
QList<QColor> lightBackgroundSelectedColors = settings->boardPenLightBackgroundSelectedColors->colors();
@ -332,6 +340,10 @@ void UBPreferencesController::defaultSettings()
}
void UBPreferencesController::penPreviewFromSizeChanged(int value)
{
UBSettings::settings()->setPenPreviewFromSize(value);
}
void UBPreferencesController::widthSliderChanged(int value)
{

@ -89,6 +89,7 @@ class UBPreferencesController : public QObject
void close();
void defaultSettings();
void penPreviewFromSizeChanged(int value);
void widthSliderChanged(int value);
void opacitySliderChanged(int value);
void colorSelected(const QColor&);

@ -85,6 +85,12 @@ QColor UBSettings::markerCircleBrushColorLightBackground = QColor(255, 255, 255,
QColor UBSettings::markerCirclePenColorDarkBackground = QColor(255, 255, 255, 127);
QColor UBSettings::markerCirclePenColorLightBackground = QColor(0, 0, 0, 127);
QColor UBSettings::penCircleBrushColorDarkBackground = QColor(127, 127, 127, 80);
QColor UBSettings::penCircleBrushColorLightBackground = QColor(255, 255, 255, 30);
QColor UBSettings::penCirclePenColorDarkBackground = QColor(255, 255, 255, 127);
QColor UBSettings::penCirclePenColorLightBackground = QColor(0, 0, 0, 127);
QColor UBSettings::documentSizeMarkColorDarkBackground = QColor(44, 44, 44, 200);
QColor UBSettings::documentSizeMarkColorLightBackground = QColor(241, 241, 241);
@ -323,6 +329,8 @@ void UBSettings::init()
showEraserPreviewCircle = new UBSetting(this, "Board", "ShowEraserPreviewCircle", true);
showMarkerPreviewCircle = new UBSetting(this, "Board", "ShowMarkerPreviewCircle", true);
showPenPreviewCircle = new UBSetting(this, "Board", "ShowPenPreviewCircle", true);
penPreviewFromSize = new UBSetting(this, "Board", "PenPreviewFromSize", 5);
webUseExternalBrowser = new UBSetting(this, "Web", "UseExternalBrowser", false);
@ -784,6 +792,15 @@ void UBSettings::setPenPressureSensitive(bool sensitive)
boardPenPressureSensitive->set(sensitive);
}
void UBSettings::setPenPreviewCircle(bool circle)
{
showPenPreviewCircle->set(circle);
}
void UBSettings::setPenPreviewFromSize(int size)
{
penPreviewFromSize->set(size);
}
void UBSettings::setMarkerPressureSensitive(bool sensitive)
{

@ -177,6 +177,12 @@ class UBSettings : public QObject
static QColor markerCirclePenColorDarkBackground;
static QColor markerCirclePenColorLightBackground;
static QColor penCircleBrushColorDarkBackground;
static QColor penCircleBrushColorLightBackground;
static QColor penCirclePenColorDarkBackground;
static QColor penCirclePenColorLightBackground;
static QColor documentSizeMarkColorDarkBackground;
static QColor documentSizeMarkColorLightBackground;
@ -303,6 +309,8 @@ class UBSettings : public QObject
UBSetting* showEraserPreviewCircle;
UBSetting* showMarkerPreviewCircle;
UBSetting* showPenPreviewCircle;
UBSetting* penPreviewFromSize;
UBSetting* webUseExternalBrowser;
UBSetting* webShowPageImmediatelyOnMirroredScreen;
@ -410,6 +418,8 @@ class UBSettings : public QObject
void setStylusPaletteVisible(bool visible);
void setPenPressureSensitive(bool sensitive);
void setPenPreviewCircle(bool sensitive);
void setPenPreviewFromSize(int size);
void setMarkerPressureSensitive(bool sensitive);
QVariant value ( const QString & key, const QVariant & defaultValue = QVariant() );

@ -51,8 +51,9 @@ void UBDocumentContainer::setDocument(UBDocumentProxy* document, bool forceReloa
if (mCurrentDocument != document || forceReload)
{
mCurrentDocument = document;
reloadThumbnails();
emit documentSet(mCurrentDocument);
reloadThumbnails();
}
}
@ -68,10 +69,14 @@ void UBDocumentContainer::duplicatePages(QList<int>& pageIndexes)
bool UBDocumentContainer::movePageToIndex(int source, int target)
{
//on document view
UBPersistenceManager::persistenceManager()->moveSceneToIndex(mCurrentDocument, source, target);
deleteThumbPage(source);
insertThumbPage(target);
emit documentThumbnailsUpdated(this);
//on board thumbnails view
emit moveThumbnailRequired(source, target);
return true;
}
@ -82,16 +87,26 @@ void UBDocumentContainer::deletePages(QList<int>& pageIndexes)
foreach(int index, pageIndexes)
{
deleteThumbPage(index - offset);
emit removeThumbnailRequired(index - offset);
offset++;
}
emit documentThumbnailsUpdated(this);
}
void UBDocumentContainer::addPage(int index)
{
UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mCurrentDocument, index);
insertThumbPage(index);
emit documentThumbnailsUpdated(this);
emit addThumbnailRequired(this, index);
}
void UBDocumentContainer::initThumbPage()
{
for (int i=0; i < selectedDocument()->pageCount(); i++)
insertThumbPage(i);
}
void UBDocumentContainer::updatePage(int index)
@ -108,7 +123,6 @@ void UBDocumentContainer::deleteThumbPage(int index)
void UBDocumentContainer::updateThumbPage(int index)
{
mDocumentThumbs[index] = UBThumbnailAdaptor::get(mCurrentDocument, index);
emit documentPageUpdated(index);
}
void UBDocumentContainer::insertThumbPage(int index)

@ -53,6 +53,7 @@ class UBDocumentContainer : public QObject
void duplicatePages(QList<int>& pageIndexes);
bool movePageToIndex(int source, int target);
void deletePages(QList<int>& pageIndexes);
void initThumbPage();
void addPage(int index);
void updatePage(int index);
void addEmptyThumbPage();
@ -73,6 +74,12 @@ class UBDocumentContainer : public QObject
signals:
void documentSet(UBDocumentProxy* document);
void documentPageUpdated(int index);
void initThumbnailsRequired(UBDocumentContainer* source);
void addThumbnailRequired(UBDocumentContainer* source, int index);
void removeThumbnailRequired(int index);
void moveThumbnailRequired(int from, int to);
void documentThumbnailsUpdated(UBDocumentContainer* source);
};

@ -467,15 +467,16 @@ void UBDocumentController::openSelectedItem()
if (selectedItems.count() > 0)
{
UBSceneThumbnailPixmap* thumb = dynamic_cast<UBSceneThumbnailPixmap*> (selectedItems.last());
UBThumbnailPixmap* thumb = dynamic_cast<UBThumbnailPixmap*> (selectedItems.last());
if (thumb)
{
UBDocumentProxy* proxy = thumb->proxy();
UBDocumentProxy* proxy = thumb->documentProxy();
if (proxy && isOKToOpenDocument(proxy))
{
UBApplication::applicationController->showBoard();
UBApplication::applicationController->showBoard();
}
}
}
@ -504,10 +505,10 @@ void UBDocumentController::duplicateSelectedItem()
QList<int> selectedSceneIndexes;
foreach (QGraphicsItem *item, selectedItems)
{
UBSceneThumbnailPixmap *thumb = dynamic_cast<UBSceneThumbnailPixmap*>(item);
UBThumbnailPixmap *thumb = dynamic_cast<UBThumbnailPixmap*>(item);
if (thumb)
{
UBDocumentProxy *proxy = thumb->proxy();
UBDocumentProxy *proxy = thumb->documentProxy();
if (proxy)
{
@ -1365,7 +1366,7 @@ void UBDocumentController::selectionChanged()
mMainWindow->actionDuplicate->setEnabled(!trashSelected);
else{
for(int i = 0; i < selection.count() && !firstSceneSelected; i += 1){
if(dynamic_cast<UBSceneThumbnailPixmap*>(selection.at(i))->sceneIndex() == 0){
if(dynamic_cast<UBThumbnailPixmap*>(selection.at(i))->sceneIndex() == 0){
mMainWindow->actionDuplicate->setEnabled(!trashSelected);
firstSceneSelected = true;
}
@ -1515,11 +1516,11 @@ void UBDocumentController::addToDocument()
foreach (QGraphicsItem* item, selectedItems)
{
UBSceneThumbnailPixmap* thumb = dynamic_cast<UBSceneThumbnailPixmap*> (item);
UBThumbnailPixmap* thumb = dynamic_cast<UBThumbnailPixmap*> (item);
if (thumb && thumb->proxy())
if (thumb && thumb->documentProxy())
{
QPair<UBDocumentProxy*, int> pageInfo(thumb->proxy(), thumb->sceneIndex());
QPair<UBDocumentProxy*, int> pageInfo(thumb->documentProxy(), thumb->sceneIndex());
pageInfoList << pageInfo;
}
}
@ -1808,11 +1809,11 @@ void UBDocumentController::deletePages(QList<QGraphicsItem *> itemsToDelete)
foreach (QGraphicsItem* item, itemsToDelete)
{
UBSceneThumbnailPixmap* thumb = dynamic_cast<UBSceneThumbnailPixmap*> (item);
UBThumbnailPixmap* thumb = dynamic_cast<UBThumbnailPixmap*> (item);
if (thumb)
{
proxy = thumb->proxy();
proxy = thumb->documentProxy();
if (proxy)
{
sceneIndexes.append(thumb->sceneIndex());
@ -1842,7 +1843,7 @@ int UBDocumentController::getSelectedItemIndex()
if (selectedItems.count() > 0)
{
UBSceneThumbnailPixmap* thumb = dynamic_cast<UBSceneThumbnailPixmap*> (selectedItems.last());
UBThumbnailPixmap* thumb = dynamic_cast<UBThumbnailPixmap*> (selectedItems.last());
return thumb->sceneIndex();
}
else return -1;
@ -1867,11 +1868,11 @@ void UBDocumentController::refreshDocumentThumbnailsView(UBDocumentContainer*)
if (proxy)
{
setDocument(proxy);
initThumbPage();
for (int i = 0; i < selectedDocument()->pageCount(); i++)
{
const QPixmap* pix = pageAt(i);
QGraphicsPixmapItem *pixmapItem = new UBSceneThumbnailPixmap(*pix, proxy, i); // deleted by the tree widget
QGraphicsPixmapItem *pixmapItem = new UBThumbnailPixmap(*pix, proxy, i); // deleted by the tree widget
if (proxy == mBoardController->selectedDocument() && mBoardController->activeSceneIndex() == i)
{
@ -1898,7 +1899,7 @@ void UBDocumentController::refreshDocumentThumbnailsView(UBDocumentContainer*)
if (selection) {
disconnect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged()));
UBSceneThumbnailPixmap *currentScene = dynamic_cast<UBSceneThumbnailPixmap*>(selection);
UBThumbnailPixmap *currentScene = dynamic_cast<UBThumbnailPixmap*>(selection);
if (currentScene)
mDocumentUI->thumbnailWidget->hightlightItem(currentScene->sceneIndex());
connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged()));

@ -0,0 +1,128 @@
#include "UBDragableThumbnail.h"
#include <QPainter>
#include <QMimeData>
#include <QDrag>
UBDraggableThumbnail::UBDraggableThumbnail(QWidget* parent, const QPixmap& pixmap) :
QFrame(parent)
, mThumbnail(new QLabel(this))
, mHBoxLayout(new QHBoxLayout(this))
{
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);
//set stylesheet
setObjectName("DockPaletteWidgetBox");
setStyleSheet("background:white");
mHBoxLayout->setAlignment(Qt::AlignHCenter);
setThumbnail(pixmap);
setLayout(mHBoxLayout);
}
void UBDraggableThumbnail::setThumbnail(const QPixmap& pixmap)
{
mThumbnail->setAttribute(Qt::WA_DeleteOnClose);
setPixmap(pixmap);
mHBoxLayout->addWidget(mThumbnail);
}
void UBDraggableThumbnail::setPixmap(const QPixmap& pixmap)
{
mThumbnail->setPixmap(pixmap);
}
void UBDraggableThumbnail::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
void UBDraggableThumbnail::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
void UBDraggableThumbnail::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QPixmap pixmap;
QPoint offset;
dataStream >> pixmap >> offset;
//don't have to delete previous Thumbnail (Drag'n'Drop behavior with WA_DeleteOnClose attribute will do it)
mThumbnail = new QLabel(this);
setThumbnail(pixmap);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
void UBDraggableThumbnail::mousePressEvent(QMouseEvent *event)
{
QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
if (!child)
return;
QPixmap pixmap = *child->pixmap();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << QPoint(event->pos() - child->pos());
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(event->pos() - child->pos());
QPixmap tempPixmap = pixmap;
QPainter painter;
painter.begin(&tempPixmap);
painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
painter.end();
child->setPixmap(tempPixmap);
if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction)
child->close();
else {
child->show();
child->setPixmap(pixmap);
}
}

@ -0,0 +1,31 @@
#ifndef UBDRAGABLELABEL_H
#define UBDRAGABLELABEL_H
#include <QFrame>
#include <QLabel>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QHBoxLayout>
#include <QPixmap>
class UBDraggableThumbnail : public QFrame
{
public:
UBDraggableThumbnail(QWidget* parent =0, const QPixmap& pixmap = QPixmap(":images/libpalette/notFound.png"));
void setThumbnail(const QPixmap &pixmap);
void setPixmap(const QPixmap & pixmap);
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
QLabel* mThumbnail;
QHBoxLayout* mHBoxLayout;
};
#endif // UBDRAGABLELABEL_H

@ -184,7 +184,7 @@ void UBGraphicsPolygonItem::copyItemParameters(UBItem *copy) const
void UBGraphicsPolygonItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
if(mHasAlpha && scene() && scene()->isLightBackground())
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->setCompositionMode(QPainter::CompositionMode_Darken);
painter->setRenderHints(QPainter::Antialiasing);

@ -109,6 +109,8 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem
qreal originalWidth() { return mOriginalWidth;}
bool isNominalLine() {return mIsNominalLine;}
void setNominalLine(bool isNominalLine) { mIsNominalLine = isNominalLine; }
QColor colorOnDarkBackground() const
{
return mColorOnDarkBackground;

@ -48,6 +48,7 @@
#include "gui/UBMagnifer.h"
#include "gui/UBMainWindow.h"
#include "gui/UBToolWidget.h"
#include "gui/UBResources.h"
#include "tools/UBGraphicsRuler.h"
#include "tools/UBGraphicsProtractor.h"
@ -317,6 +318,7 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent, bool enableUndoRedoSta
, mEraser(0)
, mPointer(0)
, mMarkerCircle(0)
, mPenCircle(0)
, mDocument(parent)
, mDarkBackground(false)
, mPageBackground(UBPageBackground::plain)
@ -346,6 +348,7 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent, bool enableUndoRedoSta
createEraiser();
createPointer();
createMarkerCircle();
createPenCircle();
if (UBApplication::applicationController)
{
@ -410,6 +413,10 @@ bool UBGraphicsScene::inputDevicePress(const QPointF& scenePos, const qreal& pre
if (currentTool == UBStylusTool::Marker)
hideMarkerCircle();
// hide the pen preview circle
if (currentTool == UBStylusTool::Pen)
hidePenCircle();
// ---------------------------------------------------------------
// Create a new Stroke. A Stroke is a collection of QGraphicsLines
// ---------------------------------------------------------------
@ -492,6 +499,15 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
}
}
else if (currentTool == UBStylusTool::Pen) {
if (mInputDeviceIsPressed)
hidePenCircle();
else {
drawPenCircle(position);
accepted = true;
}
}
if (mInputDeviceIsPressed)
{
if (dc->isDrawingTool())
@ -799,6 +815,28 @@ void UBGraphicsScene::drawMarkerCircle(const QPointF &pPoint)
}
void UBGraphicsScene::drawPenCircle(const QPointF &pPoint)
{
if (mPenCircle && UBSettings::settings()->showPenPreviewCircle->get().toBool() &&
UBSettings::settings()->currentPenWidth() >= UBSettings::settings()->penPreviewFromSize->get().toInt()) {
qreal penDiameter = UBSettings::settings()->currentPenWidth();
penDiameter /= UBApplication::boardController->systemScaleFactor();
penDiameter /= UBApplication::boardController->currentZoom();
qreal penRadius = penDiameter/2;
mPenCircle->setRect(QRectF(pPoint.x() - penRadius, pPoint.y() - penRadius,
penDiameter, penDiameter));
controlView()->viewport()->setCursor(QCursor (Qt::BlankCursor));
mPenCircle->show();
}
else
{
controlView()->viewport()->setCursor(UBResources::resources()->penCursor);
}
}
void UBGraphicsScene::hideMarkerCircle()
{
if (mMarkerCircle) {
@ -806,6 +844,12 @@ void UBGraphicsScene::hideMarkerCircle()
}
}
void UBGraphicsScene::hidePenCircle()
{
if (mPenCircle)
mPenCircle->hide();
}
// call this function when user release mouse button in Magnifier mode
void UBGraphicsScene::DisposeMagnifierQWidgets()
{
@ -989,6 +1033,7 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
UBGraphicsPolygonItem* polygonItem = new UBGraphicsPolygonItem(intersectedPolygons[i][j], intersectedPolygonItem->parentItem());
intersectedPolygonItem->copyItemParameters(polygonItem);
polygonItem->setNominalLine(false);
polygonItem->setStroke(intersectedPolygonItem->stroke());
polygonItem->setStrokesGroup(intersectedPolygonItem->strokesGroup());
intersectedPolygonItem->strokesGroup()->addToGroup(polygonItem);
@ -1050,6 +1095,7 @@ void UBGraphicsScene::setBackground(bool pIsDark, UBPageBackground pBackground)
updateEraserColor();
updateMarkerCircleColor();
updatePenCircleColor();
recolorAllItems();
needRepaint = true;
@ -1270,6 +1316,7 @@ void UBGraphicsScene::hideTool()
{
hideEraser();
hideMarkerCircle();
hidePenCircle();
}
void UBGraphicsScene::leaveEvent(QEvent * event)
@ -2791,6 +2838,25 @@ void UBGraphicsScene::createMarkerCircle()
}
}
void UBGraphicsScene::createPenCircle()
{
if (UBSettings::settings()->showPenPreviewCircle->get().toBool()) {
mPenCircle = new QGraphicsEllipseItem();
mPenCircle->setRect(QRect(0, 0, 0, 0));
mPenCircle->setVisible(false);
mPenCircle->setPen(Qt::DotLine);
updatePenCircleColor();
mPenCircle->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control));
mPenCircle->setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::Eraiser));
mTools << mPenCircle;
addItem(mPenCircle);
}
}
void UBGraphicsScene::updateEraserColor()
{
if (!mEraser)
@ -2828,6 +2894,27 @@ void UBGraphicsScene::updateMarkerCircleColor()
mMarkerCircle->setPen(mcPen);
}
void UBGraphicsScene::updatePenCircleColor()
{
if (!mPenCircle)
return;
QPen mcPen = mPenCircle->pen();
if (mDarkBackground) {
mcPen.setColor(UBSettings::penCirclePenColorDarkBackground);
mPenCircle->setBrush(UBSettings::penCircleBrushColorDarkBackground);
}
else {
mcPen.setColor(UBSettings::penCirclePenColorLightBackground);
mPenCircle->setBrush(UBSettings::penCircleBrushColorLightBackground);
}
mcPen.setStyle(Qt::DotLine);
mPenCircle->setPen(mcPen);
}
void UBGraphicsScene::setToolCursor(int tool)
{
if (tool == (int)UBStylusTool::Selector ||

@ -383,7 +383,9 @@ public slots:
void hideEraser();
void drawPointer(const QPointF& pEndPoint, bool isFirstDraw = false);
void drawMarkerCircle(const QPointF& pEndPoint);
void drawPenCircle(const QPointF& pEndPoint);
void hideMarkerCircle();
void hidePenCircle();
void DisposeMagnifierQWidgets();
@ -404,14 +406,17 @@ public slots:
void createEraiser();
void createPointer();
void createMarkerCircle();
void createPenCircle();
void updateEraserColor();
void updateMarkerCircleColor();
void updatePenCircleColor();
bool hasTextItemWithFocus(UBGraphicsGroupContainerItem* item);
void simplifyCurrentStroke();
QGraphicsEllipseItem* mEraser;
QGraphicsEllipseItem* mPointer; // "laser" pointer
QGraphicsEllipseItem* mMarkerCircle; // dotted circle around marker
QGraphicsEllipseItem* mPenCircle; // dotted circle around pen
QSet<QGraphicsItem*> mAddedItems;
QSet<QGraphicsItem*> mRemovedItems;

@ -164,12 +164,10 @@ bool UBGraphicsStroke::hasPressure()
if (!pol->isNominalLine() || pol->originalWidth() != nominalWidth)
return true;
}
return false;
}
else
return true;
return false;
}

@ -188,6 +188,11 @@ void UBGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
}
void UBGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
}
void UBGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
// scene()->itemAt(pos) returns 0 if pos is not over text, but over text item, but mouse press comes.

@ -118,6 +118,8 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes
virtual void keyPressEvent(QKeyEvent *event);
virtual void keyReleaseEvent(QKeyEvent *event);
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);

@ -339,7 +339,10 @@ void UBGraphicsTextItemDelegate::pickFont()
curCursor.mergeCharFormat(format);
delegated()->setTextCursor(curCursor);
delegated()->setFont(selectedFont);
if (curCursor.selectedText().length() == 0)
delegated()->setFont(selectedFont);
delegated()->setSelected(true);
delegated()->document()->adjustSize();
delegated()->contentsChanged();
@ -751,10 +754,5 @@ QVariant UBGraphicsTextItemDelegate::itemChange(QGraphicsItem::GraphicsItemChang
}
}
if (value.toBool() == false && delegated()->document()->toPlainText().isEmpty()) {
int wdth = QFontMetrics(delegated()->font()).width(delegated()->mTypeTextHereLabel);
delegated()->setTextWidth(qMax(wdth, (int)(delegated()->textWidth())));
}
return UBGraphicsItemDelegate::itemChange(change, value);
}

@ -0,0 +1,301 @@
/*
* Copyright (C) 2015-2016 Département de l'Instruction Publique (DIP-SEM)
*
* Copyright (C) 2013 Open Education Foundation
*
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
* l'Education Numérique en Afrique (GIP ENA)
*
* This file is part of OpenBoard.
*
* OpenBoard 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, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard 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 OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QList>
#include <QPointF>
#include <QPixmap>
#include <QTransform>
#include <QScrollBar>
#include <QFontMetrics>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include "core/UBApplication.h"
#include "UBBoardThumbnailsView.h"
#include "board/UBBoardController.h"
#include "adaptors/UBThumbnailAdaptor.h"
#include "adaptors/UBSvgSubsetAdaptor.h"
#include "document/UBDocumentController.h"
#include "domain/UBGraphicsScene.h"
#include "board/UBBoardPaletteManager.h"
#include "core/UBApplicationController.h"
#include "core/UBPersistenceManager.h"
#include "UBThumbnailView.h"
UBBoardThumbnailsView::UBBoardThumbnailsView(QWidget *parent, const char *name)
: QGraphicsView(parent)
, mThumbnailWidth(0)
, mThumbnailMinWidth(100)
, mMargin(20)
, mDropSource(NULL)
, mDropTarget(NULL)
, mDropBar(new QGraphicsRectItem(0))
, mLongPressInterval(150)
{
setScene(new QGraphicsScene(this));
mDropBar->setPen(QPen(Qt::darkGray));
mDropBar->setBrush(QBrush(Qt::lightGray));
scene()->addItem(mDropBar);
mDropBar->hide();
setObjectName(name);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFrameShadow(QFrame::Plain);
mThumbnailWidth = width() - 2*mMargin;
mLongPressTimer.setInterval(mLongPressInterval);
mLongPressTimer.setSingleShot(true);
connect(UBApplication::boardController, SIGNAL(initThumbnailsRequired(UBDocumentContainer*)), this, SLOT(initThumbnails(UBDocumentContainer*)), Qt::UniqueConnection);
connect(UBApplication::boardController, SIGNAL(addThumbnailRequired(UBDocumentContainer*, int)), this, SLOT(addThumbnail(UBDocumentContainer*, int)), Qt::UniqueConnection);
connect(UBApplication::boardController, SIGNAL(moveThumbnailRequired(int, int)), this, SLOT(moveThumbnail(int, int)), Qt::UniqueConnection);
connect(this, SIGNAL(moveThumbnailRequired(int, int)), this, SLOT(moveThumbnail(int, int)), Qt::UniqueConnection);
connect(UBApplication::boardController, SIGNAL(removeThumbnailRequired(int)), this, SLOT(removeThumbnail(int)), Qt::UniqueConnection);
connect(&mLongPressTimer, SIGNAL(timeout()), this, SLOT(longPressTimeout()), Qt::UniqueConnection);
connect(this, SIGNAL(mousePressAndHoldEventRequired(QPoint)), this, SLOT(mousePressAndHoldEvent(QPoint)), Qt::UniqueConnection);
connect(UBApplication::boardController, SIGNAL(pageSelectionChanged(int)), this, SLOT(scrollToSelectedPage(int)), Qt::UniqueConnection);
}
void UBBoardThumbnailsView::moveThumbnail(int from, int to)
{
mThumbnails.move(from, to);
updateThumbnailsPos();
}
void UBBoardThumbnailsView::removeThumbnail(int i)
{
UBDraggableThumbnailView* item = mThumbnails.at(i);
scene()->removeItem(item->pageNumber());
scene()->removeItem(item);
mThumbnails.removeAt(i);
updateThumbnailsPos();
}
UBDraggableThumbnailView* UBBoardThumbnailsView::createThumbnail(UBDocumentContainer* source, int i)
{
UBGraphicsScene* pageScene = UBPersistenceManager::persistenceManager()->loadDocumentScene(source->selectedDocument(), i);
UBThumbnailView* pageView = new UBThumbnailView(pageScene);
return new UBDraggableThumbnailView(pageView, source->selectedDocument(), i);
}
void UBBoardThumbnailsView::addThumbnail(UBDocumentContainer* source, int i)
{
UBDraggableThumbnailView* item = createThumbnail(source, i);
mThumbnails.insert(i, item);
scene()->addItem(item);
scene()->addItem(item->pageNumber());
updateThumbnailsPos();
}
void UBBoardThumbnailsView::clearThumbnails()
{
qDeleteAll(mThumbnails);
mThumbnails.clear();
}
void UBBoardThumbnailsView::initThumbnails(UBDocumentContainer* source)
{
clearThumbnails();
for(int i = 0; i < source->selectedDocument()->pageCount(); i++)
{
mThumbnails.append(createThumbnail(source, i));
scene()->addItem(mThumbnails.last());
scene()->addItem(mThumbnails.last()->pageNumber());
}
updateThumbnailsPos();
}
void UBBoardThumbnailsView::scrollToSelectedPage(int index)
{
centerOn(mThumbnails.at(index));
}
void UBBoardThumbnailsView::updateThumbnailsPos()
{
qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio;
for (int i=0; i < mThumbnails.length(); i++)
{
mThumbnails.at(i)->setSceneIndex(i);
mThumbnails.at(i)->setPageNumber(i);
mThumbnails.at(i)->updatePos(mThumbnailWidth, thumbnailHeight);
}
scene()->setSceneRect(scene()->itemsBoundingRect());
}
void UBBoardThumbnailsView::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
// Update the thumbnails width
mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*mMargin : mThumbnailMinWidth;
// Refresh the scene
updateThumbnailsPos();
}
void UBBoardThumbnailsView::mousePressEvent(QMouseEvent *event)
{
mLongPressTimer.start();
mLastPressedMousePos = event->pos();
QGraphicsView::mousePressEvent(event);
}
void UBBoardThumbnailsView::mouseMoveEvent(QMouseEvent *event)
{
mLastPressedMousePos = event->pos();
QGraphicsView::mouseMoveEvent(event);
}
void UBBoardThumbnailsView::longPressTimeout()
{
emit mousePressAndHoldEventRequired(mLastPressedMousePos);
mLongPressTimer.stop();
}
void UBBoardThumbnailsView::mousePressAndHoldEvent(QPoint pos)
{
UBDraggableThumbnailView* item = dynamic_cast<UBDraggableThumbnailView*>(itemAt(pos));
if (item)
{
mDropSource = item;
mDropTarget = item;
QPixmap pixmap = item->widget()->grab().scaledToWidth(UBSettings::defaultThumbnailWidth);
QDrag *drag = new QDrag(this);
drag->setMimeData(new QMimeData());
drag->setPixmap(pixmap);
drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
drag->exec();
}
}
void UBBoardThumbnailsView::mouseReleaseEvent(QMouseEvent *event)
{
mLongPressTimer.stop();
UBDraggableThumbnailView* item = dynamic_cast<UBDraggableThumbnailView*>(itemAt(event->pos()));
if (item)
UBApplication::boardController->setActiveDocumentScene(item->sceneIndex());
QGraphicsView::mouseReleaseEvent(event);
}
void UBBoardThumbnailsView::dragEnterEvent(QDragEnterEvent *event)
{
mDropBar->show();
if (event->source() == this)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
else
{
event->acceptProposedAction();
}
}
void UBBoardThumbnailsView::dragMoveEvent(QDragMoveEvent *event)
{
QPointF position = event->pos();
//autoscroll during drag'n'drop
QPointF scenePos = mapToScene(position.toPoint());
int thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio;
QRectF thumbnailArea(0, scenePos.y() - thumbnailHeight/2, mThumbnailWidth, thumbnailHeight);
ensureVisible(thumbnailArea);
UBDraggableThumbnailView* item = dynamic_cast<UBDraggableThumbnailView*>(itemAt(position.toPoint()));
if (item)
{
if (item != mDropTarget)
mDropTarget = item;
qreal scale = item->transform().m11();
QPointF itemCenter(item->pos().x() + item->boundingRect().width() * scale / 2,
item->pos().y() + item->boundingRect().height() * scale / 2);
bool dropAbove = mapToScene(position.toPoint()).y() < itemCenter.y();
bool movingUp = mDropSource->sceneIndex() > item->sceneIndex();
qreal y = 0;
if (movingUp)
{
if (dropAbove)
{
y = item->pos().y() - UBSettings::thumbnailSpacing / 2;
if (mDropBar->y() != y)
mDropBar->setRect(QRectF(item->pos().x(), y, item->boundingRect().width() * scale, 3));
}
}
else
{
if (!dropAbove)
{
y = item->pos().y() + item->boundingRect().height() * scale + UBSettings::thumbnailSpacing / 2;
if (mDropBar->y() != y)
mDropBar->setRect(QRectF(item->pos().x(), y, item->boundingRect().width() * scale, 3));
}
}
}
event->acceptProposedAction();
}
void UBBoardThumbnailsView::dropEvent(QDropEvent *event)
{
Q_UNUSED(event);
UBApplication::boardController->moveSceneToIndex(mDropSource->sceneIndex(), mDropTarget->sceneIndex());
mDropSource = NULL;
mDropTarget = NULL;
mDropBar->hide();
}

@ -27,63 +27,67 @@
#ifndef UBDOCUMENTNAVIGATOR_H
#define UBDOCUMENTNAVIGATOR_H
#ifndef UBBOARDTHUMBNAILSVIEW_H
#define UBBOARDTHUMBNAILSVIEW_H
#include <QResizeEvent>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QThread>
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentContainer.h"
#include "UBThumbnailWidget.h"
#define NO_PAGESELECTED -1
class UBDocumentNavigator : public QGraphicsView
class UBBoardThumbnailsView : public QGraphicsView
{
Q_OBJECT
public:
UBDocumentNavigator(QWidget* parent=0, const char* name="documentNavigator");
~UBDocumentNavigator();
void setNbColumns(int nbColumns);
int nbColumns();
void setThumbnailMinWidth(int width);
int thumbnailMinWidth();
UBBoardThumbnailsView(QWidget* parent=0, const char* name="UBBoardThumbnailsView");
public slots:
void onScrollToSelectedPage(int index);// { if (mCrntItem) centerOn(mCrntItem); }
void generateThumbnails(UBDocumentContainer* source);
void updateSpecificThumbnail(int iPage);
void scrollToSelectedPage(int index);
void clearThumbnails();
void initThumbnails(UBDocumentContainer* source);
void addThumbnail(UBDocumentContainer* source, int i);
void moveThumbnail(int from, int to);
void removeThumbnail(int i);
void longPressTimeout();
void mousePressAndHoldEvent(QPoint pos);
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void dragEnterEvent(QDragEnterEvent* event);
virtual void dragMoveEvent(QDragMoveEvent* event);
virtual void dropEvent(QDropEvent* event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
private:
signals:
void mousePressAndHoldEventRequired(QPoint pos);
void moveThumbnailRequired(int from, int to);
void refreshScene();
int border();
private:
UBDraggableThumbnailView* createThumbnail(UBDocumentContainer* source, int i);
void updateThumbnailsPos();
QList<UBDraggableThumbnailView*> mThumbnails;
/** The scene */
QGraphicsScene* mScene;
/** The current selected item */
//UBSceneThumbnailNavigPixmap* mCrntItem;
/** The list of current thumbnails with labels*/
QList<UBImgTextThumbnailElement> mThumbsWithLabels;
/** The current number of columns */
int mNbColumns;
/** The current thumbnails width */
int mThumbnailWidth;
/** The current thumbnails minimum width */
int mThumbnailMinWidth;
/** The selected thumbnail */
UBSceneThumbnailNavigPixmap* mSelectedThumbnail;
const int mThumbnailMinWidth;
const int mMargin;
UBDraggableThumbnailView* mDropSource;
UBDraggableThumbnailView* mDropTarget;
QGraphicsRectItem *mDropBar;
int mLongPressInterval;
QTimer mLongPressTimer;
QPoint mLastPressedMousePos;
};
#endif // UBDOCUMENTNAVIGATOR_H
#endif // UBBOARDTHUMBNAILSVIEW_H

@ -1,311 +0,0 @@
/*
* Copyright (C) 2015-2016 Département de l'Instruction Publique (DIP-SEM)
*
* Copyright (C) 2013 Open Education Foundation
*
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
* l'Education Numérique en Afrique (GIP ENA)
*
* This file is part of OpenBoard.
*
* OpenBoard 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, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard 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 OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QList>
#include <QPointF>
#include <QPixmap>
#include <QTransform>
#include <QScrollBar>
#include <QFontMetrics>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include "core/UBApplication.h"
#include "UBDocumentNavigator.h"
#include "board/UBBoardController.h"
#include "adaptors/UBThumbnailAdaptor.h"
#include "adaptors/UBSvgSubsetAdaptor.h"
#include "document/UBDocumentController.h"
#include "domain/UBGraphicsScene.h"
#include "board/UBBoardPaletteManager.h"
#include "core/UBApplicationController.h"
#include "core/memcheck.h"
/**
* \brief Constructor
* @param parent as the parent widget
* @param name as the object name
*/
UBDocumentNavigator::UBDocumentNavigator(QWidget *parent, const char *name):QGraphicsView(parent)
, mScene(NULL)
, mNbColumns(1)
, mThumbnailWidth(0)
, mThumbnailMinWidth(100)
, mSelectedThumbnail(NULL)
{
setObjectName(name);
mScene = new QGraphicsScene(this);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setScene(mScene);
mThumbnailWidth = width() - 2*border();
setFrameShadow(QFrame::Plain);
connect(UBApplication::boardController, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(generateThumbnails(UBDocumentContainer*)));
connect(UBApplication::boardController, SIGNAL(documentPageUpdated(int)), this, SLOT(updateSpecificThumbnail(int)));
connect(UBApplication::boardController, SIGNAL(pageSelectionChanged(int)), this, SLOT(onScrollToSelectedPage(int)));
}
/**
* \brief Destructor
*/
UBDocumentNavigator::~UBDocumentNavigator()
{
if(NULL != mScene)
{
delete mScene;
mScene = NULL;
}
}
/**
* \brief Generate the thumbnails
*/
void UBDocumentNavigator::generateThumbnails(UBDocumentContainer* source)
{
mThumbsWithLabels.clear();
int selectedIndex = -1;
QList<QGraphicsItem*> graphicsItemList = mScene->items();
for(int i = 0; i < graphicsItemList.size(); i+=1)
{
QGraphicsItem* item = graphicsItemList.at(i);
if(item->isSelected())
selectedIndex = i;
mScene->removeItem(item);
delete item;
item = NULL;
}
for(int i = 0; i < source->selectedDocument()->pageCount(); i++)
{
//claudio This is a very bad hack and shows a architectural problem
// source->selectedDocument()->pageCount() != source->pageCount()
if(i>=source->pageCount() || source->pageAt(i)->isNull())
source->insertThumbPage(i);
const QPixmap* pix = source->pageAt(i);
Q_ASSERT(!pix->isNull());
int pageIndex = UBDocumentContainer::pageFromSceneIndex(i);
UBSceneThumbnailNavigPixmap* pixmapItem = new UBSceneThumbnailNavigPixmap(*pix, source->selectedDocument(), i);
QString label = tr("Page %0").arg(pageIndex);
UBThumbnailTextItem *labelItem = new UBThumbnailTextItem(label);
UBImgTextThumbnailElement thumbWithText(pixmapItem, labelItem);
thumbWithText.setBorder(border());
mThumbsWithLabels.append(thumbWithText);
mScene->addItem(pixmapItem);
mScene->addItem(labelItem);
}
if (selectedIndex >= 0 && selectedIndex < mThumbsWithLabels.count())
mSelectedThumbnail = mThumbsWithLabels.at(selectedIndex).getThumbnail();
else
mSelectedThumbnail = NULL;
// Draw the items
refreshScene();
}
void UBDocumentNavigator::onScrollToSelectedPage(int index)
{
int c = 0;
foreach(UBImgTextThumbnailElement el, mThumbsWithLabels)
{
if (c==index)
{
el.getThumbnail()->setSelected(true);
mSelectedThumbnail = el.getThumbnail();
}
else
{
el.getThumbnail()->setSelected(false);
}
c++;
}
if(NULL != mSelectedThumbnail)
centerOn(mSelectedThumbnail);
}
/**
* \brief Refresh the given thumbnail
* @param iPage as the given page related thumbnail
*/
void UBDocumentNavigator::updateSpecificThumbnail(int iPage)
{
const QPixmap* pix = UBApplication::boardController->pageAt(iPage);
UBSceneThumbnailNavigPixmap* newItem = new UBSceneThumbnailNavigPixmap(*pix, UBApplication::boardController->selectedDocument(), iPage);
// Get the old thumbnail
UBSceneThumbnailNavigPixmap* oldItem = mThumbsWithLabels.at(iPage).getThumbnail();
if(NULL != oldItem)
{
mScene->removeItem(oldItem);
mScene->addItem(newItem);
mThumbsWithLabels[iPage].setThumbnail(newItem);
delete oldItem;
oldItem = NULL;
}
}
/**
* \brief Put the element in the right place in the scene.
*/
void UBDocumentNavigator::refreshScene()
{
qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio;
for(int i = 0; i < mThumbsWithLabels.size(); i++)
{
// Get the item
UBImgTextThumbnailElement& item = mThumbsWithLabels[i];
int columnIndex = i % mNbColumns;
int rowIndex = i / mNbColumns;
item.Place(rowIndex, columnIndex, mThumbnailWidth, thumbnailHeight);
}
scene()->setSceneRect(scene()->itemsBoundingRect());
}
/**
* \brief Set the number of thumbnails columns
* @param nbColumns as the number of columns
*/
void UBDocumentNavigator::setNbColumns(int nbColumns)
{
mNbColumns = nbColumns;
}
/**
* \brief Get the number of columns
* @return the number of thumbnails columns
*/
int UBDocumentNavigator::nbColumns()
{
return mNbColumns;
}
/**
* \brief Set the thumbnails minimum width
* @param width as the minimum width
*/
void UBDocumentNavigator::setThumbnailMinWidth(int width)
{
mThumbnailMinWidth = width;
}
/**
* \brief Get the thumbnails minimum width
* @return the minimum thumbnails width
*/
int UBDocumentNavigator::thumbnailMinWidth()
{
return mThumbnailMinWidth;
}
/**
* \brief Get the border size
* @return the border size in pixels
*/
int UBDocumentNavigator::border()
{
return 20;
}
/**
* \brief Handle the resize event
* @param event as the resize event
*/
void UBDocumentNavigator::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
// Update the thumbnails width
mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*border() : mThumbnailMinWidth;
if(mSelectedThumbnail)
centerOn(mSelectedThumbnail);
// Refresh the scene
refreshScene();
}
/**
* \brief Handle the mouse press event
* @param event as the mouse event
*/
void UBDocumentNavigator::mousePressEvent(QMouseEvent *event)
{
QGraphicsItem* pClickedItem = itemAt(event->pos());
if(NULL != pClickedItem)
{
// First, select the clicked item
UBSceneThumbnailNavigPixmap* pCrntItem = dynamic_cast<UBSceneThumbnailNavigPixmap*>(pClickedItem);
if(NULL == pCrntItem)
{
// If we fall here we may have clicked on the label instead of the thumbnail
UBThumbnailTextItem* pTextItem = dynamic_cast<UBThumbnailTextItem*>(pClickedItem);
if(NULL != pTextItem)
{
for(int i = 0; i < mThumbsWithLabels.size(); i++)
{
const UBImgTextThumbnailElement& el = mThumbsWithLabels.at(i);
if(el.getCaption() == pTextItem)
{
pCrntItem = el.getThumbnail();
break;
}
}
}
}
int index = 0;
for(int i = 0; i < mThumbsWithLabels.size(); i++)
{
if (mThumbsWithLabels.at(i).getThumbnail() == pCrntItem)
{
mSelectedThumbnail = pCrntItem;
index = i;
break;
}
}
UBApplication::boardController->setActiveDocumentScene(index);
}
QGraphicsView::mousePressEvent(event);
}
void UBDocumentNavigator::mouseReleaseEvent(QMouseEvent *event)
{
event->accept();
}

@ -75,17 +75,17 @@ void UBDocumentThumbnailWidget::mouseMoveEvent(QMouseEvent *event)
QList<QGraphicsItem*> graphicsItems = items(mMousePressPos);
UBSceneThumbnailPixmap* sceneItem = 0;
UBThumbnailPixmap* sceneItem = 0;
while (!graphicsItems.isEmpty() && !sceneItem)
sceneItem = dynamic_cast<UBSceneThumbnailPixmap*>(graphicsItems.takeFirst());
sceneItem = dynamic_cast<UBThumbnailPixmap*>(graphicsItems.takeFirst());
if (sceneItem)
{
QDrag *drag = new QDrag(this);
QList<UBMimeDataItem> mimeDataItems;
foreach (QGraphicsItem *item, selectedItems())
mimeDataItems.append(UBMimeDataItem(sceneItem->proxy(), mGraphicItems.indexOf(item)));
mimeDataItems.append(UBMimeDataItem(sceneItem->documentProxy(), mGraphicItems.indexOf(item)));
UBMimeData *mime = new UBMimeData(mimeDataItems);
drag->setMimeData(mime);
@ -150,21 +150,21 @@ void UBDocumentThumbnailWidget::dragMoveEvent(QDragMoveEvent *event)
mScrollTimer->stop();
}
QList<UBSceneThumbnailPixmap*> pixmapItems;
QList<UBThumbnailPixmap*> pixmapItems;
foreach (QGraphicsItem *item, scene()->items(mapToScene(boundingFrame)))
{
UBSceneThumbnailPixmap* sceneItem = dynamic_cast<UBSceneThumbnailPixmap*>(item);
UBThumbnailPixmap* sceneItem = dynamic_cast<UBThumbnailPixmap*>(item);
if (sceneItem)
pixmapItems.append(sceneItem);
}
int minDistance = 0;
QGraphicsItem *underlyingItem = itemAt(event->pos());
mClosestDropItem = dynamic_cast<UBSceneThumbnailPixmap*>(underlyingItem);
mClosestDropItem = dynamic_cast<UBThumbnailPixmap*>(underlyingItem);
if (!mClosestDropItem)
{
foreach (UBSceneThumbnailPixmap *item, pixmapItems)
foreach (UBThumbnailPixmap *item, pixmapItems)
{
qreal scale = item->transform().m11();
QPointF itemCenter(
@ -305,7 +305,7 @@ void UBDocumentThumbnailWidget::hightlightItem(int index)
}
if (0 <= index && index < mGraphicItems.length())
{
UBSceneThumbnailPixmap *thumbnail = dynamic_cast<UBSceneThumbnailPixmap*>(mGraphicItems.at(index));
UBThumbnailPixmap *thumbnail = dynamic_cast<UBThumbnailPixmap*>(mGraphicItems.at(index));
if (thumbnail)
thumbnail->highlight();
}

@ -71,7 +71,7 @@ class UBDocumentThumbnailWidget: public UBThumbnailWidget
void deleteDropCaret();
QGraphicsRectItem *mDropCaretRectItem;
UBSceneThumbnailPixmap *mClosestDropItem;
UBThumbnailPixmap *mClosestDropItem;
bool mDropIsRight;
bool mDragEnabled;
QTimer* mScrollTimer;

@ -60,7 +60,7 @@ UBPageNavigationWidget::UBPageNavigationWidget(QWidget *parent, const char *name
mLayout = new QVBoxLayout(this);
setLayout(mLayout);
mNavigator = new UBDocumentNavigator(this);
mNavigator = new UBBoardThumbnailsView(this);
mLayout->addWidget(mNavigator, 1);
mHLayout = new QHBoxLayout();

@ -38,7 +38,7 @@
#include <QLabel>
#include <QString>
#include "UBDocumentNavigator.h"
#include "UBBoardThumbnailsView.h"
#include "UBDockPaletteWidget.h"
#include "document/UBDocumentProxy.h"
@ -70,7 +70,7 @@ private:
int border();
/** The thumbnails navigator widget */
UBDocumentNavigator* mNavigator;
UBBoardThumbnailsView* mNavigator;
/** The layout */
QVBoxLayout* mLayout;
QHBoxLayout* mHLayout;

@ -34,34 +34,29 @@
#include "core/memcheck.h"
UBThumbnailView::UBThumbnailView()
UBThumbnailView::UBThumbnailView(UBGraphicsScene *scene, QWidget* parent)
: QGraphicsView(scene, parent)
, mHBoxLayout(new QHBoxLayout(this))
{
setAcceptDrops(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
}
UBThumbnailView::~UBThumbnailView()
{
// NOOP
}
int nominalWidth = scene->nominalSize().width();
int nominalHeight = scene->nominalSize().height();
QRectF nominalSceneRect(-nominalWidth/2, -nominalHeight/2, nominalWidth, nominalHeight);
fitInView(nominalSceneRect, Qt::KeepAspectRatio);
setSceneRect(nominalSceneRect);
void UBThumbnailView::drawBackground(QPainter *painter, const QRectF &rect)
{
// Do not draw crossed background in thumbnails
if (qobject_cast<UBGraphicsScene*>(scene())->isDarkBackground())
{
painter->fillRect(rect, QBrush(QColor(Qt::black)));
}
else
{
painter->fillRect(rect, QBrush(QColor(Qt::white)));
}
}
setStyleSheet( "QGraphicsView { border-style: none; }" );
void UBThumbnailView::mouseDoubleClickEvent ( QMouseEvent * event )
{
Q_UNUSED(event);
emit doubleClicked();
}
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
//set stylesheet
setObjectName("DockPaletteWidgetBox");
setStyleSheet("background:white");
mHBoxLayout->setAlignment(Qt::AlignHCenter);
setLayout(mHBoxLayout);
}

@ -31,6 +31,9 @@
#define UBTHUMBNAILVIEW_H_
#include <QGraphicsView>
#include <QLabel>
#include <QHBoxLayout>
#include <QDebug>
class UBGraphicsScene;
@ -39,15 +42,15 @@ class UBThumbnailView : public QGraphicsView
Q_OBJECT
public:
UBThumbnailView();
virtual ~UBThumbnailView();
signals:
void doubleClicked();
UBThumbnailView(UBGraphicsScene *scene, QWidget* parent =0);
virtual ~UBThumbnailView()
{
protected:
virtual void drawBackground(QPainter *painter, const QRectF &rect);
virtual void mouseDoubleClickEvent ( QMouseEvent * event );
}
private:
QHBoxLayout* mHBoxLayout;
};

@ -34,6 +34,8 @@
#include "UBRubberBand.h"
#include "UBMainWindow.h"
#include <QWidget>
#include "board/UBBoardController.h"
#include "core/UBSettings.h"
@ -42,6 +44,8 @@
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
#include "board/UBBoardPaletteManager.h"
#include "core/memcheck.h"
UBThumbnailWidget::UBThumbnailWidget(QWidget* parent)
@ -225,7 +229,7 @@ void UBThumbnailWidget::mousePressEvent(QMouseEvent *event)
mClickTime = QTime::currentTime();
mMousePressPos = event->pos();
UBSceneThumbnailPixmap* sceneItem = dynamic_cast<UBSceneThumbnailPixmap*>(itemAt(mMousePressPos));
UBThumbnailPixmap* sceneItem = dynamic_cast<UBThumbnailPixmap*>(itemAt(mMousePressPos));
if(sceneItem==NULL)
{
event->ignore();
@ -359,7 +363,7 @@ void UBThumbnailWidget::mouseMoveEvent(QMouseEvent *event)
{
if (lassoSelectedItem)
{
UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast<UBSceneThumbnailPixmap*>(lassoSelectedItem);
UBThumbnailPixmap *thumbnailItem = dynamic_cast<UBThumbnailPixmap*>(lassoSelectedItem);
if (thumbnailItem)
lassoSelectedThumbnailItems += lassoSelectedItem;
}
@ -385,7 +389,7 @@ void UBThumbnailWidget::mouseMoveEvent(QMouseEvent *event)
{
if (lassoSelectedItem)
{
UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast<UBSceneThumbnailPixmap*>(lassoSelectedItem);
UBThumbnailPixmap *thumbnailItem = dynamic_cast<UBThumbnailPixmap*>(lassoSelectedItem);
if (thumbnailItem)
lassoSelectedThumbnailItems += lassoSelectedItem;
@ -767,163 +771,226 @@ UBThumbnail::~UBThumbnail()
delete mSelectionItem;
}
UBSceneThumbnailNavigPixmap::UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex)
: UBSceneThumbnailPixmap(pix, proxy, pSceneIndex)
, bButtonsVisible(false)
, bCanDelete(false)
, bCanMoveUp(false)
, bCanMoveDown(false)
void UBWidgetTextThumbnailElement::Place(int row, int col, qreal width, qreal height)
{
if(0 <= UBDocumentContainer::pageFromSceneIndex(pSceneIndex)){
setAcceptHoverEvents(true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
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();
UBSceneThumbnailNavigPixmap::~UBSceneThumbnailNavigPixmap()
{
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);
void UBSceneThumbnailNavigPixmap::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
bButtonsVisible = true;
bCanDelete = true;
bCanMoveDown = false;
bCanMoveUp = false;
if(sceneIndex() < proxy()->pageCount() - 1)
bCanMoveDown = true;
if(sceneIndex() > 0)
bCanMoveUp = true;
if(proxy()->pageCount() == 1)
bCanDelete = false;
update();
}
// Apply the scaling
this->thumbnail->setTransform(transform);
this->thumbnail->setFlag(QGraphicsItem::ItemIsSelectable, true);
void UBSceneThumbnailNavigPixmap::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
bButtonsVisible = false;
update();
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);
}
}
}
void UBSceneThumbnailNavigPixmap::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
void UBDraggableThumbnail::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QGraphicsProxyWidget::paint(painter, option, widget);
using namespace UBThumbnailUI;
UBSceneThumbnailPixmap::paint(painter, option, widget);
if(bButtonsVisible)
{
if(bCanDelete)
painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/close.svg"));
if (editable())
{
if(deletable())
draw(painter, *getIcon("close"));
else
painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/closeDisabled.svg"));
draw(painter, *getIcon("closeDisabled"));
painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicate.svg"));
draw(painter, *getIcon("duplicate"));
if(bCanMoveUp)
painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUp.svg"));
if(movableUp())
draw(painter, *getIcon("moveUp"));
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"));
draw(painter, *getIcon("moveUpDisabled"));
if(movableDown())
draw(painter, *getIcon("moveDown"));
else
painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menuDisabled.svg"));
draw(painter, *getIcon("moveDownDisabled"));
}
}
void UBSceneThumbnailNavigPixmap::mousePressEvent(QGraphicsSceneMouseEvent *event)
void UBDraggableThumbnail::hoverEnterEvent(QGraphicsSceneHoverEvent *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(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();
showUI();
update();
}
void UBDraggableThumbnail::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
hideUI();
update();
}
void UBSceneThumbnailNavigPixmap::deletePage()
void UBDraggableThumbnail::deletePage()
{
if(UBApplication::mainWindow->yesNoQuestion(QObject::tr("Remove Page"), QObject::tr("Are you sure you want to remove 1 page from the selected document '%0'?").arg(UBApplication::documentController->selectedDocument()->metaData(UBSettings::documentName).toString()))){
UBApplication::boardController->deleteScene(sceneIndex());
}
}
void UBSceneThumbnailNavigPixmap::duplicatePage()
void UBDraggableThumbnail::duplicatePage()
{
UBApplication::boardController->duplicateScene(sceneIndex());
}
void UBSceneThumbnailNavigPixmap::moveUpPage()
void UBDraggableThumbnail::moveUpPage()
{
if (sceneIndex()!=0)
UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() - 1);
}
void UBSceneThumbnailNavigPixmap::moveDownPage()
void UBDraggableThumbnail::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)
void UBDraggableThumbnail::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
int labelSpacing = 0;
if(this->caption)
event->accept();
}
void UBDraggableThumbnail::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
QPointF p = event->pos();
using namespace UBThumbnailUI;
if (triggered(p.y()))
{
QFontMetrics fm(this->caption->font());
labelSpacing = UBSettings::thumbnailSpacing + fm.height();
if(deletable() && getIcon("close")->triggered(p.x()))
deletePage();
else if(getIcon("duplicate")->triggered(p.x()))
duplicatePage();
else if(movableUp() && getIcon("moveUp")->triggered(p.x()))
moveUpPage();
else if (movableDown() && getIcon("moveDown")->triggered(p.x()))
moveDownPage();
}
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);
event->accept();
}
QTransform transform;
transform.scale(scaleFactor, scaleFactor);
// Apply the scaling
this->thumbnail->setTransform(transform);
this->thumbnail->setFlag(QGraphicsItem::ItemIsSelectable, true);
void UBDraggableThumbnailView::updatePos(qreal width, qreal height)
{
QFontMetrics fm(mPageNumber->font());
int labelSpacing = UBSettings::thumbnailSpacing + fm.height();
if(pix)
{
pix->setColumn(col);
pix->setRow(row);
}
int w = boundingRect().width();
int h = boundingRect().height();
QPointF pos(border + (width - w * scaleFactor) / 2 + col * (width + border),
border + row * (height + border + labelSpacing) + (height - h * scaleFactor) / 2);
qreal scaledWidth = width / w;
qreal scaledHeight = height / h;
qreal scaledFactor = qMin(scaledWidth, scaledHeight);
this->thumbnail->setPos(pos);
QTransform transform;
transform.scale(scaledFactor, scaledFactor);
if(this->caption)
{
QFontMetrics fm(this->caption->font());
QString elidedText = fm.elidedText(this->caption->toPlainText(), Qt::ElideRight, width);
// Apply the scaling
setTransform(transform);
setFlag(QGraphicsItem::ItemIsSelectable, true);
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);
}
}
QPointF position((width - w * scaledFactor) / 2,
sceneIndex() * (height + labelSpacing) + (height - h * scaledFactor) / 2);
setPos(position);
position.setY(position.y() + (height + h * scaledFactor) / 2);
position.setX(position.x() + (w * scaledFactor - fm.width(mPageNumber->toPlainText())) / 2);
mPageNumber->setPos(position);
}
UBThumbnailUI::UBThumbnailUIIcon* UBThumbnailUI::addIcon(const QString& thumbnailIcon, int pos)
{
QString thumbnailIconPath = ":images/" + thumbnailIcon + ".svg";
UBThumbnailUIIcon* newIcon = new UBThumbnailUIIcon(thumbnailIconPath, pos);
using namespace UBThumbnailUI::_private;
if (!newIcon)
qDebug() << "cannot add Icon : check path : " + thumbnailIconPath;
else
catalog.insert(thumbnailIcon, newIcon);
return newIcon;
}
UBThumbnailUI::UBThumbnailUIIcon* UBThumbnailUI::getIcon(const QString& thumbnailIcon)
{
using namespace UBThumbnailUI::_private;
if (!catalog.contains(thumbnailIcon))
qDebug() << "cannot get Icon: check path ':images/" + thumbnailIcon + ".svg'";
return catalog.value(thumbnailIcon, NULL);
}
void UBThumbnailUI::draw(QPainter *painter, const UBThumbnailUIIcon &thumbnailIcon)
{
using namespace UBThumbnailUI;
painter->drawPixmap(thumbnailIcon.pos() * (ICONSIZE + ICONSPACING), 0, ICONSIZE, ICONSIZE, thumbnailIcon);
}
void UBThumbnailUI::_private::initCatalog()
{
using namespace UBThumbnailUI;
using namespace UBThumbnailUI::_private;
addIcon("close", 0);
addIcon("closeDisabled", 0);
addIcon("duplicate", 1);
addIcon("moveUp", 2);
addIcon("moveUpDisabled", 2);
addIcon("moveDown", 3);
addIcon("moveDownDisabled", 3);
}
bool UBThumbnailUI::triggered(qreal y)
{
return (y >= 0 && y <= UBThumbnailUI::ICONSIZE);
}

@ -38,10 +38,14 @@
#include "frameworks/UBCoreGraphicsScene.h"
#include "core/UBSettings.h"
#include "domain/UBItem.h"
#include "gui/UBThumbnailView.h"
#include "document/UBDocumentProxy.h"
#include <QLabel>
#include <QHBoxLayout>
#define STARTDRAGTIME 1000000
#define BUTTONSIZE 48
#define BUTTONSPACING 5
class UBDocumentProxy;
class UBThumbnailTextItem;
@ -135,7 +139,6 @@ class UBThumbnailWidget : public QGraphicsView
QTime mClickTime;
};
class UBThumbnail
{
public:
@ -190,6 +193,8 @@ class UBThumbnail
void setColumn(int column) { mColumn = column; }
int row() { return mRow; }
void setRow(int row) { mRow = row; }
UBThumbnailTextItem *label(){return mLabel;}
void setLabel(UBThumbnailTextItem *label){mLabel = label;}
protected:
QGraphicsRectItem *mSelectionItem;
@ -198,41 +203,112 @@ class UBThumbnail
int mColumn;
int mRow;
UBThumbnailTextItem *mLabel;
};
class UBThumbnailSvg : public QGraphicsSvgItem, public UBThumbnail
class UBThumbnailTextItem : public QGraphicsTextItem
{
public:
UBThumbnailSvg(const QString& path)
: QGraphicsSvgItem(path)
UBThumbnailTextItem(int index)
: QGraphicsTextItem(tr("Page %0").arg(index+1))
, mWidth(0)
, mUnelidedText(toPlainText())
, mIsHighlighted(false)
{
}
UBThumbnailTextItem(const QString& text)
: QGraphicsTextItem(text)
, mWidth(0)
, mUnelidedText(text)
, mIsHighlighted(false)
{
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
virtual ~UBThumbnailSvg()
QRectF boundingRect() const { return QRectF(QPointF(0.0, 0.0), QSize(mWidth, QFontMetricsF(font()).height() + 5));}
void setWidth(qreal pWidth)
{
// NOOP
if (mWidth != pWidth)
{
prepareGeometryChange();
mWidth = pWidth;
computeText();
}
}
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
qreal width() {return mWidth;}
void highlight()
{
QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option);
QGraphicsSvgItem::paint(painter, &styleOption, widget);
if (!mIsHighlighted)
{
mIsHighlighted = true;
computeText();
}
}
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
void computeText()
{
UBThumbnail::itemChange(this, change, value);
return QGraphicsSvgItem::itemChange(change, value);
QFontMetricsF fm(font());
QString elidedText = fm.elidedText(mUnelidedText, Qt::ElideRight, mWidth);
if (mIsHighlighted)
{
setHtml("<span style=\"color: #6682b5\">" + elidedText + "</span>");
}
else
{
setPlainText(elidedText);
}
}
private:
qreal mWidth;
QString mUnelidedText;
bool mIsHighlighted;
};
class UBWidgetTextThumbnailElement
{
protected:
QGraphicsItem* thumbnail;
UBThumbnailTextItem* caption;
int border;
public:
UBWidgetTextThumbnailElement(QGraphicsProxyWidget* proxyWidget, UBThumbnailTextItem* text)
: thumbnail(proxyWidget)
, caption(text)
, border(0)
{
}
QGraphicsItem* getThumbnail() const { return this->thumbnail; }
void setThumbnail(QGraphicsItem* newGItem) { this->thumbnail = newGItem; }
UBThumbnailTextItem* getCaption() const { return this->caption; }
void setCaption(UBThumbnailTextItem* newcaption) { this->caption = newcaption; }
void Place(int row, int col, qreal width, qreal height);
int getBorder() const { return this->border; }
void setBorder(int newBorder) { this->border = newBorder; }
};
class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail
{
public:
UBThumbnailPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex)
: QGraphicsPixmapItem(pix)
, mDocumentProxy(proxy)
, mSceneIndex(pSceneIndex)
{
}
UBThumbnailPixmap(const QPixmap& pix)
: QGraphicsPixmapItem(pix)
{
@ -241,11 +317,6 @@ class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
virtual ~UBThumbnailPixmap()
{
// NOOP
}
virtual QPainterPath shape () const
{
QPainterPath path;
@ -253,7 +324,6 @@ class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail
return path;
}
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option);
@ -265,28 +335,44 @@ class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail
UBThumbnail::itemChange(this, change, value);
return QGraphicsPixmapItem::itemChange(change, value);
}
};
void highlight()
{
class UBSceneThumbnailPixmap : public UBThumbnailPixmap
}
UBDocumentProxy* documentProxy()
{
return mDocumentProxy;
}
int sceneIndex()
{
return mSceneIndex;
}
protected:
UBDocumentProxy* mDocumentProxy;
int mSceneIndex;
};
class UBThumbnailProxyWidget : public QGraphicsProxyWidget
{
public:
UBSceneThumbnailPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex)
: UBThumbnailPixmap(pix)
, mProxy(proxy)
, mSceneIndex(pSceneIndex)
UBThumbnailProxyWidget(UBDocumentProxy* proxy, int index)
: mDocumentProxy(proxy)
, mSceneIndex(index)
{
// NOOP
}
virtual ~UBSceneThumbnailPixmap()
UBDocumentProxy* documentProxy()
{
// NOOP
return mDocumentProxy;
}
UBDocumentProxy* proxy()
void setSceneIndex(int i)
{
return mProxy;
mSceneIndex = i;
}
int sceneIndex()
@ -294,27 +380,62 @@ class UBSceneThumbnailPixmap : public UBThumbnailPixmap
return mSceneIndex;
}
void highlight()
{
//NOOP
}
private:
UBDocumentProxy* mProxy;
private:
UBDocumentProxy* mDocumentProxy;
int mSceneIndex;
};
class UBSceneThumbnailNavigPixmap : public UBSceneThumbnailPixmap
class UBDraggableThumbnail : public UBThumbnailProxyWidget
{
public:
UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex);
~UBSceneThumbnailNavigPixmap();
UBDraggableThumbnail(UBDocumentProxy* documentProxy, int index)
: UBThumbnailProxyWidget(documentProxy, index)
, mEditable(false)
{
}
bool editable()
{
return mEditable;
}
bool deletable()
{
return documentProxy()->pageCount() > 1;
}
bool movableUp()
{
return sceneIndex() > 0;
}
bool movableDown()
{
return sceneIndex() < (documentProxy()->pageCount() -1);
}
void showUI()
{
setEditable(true);
}
void hideUI()
{
setEditable(false);
}
void setEditable(bool editable)
{
mEditable = editable;
}
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
void deletePage();
@ -322,117 +443,104 @@ class UBSceneThumbnailNavigPixmap : public UBSceneThumbnailPixmap
void moveUpPage();
void moveDownPage();
bool bButtonsVisible;
bool bCanDelete;
bool bCanMoveUp;
bool bCanMoveDown;
bool mEditable;
};
class UBThumbnailVideo : public UBThumbnailPixmap
class UBDraggableThumbnailPixmap : public UBDraggableThumbnail
{
public:
UBThumbnailVideo(const QUrl &path)
: UBThumbnailPixmap(QPixmap(":/images/movie.svg"))
, mPath(path)
{
// NOOP
}
virtual ~UBThumbnailVideo()
{
// NOOP
}
QUrl path()
{
return mPath;
}
private:
QUrl mPath;
UBDraggableThumbnailPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex);
~UBDraggableThumbnailPixmap();
};
class UBThumbnailTextItem : public QGraphicsTextItem
class UBDraggableThumbnailView : public UBDraggableThumbnail
{
public:
UBThumbnailTextItem(const QString& text)
: QGraphicsTextItem(text)
, mUnelidedText(text)
, mIsHighlighted(false)
UBDraggableThumbnailView(UBThumbnailView* thumbnailView, UBDocumentProxy* documentProxy, int index)
: UBDraggableThumbnail(documentProxy, index)
, mThumbnailView(thumbnailView)
, mPageNumber(new UBThumbnailTextItem(index))
{
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setWidget(mThumbnailView);
setAcceptDrops(true);
}
QRectF boundingRect() const { return QRectF(QPointF(0.0, 0.0), QSize(mWidth, QFontMetricsF(font()).height() + 5));}
void setWidth(qreal pWidth)
~UBDraggableThumbnailView()
{
if (mWidth != pWidth)
{
prepareGeometryChange();
mWidth = pWidth;
computeText();
}
};
delete mPageNumber; // not a child of "this" QObject so it has to be deleted manually
}
qreal width() {return mWidth;}
void updatePos(qreal w, qreal h);
void highlight()
UBThumbnailView* thumbnailView()
{
if (!mIsHighlighted)
{
mIsHighlighted = true;
computeText();
}
return mThumbnailView;
}
void computeText()
UBThumbnailTextItem* pageNumber()
{
QFontMetricsF fm(font());
QString elidedText = fm.elidedText(mUnelidedText, Qt::ElideRight, mWidth);
return mPageNumber;
}
if (mIsHighlighted)
{
setHtml("<span style=\"color: #6682b5\">" + elidedText + "</span>");
}
else
{
setPlainText(elidedText);
}
void setPageNumber(int i)
{
mPageNumber->setPlainText(tr("Page %0").arg(i+1));
}
private:
qreal mWidth;
QString mUnelidedText;
bool mIsHighlighted;
private:
UBThumbnailView* mThumbnailView;
UBThumbnailTextItem* mPageNumber;
};
class UBImgTextThumbnailElement
namespace UBThumbnailUI
{
private:
UBSceneThumbnailNavigPixmap* thumbnail;
UBThumbnailTextItem* caption;
int border;
const int ICONSIZE = 96;
const int ICONSPACING = 10;
public:
UBImgTextThumbnailElement(UBSceneThumbnailNavigPixmap* thumb, UBThumbnailTextItem* text): border(0)
class UBThumbnailUIIcon : public QPixmap
{
this->thumbnail = thumb;
this->caption = text;
}
public:
UBSceneThumbnailNavigPixmap* getThumbnail() const { return this->thumbnail; }
void setThumbnail(UBSceneThumbnailNavigPixmap* newGItem) { this->thumbnail = newGItem; }
UBThumbnailUIIcon(const QString& filename, int pos)
: QPixmap(QSize(ICONSIZE, ICONSIZE))
, mPos(pos)
{
QSvgRenderer svgRenderer(filename);
QPainter painter;
fill(Qt::transparent);
painter.begin(this);
svgRenderer.render(&painter);
painter.end();
}
UBThumbnailTextItem* getCaption() const { return this->caption; }
void setCaption(UBThumbnailTextItem* newcaption) { this->caption = newcaption; }
int pos() const
{
return mPos;
}
void Place(int row, int col, qreal width, qreal height);
bool triggered(qreal x) const
{
using namespace UBThumbnailUI;
return (x >= pos()*(ICONSIZE + ICONSPACING) && x <= (pos()+1)*ICONSIZE + pos()*ICONSPACING);
}
int getBorder() const { return this->border; }
void setBorder(int newBorder) { this->border = newBorder; }
};
private:
int mPos;
};
namespace _private
{
//do not use this directly
static QMap<QString, UBThumbnailUIIcon*> catalog;
void initCatalog();
}
UBThumbnailUIIcon* addIcon(const QString& thumbnailIcon, int pos);
UBThumbnailUIIcon* getIcon(const QString& thumbnailIcon);
void draw(QPainter* painter, const UBThumbnailUIIcon& thumbnailIcon);
bool triggered(qreal y);
}
#endif /* UBTHUMBNAILWIDGET_H_ */

@ -24,7 +24,6 @@ HEADERS += src/gui/UBThumbnailView.h \
src/gui/UBActionPalette.h \
src/gui/UBFavoriteToolPalette.h \
src/gui/UBKeyboardPalette.h \
src/gui/UBDocumentNavigator.h \
src/gui/UBDockPalette.h \
src/gui/UBPropertyPalette.h \
src/gui/UBUpdateDlg.h \
@ -41,7 +40,8 @@ HEADERS += src/gui/UBThumbnailView.h \
src/gui/UBMessagesDialog.h \
src/gui/UBOpenSankoreImporterWidget.h \
src/gui/UBStartupHintsPalette.h \
src/gui/UBBackgroundPalette.h
src/gui/UBBackgroundPalette.h \
src/gui/UBBoardThumbnailsView.h
SOURCES += src/gui/UBThumbnailView.cpp \
src/gui/UBFloatingPalette.cpp \
src/gui/UBToolbarButtonGroup.cpp \
@ -68,7 +68,6 @@ SOURCES += src/gui/UBThumbnailView.cpp \
src/gui/UBActionPalette.cpp \
src/gui/UBFavoriteToolPalette.cpp \
src/gui/UBKeyboardPalette.cpp \
src/gui/UBDocumentNavigator.cpp \
src/gui/UBDockPalette.cpp \
src/gui/UBPropertyPalette.cpp \
src/gui/UBUpdateDlg.cpp \
@ -85,7 +84,8 @@ SOURCES += src/gui/UBThumbnailView.cpp \
src/gui/UBMessagesDialog.cpp \
src/gui/UBOpenSankoreImporterWidget.cpp \
src/gui/UBStartupHintsPalette.cpp \
src/gui/UBBackgroundPalette.cpp
src/gui/UBBackgroundPalette.cpp \
src/gui/UBBoardThumbnailsView.cpp
win32:SOURCES += src/gui/UBKeyboardPalette_win.cpp
macx:OBJECTIVE_SOURCES += src/gui/UBKeyboardPalette_mac.mm
linux-g++:SOURCES += src/gui/UBKeyboardPalette_linux.cpp

@ -304,6 +304,7 @@ void UBGraphicsCompass::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
updateResizeCursor();
updateDrawCursor();
mDrewCenterCross = false;
event->accept();
}
else if (closeButtonRect().contains(event->pos()))

Loading…
Cancel
Save