Merge branch 'dev' into 1.4-dev

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

@ -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>
<message>
<source>Ruled Light Background</source>
@ -862,7 +862,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>
@ -884,19 +884,19 @@
</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>
@ -910,11 +910,11 @@
<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>
@ -934,11 +934,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>
@ -954,11 +954,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>
@ -1019,7 +1019,7 @@
</message>
<message>
<source>Show OpenBoard</source>
<translation type="unfinished"></translation>
<translation>Zeige OpenBoard</translation>
</message>
</context>
<context>
@ -1046,7 +1046,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>
@ -1066,7 +1066,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>
@ -1078,7 +1078,7 @@
</message>
<message>
<source>Emptied trash</source>
<translation>Papierkorb geleert</translation>
<translation>Papierkorb wurde geleert</translation>
</message>
<message>
<source>Remove Folder</source>
@ -1086,7 +1086,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>
@ -1114,7 +1114,7 @@
</message>
<message>
<source>Empty</source>
<translation>Leer</translation>
<translation>Leeren</translation>
</message>
<message>
<source>Trash</source>
@ -1153,15 +1153,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>
@ -1200,11 +1200,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>
@ -1227,8 +1227,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>
@ -1249,26 +1249,6 @@
<source>Warnings during export was appeared</source>
<translation type="unfinished">Warnungen beim Exportieren aufgetreten</translation>
</message>
<message>
<source>Exporting document...</source>
<translation type="unfinished">Dokument wird exportiert...</translation>
</message>
<message>
<source>Export failed</source>
<translation type="unfinished"></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>
</message>
<message>
<source>Export failed: location not writable</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Export successful.</source>
<translation type="unfinished">Export erfolgreich.</translation>
</message>
</context>
<context>
<name>UBExportCFF</name>
@ -1305,11 +1285,11 @@
</message>
<message>
<source>Exporting document...</source>
<translation type="vanished">Dokument wird exportiert...</translation>
<translation>Dokument wird exportiert...</translation>
</message>
<message>
<source>Export successful.</source>
<translation type="vanished">Export erfolgreich.</translation>
<translation>Export erfolgreich.</translation>
</message>
<message>
<source>Exporting %1 %2 of %3</source>
@ -1317,7 +1297,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>Export fehlgeschlagen: Zielpfad nicht beschreibbar</translation>
</message>
<message>
<source>Export failed</source>
<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>Export im ausgewählten Zielpfad nicht möglich. Sie haben nicht die erforderliche Berechtigung um die Datei zu speichern.</translation>
</message>
</context>
<context>
@ -1328,16 +1320,28 @@
</message>
<message>
<source>Exporting document...</source>
<translation type="vanished">Dokument wird exportiert...</translation>
<translation>Dokument wird exportiert...</translation>
</message>
<message>
<source>Export successful.</source>
<translation type="vanished">Export erfolgreich.</translation>
<translation>Export erfolgreich.</translation>
</message>
<message>
<source>Export to PDF</source>
<translation>In PDF-Datei exportieren</translation>
</message>
<message>
<source>Export failed: location not writable</source>
<translation>Export fehlgeschlagen: Zielpfad nicht beschreibbar.</translation>
</message>
<message>
<source>Export failed</source>
<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>Export im ausgewählten Zielpfad nicht möglich. Sie haben nicht die erforderliche Berechtigung um die Datei zu speichern.</translation>
</message>
</context>
<context>
<name>UBExportPDF</name>
@ -1347,11 +1351,11 @@
</message>
<message>
<source>Exporting document...</source>
<translation type="vanished">Dokument wird exportiert...</translation>
<translation>Dokument wird exportiert...</translation>
</message>
<message>
<source>Export successful.</source>
<translation type="vanished">Export erfolgreich.</translation>
<translation>Export erfolgreich.</translation>
</message>
<message>
<source>Exporting page %1 of %2</source>
@ -1542,19 +1546,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>
@ -1593,11 +1597,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>
@ -1612,7 +1616,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>
@ -1639,7 +1643,7 @@
</message>
<message>
<source>OpenBoard (*.ubz)</source>
<translation type="unfinished"></translation>
<translation>OpenBoard (*.ubz)</translation>
</message>
</context>
<context>
@ -1735,7 +1739,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>
@ -1750,15 +1754,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>
@ -1766,11 +1770,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>
@ -1785,7 +1789,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>
@ -1839,7 +1843,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>
@ -2013,7 +2017,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>
@ -2031,7 +2035,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>
@ -2057,7 +2061,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>
@ -2160,7 +2164,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>
@ -2257,19 +2261,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>
@ -2330,7 +2334,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>
@ -2384,7 +2388,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>
@ -2403,7 +2407,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>
@ -2415,7 +2419,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<source>Strong</source>
<translation>Stark</translation>
<translation>Dick</translation>
</message>
<message>
<source>Fine</source>
@ -2461,7 +2465,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>
@ -2548,11 +2552,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>
@ -2605,19 +2609,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
@ -951,10 +953,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;
@ -1190,11 +1193,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)
@ -1215,6 +1213,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;
@ -1576,7 +1582,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();
@ -1612,9 +1618,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();
}
@ -2567,6 +2573,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();
@ -2593,6 +2600,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);
@ -2635,6 +2644,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)
{

@ -90,7 +90,6 @@ UBApplicationController::UBApplicationController(UBBoardView *pControlView,
, mAutomaticCheckForUpdates(false)
, mCheckingForUpdates(false)
, mIsShowingDesktop(false)
, mHttp(0)
{
mDisplayManager = new UBDisplayManager(this);
@ -121,7 +120,7 @@ UBApplicationController::UBApplicationController(UBBoardView *pControlView,
connect(UBApplication::webController, SIGNAL(imageCaptured(const QPixmap &, bool, const QUrl&))
, this, SLOT(addCapturedPixmap(const QPixmap &, bool, const QUrl&)));
networkAccessManager = new QNetworkAccessManager (this);
mNetworkAccessManager = new QNetworkAccessManager (this);
QTimer::singleShot (1000, this, SLOT (checkAtLaunch()));
}
@ -136,8 +135,6 @@ UBApplicationController::~UBApplicationController()
delete mBlackScene;
delete mMirror;
if (mHttp) delete mHttp;
delete(mOpenSankoreImporter);
mOpenSankoreImporter = NULL;
}
@ -478,85 +475,71 @@ void UBApplicationController::showDesktop(bool dontSwitchFrontProcess)
}
void UBApplicationController::checkUpdate(QString urlString)
void UBApplicationController::checkUpdate(const QUrl& url)
{
QUrl jsonUrl = url;
if (url.isEmpty())
jsonUrl = UBSettings::settings()->appSoftwareUpdateURI->get().toUrl();
qDebug() << "Checking for update at url: " << jsonUrl.toString();
#if defined(QT_NO_DEBUG)
/*
if(mHttp)
mHttp->deleteLater();
QUrl url(urlString);
mHttp = new QHttpPart(url.host());
connect(mHttp, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool)));
connect(mHttp, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(updateHeaderReceived(QHttpResponseHeader)));
mHttp->get(url.path());
*/
#else
if(mHttpreply)
mHttpreply->deleteLater();
QUrl url(urlString);
mHttpreply = qnam.get(QNetworkRequest(url));
connect(mHttpreply, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool)));
connect(mHttpreply, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(updateHeaderReceived(QHttpResponseHeader)));
// mHttpreply->setUrl(url.path());
//mHttp->get(url.path());
connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(updateRequestFinished(QNetworkReply*)));
mNetworkAccessManager->get(QNetworkRequest(jsonUrl));
#endif
}
/*
void UBApplicationController::updateHeaderReceived(QHttpResponseHeader header)
void UBApplicationController::updateRequestFinished(QNetworkReply * reply)
{
if(header.statusCode() == 302 && header.hasKey("Location")){
mHttp->close();
checkUpdate(header.value("Location"));
if (reply->error()) {
qWarning() << "Error downloading update file: " << reply->errorString();
return;
}
}
*/
void UBApplicationController::updateHeaderReceived(QNetworkRequest header )
{
//if(header.attribute(QNetworkRequest::HttpStatusCodeAttribute) == 302 && header.header(QNetworkRequest::LocationHeader)){
// mHttp->close();
mHttpreply->close();
//checkUpdate(header.value("Location"));
// }
}
// Check if we are being redirected. If so, call checkUpdate again
void UBApplicationController::updateRequestFinished(int id, bool error)
{
if (error){
qWarning() << "http command id" << id << "return an error";
}
else{
/* QString responseString = QString(mHttp->readAll());
qDebug() << responseString;
if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){
mHttp->close();
mHttp->deleteLater();
mHttp = 0;
downloadJsonFinished(responseString);
}
*/
QString responseString = QString(mHttpreply->readAll());
qDebug() << responseString;
if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){
mHttpreply->close();
mHttpreply->deleteLater();
mHttpreply = 0;
downloadJsonFinished(responseString);
}
}
}
QVariant redirect_target = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (!redirect_target.isNull()) {
// The returned URL might be relative. resolved() creates an absolute url from it
QUrl redirect_url(reply->url().resolved(redirect_target.toUrl()));
checkUpdate(redirect_url);
return;
}
// No error and no redirect => we read the whole response
QString responseString = QString(reply->readAll());
if (!responseString.isEmpty() &&
responseString.contains("version") &&
responseString.contains("url")) {
reply->close();
reply->deleteLater();
downloadJsonFinished(responseString);
}
}
void UBApplicationController::downloadJsonFinished(QString currentJson)
{
/*
The .json files simply specify the latest version number available, and
the URL to send the user to, so they can download it.
They look like:
{
"version": "1.3.5",
"url": "http://openboard.ch"
}
*/
QScriptValue scriptValue;
QScriptEngine scriptEngine;
scriptValue = scriptEngine.evaluate ("(" + currentJson + ")");
@ -564,17 +547,18 @@ void UBApplicationController::downloadJsonFinished(QString currentJson)
UBVersion installedVersion (qApp->applicationVersion());
UBVersion jsonVersion (scriptValue.property("version").toString());
qDebug() << "json version: " << jsonVersion.toUInt();
qDebug() << "installed version: " << installedVersion.toUInt();
if (jsonVersion > installedVersion) {
if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){
QUrl url(scriptValue.property ("url").toString());
QDesktopServices::openUrl (url);
}
}
else {
if (isNoUpdateDisplayed) {
mMainWindow->information(tr("Update"), tr("No update available"));
if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){
QUrl url(scriptValue.property("url").toString());
QDesktopServices::openUrl(url);
}
}
else if (isNoUpdateDisplayed) {
mMainWindow->information(tr("Update"), tr("No update available"));
}
}
void UBApplicationController::checkAtLaunch()
@ -583,14 +567,14 @@ void UBApplicationController::checkAtLaunch()
if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()){
isNoUpdateDisplayed = false;
//checkUpdate ();
checkUpdate();
}
}
void UBApplicationController::checkUpdateRequest()
{
isNoUpdateDisplayed = true;
//checkUpdate ();
checkUpdate();
}
void UBApplicationController::hideDesktop()
@ -658,7 +642,6 @@ void UBApplicationController::closing()
if (mUninoteController)
{
mUninoteController->hideWindow();
mUninoteController->close();
}

@ -53,12 +53,8 @@ class UBVersion;
class UBSoftwareUpdate;
class QNetworkAccessManager;
class QNetworkReply;
class QHttpPart;
class UBRightPalette;
class UBOpenSankoreImporter;
class QScriptValue;
class QScriptEngine;
class QNetworkReply;
class UBApplicationController : public QObject
{
@ -158,8 +154,8 @@ class UBApplicationController : public QObject
void checkAtLaunch();
private slots:
void updateRequestFinished(int id, bool error);
void updateHeaderReceived(QNetworkRequest header );
void updateRequestFinished(QNetworkReply * reply);
protected:
@ -193,13 +189,10 @@ class UBApplicationController : public QObject
bool mIsShowingDesktop;
bool isNoUpdateDisplayed;
void checkUpdate (QString urlString = "http://get.openboard.org/update.json");
QNetworkAccessManager *networkAccessManager;
void checkUpdate(const QUrl &url = QUrl());
QNetworkAccessManager * mNetworkAccessManager;
void downloadJsonFinished(QString updateString);
QHttpPart* mHttp;
QNetworkAccessManager qnam;
QNetworkReply *mHttpreply;
};
#endif /* UBAPPLICATIONCONTROLLER_H_ */

@ -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);

@ -73,9 +73,6 @@ 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));
@ -231,6 +228,7 @@ void UBSettings::init()
appToolBarDisplayText = new UBSetting(this, "App", "ToolBarDisplayText", true);
appEnableAutomaticSoftwareUpdates = new UBSetting(this, "App", "EnableAutomaticSoftwareUpdates", false);
appEnableSoftwareUpdates = new UBSetting(this, "App", "EnableSoftwareUpdates", true);
appSoftwareUpdateURI = new UBSetting(this, "App", "SoftwareUpdateURI", "http://www.openboard.ch/update.json");
appToolBarOrientationVertical = new UBSetting(this, "App", "ToolBarOrientationVertical", false);
appPreferredLanguage = new UBSetting(this,"App","PreferredLanguage", "");
@ -282,6 +280,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;
@ -246,6 +244,7 @@ class UBSettings : public QObject
UBSetting* appToolBarDisplayText;
UBSetting* appEnableAutomaticSoftwareUpdates;
UBSetting* appEnableSoftwareUpdates;
UBSetting* appSoftwareUpdateURI;
UBSetting* appToolBarOrientationVertical;
UBSetting* appPreferredLanguage;
@ -286,6 +285,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;

@ -1290,15 +1290,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())
@ -2503,9 +2510,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;

@ -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();

@ -111,9 +111,15 @@ void UBSelectionFrame::setEnclosedItems(const QList<QGraphicsItem*> pGraphicsIte
QRegion resultRegion;
UBGraphicsFlags resultFlags;
mEnclosedtems.clear();
// If at least one of the enclosed items is locked, the entire selection is
// considered to be locked.
mIsLocked = false;
foreach (QGraphicsItem *nextItem, pGraphicsItems) {
UBGraphicsItemDelegate *nextDelegate = UBGraphicsItem::Delegate(nextItem);
if (nextDelegate) {
mIsLocked = (mIsLocked || nextDelegate->isLocked());
mEnclosedtems.append(nextDelegate);
resultRegion |= nextItem->boundingRegion(nextItem->sceneTransform());
resultFlags |= nextDelegate->ubflags();
@ -129,6 +135,14 @@ void UBSelectionFrame::setEnclosedItems(const QList<QGraphicsItem*> pGraphicsIte
if (resultRect.isEmpty()) {
hide();
}
if (mIsLocked) {
QColor baseColor = UBSettings::paletteColor;
baseColor.setAlphaF(baseColor.alphaF() / 3);
setLocalBrush(QBrush(baseColor));
}
else
setLocalBrush(QBrush(UBSettings::paletteColor));
}
void UBSelectionFrame::updateRect()
@ -168,6 +182,9 @@ void UBSelectionFrame::mousePressEvent(QGraphicsSceneMouseEvent *event)
void UBSelectionFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (mIsLocked)
return;
QPointF dp = event->pos() - mPressedPos;
QPointF rotCenter = mapToScene(rect().center());

@ -103,6 +103,8 @@ private:
QPointF mLastTranslateOffset;
qreal mRotationAngle;
bool mIsLocked;
QList<DelegateButton*> mButtons;
DelegateButton *mDeleteButton;

@ -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;

@ -42,21 +42,32 @@ UBVersion::UBVersion(const QString &string)
uint UBVersion::toUInt() const
{
/* Based on semantic versioning, version numbers look like:
* Major.Minor.Patch-Type.Build
*
* To compare version numbers, the string is split into each part, and they are multiplied
* to give a number where the first two digits are the Major version, the next two are the
* Minor version, and so on.
*
* i.e if Major, Minor etc. are named A, B, C, D, E, the number will look like:
* AABBCCDDEE
*/
uint result = 0;
QStringList list = mString.split(".");
QStringList list = mString.split(QRegExp("[-\\.]"));
switch (list.count()) {
case 2:
//short version 1.0
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (Release * 100);
result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + (Release * 100);
break;
case 3:
//release version 1.0.0
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (Release * 100) + list.at(2).toUInt();
result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + list.at(2).toUInt()*10000 + (Release * 100);
break;
case 4:{
//standard version 1.0.a/b/r.0
uint releaseStage = list.at(2).startsWith("a") ? Alpha :(list.at(2).startsWith("b") ? Beta : ReleaseCandidate);
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (releaseStage * 100) + list.at(3).toUInt();
case 5:{
//standard version 1.0.0.a/b/rc.0
uint releaseStage = list.at(3).startsWith("a") ? Alpha :(list.at(3).startsWith("b") ? Beta : ReleaseCandidate);
result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + (list.at(2).toUInt() * 10000) + (releaseStage * 100) + list.at(4).toUInt();
break;
}
default:

@ -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;

@ -125,25 +125,25 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem
bool mDrewCenterCross;
// 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;
@ -607,19 +647,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()));
@ -821,9 +863,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());
@ -875,9 +917,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());
@ -950,6 +992,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