Merge branch 'dev' (1.3.5 release)

preferencesAboutTextFull
Craig Watson 7 years ago
commit 00ab81e321
  1. 2
      OpenBoard.pro
  2. 2
      release_scripts/windows/OpenBoard.iss
  3. 150
      resources/i18n/OpenBoard_de.ts
  4. 3187
      resources/i18n/OpenBoard_eu.ts
  5. 58
      src/adaptors/UBSvgSubsetAdaptor.cpp
  6. 2
      src/adaptors/UBSvgSubsetAdaptor.h
  7. 14
      src/board/UBBoardView.cpp
  8. 8
      src/core/UBApplicationController.cpp
  9. 2
      src/core/UBDisplayManager.cpp
  10. 8
      src/core/UBOpenSankoreImporter.cpp
  11. 25
      src/core/UBPersistenceManager.cpp
  12. 4
      src/core/UBPersistenceManager.h
  13. 11
      src/core/UBSettings.cpp
  14. 5
      src/core/UBSettings.h
  15. 5
      src/desktop/UBDesktopAnnotationController.cpp
  16. 10
      src/document/UBDocumentController.cpp
  17. 3
      src/document/UBDocumentController.h
  18. 5
      src/domain/UBGraphicsGroupContainerItem.cpp
  19. 6
      src/domain/UBGraphicsMediaItem.cpp
  20. 1
      src/domain/UBGraphicsMediaItem.h
  21. 22
      src/domain/UBGraphicsScene.cpp
  22. 11
      src/domain/UBGraphicsStrokesGroup.cpp
  23. 41
      src/domain/UBGraphicsTextItem.cpp
  24. 2
      src/domain/UBGraphicsTextItem.h
  25. 28
      src/domain/UBGraphicsTextItemDelegate.cpp
  26. 1
      src/domain/UBGraphicsTextItemDelegate.h
  27. 2
      src/frameworks/UBGeometryUtils.cpp
  28. 139
      src/gui/UBDocumentTreeWidget.cpp
  29. 2
      src/gui/UBDocumentTreeWidget.h
  30. 22
      src/tools/UBGraphicsCompass.h
  31. 13
      src/tools/UBGraphicsProtractor.cpp
  32. 1
      src/tools/UBGraphicsProtractor.h
  33. 161
      src/tools/UBGraphicsTriangle.cpp
  34. 10
      src/tools/UBGraphicsTriangle.h

@ -10,7 +10,7 @@ CONFIG += debug_and_release \
VERSION_MAJ = 1
VERSION_MIN = 3
VERSION_PATCH = 4
VERSION_PATCH = 5
VERSION_TYPE = r # a = alpha, b = beta, rc = release candidate, r = release, other => error
VERSION_BUILD = 0

@ -119,7 +119,7 @@ Source: "{#QtDir}\plugins\mediaservice\wmfengine.dll"; DestDir: "{app}\mediaserv
Source: "{#QtDir}\plugins\mediaservice\wmfengined.dll"; DestDir: "{app}\mediaservice"; Flags: ignoreversion
;OpenBoardImporter
Source: "{#ProjectRoot}\..\OpenBoard-Importer\release\OpenBoardImporter.exe"; DestDir: "{app}\Importer"; Flags: ignoreversion
Source: "{#ProjectRoot}\..\OpenBoard-Importer\release\OpenBoardImporter.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtLibs}\Qt5Core.dll"; DestDir: "{app}"
Source: "{#QtLibs}\Qt5Gui.dll"; DestDir: "{app}"

@ -169,7 +169,7 @@
</message>
<message>
<source>Quit</source>
<translation>Verlassen</translation>
<translation>Beenden</translation>
</message>
<message>
<source>Eraser</source>
@ -409,7 +409,7 @@
</message>
<message>
<source>Multi Screen</source>
<translation>Geteilter Bildschirm</translation>
<translation>Mehrere Bildschirme</translation>
</message>
<message>
<source>Wide Size (16/9)</source>
@ -477,7 +477,7 @@
</message>
<message>
<source>Light</source>
<translation>Licht</translation>
<translation>Hell</translation>
</message>
<message>
<source>Grid Light Background</source>
@ -561,7 +561,7 @@
</message>
<message>
<source>Highlight </source>
<translation>Highlight </translation>
<translation>Hervorheben </translation>
</message>
<message>
<source>Ctrl+M</source>
@ -569,7 +569,7 @@
</message>
<message>
<source>Selector</source>
<translation>Selector</translation>
<translation>Auswahl</translation>
</message>
<message>
<source>Select And Modify Objects</source>
@ -697,7 +697,7 @@
</message>
<message>
<source>Flash Trap</source>
<translation>Falle einblenden</translation>
<translation>Einblendung einfangen</translation>
</message>
<message>
<source>Trap Flash Content</source>
@ -705,7 +705,7 @@
</message>
<message>
<source>Web Trap</source>
<translation>Webfalle</translation>
<translation>Internet einfangen</translation>
</message>
<message>
<source>Trap Web Content</source>
@ -793,11 +793,11 @@
</message>
<message>
<source>Open Tutorial</source>
<translation type="unfinished"></translation>
<translation>Anleitung öffnen</translation>
</message>
<message>
<source>Open the tutorial web page</source>
<translation type="unfinished"></translation>
<translation>Öffnen der Anleitung im Internet</translation>
</message>
</context>
<context>
@ -854,7 +854,7 @@
</message>
<message>
<source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
<translation type="unfinished">Wollen Sie wirklich 1 Seite des gewählten Dokuments &apos;%0&apos; entfernen?</translation>
<translation>Wollen Sie wirklich die ausgewählte Seite des Dokuments &apos;%0&apos; entfernen?</translation>
</message>
</context>
<context>
@ -876,30 +876,30 @@
</message>
<message>
<source>New update available, would you go to the web page ?</source>
<translation>Neues Update verfügbar, möchten Sie auf die Webseite gehen?</translation>
<translation>Neue Aktualisierung verfügbar, möchten Sie auf die Internetseite gehen?</translation>
</message>
<message>
<source>No update available</source>
<translation>Kein Update verfügbar</translation>
<translation>Keine Aktualisierung verfügbar</translation>
</message>
<message>
<source>Update available</source>
<translation>Update verfügbar</translation>
<translation>Aktualisierung verfügbar</translation>
</message>
<message>
<source>Update</source>
<translation>Update</translation>
<translation>Aktualisierung</translation>
</message>
</context>
<context>
<name>UBBoardController</name>
<message>
<source>Downloading content %1 failed</source>
<translation>Fehler beim Download von %1</translation>
<translation>Fehler beim Herunterladen von %1</translation>
</message>
<message>
<source>Download finished</source>
<translation>Download beendet</translation>
<translation>Herunterladen beendet</translation>
</message>
<message>
<source>Unknown tool type %1</source>
@ -919,11 +919,11 @@
</message>
<message>
<source>Delete page %1 from document</source>
<translation type="unfinished">Seite %1 des Dokuments löschen</translation>
<translation>Seite %1 des Dokuments löschen</translation>
</message>
<message>
<source>Page %1 deleted</source>
<translation type="unfinished">Seite %1 gelöscht</translation>
<translation>Seite %1 gelöscht</translation>
</message>
<message>
<source>Add file operation failed: file copying error</source>
@ -939,11 +939,11 @@
</message>
<message>
<source>Saving document...</source>
<translation type="unfinished"></translation>
<translation>Dokument wird gespeichert...</translation>
</message>
<message>
<source>Document has just been saved...</source>
<translation type="unfinished"></translation>
<translation>Dokument wurde gespeichert...</translation>
</message>
</context>
<context>
@ -1004,7 +1004,7 @@
</message>
<message>
<source>Show OpenBoard</source>
<translation type="unfinished"></translation>
<translation>Zeige OpenBoard</translation>
</message>
</context>
<context>
@ -1031,7 +1031,7 @@
</message>
<message>
<source>Duplicating Document %1</source>
<translation>Dokument %1 wird kopiert</translation>
<translation>Dokument %1 wird dupliziert</translation>
</message>
<message>
<source>Document %1 copied</source>
@ -1051,7 +1051,7 @@
</message>
<message>
<source>Empty Trash</source>
<translation>Leerer Papierkorb</translation>
<translation>Papierkorb leeren</translation>
</message>
<message>
<source>Are you sure you want to empty trash?</source>
@ -1063,7 +1063,7 @@
</message>
<message>
<source>Emptied trash</source>
<translation>Papierkorb geleert</translation>
<translation>Papierkorb wurde geleert</translation>
</message>
<message>
<source>Remove Folder</source>
@ -1071,7 +1071,7 @@
</message>
<message>
<source>Are you sure you want to remove the folder &apos;%1&apos; and all its content?</source>
<translation>Möchten Sie den Ordner &apos;%1 mit dem gesamten Inhalt wirklich entfernen?</translation>
<translation>Möchten Sie den Ordner &apos;%1 und seinen gesamten Inhalt wirklich entfernen?</translation>
</message>
<message>
<source>No document selected!</source>
@ -1099,7 +1099,7 @@
</message>
<message>
<source>Empty</source>
<translation>Leer</translation>
<translation>Leeren</translation>
</message>
<message>
<source>Trash</source>
@ -1138,15 +1138,15 @@
</message>
<message>
<source>The document &apos;%1&apos; has been generated with a newer version of OpenBoard (%2). By opening it, you may lose some information. Do you want to proceed?</source>
<translation type="unfinished"></translation>
<translation>Das Dokument &apos;%1&apos; wurde mit einer neueren Version von OpenBoard erstellt (%2). Beim Öffnen können einige Informationen verloren gehen. Möchten Sie fortfahren?</translation>
</message>
<message>
<source>Are you sure you want to remove all selected documents?</source>
<translation type="unfinished"></translation>
<translation>Möchten sie wirklich alle ausgewählten Dokumente entfernen?</translation>
</message>
<message>
<source>Remove multiple documents</source>
<translation type="unfinished"></translation>
<translation>Mehrere Dokumente entfernen</translation>
</message>
</context>
<context>
@ -1185,11 +1185,11 @@
</message>
<message>
<source>Import of file %1 successful.</source>
<translation type="unfinished">Import des Dokuments %1 erfolgreich.</translation>
<translation>Import der Datei %1 erfolgreich.</translation>
</message>
<message>
<source>Importing file %1</source>
<translation type="unfinished">Importieren von %1</translation>
<translation>Datei %1 wird importiert</translation>
</message>
</context>
<context>
@ -1212,8 +1212,8 @@
<message numerus="yes">
<source>%1 pages copied</source>
<translation>
<numerusform>%1 Seite kopiert</numerusform>
<numerusform>%1 Seiten kopiert</numerusform>
<numerusform>%1 Seite wurde kopiert</numerusform>
<numerusform>%1 Seiten wurden kopiert</numerusform>
</translation>
</message>
</context>
@ -1282,19 +1282,19 @@
</message>
<message>
<source>Export to OpenBoard Format</source>
<translation type="unfinished"></translation>
<translation>In das OpenBoard Format exportieren</translation>
</message>
<message>
<source>Export failed: location not writable</source>
<translation type="unfinished"></translation>
<translation>Export fehlgeschlagen: Zielpfad nicht beschreibbar</translation>
</message>
<message>
<source>Export failed</source>
<translation type="unfinished"></translation>
<translation>Export fehlgeschlagen</translation>
</message>
<message>
<source>Unable to export to the selected location. You do not have the permissions necessary to save the file.</source>
<translation type="unfinished"></translation>
<translation>Export im ausgewählten Zielpfad nicht möglich. Sie haben nicht die erforderliche Berechtigung um die Datei zu speichern.</translation>
</message>
</context>
<context>
@ -1317,15 +1317,15 @@
</message>
<message>
<source>Export failed: location not writable</source>
<translation type="unfinished"></translation>
<translation>Export fehlgeschlagen: Zielpfad nicht beschreibbar.</translation>
</message>
<message>
<source>Export failed</source>
<translation type="unfinished"></translation>
<translation>Export fehlgeschlagen</translation>
</message>
<message>
<source>Unable to export to the selected location. You do not have the permissions necessary to save the file.</source>
<translation type="unfinished"></translation>
<translation>Export im ausgewählten Zielpfad nicht möglich. Sie haben nicht die erforderliche Berechtigung um die Datei zu speichern.</translation>
</message>
</context>
<context>
@ -1531,19 +1531,19 @@
<name>UBGraphicsMediaItem</name>
<message>
<source>Media resource couldn&apos;t be resolved</source>
<translation type="unfinished"></translation>
<translation>Medienquelle konnte nicht aufgelöst werden</translation>
</message>
<message>
<source>Unsupported media format</source>
<translation type="unfinished"></translation>
<translation>Medienformat wird nicht unterstützt</translation>
</message>
<message>
<source>Media playback service not found</source>
<translation type="unfinished"></translation>
<translation>Dienst zum Abspielen von Mediainhalten nicht gefunden</translation>
</message>
<message>
<source>Media error: </source>
<translation type="unfinished"></translation>
<translation>Medienfehler: </translation>
</message>
</context>
<context>
@ -1582,11 +1582,11 @@
<name>UBGraphicsWidgetItemDelegate</name>
<message>
<source>Frozen</source>
<translation>Erstarrt</translation>
<translation>Fixiert</translation>
</message>
<message>
<source>Transform as Tool </source>
<translation>In Extra umwandeln</translation>
<translation>In Werkzeug umwandeln</translation>
</message>
</context>
<context>
@ -1601,7 +1601,7 @@
</message>
<message>
<source>Import of file %1 failed.</source>
<translation type="vanished">Import der Datei %1 fehlgeschlagen.</translation>
<translation type="vanished">Import der Datei %1 fehlgeschlagen.</translation>
</message>
<message>
<source>Import successful.</source>
@ -1628,7 +1628,7 @@
</message>
<message>
<source>OpenBoard (*.ubz)</source>
<translation type="unfinished"></translation>
<translation>OpenBoard (*.ubz)</translation>
</message>
</context>
<context>
@ -1724,7 +1724,7 @@ Do you want to ignore these errors for this host?</source>
%2
Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
Möchten Sie diese Fehler für diesen Computer ignorieren?</translation>
</message>
<message>
<source>Yes</source>
@ -1739,15 +1739,15 @@ Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
<name>UBOpenSankoreImporterWidget</name>
<message>
<source>Open-Sankore Documents Detected</source>
<translation type="unfinished"></translation>
<translation>Geöffnete Open-Sankore Dokumente festgestellt</translation>
</message>
<message>
<source>Show this panel next time</source>
<translation type="unfinished"></translation>
<translation>Diesen Dialog erneut anzeigen</translation>
</message>
<message>
<source>You can always access the OpenBoard Document Importer through the Preferences panel in the About tab. Warning, if you have already imported your Open-Sankore datas, you might loose your current OpenBoard documents.</source>
<translation type="unfinished"></translation>
<translation>Sie können jederzeit im Einstellungsdialog im Menü "Über" auf den OpenBoard Document Importer zugreifen. Warnung, falls sie bereits Ihre Open-Sankore Daten importiert haben, können Sie Ihre aktuellen OpenBoard Dokumente verlieren.</translation>
</message>
<message>
<source>Cancel</source>
@ -1755,11 +1755,11 @@ Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
</message>
<message>
<source>Proceed</source>
<translation type="unfinished"></translation>
<translation>Fortfahren</translation>
</message>
<message>
<source>Open-Sankoré documents are present on your computer. It is possible to import them to OpenBoard by pressing the Proceed button to launch the importer application.</source>
<translation type="unfinished"></translation>
<translation>Auf Ihrem Computer befinden sich Open-Sankoré Dokumente. Um diese in OpenBoard zu importieren drücken Sie den "Fortfahren" Knopf um die Importanwendung zu starten.</translation>
</message>
</context>
<context>
@ -1774,7 +1774,7 @@ Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
</message>
<message>
<source>has lost access to the document repository &apos;%1&apos;. Unfortunately the application must shut down to avoid data corruption. Latest changes may be lost as well.</source>
<translation type="unfinished"></translation>
<translation>Verbindung zum Dokumentenarchiv verloren. Um fehlerhafte Daten zu vermeiden muss die Anwendung leider geschlossen werden. Letzte Änderungen können auch verloren gehen.</translation>
</message>
</context>
<context>
@ -1828,7 +1828,7 @@ Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
</message>
<message>
<source>Podcast recording error (%1)</source>
<translation>Podcast registriert einen Fehler (%1)</translation>
<translation>Fehler bei der Podcast Aufnahme (%1)</translation>
</message>
<message>
<source>Default Audio Input</source>
@ -2002,7 +2002,7 @@ Möchten Sie diese Fehler auf diesem Computer ignorieren?</translation>
</message>
<message>
<source>Update</source>
<translation>Update</translation>
<translation>Aktualisierung</translation>
</message>
<message>
<source>Select a backup folder</source>
@ -2020,7 +2020,7 @@ Bitte starten Sie die Anwendung erneut, um auf die aktualisierten Dokumente zugr
</message>
<message>
<source>Files update results</source>
<translation>Ergebnis des Daten-Updates</translation>
<translation>Ergebnis der Dateien-Aktualisierung</translation>
</message>
<message>
<source>Updating file </source>
@ -2046,7 +2046,7 @@ Bitte starten Sie die Anwendung erneut, um auf die aktualisierten Dokumente zugr
<name>UBWidgetUniboardAPI</name>
<message>
<source>%0 called (method=%1, status=%2)</source>
<translation>%0 abgerufen (Methode=%1, Status=%2)</translation>
<translation>%0 aufgerufen (Methode=%1, Status=%2)</translation>
</message>
</context>
<context>
@ -2149,7 +2149,7 @@ Bitte starten Sie die Anwendung erneut, um auf die aktualisierten Dokumente zugr
</message>
<message>
<source>Download canceled: %1</source>
<translation>Download abgebrochen %1</translation>
<translation>Herunterladen abgebrochen %1</translation>
</message>
<message>
<source>Error opening saved file: %1</source>
@ -2246,19 +2246,19 @@ Bitte starten Sie die Anwendung erneut, um auf die aktualisierten Dokumente zugr
<name>WBTabBar</name>
<message>
<source>New &amp;Tab</source>
<translation>Tab Neu &amp; </translation>
<translation>&amp;Tab Neu</translation>
</message>
<message>
<source>Clone Tab</source>
<translation>Tab Klon</translation>
<translation>Tab duplizieren</translation>
</message>
<message>
<source>&amp;Close Tab</source>
<translation>Tab &amp; Schließen</translation>
<translation>Tab &amp;Schließen</translation>
</message>
<message>
<source>Close &amp;Other Tabs</source>
<translation>Tabs Schließen &amp; Andere</translation>
<translation>&amp;Andere Tabs schließen</translation>
</message>
<message>
<source>Reload Tab</source>
@ -2319,7 +2319,7 @@ Bitte starten Sie die Anwendung erneut, um auf die aktualisierten Dokumente zugr
</message>
<message>
<source>Download PDF Document: would you prefer to download the PDF file or add it to the current OpenBoard document?</source>
<translation type="unfinished"></translation>
<translation>PDF Dokument herunterladen: Möchten Sie die PDF-Datei herunterladen oder sie zum aktuellen OpenBoard Dokument hinzufügen?</translation>
</message>
</context>
<context>
@ -2373,7 +2373,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Restore credentials on reboot</source>
<translation type="unfinished"></translation>
<translation>Zugangsdaten beim Neustarten wiederherstellen</translation>
</message>
<message>
<source>OpenBoard</source>
@ -2392,7 +2392,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Opacity</source>
<translation>Lichtundurchlässigkeit</translation>
<translation>Deckkraft</translation>
</message>
<message>
<source>Line Width</source>
@ -2404,7 +2404,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Strong</source>
<translation>Stark</translation>
<translation>Dick</translation>
</message>
<message>
<source>Fine</source>
@ -2442,7 +2442,7 @@ p, li { white-space: pre-wrap; }
<name>documents</name>
<message>
<source>OpenBoard Documents</source>
<translation type="unfinished"></translation>
<translation>OpenBoard Dokumente</translation>
</message>
</context>
<context>
@ -2529,11 +2529,11 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Software Update</source>
<translation>Software-Update</translation>
<translation>Software-Aktualisierung</translation>
</message>
<message>
<source>Check software update at launch</source>
<translation>Software-Update beim Start prüfen</translation>
<translation>Software-Aktualisierung beim Start prüfen</translation>
</message>
<message>
<source>Licences</source>
@ -2586,19 +2586,19 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Open-Sankoré Importer</source>
<translation type="unfinished"></translation>
<translation>Open-Sankoré Importer</translation>
</message>
<message>
<source>Check if Open-Sankoré data could be imported at launch</source>
<translation type="unfinished"></translation>
<translation>Prüfen, ob Open-Sankoré Daten beim Start importiert werden können</translation>
</message>
<message>
<source>Use system keyboard (recommended)</source>
<translation type="unfinished"></translation>
<translation>Benutze System-Tastatur (empfohlen)</translation>
</message>
<message>
<source>Built-in virtual keyboard button size:</source>
<translation type="unfinished"></translation>
<translation>Tastengröße der integrierten virtuellen Tastatur</translation>
</message>
</context>
<context>

File diff suppressed because it is too large Load Diff

@ -355,6 +355,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
mScene = 0;
UBGraphicsWidgetItem *currentWidget = 0;
bool pageDpiSpecified = true;
saveSceneAfterLoading = false;
mFileVersion = 40100; // default to 4.1.0
@ -371,6 +372,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
if (!mScene)
{
mScene = new UBGraphicsScene(mProxy, false);
mScene->setModified(false);
}
// introduced in UB 4.2
@ -914,10 +916,11 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
mScene->addItem(iterator.value());
}
if (mScene)
mScene->setModified(false);
if (mScene) {
mScene->setModified(saveSceneAfterLoading);
mScene->enableUndoRedoStack();
}
mScene->enableUndoRedoStack();
qDebug() << "loadScene() : created scene and read file";
qDebug() << "spent milliseconds: " << time.elapsed();
return mScene;
@ -1142,11 +1145,6 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy,
mXmlWriter.writeStartElement("g");
openStroke = currentStroke;
QMatrix matrix = item->sceneMatrix();
if (!matrix.isIdentity())
mXmlWriter.writeAttribute("transform", toSvgTransform(matrix));
UBGraphicsStroke* stroke = dynamic_cast<UBGraphicsStroke* >(currentStroke);
if (stroke)
@ -1167,6 +1165,14 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy,
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(sg->uuid()));
QVariant locked = sg->data(UBGraphicsItemData::ItemLocked);
if (!locked.isNull() && locked.toBool())
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "locked", xmlTrue);
QMatrix matrix = sg->sceneMatrix();
if (!matrix.isIdentity())
mXmlWriter.writeAttribute("transform", toSvgTransform(matrix));
qDebug() << "Attributes written";
groupHoldsInfo = true;
@ -1528,7 +1534,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgPolygon(UBGraphicsPo
QString points = pointsToSvgPointsAttribute(polygon);
mXmlWriter.writeAttribute("points", points);
mXmlWriter.writeAttribute("transform",toSvgTransform(polygonItem->sceneMatrix()));
mXmlWriter.writeAttribute("transform",toSvgTransform(polygonItem->matrix()));
mXmlWriter.writeAttribute("fill", polygonItem->brush().color().name());
qreal alpha = polygonItem->brush().color().alphaF();
@ -1562,9 +1568,9 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgPolygon(UBGraphicsPo
}
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(polygonItem->uuid()));
if (polygonItem->parentItem()) {
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", UBStringUtils::toCanonicalUuid(UBGraphicsItem::getOwnUuid(polygonItem->parentItem())));
}
UBGraphicsStrokesGroup* sg = polygonItem->strokesGroup();
if (sg)
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", UBStringUtils::toCanonicalUuid(sg->uuid()));
mXmlWriter.writeEndElement();
}
@ -2496,6 +2502,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::textItemToSvg(UBGraphicsTextItem* it
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "width", QString("%1").arg(item->textWidth()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "height", QString("%1").arg(item->textHeight()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "pixels-per-point", QString("%1").arg(item->pixelsPerPoint()));
QColor colorDarkBg = item->colorOnDarkBackground();
QColor colorLightBg = item->colorOnLightBackground();
@ -2522,6 +2529,8 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg()
qreal width = mXmlReader.attributes().value("width").toString().toFloat();
qreal height = mXmlReader.attributes().value("height").toString().toFloat();
qreal originalPixelsPerPoint = mXmlReader.attributes().value(mNamespaceUri, "pixels-per-point").toString().toDouble();
UBGraphicsTextItem* textItem = new UBGraphicsTextItem();
graphicsItemFromSvg(textItem);
@ -2564,6 +2573,31 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg()
if (mXmlReader.name() == "itemTextContent") {
text = mXmlReader.readElementText();
textItem->setHtml(text);
// Fonts sizes are not displayed the same across platforms: e.g a text item with the same
// font size (in Pts) is displayed smaller on Linux than Windows. This messes up layouts
// when importing documents created on another computer, so if a font is being displayed
// at a different size (relative to the rest of the document) than it was when created,
// we adjust its size.
if (originalPixelsPerPoint != 0) {
qreal pixelsPerPoint = textItem->pixelsPerPoint();
qDebug() << "Pixels per point: original/current" << originalPixelsPerPoint
<< "/" << pixelsPerPoint;
qreal ratio = originalPixelsPerPoint/pixelsPerPoint;
if (ratio != 1) {
qDebug() << "Scaling text by " << ratio;
UBGraphicsTextItemDelegate* textDelegate = dynamic_cast<UBGraphicsTextItemDelegate*>(textItem->Delegate());
if (textDelegate)
textDelegate->scaleTextSize(ratio);
}
}
else
// mark scene as modified so the text item will be saved with a pixelsPerPoint value
saveSceneAfterLoading = true;
textItem->resize(width, height);
if (textItem->toPlainText().isEmpty()) {
delete textItem;

@ -168,6 +168,8 @@ class UBSvgSubsetAdaptor
qreal mGroupZIndex;
bool mGroupHasInfo;
bool saveSceneAfterLoading;
QString mNamespaceUri;
UBGraphicsScene *mScene;

@ -555,6 +555,8 @@ Here we determines cases when items should to get mouse press event at pressing
return true;
case UBGraphicsMediaItem::Type:
case UBGraphicsVideoItem::Type:
case UBGraphicsAudioItem::Type:
return false;
case UBGraphicsTextItem::Type:
@ -626,6 +628,8 @@ bool UBBoardView::itemShouldReceiveSuspendedMousePressEvent(QGraphicsItem *item)
case DelegateButton::Type:
case UBGraphicsMediaItem::Type:
case UBGraphicsVideoItem::Type:
case UBGraphicsAudioItem::Type:
return true;
}
@ -858,6 +862,8 @@ void UBBoardView::moveRubberedItems(QPointF movingVector)
if (item->type() == UBGraphicsW3CWidgetItem::Type
|| item->type() == UBGraphicsPixmapItem::Type
|| item->type() == UBGraphicsMediaItem::Type
|| item->type() == UBGraphicsVideoItem::Type
|| item->type() == UBGraphicsAudioItem::Type
|| item->type() == UBGraphicsSvgItem::Type
|| item->type() == UBGraphicsTextItem::Type
|| item->type() == UBGraphicsStrokesGroup::Type
@ -1170,7 +1176,8 @@ void UBBoardView::mouseMoveEvent (QMouseEvent *event)
if (item->type() == UBGraphicsW3CWidgetItem::Type
|| item->type() == UBGraphicsPixmapItem::Type
|| item->type() == UBGraphicsMediaItem::Type
|| item->type() == UBGraphicsVideoItem::Type
|| item->type() == UBGraphicsAudioItem::Type
|| item->type() == UBGraphicsSvgItem::Type
|| item->type() == UBGraphicsTextItem::Type
|| item->type() == UBGraphicsStrokesGroup::Type
@ -1328,6 +1335,7 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event)
textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
textItem->setSelected (true);
textItem->setTextWidth(0);
textItem->setFocus();
}
}
@ -1597,9 +1605,9 @@ void UBBoardView::drawBackground (QPainter *painter, const QRectF &rect)
QColor bgCrossColor;
if (darkBackground)
bgCrossColor = UBSettings::crossDarkBackground;
bgCrossColor = QColor(UBSettings::settings()->boardCrossColorDarkBackground->get().toString());
else
bgCrossColor = UBSettings::crossLightBackground;
bgCrossColor = QColor(UBSettings::settings()->boardCrossColorLightBackground->get().toString());
if (transform ().m11 () < 1.0)
{

@ -658,7 +658,6 @@ void UBApplicationController::closing()
if (mUninoteController)
{
mUninoteController->hideWindow();
mUninoteController->close();
}
@ -721,6 +720,13 @@ void UBApplicationController::importFile(const QString& pFilePath)
void UBApplicationController::useMultiScreen(bool use)
{
if (use && !mMirror)
mMirror = new UBScreenMirror();
if (!use && mMirror) {
delete mMirror;
mMirror = NULL;
}
mDisplayManager->setUseMultiScreen(use);
mDisplayManager->adjustScreens(0);
UBSettings::settings()->appUseMultiscreen->set(use);

@ -55,7 +55,7 @@ UBDisplayManager::UBDisplayManager(QObject *parent)
{
mDesktop = qApp->desktop();
mUseMultiScreen = true;
mUseMultiScreen = UBSettings::settings()->appUseMultiscreen->get().toBool();
initScreenIndexes();

@ -56,11 +56,9 @@ void UBOpenSankoreImporter::onProceedClicked()
newProcess.startDetached(qApp->applicationDirPath()+"/importer/OpenBoardImporter");
#elif defined Q_OS_OSX
newProcess.startDetached(qApp->applicationDirPath()+"/../Resources/OpenBoardImporter.app/Contents/MacOS/OpenBoardImporter");
#else
// Windows does not allows to run easily an exe located in a subdirectory when the main
// directory is placed into programs files.
//newProcess.startDetached(qApp->applicationDirPath()+"\\Importer\\OpenBoardImporter.exe");
newProcess.startDetached("C:/OpenBoard/Importer/OpenBoardImporter.exe");
#elif defined Q_OS_WIN
QString importerPath = QDir::toNativeSeparators(qApp->applicationDirPath())+"\\OpenBoardImporter.exe";
newProcess.startDetached("explorer.exe", QStringList() << importerPath);
#endif
qApp->exit(0);

@ -67,6 +67,7 @@ UBPersistenceManager * UBPersistenceManager::sSingleton = 0;
UBPersistenceManager::UBPersistenceManager(QObject *pParent)
: QObject(pParent)
, mHasPurgedDocuments(false)
, mIsApplicationClosing(false)
, mIsWorkerFinished(false)
{
@ -131,8 +132,10 @@ void UBPersistenceManager::destroy()
void UBPersistenceManager::onScenePersisted(UBGraphicsScene* scene)
{
delete scene;
scene = NULL;
if (!mIsApplicationClosing) {
delete scene;
scene = NULL;
}
}
void UBPersistenceManager::onMetadataPersisted(UBDocumentProxy* proxy)
@ -147,6 +150,8 @@ void UBPersistenceManager::onWorkerFinished()
UBPersistenceManager::~UBPersistenceManager()
{
mIsApplicationClosing = true;
if(mWorker)
mWorker->applicationWillClose();
@ -483,7 +488,7 @@ void UBPersistenceManager::deleteDocumentScenes(UBDocumentProxy* proxy, const QL
foreach(int index, compactedIndexes)
{
UBGraphicsScene *scene = loadDocumentScene(proxy, index);
UBGraphicsScene *scene = loadDocumentScene(proxy, index, false);
if (scene)
{
//scene is about to move into new document
@ -727,7 +732,7 @@ void UBPersistenceManager::moveSceneToIndex(UBDocumentProxy* proxy, int source,
}
UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex)
UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex, bool cacheNeighboringScenes)
{
UBGraphicsScene* scene = NULL;
@ -740,11 +745,13 @@ UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy,
mSceneCache.insert(proxy, sceneIndex, scene);
}
if(sceneIndex + 1 < proxy->pageCount() && !mSceneCache.contains(proxy, sceneIndex + 1))
mWorker->readScene(proxy,sceneIndex+1);
if (cacheNeighboringScenes) {
if(sceneIndex + 1 < proxy->pageCount() && !mSceneCache.contains(proxy, sceneIndex + 1))
mWorker->readScene(proxy,sceneIndex+1);
if(sceneIndex - 1 >= 0 && !mSceneCache.contains(proxy, sceneIndex - 1))
mWorker->readScene(proxy,sceneIndex-1);
if(sceneIndex - 1 >= 0 && !mSceneCache.contains(proxy, sceneIndex - 1))
mWorker->readScene(proxy,sceneIndex-1);
}
return scene;
}
@ -941,7 +948,6 @@ bool UBPersistenceManager::isEmpty(UBDocumentProxy* pDocumentProxy)
empty = theSoleScene->isEmpty();
if(empty){
mSceneCache.removeScene(pDocumentProxy,0);
delete theSoleScene;
theSoleScene = NULL;
}
else{
@ -958,7 +964,6 @@ bool UBPersistenceManager::isEmpty(UBDocumentProxy* pDocumentProxy)
}
if(!usefulItemFound){
mSceneCache.removeScene(pDocumentProxy,0);
delete theSoleScene;
theSoleScene = NULL;
empty = true;
}

@ -85,7 +85,7 @@ class UBPersistenceManager : public QObject
virtual void moveSceneToIndex(UBDocumentProxy* pDocumentProxy, int source, int target);
virtual UBGraphicsScene* loadDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex);
virtual UBGraphicsScene* loadDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex, bool cacheNeighboringScenes = true);
UBGraphicsScene *getDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex) {return mSceneCache.value(pDocumentProxy, sceneIndex);}
QList<QPointer<UBDocumentProxy> > documentProxies;
@ -157,6 +157,8 @@ class UBPersistenceManager : public QObject
QThread* mThread;
bool mIsWorkerFinished;
bool mIsApplicationClosing;
private slots:
void documentRepositoryChanged(const QString& path);
void errorString(QString error);

@ -71,17 +71,14 @@ const char *UBSettings::sDefaultFontFamily = "Arial";
QString UBSettings::currentFileVersion = "4.8.0";
QColor UBSettings::crossDarkBackground = QColor(44, 44, 44, 200);
QColor UBSettings::crossLightBackground = QColor(165, 225, 255);
QBrush UBSettings::eraserBrushDarkBackground = QBrush(QColor(127, 127, 127, 80));
QBrush UBSettings::eraserBrushLightBackground = QBrush(QColor(255, 255, 255, 30));
QPen UBSettings::eraserPenDarkBackground = QPen(QColor(255, 255, 255, 127));
QPen UBSettings::eraserPenLightBackground = QPen(QColor(0, 0, 0, 127));
QColor UBSettings::markerCircleBrushColorDarkBackground = QColor(127, 127, 127, 0);
QColor UBSettings::markerCircleBrushColorLightBackground = QColor(255, 255, 255, 0);
QColor UBSettings::markerCircleBrushColorDarkBackground = QColor(127, 127, 127, 80);
QColor UBSettings::markerCircleBrushColorLightBackground = QColor(255, 255, 255, 30);
QColor UBSettings::markerCirclePenColorDarkBackground = QColor(255, 255, 255, 127);
QColor UBSettings::markerCirclePenColorLightBackground = QColor(0, 0, 0, 127);
@ -272,6 +269,10 @@ void UBSettings::init()
pageSize = new UBSetting(this, "Board", "DefaultPageSize", documentSizes.value(DocumentSizeRatio::Ratio4_3));
boardCrossColorDarkBackground = new UBSetting(this, "Board", "CrossColorDarkBackground", "#C82C2C2C");
boardCrossColorLightBackground = new UBSetting(this, "Board", "CrossColorLightBackground", "#A5E1FF");
QStringList penLightBackgroundColors;
penLightBackgroundColors << "#000000" << "#FF0000" <<"#004080" << "#008000" << "#FFDD00" << "#C87400" << "#800040" << "#008080" << "#5F2D0A" << "#FFFFFF";
boardPenLightBackgroundColors = new UBColorListSetting(this, "Board", "PenLightBackgroundColors", penLightBackgroundColors, 1.0);

@ -160,8 +160,6 @@ class UBSettings : public QObject
static int pointerDiameter;
static int boardMargin;
static QColor crossDarkBackground;
static QColor crossLightBackground;
static QColor paletteColor;
static QColor opaquePaletteColor;
@ -275,6 +273,9 @@ class UBSettings : public QObject
UBSetting* featureSliderPosition;
UBSetting* boardCrossColorDarkBackground;
UBSetting* boardCrossColorLightBackground;
UBColorListSetting* boardPenLightBackgroundColors;
UBColorListSetting* boardPenLightBackgroundSelectedColors;

@ -354,7 +354,10 @@ void UBDesktopAnnotationController::showWindow()
void UBDesktopAnnotationController::close()
{
// NOOP
if (mTransparentDrawingView)
mTransparentDrawingView->hide();
mDesktopPalette->hide();
}

@ -805,10 +805,12 @@ void UBDocumentController::deleteTreeItem(QTreeWidgetItem * item, bool showConfi
document->parent()->removeChild(document);
UBPersistenceManager::persistenceManager()->deleteDocument(document->proxy());
if (mTrashTi->childCount()==0)
selectDocument(NULL);
else
selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy());
if (selectNewDocument) {
if (mTrashTi->childCount()==0)
selectDocument(NULL);
else
selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy());
}
reloadThumbnails();
}

@ -55,6 +55,8 @@ class UBDocumentController : public UBDocumentContainer
{
Q_OBJECT
friend class UBDocumentTreeWidget;
public:
UBDocumentController(UBMainWindow* mainWindow);
virtual ~UBDocumentController();
@ -163,5 +165,4 @@ class UBDocumentController : public UBDocumentContainer
};
#endif /* UBDOCUMENTCONTROLLER_H_ */

@ -162,7 +162,10 @@ void UBGraphicsGroupContainerItem::removeFromGroup(QGraphicsItem *item)
void UBGraphicsGroupContainerItem::deselectCurrentItem()
{
if (mCurrentItem && mCurrentItem->type() == UBGraphicsMediaItem::Type){
if (mCurrentItem && (mCurrentItem->type() == UBGraphicsMediaItem::Type
|| mCurrentItem->type() == UBGraphicsVideoItem::Type
|| mCurrentItem->type() == UBGraphicsAudioItem::Type))
{
dynamic_cast<UBGraphicsMediaItem*>(mCurrentItem)->Delegate()->getToolBarItem()->hide();
mCurrentItem->setSelected(false);

@ -252,6 +252,12 @@ void UBGraphicsMediaItem::setMinimumSize(const QSize& size)
this->setSize(width, height);
}
void UBGraphicsMediaItem::setUuid(const QUuid &pUuid)
{
UBItem::setUuid(pUuid);
setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid));
}
void UBGraphicsMediaItem::setMediaFileUrl(QUrl url)
{
mMediaFileUrl = url;

@ -100,6 +100,7 @@ public:
virtual void setSourceUrl(const QUrl &pSourceUrl);
void setSelected(bool selected);
void setMinimumSize(const QSize& size);
void setUuid(const QUuid &pUuid);
virtual void copyItemParameters(UBItem *copy) const;

@ -1178,15 +1178,22 @@ UBGraphicsScene* UBGraphicsScene::sceneDeepCopy() const
UBGraphicsGroupContainerItem* groupCloned = group->deepCopyNoChildDuplication();
groupCloned->resetMatrix();
groupCloned->resetTransform();
groupCloned->setMatrix(group->matrix());
groupCloned->setTransform(group->transform());
groupCloned->setPos(0, 0);
bool locked = groupCloned->Delegate()->isLocked();
foreach(QGraphicsItem* eachItem ,group->childItems()){
QGraphicsItem* copiedChild = dynamic_cast<QGraphicsItem*>(dynamic_cast<UBItem*>(eachItem)->deepCopy());
copy->addItem(copiedChild);
groupCloned->addToGroup(copiedChild);
}
if (locked)
groupCloned->setData(UBGraphicsItemData::ItemLocked, QVariant(true));
copy->addItem(groupCloned);
groupCloned->setMatrix(group->matrix());
groupCloned->setTransform(QTransform::fromTranslate(group->pos().x(), group->pos().y()));
groupCloned->setTransform(group->transform(), true);
}
if (ubItem && !stroke && !group && item->isVisible())
@ -2391,9 +2398,9 @@ void UBGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
QColor bgCrossColor;
if (darkBackground)
bgCrossColor = UBSettings::crossDarkBackground;
bgCrossColor = QColor(UBSettings::settings()->boardCrossColorDarkBackground->get().toString());
else
bgCrossColor = UBSettings::crossLightBackground;
bgCrossColor = QColor(UBSettings::settings()->boardCrossColorLightBackground->get().toString());
if (mZoomFactor < 1.0)
{
int alpha = 255 * mZoomFactor / 2;
@ -2608,20 +2615,19 @@ void UBGraphicsScene::updateMarkerCircleColor()
if (!mMarkerCircle)
return;
QBrush mcBrush = mMarkerCircle->brush();
QPen mcPen = mMarkerCircle->pen();
if (mDarkBackground) {
mcBrush.setColor(UBSettings::markerCircleBrushColorDarkBackground);
mcPen.setColor(UBSettings::markerCirclePenColorDarkBackground);
mMarkerCircle->setBrush(UBSettings::markerCircleBrushColorDarkBackground);
}
else {
mcBrush.setColor(UBSettings::markerCircleBrushColorLightBackground);
mcPen.setColor(UBSettings::markerCirclePenColorLightBackground);
mMarkerCircle->setBrush(UBSettings::markerCircleBrushColorLightBackground);
}
mMarkerCircle->setBrush(mcBrush);
mcPen.setStyle(Qt::DotLine);
mMarkerCircle->setPen(mcPen);
}

@ -128,10 +128,12 @@ void UBGraphicsStrokesGroup::mousePressEvent(QGraphicsSceneMouseEvent *event)
void UBGraphicsStrokesGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItemGroup::mouseMoveEvent(event);
if (!isLocked(this)) {
QGraphicsItemGroup::mouseMoveEvent(event);
event->accept();
setSelected(false);
event->accept();
setSelected(false);
}
}
void UBGraphicsStrokesGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
@ -173,7 +175,7 @@ UBItem* UBGraphicsStrokesGroup::deepCopy() const
}
}
const_cast<UBGraphicsStrokesGroup*>(this)->setTransform(groupTransform);
copy->setTransform(sceneTransform());
copy->setTransform(groupTransform);
return copy;
}
@ -184,6 +186,7 @@ void UBGraphicsStrokesGroup::copyItemParameters(UBItem *copy) const
if(NULL != cp)
{
cp->setTransform(transform());
cp->setPos(pos());
cp->setFlag(QGraphicsItem::ItemIsMovable, true);
cp->setFlag(QGraphicsItem::ItemIsSelectable, true);

@ -306,8 +306,12 @@ QPainterPath UBGraphicsTextItem::shape() const
void UBGraphicsTextItem::setTextWidth(qreal width)
{
qreal strictMin = 155; // the size of the font customization panel
qreal newWidth = qMax(strictMin, width);
qreal titleBarWidth = 0;
UBGraphicsTextItemDelegate * del = dynamic_cast<UBGraphicsTextItemDelegate*>(Delegate());
if (del)
titleBarWidth = del->titleBarWidth();
qreal newWidth = qMax(titleBarWidth, width);
QGraphicsTextItem::setTextWidth(newWidth);
}
@ -328,6 +332,39 @@ qreal UBGraphicsTextItem::textHeight() const
return mTextHeight;
}
/**
* @brief Get the ratio between font size in pixels and points.
* @return The ratio of pixel size to point size of the first character, or 0 if the text item is empty.
*
* Qt may display fonts differently on different platforms -- on the same display,
* the same point size may be displayed at different pixel sizes. This function returns the
* ratio of pixel size to point size, based on the first character in the text item.
*/
qreal UBGraphicsTextItem::pixelsPerPoint() const
{
QTextCursor cursor = textCursor();
if (cursor.isNull())
return 0;
cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
QFont f = cursor.charFormat().font();
qDebug() << "ppp. Font: " << f;
QFontInfo fi(cursor.charFormat().font());
qreal pixelSize = fi.pixelSize();
qreal pointSize = fi.pointSizeF();
//qDebug() << "Pixel size: " << pixelSize;
//qDebug() << "Point size: " << pointSize;
if (pointSize == 0)
return 0;
return pixelSize/pointSize;
}
void UBGraphicsTextItem::contentsChanged()
{

@ -65,6 +65,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes
void setTextWidth(qreal width);
void setTextHeight(qreal height);
qreal textHeight() const;
qreal pixelsPerPoint() const;
void contentsChanged();
@ -101,6 +102,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes
QString mTypeTextHereLabel;
signals:
void textUndoCommandAdded(UBGraphicsTextItem *textItem);

@ -204,6 +204,31 @@ void UBGraphicsTextItemDelegate::createControls()
}
/**
* @brief Calculate the width of the toolbar containing the text item-related buttons
* @return The space between the left-most and right-most buttons in pixels
*/
qreal UBGraphicsTextItemDelegate::titleBarWidth()
{
if (!mFontButton)
return 0;
// refresh the frame and buttons' positions
positionHandles();
qreal titleBarWidth(0);
qreal frameLeftCoordinate = mFontButton->pos().x();
qreal frameRightCoordinate = frameLeftCoordinate;
foreach(DelegateButton* button, mButtons) {
if (button->getSection() == Qt::TitleBarArea) {
frameLeftCoordinate = qMin(button->pos().x(), frameLeftCoordinate);
frameRightCoordinate = qMax(button->pos().x() + button->boundingRect().width(), frameRightCoordinate);
}
}
return frameRightCoordinate - frameLeftCoordinate;
}
void UBGraphicsTextItemDelegate::freeButtons()
{
@ -532,6 +557,9 @@ bool UBGraphicsTextItemDelegate::keyReleaseEvent(QKeyEvent *event)
void UBGraphicsTextItemDelegate::ChangeTextSize(qreal factor, textChangeMode changeMode)
{
// round it to the nearest hundredth
factor = floor(factor*100+0.5)/100.;
if (scaleSize == changeMode)
{
if (1 == factor)

@ -114,6 +114,7 @@ class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate
void scaleTextSize(qreal multiplyer);
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
virtual void createControls();
qreal titleBarWidth();
public slots:
void contentsChanged();

@ -188,7 +188,7 @@ QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAng
qreal radiusLength = startRadius.length();
qreal angle = 2 * asin(width / (2 * radiusLength)) * 180 / PI;
bool overlap = abs(spanAngleInDegrees) > 360 - angle;
bool overlap = qAbs(spanAngleInDegrees) > 360 - angle;
if (overlap)
spanAngleInDegrees = spanAngleInDegrees < 0 ? -360 : 360;

@ -214,79 +214,39 @@ void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event)
QTreeWidget::focusInEvent(event);
}
void UBDocumentTreeWidget::dropEvent(QDropEvent *event)
{
if (mDropTargetProxyTi)
{
if (mDropTargetProxyTi) {
mDropTargetProxyTi->setBackground(0, mBackground);
mDropTargetProxyTi = 0;
}
QTreeWidgetItem* underlyingItem = this->itemAt(event->pos());
UBDocumentGroupTreeItem *groupItem = dynamic_cast<UBDocumentGroupTreeItem*>(underlyingItem);
if (groupItem && mSelectedProxyTi && mSelectedProxyTi->proxy())
{
UBDocumentGroupTreeItem *sourceGroupItem = dynamic_cast<UBDocumentGroupTreeItem*>(mSelectedProxyTi->parent());
bool isTrashItem = sourceGroupItem && sourceGroupItem->isTrashFolder();
if ((isTrashItem && !groupItem->isTrashFolder()) ||
(!isTrashItem && mSelectedProxyTi->proxy()->groupName() != groupItem->groupName()))
{
QString groupName;
if (groupItem->isTrashFolder())
{
QString oldGroupName = mSelectedProxyTi->proxy()->metaData(UBSettings::documentGroupName).toString();
groupName = UBSettings::trashedDocumentGroupNamePrefix + oldGroupName;
}
else
{
if (groupItem->groupName() == UBApplication::app()->documentController->defaultDocumentGroupName())
groupName = "";
else
groupName = groupItem->groupName();
}
mSelectedProxyTi->proxy()->setMetaData(UBSettings::documentGroupName, groupName);
UBPersistenceManager::persistenceManager()->persistDocumentMetadata(mSelectedProxyTi->proxy());
QTreeWidgetItem * underlyingItem = this->itemAt(event->pos());
mSelectedProxyTi->parent()->removeChild(mSelectedProxyTi);
// If the destination is a folder, move the selected document(s) there
UBDocumentGroupTreeItem * destinationFolder = dynamic_cast<UBDocumentGroupTreeItem*>(underlyingItem);
int i = 0;
for (i = 0; i < groupItem->childCount(); i++)
{
QTreeWidgetItem *ti = groupItem->child(i);
UBDocumentProxyTreeItem* pi = dynamic_cast<UBDocumentProxyTreeItem*>(ti);
if (pi)
{
if (mSelectedProxyTi->proxy()->metaData(UBSettings::documentDate).toString() >= pi->proxy()->metaData(UBSettings::documentDate).toString())
{
break;
}
}
}
groupItem->insertChild(i, mSelectedProxyTi);
if (isTrashItem)
mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() | Qt::ItemIsEditable);
if (groupItem->isTrashFolder())
mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable);
expandItem(groupItem);
scrollToItem(mSelectedProxyTi);
if (destinationFolder) {
UBDocumentProxyTreeItem * lastMovedDocument;
foreach(QTreeWidgetItem * item, this->selectedItems()) {
UBDocumentProxyTreeItem * document = dynamic_cast<UBDocumentProxyTreeItem*>(item);
if (document && moveDocument(document, destinationFolder))
lastMovedDocument = document;
}
// disabled, as those 2 calls are buggy on windows, the item disappears if we selected them
//
setCurrentItem(mSelectedProxyTi);
mSelectedProxyTi->setSelected(true);
if (lastMovedDocument) {
expandItem(destinationFolder);
scrollToItem(lastMovedDocument);
setCurrentItem(lastMovedDocument);
lastMovedDocument->setSelected(true);
event->setDropAction(Qt::IgnoreAction);
event->accept();
}
}
else
{
// If the destination is a document and the dropped item is a page, copy the page to that document
else {
QTreeWidgetItem* underlyingTreeItem = this->itemAt(event->pos());
UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast<UBDocumentProxyTreeItem*>(underlyingTreeItem);
@ -393,6 +353,67 @@ void UBDocumentTreeWidget::documentUpdated(UBDocumentProxy *pDocument)
}
}
/**
* @brief Move a document to the specified destination folder
* @param document Pointer to the document to move
* @param destinationFolder Pointer to the folder to move the document to
* @return true if document was moved successfully, false otherwise
*/
bool UBDocumentTreeWidget::moveDocument(UBDocumentProxyTreeItem* document, UBDocumentGroupTreeItem* destinationFolder)
{
if (!document || !(document->proxy()) || !destinationFolder)
return false;
UBDocumentGroupTreeItem * sourceFolder = dynamic_cast<UBDocumentGroupTreeItem*>(document->parent());
bool documentIsInTrash = (sourceFolder && sourceFolder->isTrashFolder());
if (documentIsInTrash && destinationFolder->isTrashFolder())
return false;
if (!documentIsInTrash && document->proxy()->groupName() == destinationFolder->groupName())
return false;
QString destinationFolderName;
if (destinationFolder->isTrashFolder()) {
UBApplication::app()->documentController->moveDocumentToTrash(sourceFolder, document, true);
destinationFolderName = document->proxy()->metaData(UBSettings::documentGroupName).toString();
}
else {
if (destinationFolder->groupName() == UBApplication::app()->documentController->defaultDocumentGroupName())
destinationFolderName = "";
else
destinationFolderName = destinationFolder->groupName();
}
// Update the folder name in the document
document->proxy()->setMetaData(UBSettings::documentGroupName, destinationFolderName);
UBPersistenceManager::persistenceManager()->persistDocumentMetadata(document->proxy());
// Remove document from its old folder
document->parent()->removeChild(document);
// Insert document at the right spot in the destination folder (ordered by document date)
int i = 0;
for (i = 0; i < destinationFolder->childCount(); i++) {
QTreeWidgetItem *ti = destinationFolder->child(i);
UBDocumentProxyTreeItem* pi = dynamic_cast<UBDocumentProxyTreeItem*>(ti);
if (pi && document->proxy()->metaData(UBSettings::documentDate).toString() >= pi->proxy()->metaData(UBSettings::documentDate).toString())
break;
}
destinationFolder->insertChild(i, document);
// Update editable status of the document if it was moved to or from the trash
if (documentIsInTrash)
document->setFlags(document->flags() | Qt::ItemIsEditable);
if (destinationFolder->isTrashFolder())
document->setFlags(document->flags() ^ Qt::ItemIsEditable);
return true;
}
UBDocumentProxyTreeItem::UBDocumentProxyTreeItem(QTreeWidgetItem * parent, UBDocumentProxy* proxy, bool isEditable)
: QTreeWidgetItem()

@ -35,6 +35,7 @@
class UBDocumentProxy;
class UBDocumentProxyTreeItem;
class UBDocumentGroupTreeItem;
class UBDocumentTreeWidget : public QTreeWidget
{
@ -60,6 +61,7 @@ class UBDocumentTreeWidget : public QTreeWidget
void autoScroll();
private:
bool moveDocument(UBDocumentProxyTreeItem* document, UBDocumentGroupTreeItem* destinationFolder);
UBDocumentProxyTreeItem *mSelectedProxyTi;
QTreeWidgetItem *mDropTargetProxyTi;
QBrush mBackground;

@ -126,25 +126,25 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem
int mPixelsPerMillimeter;
// Constants
static const int sNeedleLength = 18;
static const int sNeedleLength = 12;
static const int sNeedleWidth = 3;
static const int sNeedleBaseLength = 12;
static const int sNeedleBaseWidth = 12;
static const int sNeedleBaseLength = 9;
static const int sNeedleBaseWidth = 9;
static const int sNeedleArmLeftWidth = 18;
static const int sNeedleArmRigthWidth = 24;
static const int sNeedleArmLeftWidth = 12;
static const int sNeedleArmRigthWidth = 16;
static const int sPencilLength = 12;
static const int sPencilWidth = 3;
static const int sPencilWidth = 2;
static const int sPencilBaseLength = 18;
static const int sPencilBaseWidth = 12;
static const int sPencilBaseLength = 9;
static const int sPencilBaseWidth = 9;
static const int sPencilArmLeftWidth = 24;
static const int sPencilArmRightWidth = 18;
static const int sPencilArmLeftWidth = 16;
static const int sPencilArmRightWidth = 12;
static const int sCornerRadius = 3;
static const int sCornerRadius = 2;
static const QRect sDefaultRect;
static const int sMinRadius;

@ -41,6 +41,7 @@
const QRectF UBGraphicsProtractor::sDefaultRect = QRectF(-250, -250, 500, 500);
const qreal UBGraphicsProtractor::minRadius = 70;
UBGraphicsProtractor::UBGraphicsProtractor()
: QGraphicsEllipseItem(sDefaultRect)
@ -213,11 +214,13 @@ void UBGraphicsProtractor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
case Resize :
prepareGeometryChange();
setTransform(QTransform::fromTranslate(rect().center().x(), rect().center().y()), true);
setTransform(QTransform::fromScale(scaleFactor, scaleFactor), true);
setTransform(QTransform::fromTranslate(-rect().center().x(), -rect().center().y()), true);
mScaleFactor *= scaleFactor;
if (radius() * mScaleFactor * scaleFactor > minRadius) {
prepareGeometryChange();
setTransform(QTransform::fromTranslate(rect().center().x(), rect().center().y()), true);
setTransform(QTransform::fromScale(scaleFactor, scaleFactor), true);
setTransform(QTransform::fromTranslate(-rect().center().x(), -rect().center().y()), true);
mScaleFactor *= scaleFactor;
}
break;
case MoveMarker :

@ -119,6 +119,7 @@ class UBGraphicsProtractor : public UBAbstractDrawRuler, public QGraphicsEllipse
QGraphicsSvgItem* mRotateSvgItem;
static const QRectF sDefaultRect;
static const qreal minRadius;
virtual void rotateAroundCenter(qreal angle);
virtual QPointF rotationCenter() const;

@ -49,6 +49,7 @@ UBGraphicsTriangle::UBGraphicsTriangle()
, mResizing1(false)
, mResizing2(false)
, mRotating(false)
, mShouldPaintInnerTriangle(true)
{
setRect(sDefaultRect, sDefaultOrientation);
@ -224,6 +225,29 @@ void UBGraphicsTriangle::calculatePoints(const QRectF& r)
C2.setX(r.left() + L); C2.setY(r.bottom() - d);
break;
}
bool paintInnerTriangle = true;
switch(mOrientation)
{
case BottomLeft:
if (B2.x() > C2.x() || B2.y() < A2.y())
paintInnerTriangle = false;
break;
case TopLeft:
if (B2.x() > C2.x() || B2.y() > A2.y())
paintInnerTriangle = false;
break;
case TopRight:
if (B2.x() < C2.x() || B2.y() > A2.y())
paintInnerTriangle = false;
break;
case BottomRight:
if (B2.x() < C2.x() || B2.y() < A2.y())
paintInnerTriangle = false;
break;
}
mShouldPaintInnerTriangle = paintInnerTriangle;
W1 = rect().height() * d / C;
H1 = rect().width() * d / C;
@ -251,40 +275,54 @@ void UBGraphicsTriangle::paint(QPainter *painter, const QStyleOptionGraphicsItem
QPolygonF polygon;
QLinearGradient gradient1(QPointF(A1.x(), 0), QPointF(A2.x(), 0));
gradient1.setColorAt(0, edgeFillColor());
gradient1.setColorAt(1, middleFillColor());
painter->setBrush(gradient1);
polygon << A1 << A2 << B2 << B1;
painter->drawPolygon(polygon);
polygon.clear();
QLinearGradient gradient2(QPointF(0, B1.y()), QPointF(0, B2.y()));
gradient2.setColorAt(0, edgeFillColor());
gradient2.setColorAt(1, middleFillColor());
painter->setBrush(gradient2);
polygon << B1 << B2 << C2 << C1;
painter->drawPolygon(polygon);
polygon.clear();
QLinearGradient gradient3(CC, C2);
gradient3.setColorAt(0, edgeFillColor());
gradient3.setColorAt(1, middleFillColor());
painter->setBrush(gradient3);
polygon << C1 << C2 << A2 << A1;
painter->drawPolygon(polygon);
polygon.clear();
painter->setBrush(Qt::NoBrush);
painter->setPen(drawColor());
if (mShouldPaintInnerTriangle) {
QLinearGradient gradient1(QPointF(A1.x(), 0), QPointF(A2.x(), 0));
gradient1.setColorAt(0, edgeFillColor());
gradient1.setColorAt(1, middleFillColor());
painter->setBrush(gradient1);
polygon << A1 << A2 << B2 << B1;
painter->drawPolygon(polygon);
polygon.clear();
QLinearGradient gradient2(QPointF(0, B1.y()), QPointF(0, B2.y()));
gradient2.setColorAt(0, edgeFillColor());
gradient2.setColorAt(1, middleFillColor());
painter->setBrush(gradient2);
polygon << B1 << B2 << C2 << C1;
painter->drawPolygon(polygon);
polygon.clear();
QLinearGradient gradient3(CC, C2);
gradient3.setColorAt(0, edgeFillColor());
gradient3.setColorAt(1, middleFillColor());
painter->setBrush(gradient3);
polygon << C1 << C2 << A2 << A1;
painter->drawPolygon(polygon);
polygon.clear();
painter->setBrush(Qt::NoBrush);
painter->setPen(drawColor());
polygon << A1 << B1 << C1;
painter->drawPolygon(polygon);
polygon.clear();
polygon << A2 << B2 << C2;
painter->drawPolygon(polygon);
}
polygon << A1 << B1 << C1;
painter->drawPolygon(polygon);
polygon.clear();
else {
QLinearGradient gradient(QPointF(A1.x(), 0), QPointF(C1.x(), 0));
gradient.setColorAt(0, edgeFillColor());
gradient.setColorAt(1, middleFillColor());
painter->setBrush(gradient);
painter->setPen(drawColor());
polygon << A1 << B1 << C1;
painter->drawPolygon(polygon);
polygon.clear();
}
polygon << A2 << B2 << C2;
painter->drawPolygon(polygon);
paintGraduations(painter);
@ -329,9 +367,11 @@ QPainterPath UBGraphicsTriangle::shape() const
tShape.addPolygon(tPolygon);
tPolygon.clear();
tPolygon << A2 << B2 << C2;
tShape.addPolygon(tPolygon);
tPolygon.clear();
if (mShouldPaintInnerTriangle) {
tPolygon << A2 << B2 << C2;
tShape.addPolygon(tPolygon);
tPolygon.clear();
}
//qDebug() << "UBGraphicsTriangle shape()"<<"A1 ="<<A1<<"B1 ="<<B1<<"C1 ="<<C1;
//qDebug() << "UBGraphicsTriangle shape()"<<"A2 ="<<A2<<"B2 ="<<B2<<"C2 ="<<C2;
@ -592,19 +632,21 @@ QRectF UBGraphicsTriangle::vFlipRect() const
QRectF UBGraphicsTriangle::rotateRect() const
{
QPointF p(C2);
qreal buttonsX = vFlipRect().left();
switch(mOrientation)
{
case BottomLeft:
p += QPointF(20, 5);
p = QPointF(qMax(p.x() + 20, buttonsX), p.y() + 5);
break;
case TopLeft:
p += QPointF(20, -5 - mRotateSvgItem->boundingRect().height());
p = QPointF(qMax(p.x() + 20, buttonsX), p.y() -5 - mRotateSvgItem->boundingRect().height());
break;
case TopRight:
p += QPointF(-20 - mRotateSvgItem->boundingRect().width(), -5 - mRotateSvgItem->boundingRect().height());
p = QPointF(qMin(p.x() -20 - mRotateSvgItem->boundingRect().width(), buttonsX), p.y() - 5 - mRotateSvgItem->boundingRect().height());
break;
case BottomRight:
p += QPointF(-20 - mRotateSvgItem->boundingRect().width(), 5);
p = QPointF(qMin(p.x() -20 - mRotateSvgItem->boundingRect().width(), buttonsX), p.y() + 5);
break;
}
return QRectF(p, QSizeF(mRotateSvgItem->boundingRect().size()));
@ -806,9 +848,9 @@ void UBGraphicsTriangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
mShowButtons = true;
mCloseSvgItem->setVisible(true);
mHFlipSvgItem->setVisible(true);
mVFlipSvgItem->setVisible(true);
mRotateSvgItem->setVisible(true);
mHFlipSvgItem->setVisible(contains(hFlipRect()));
mVFlipSvgItem->setVisible(contains(vFlipRect()));
mRotateSvgItem->setVisible(contains(rotateRect()));
if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
setCursor(resizeCursor1());
@ -860,9 +902,9 @@ void UBGraphicsTriangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
currentTool == UBStylusTool::Play)
{
mCloseSvgItem->setVisible(mShowButtons);
mVFlipSvgItem->setVisible(mShowButtons);
mHFlipSvgItem->setVisible(mShowButtons);
mRotateSvgItem->setVisible(mShowButtons);
mVFlipSvgItem->setVisible(mShowButtons && contains(vFlipRect()));
mHFlipSvgItem->setVisible(mShowButtons && contains(hFlipRect()));
mRotateSvgItem->setVisible(mShowButtons && contains(rotateRect()));
if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
setCursor(resizeCursor1());
@ -935,6 +977,35 @@ void UBGraphicsTriangle::DrawLine(const QPointF &scenePos, qreal width)
UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker);
}
/**
* @brief Check whether a given QRectF is inside the triangle (A1, B1, C1).
*
* Returns true if any corner of the rectangle is within the triangle or, if strict is set to true,
* if all corners of the rectangle are within the triangle.
*/
bool UBGraphicsTriangle::contains(const QRectF &rect, bool strict)
{
QPolygonF poly;
poly << A1 << B1 << C1 << A1;
QPainterPath path;
path.addPolygon(poly);
QList<QPointF> points;
points << rect.bottomRight() << rect.topLeft() << rect.topRight();
bool inside = path.contains(rect.bottomLeft());
foreach(QPointF p, points) {
if (strict)
inside = inside && path.contains(p);
else
inside = inside || path.contains(p);
}
return inside;
}
void UBGraphicsTriangle::EndLine()
{
}

@ -98,7 +98,7 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
void setRect(const QRectF &rect, UBGraphicsTriangleOrientation orientation)
{
qDebug() << "setRect"<<"rect = "<<rect<<"orientation :"<<orientation;
//qDebug() << "setRect"<<"rect = "<<rect<<"orientation :"<<orientation;
setRect(rect.x(), rect.y(), rect.width(), rect.height(), orientation);
}
@ -178,11 +178,15 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
QPointF CC; // Hyp. fillining gradient - top point
void calculatePoints(const QRectF& rect);
bool mShouldPaintInnerTriangle;
static const int d = 70; // width of triangle border
static const int sArrowLength = 30;
static const int sMinWidth = 380;
static const int sMinHeight = 200;
static const int sMinWidth = 240;
static const int sMinHeight = 120;
qreal mStrokeWidth;
bool contains(const QRectF &rect, bool strict = true);
};
#endif /* UBGRAPHICSTRIANGLE_H_ */

Loading…
Cancel
Save