diff --git a/resources/etc/OpenBoard.config b/resources/etc/OpenBoard.config index cdef9239..c332d35a 100644 --- a/resources/etc/OpenBoard.config +++ b/resources/etc/OpenBoard.config @@ -1,7 +1,6 @@ [App] AngleTolerance=4 EnableAutomaticSoftwareUpdates=false -EnableSoftwareUpdates=true EnableStartupHints=true FavoriteToolURIs=openboardtool://openboard/mask, openboardtool://ruler, openboardtool://compass, openboardtool://protractor, openboardtool://triangle, openboardtool://magnifier, openboardtool://cache IsInSoftwareUpdateProcess=false diff --git a/resources/i18n/OpenBoard_it.ts b/resources/i18n/OpenBoard_it.ts index 3f6a5947..e217bf25 100644 --- a/resources/i18n/OpenBoard_it.ts +++ b/resources/i18n/OpenBoard_it.ts @@ -1,6 +1,6 @@ - + BlackoutWidget @@ -793,11 +793,11 @@ Open Tutorial - + Apri tutorial Open the tutorial web page - + Apri la pagina web del tutorial Ruled Light Background @@ -850,11 +850,11 @@ QObject Element ID = - Elemento ID = + Elemento ID = Content is not supported in destination format. - Il contenuto non è supportato nel formato di destinazione. + Il contenuto non è supportato nel formato di destinazione. Remove Page @@ -954,11 +954,11 @@ Saving document... - + Salvataggio documento... Document has just been saved... - + Il documento è stato appena salvato... @@ -1019,7 +1019,7 @@ Show OpenBoard - + Mostra OpenBoard @@ -1138,9 +1138,9 @@ Are you sure you want to remove %n page(s) from the selected document '%1'? - - Sei sicuro di voler rimuovere %n pagine dal documento '%1' selezionato? - + + Sei sicuro di voler rimuovere %n pagina dal documento '%1' selezionato? + Sei sicuro di voler rimuovere %n pagine dal documento '%1' selezionato? @@ -1153,15 +1153,15 @@ The document '%1' has been generated with a newer version of OpenBoard (%2). By opening it, you may lose some information. Do you want to proceed? - + Il documento "%1" è stato generato con una più recente versione di OpenBoard (%2). Aprendolo, si possono perdere alcune informazioni. Procedere ugualmente? Are you sure you want to remove all selected documents? - + Sicuri di voler rimuovere tutti i documenti selezionati? Remove multiple documents - + Rimuovi documenti multipli @@ -1227,8 +1227,8 @@ %1 pages copied - %1 pagine copiate - + %1 pagina copiata + %1 pagine copiate @@ -1274,23 +1274,23 @@ UBExportCFF Export to IWB - Esporta in IWB + Esporta in IWB Export as IWB File - Esporta come file IWB + Esporta come file IWB Exporting document... - Esportazione documento in corso... + Esportazione documento in corso... Export successful. - Esportazione conclusa con successo. + Esportazione conclusa con successo. Export failed. - Esportazione fallita. + Esportazione fallita. @@ -1317,8 +1317,23 @@ Export to OpenBoard Format - + Esporta nel formato OpenBoard + +<<<<<<< HEAD +======= + + Export failed: location not writable + Exportazione fallita: posizione non scrivibile + + + Export failed + Esportazione fallita + + + Unable to export to the selected location. You do not have the permissions necessary to save the file. + Impossibile esportare nella posizione selezionata. Non possiedi i permessi necessari a salvare il file. +>>>>>>> dev UBExportFullPDF @@ -1338,6 +1353,21 @@ Export to PDF Esporta in PDF +<<<<<<< HEAD +======= + + Export failed: location not writable + Esportazione fallita: posizione non scrivibile + + + Export failed + Esportazione fallita + + + Unable to export to the selected location. You do not have the permissions necessary to save the file. + Impossibile esportare alla posizione selezionata. Non possiedi i permessi necessari a salvare il file. + +>>>>>>> dev UBExportPDF @@ -1542,19 +1572,19 @@ UBGraphicsMediaItem Media resource couldn't be resolved - + La risorsa multimediale non può essere gestita Unsupported media format - + Formato multimediale non supportato Media playback service not found - + Servizio di esecuzione multimediale non trovato Media error: - + Errore multimediale: @@ -1604,23 +1634,23 @@ UBImportCFF Common File Format ( - Common File Format ( + Common File Format ( Importing file %1... - Importazione del file %1 in corso... + Importazione del file %1 in corso... Import of file %1 failed. - L'importazione del file %1 è fallita. + L'importazione del file %1 è fallita. Import successful. - Importazione completata con successo. + Importazione completata con successo. Import failed. - Importazione fallita. + Importazione fallita. @@ -1639,7 +1669,7 @@ OpenBoard (*.ubz) - + OpenBoard (*.ubz) @@ -1750,27 +1780,27 @@ Vuoi ignorare gli errori per questo host? UBOpenSankoreImporterWidget Open-Sankore Documents Detected - + Rilevati documenti Open-Sankore Show this panel next time - + Mostra questo pannello la prossima volta 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. - + È sempre possibile accedere all'importatore di documenti OpenBoard tramite il pannello delle preferenze nella scheda delle informazioni su OpenBoard. Attenzione, se si è già importato dati Open-Sankore, è possibile perdere i documenti OpenBoard correnti. Cancel - Annulla + Annulla Proceed - + Procedi 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. - + Documenti Open-Sankoré sono presenti nel computer. È possibile importarli in OpenBoard premendo il pulsante “Procedi” per avviare l'applicazione di importazione. @@ -1785,7 +1815,7 @@ Vuoi ignorare gli errori per questo host? has lost access to the document repository '%1'. Unfortunately the application must shut down to avoid data corruption. Latest changes may be lost as well. - + ha perso l'accesso al repository documenti "%1". Sfortunatamente l'applicazione deve essere chiusa per evitare di rivinare i dati. Gli ultimi cambiamenti potrebbero andare persi. @@ -1871,7 +1901,7 @@ Vuoi ignorare gli errori per questo host? OpenBoard Cast - + OpenBoard Cast @@ -1930,7 +1960,7 @@ Vuoi ignorare gli errori per questo host? UBStartupHintsPalette Visible next time - + Visibile la prossima volta @@ -2330,7 +2360,7 @@ Si prega di riavviare l'applicazione per accedere ai documenti aggiornati.< Download PDF Document: would you prefer to download the PDF file or add it to the current OpenBoard document? - + Scarica il documento PDF: preferisci scaricare il file PDF o aggiungerlo al documento OpenBoard corrente? @@ -2384,11 +2414,11 @@ p, li { white-space: pre-wrap; } Restore credentials on reboot - + Ripristina le credenziali al riavvio OpenBoard - OpenBoard + OpenBoard @@ -2461,7 +2491,7 @@ p, li { white-space: pre-wrap; } documents OpenBoard Documents - + Documenti OpenBoard @@ -2504,7 +2534,7 @@ p, li { white-space: pre-wrap; } Keyboard button size: - Dimensione pulsanti tastiera: + Dimensione pulsanti tastiera: Toolbar @@ -2604,19 +2634,19 @@ p, li { white-space: pre-wrap; } Open-Sankoré Importer - + Apri l'importatore Open-Sankoré Check if Open-Sankoré data could be imported at launch - + Controlla se i dati Open-Sankoré possono venir importati all'avvio Use system keyboard (recommended) - + Usa la tastiera di sistema (raccomandato) Built-in virtual keyboard button size: - + Dimensione pulsanti tastiera virtuale incorporata: diff --git a/src/adaptors/UBExportPDF.cpp b/src/adaptors/UBExportPDF.cpp index 9f70c57b..f8d22cdc 100644 --- a/src/adaptors/UBExportPDF.cpp +++ b/src/adaptors/UBExportPDF.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "core/UBApplication.h" #include "core/UBSettings.h" @@ -40,6 +41,7 @@ #include "domain/UBGraphicsScene.h" #include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPDFItem.h" #include "document/UBDocumentProxy.h" @@ -66,56 +68,67 @@ void UBExportPDF::persist(UBDocumentProxy* pDocumentProxy) bool UBExportPDF::persistsDocument(UBDocumentProxy* pDocumentProxy, const QString& filename) { - QPrinter pdfPrinter; + QPdfWriter pdfWriter(filename); qDebug() << "exporting document to PDF" << filename; - pdfPrinter.setOutputFormat(QPrinter::PdfFormat); - pdfPrinter.setResolution(UBSettings::settings()->pdfResolution->get().toInt()); - pdfPrinter.setOutputFileName(filename); - pdfPrinter.setFullPage(true); + pdfWriter.setResolution(UBSettings::settings()->pdfResolution->get().toInt()); + pdfWriter.setPageMargins(QMarginsF()); + pdfWriter.setTitle(pDocumentProxy->name()); + pdfWriter.setCreator("OpenBoard PDF export"); //need to calculate screen resolution QDesktopWidget* desktop = UBApplication::desktop(); int dpiCommon = (desktop->physicalDpiX() + desktop->physicalDpiY()) / 2; float scaleFactor = 72.0f / dpiCommon; - + QPainter pdfPainter; bool painterNeedsBegin = true; int existingPageCount = pDocumentProxy->pageCount(); - for(int pageIndex = 0 ; pageIndex < existingPageCount; pageIndex++) - { + for(int pageIndex = 0 ; pageIndex < existingPageCount; pageIndex++) { + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, pageIndex); UBApplication::showMessage(tr("Exporting page %1 of %2").arg(pageIndex + 1).arg(existingPageCount)); + // set background to white, no crossing for PDF output bool isDark = scene->isDarkBackground(); UBPageBackground pageBackground = scene->pageBackground(); scene->setBackground(false, UBPageBackground::plain); - QSize pageSize = scene->nominalSize(); + // pageSize is the output PDF page size; it is set to equal the scene's boundary size; if the contents + // of the scene overflow from the boundaries, they will be scaled down. + QSize pageSize = scene->sceneSize(); // set high res rendering scene->setRenderingQuality(UBItem::RenderingQualityHigh); scene->setRenderingContext(UBGraphicsScene::NonScreen); - //setting page size to appropriate value - pdfPrinter.setPaperSize(QSizeF(pageSize.width()*scaleFactor, pageSize.height()*scaleFactor), QPrinter::Point); - if(painterNeedsBegin) painterNeedsBegin = !pdfPainter.begin(&pdfPrinter); - //render to PDF - scene->render(&pdfPainter, QRectF(), scene->normalizedSceneRect()); + // Setting output page size + QPageSize outputPageSize = QPageSize(QSizeF(pageSize.width()*scaleFactor, pageSize.height()*scaleFactor), QPageSize::Point); + pdfWriter.setPageSize(outputPageSize); - if (pageIndex < existingPageCount - 1) pdfPrinter.newPage(); + // Call begin only once + if(painterNeedsBegin) + painterNeedsBegin = !pdfPainter.begin(&pdfWriter); - //restore screen rendering quality + else if (pageIndex < existingPageCount) + pdfWriter.newPage(); + + // Render the scene + scene->render(&pdfPainter, QRectF(), scene->normalizedSceneRect()); + + // Restore screen rendering quality scene->setRenderingContext(UBGraphicsScene::Screen); scene->setRenderingQuality(UBItem::RenderingQualityNormal); - //restore background state + // Restore background state scene->setBackground(isDark, pageBackground); } - if(!painterNeedsBegin) pdfPainter.end(); + + if(!painterNeedsBegin) + pdfPainter.end(); return true; } diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 109b298e..414d146e 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -620,9 +620,6 @@ UBGraphicsItem *UBBoardController::duplicateItem(UBItem *item) itemSize = commonItem->boundingRect().size(); commonItem->setSelected(false); - UBGraphicsStrokesGroup *stroke = dynamic_cast(commonItem); - if (stroke) - itemPos = QPointF(shifting, shifting); } UBMimeType::Enum itemMimeType; @@ -681,7 +678,7 @@ UBGraphicsItem *UBBoardController::duplicateItem(UBItem *item) { QBuffer buffer(&pData); buffer.open(QIODevice::WriteOnly); - QString format = UBFileSystemUtils::extension(item->sourceUrl().toLocalFile()); + QString format = UBFileSystemUtils::extension(item->sourceUrl().toString(QUrl::DecodeReserved)); pixitem->pixmap().save(&buffer, format.toLatin1()); } }break; diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index 393a40ac..06cec6ed 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -74,6 +74,7 @@ #include "document/UBDocumentController.h" +#include "core/UBPersistenceManager.h" #include "core/memcheck.h" UBBoardPaletteManager::UBBoardPaletteManager(QWidget* container, UBBoardController* pBoardController) @@ -862,7 +863,11 @@ void UBBoardPaletteManager::addItemToCurrentPage() { UBGraphicsPixmapItem* item = UBApplication::boardController->activeScene()->addPixmap(mPixmap, NULL, mPos, mScaleFactor); - item->setSourceUrl(mItemUrl); + QString documentPath = UBApplication::boardController->selectedDocument()->persistencePath(); + QString fileName = UBPersistenceManager::imageDirectory + "/" + item->uuid().toString() + ".png"; + QString path = documentPath + "/" + fileName; + + item->setSourceUrl(QUrl(path)); item->setSelected(true); UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); diff --git a/src/core/UBApplication.cpp b/src/core/UBApplication.cpp index 5e205fea..9f4a8301 100644 --- a/src/core/UBApplication.cpp +++ b/src/core/UBApplication.cpp @@ -511,13 +511,7 @@ void UBApplication::decorateActionMenu(QAction* action) menu->addSeparator(); menu->addAction(mainWindow->actionPreferences); menu->addAction(mainWindow->actionMultiScreen); - // SANKORE-48: Hide the check update action if the setting - // EnableAutomaticSoftwareUpdates is false in Uniboard.config - if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()) - menu->addAction(mainWindow->actionCheckUpdate); - else - mainWindow->actionCheckUpdate->setEnabled(false); - + menu->addAction(mainWindow->actionCheckUpdate); menu->addSeparator(); menu->addAction(mainWindow->actionPodcast); diff --git a/src/core/UBApplicationController.cpp b/src/core/UBApplicationController.cpp index 44b85c25..d8bdc89f 100644 --- a/src/core/UBApplicationController.cpp +++ b/src/core/UBApplicationController.cpp @@ -479,7 +479,7 @@ void UBApplicationController::checkUpdate(const QUrl& url) { QUrl jsonUrl = url; if (url.isEmpty()) - jsonUrl = UBSettings::settings()->appSoftwareUpdateURI->get().toUrl(); + jsonUrl = UBSettings::settings()->appSoftwareUpdateURL->get().toUrl(); qDebug() << "Checking for update at url: " << jsonUrl.toString(); diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp index df58462c..4bd2bd75 100644 --- a/src/core/UBPreferencesController.cpp +++ b/src/core/UBPreferencesController.cpp @@ -190,8 +190,6 @@ void UBPreferencesController::wire() // about tab connect(mPreferencesUI->checkSoftwareUpdateAtLaunchCheckBox, SIGNAL(clicked(bool)), settings->appEnableAutomaticSoftwareUpdates, SLOT(setBool(bool))); - // As we (hopefully temporarily) don't have a website to check updates at, this setting is hidden for now - mPreferencesUI->softwareUpdateGroupBox->setVisible(false); connect(mPreferencesUI->checkOpenSankoreAtStartup, SIGNAL(clicked(bool)), settings->appLookForOpenSankoreInstall, SLOT(setBool(bool))); } diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp index 04e85bd4..e00a9b38 100644 --- a/src/core/UBSettings.cpp +++ b/src/core/UBSettings.cpp @@ -227,8 +227,7 @@ void UBSettings::init() appToolBarPositionedAtTop = new UBSetting(this, "App", "ToolBarPositionedAtTop", true); 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"); + appSoftwareUpdateURL = new UBSetting(this, "App", "SoftwareUpdateURL", "http://www.openboard.ch/update.json"); appToolBarOrientationVertical = new UBSetting(this, "App", "ToolBarOrientationVertical", false); appPreferredLanguage = new UBSetting(this,"App","PreferredLanguage", ""); @@ -281,7 +280,7 @@ void UBSettings::init() pageSize = new UBSetting(this, "Board", "DefaultPageSize", documentSizes.value(DocumentSizeRatio::Ratio4_3)); - boardCrossColorDarkBackground = new UBSetting(this, "Board", "CrossColorDarkBackground", "#C82C2C2C"); + boardCrossColorDarkBackground = new UBSetting(this, "Board", "CrossColorDarkBackground", "#C8C0C0C0"); boardCrossColorLightBackground = new UBSetting(this, "Board", "CrossColorLightBackground", "#A5E1FF"); QStringList penLightBackgroundColors; diff --git a/src/core/UBSettings.h b/src/core/UBSettings.h index 709e5c1d..aba55749 100644 --- a/src/core/UBSettings.h +++ b/src/core/UBSettings.h @@ -243,8 +243,7 @@ class UBSettings : public QObject UBSetting* appToolBarPositionedAtTop; UBSetting* appToolBarDisplayText; UBSetting* appEnableAutomaticSoftwareUpdates; - UBSetting* appEnableSoftwareUpdates; - UBSetting* appSoftwareUpdateURI; + UBSetting* appSoftwareUpdateURL; UBSetting* appToolBarOrientationVertical; UBSetting* appPreferredLanguage; diff --git a/src/document/UBDocumentController.cpp b/src/document/UBDocumentController.cpp index ebce0117..088544f8 100644 --- a/src/document/UBDocumentController.cpp +++ b/src/document/UBDocumentController.cpp @@ -546,37 +546,66 @@ void UBDocumentController::duplicateSelectedItem() } /** - * @brief When deleting multiple documents, find a new document and select it + * @brief Set the first document in the list as current document * - * This method simply selects the first un-selected document + * If there are no documents, a new one is created. */ -void UBDocumentController::selectADocumentOnMultipleTrashing() +void UBDocumentController::selectFirstDocumentInList() { - // Loop through all folders, and each document in those folders, until we find - // a document that is not in the current selection (which is being deleted) + // Loop through all folders until we find one that is not the trash and not empty, + // and select the first document in that folder for (int i(0); i < mDocumentUI->documentTreeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (!groupItem->isTrashFolder()) { - for (int j(0); j < groupItem->childCount(); ++j) { - if (!mCurrentSelection.contains( groupItem->child(j) )) { - selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy(), true); - return; - } - } + if (!groupItem->isTrashFolder() && groupItem->childCount() > 0) { + selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy(), true); + groupItem->child(0)->setSelected(true); + return; } } - - // No document found => create a new one UBDocumentGroupTreeItem* topFolder = dynamic_cast(mDocumentUI->documentTreeWidget->topLevelItem(0)); UBDocumentProxy* document = UBPersistenceManager::persistenceManager()->createDocument(topFolder->groupName()); selectDocument(document, true); +} + +/** + * @brief Find the current document, and select it in the list + * + * If selectNewCurrentDocument is true, the first document in the list is selected and set as + * current document. + */ +void UBDocumentController::selectATreeItemOnMultipleTrashing(bool selectNewCurrentDocument) +{ + mCurrentSelection.clear(); + + if (selectNewCurrentDocument) { + selectFirstDocumentInList(); + return; + } + + // Find the currently selected document, and select its corresponding tree item + // If it isn't found, then the first document in the list is selected and set as current document + + for (int i(0); i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (!groupItem->isTrashFolder()) { + for (int j(0); j < groupItem->childCount(); j++) { + if (((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy() == mBoardController->selectedDocument()) { + ((UBDocumentProxyTreeItem*)groupItem->child(j))->setSelected(true); + return; + } + } + } + } + + selectFirstDocumentInList(); } void UBDocumentController::selectADocumentOnTrashingSelectedOne(UBDocumentGroupTreeItem* groupTi,UBDocumentProxyTreeItem *proxyTi) @@ -807,9 +836,9 @@ void UBDocumentController::deleteTreeItem(QTreeWidgetItem * item, bool showConfi if (selectNewDocument) { if (mTrashTi->childCount()==0) - selectDocument(NULL); + selectATreeItemOnMultipleTrashing(false); else - selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy()); + selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy(), false); } reloadThumbnails(); @@ -849,11 +878,18 @@ void UBDocumentController::deleteSelectedItem() QList foldersToDelete; + bool currentDocumentDeleted = false; + foreach (QTreeWidgetItem * item, mCurrentSelection) { LastSelectedElementType type = itemType(item); - if (type == Document) + if (type == Document) { deleteTreeItem(item, false, false); + UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); + if (proxyItem && proxyItem->proxy() && (proxyItem->proxy() == mBoardController->selectedDocument())) + currentDocumentDeleted = true; + } + else if (type == Folder) // Delete folders later, to avoid deleting a document twice foldersToDelete << item; @@ -863,7 +899,7 @@ void UBDocumentController::deleteSelectedItem() deleteTreeItem(item, false, false); } - selectADocumentOnMultipleTrashing(); + selectATreeItemOnMultipleTrashing(currentDocumentDeleted); } else if (mSelectionType == Document || mSelectionType == Folder) { diff --git a/src/document/UBDocumentController.h b/src/document/UBDocumentController.h index 39e5f635..62160800 100644 --- a/src/document/UBDocumentController.h +++ b/src/document/UBDocumentController.h @@ -130,7 +130,8 @@ class UBDocumentController : public UBDocumentContainer QString mDefaultDocumentGroupName; void selectADocumentOnTrashingSelectedOne(UBDocumentGroupTreeItem* groupTi,UBDocumentProxyTreeItem *proxyTi); - void selectADocumentOnMultipleTrashing(); + void selectFirstDocumentInList(); + void selectATreeItemOnMultipleTrashing(bool selectNewCurrentDocument = false); void moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, UBDocumentProxyTreeItem *proxyTi, bool selectNewDocument); void moveFolderToTrash(UBDocumentGroupTreeItem* groupTi); void emptyTrash(bool showConfirmationDialog); diff --git a/src/domain/UBGraphicsItemUndoCommand.cpp b/src/domain/UBGraphicsItemUndoCommand.cpp index ee23a7bb..aae00f2b 100644 --- a/src/domain/UBGraphicsItemUndoCommand.cpp +++ b/src/domain/UBGraphicsItemUndoCommand.cpp @@ -98,7 +98,28 @@ void UBGraphicsItemUndoCommand::undo() UBApplication::boardController->freezeW3CWidget(item, true); item->setSelected(false); + + QTransform t; + bool bApplyTransform = false; + UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); + if (polygonItem){ + if (polygonItem->strokesGroup() + && polygonItem->strokesGroup()->parentItem() + && UBGraphicsGroupContainerItem::Type == polygonItem->strokesGroup()->parentItem()->type()) + { + bApplyTransform = true; + t = polygonItem->sceneTransform(); + } + else if (polygonItem->strokesGroup()) + polygonItem->resetTransform(); + + polygonItem->strokesGroup()->removeFromGroup(polygonItem); + } mScene->removeItem(item); + + if (bApplyTransform) + polygonItem->setTransform(t); + } QSetIterator itRemoved(mRemovedItems); @@ -207,7 +228,29 @@ void UBGraphicsItemUndoCommand::redo() { QGraphicsItem* item = itRemoved.next(); item->setSelected(false); + + QTransform t; + bool bApplyTransform = false; + UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); + + if (polygonItem){ + if(polygonItem->strokesGroup() + && polygonItem->strokesGroup()->parentItem() + && UBGraphicsGroupContainerItem::Type == polygonItem->strokesGroup()->parentItem()->type()) + { + bApplyTransform = true; + t = polygonItem->sceneTransform(); + } + else if (polygonItem->strokesGroup()) + polygonItem->resetTransform(); + + polygonItem->strokesGroup()->removeFromGroup(polygonItem); + } mScene->removeItem(item); + + if (bApplyTransform) + item->setTransform(t); + UBApplication::boardController->freezeW3CWidget(item, true); } diff --git a/src/domain/UBGraphicsMediaItem.cpp b/src/domain/UBGraphicsMediaItem.cpp index 4185fe40..851e38f7 100644 --- a/src/domain/UBGraphicsMediaItem.cpp +++ b/src/domain/UBGraphicsMediaItem.cpp @@ -130,7 +130,14 @@ UBGraphicsVideoItem::UBGraphicsVideoItem(const QUrl &pMediaFileUrl, QGraphicsIte mVideoItem->setData(UBGraphicsItemData::ItemLayerType, UBItemLayerType::Object); mVideoItem->setFlag(ItemStacksBehindParent, true); - mMediaObject->setVideoOutput(mVideoItem); + /* setVideoOutput has to be called only when the video item is visible on the screen, + * due to a Qt bug (QTBUG-32522). So instead of calling it here, it is called when the + * active scene has changed, or when the item is first created. + * If and when Qt fix this issue, this should be changed back. + * */ + //mMediaObject->setVideoOutput(mVideoItem); + mHasVideoOutput = false; + mMediaObject->setNotifyInterval(50); setMinimumSize(QSize(320, 240)); @@ -155,8 +162,10 @@ UBGraphicsVideoItem::UBGraphicsVideoItem(const QUrl &pMediaFileUrl, QGraphicsIte UBGraphicsMediaItem::~UBGraphicsMediaItem() { - if (mMediaObject) + if (mMediaObject) { mMediaObject->stop(); + delete mMediaObject; + } } QVariant UBGraphicsMediaItem::itemChange(GraphicsItemChange change, const QVariant &value) @@ -569,6 +578,22 @@ void UBGraphicsVideoItem::paint(QPainter *painter, const QStyleOptionGraphicsIte } +QVariant UBGraphicsVideoItem::itemChange(GraphicsItemChange change, const QVariant &value) { + if (change == QGraphicsItem::ItemVisibleChange + && value.toBool() + && !mHasVideoOutput + && UBApplication::app()->boardController + && UBApplication::app()->boardController->activeScene() == scene()) + { + //qDebug() << "Item change, setting video output"; + + mMediaObject->setVideoOutput(mVideoItem); + mHasVideoOutput = true; + } + + return UBGraphicsMediaItem::itemChange(change, value); +} + void UBGraphicsVideoItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { // Display the seek bar @@ -610,9 +635,19 @@ void UBGraphicsVideoItem::mediaStateChanged(QMediaPlayer::State state) void UBGraphicsVideoItem::activeSceneChanged() { + //qDebug() << "Active scene changed"; + // Update the visibility of the placeholder, to prevent it being hidden when switching pages setPlaceholderVisible(!mErrorString.isEmpty()); + // Call setVideoOutput, if the video is visible and if it hasn't been called already + if (!mHasVideoOutput && UBApplication::boardController->activeScene() == scene()) { + //qDebug() << "setting video output"; + mMediaObject->setMedia(mMediaFileUrl); + mMediaObject->setVideoOutput(mVideoItem); + mHasVideoOutput = true; + } + UBGraphicsMediaItem::activeSceneChanged(); } diff --git a/src/domain/UBGraphicsMediaItem.h b/src/domain/UBGraphicsMediaItem.h index dd5ed396..4af649da 100644 --- a/src/domain/UBGraphicsMediaItem.h +++ b/src/domain/UBGraphicsMediaItem.h @@ -207,11 +207,14 @@ protected: QGraphicsVideoItem *mVideoItem; + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void setPlaceholderVisible(bool visible); + + bool mHasVideoOutput; }; diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index efd58c41..9b6a1958 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -2336,15 +2336,19 @@ QList UBGraphicsScene::relativeDependencies() const while (itItems.hasNext()) { QGraphicsItem* item = itItems.next(); - UBGraphicsMediaItem *mediaItem = qgraphicsitem_cast (item); - - if (mediaItem){ - QString completeFileName = QFileInfo(mediaItem->mediaFileUrl().toLocalFile()).fileName(); - QString path; - if(mediaItem->getMediaType() == UBGraphicsMediaItem::mediaType_Video) - path = UBPersistenceManager::videoDirectory + "/"; - else - path = UBPersistenceManager::audioDirectory + "/"; + + UBGraphicsVideoItem *videoItem = qgraphicsitem_cast (item); + if (videoItem){ + QString completeFileName = QFileInfo(videoItem->mediaFileUrl().toLocalFile()).fileName(); + QString path = UBPersistenceManager::videoDirectory + "/"; + relativePathes << QUrl(path + completeFileName); + continue; + } + + UBGraphicsAudioItem *audioItem = qgraphicsitem_cast (item); + if (audioItem){ + QString completeFileName = QFileInfo(audioItem->mediaFileUrl().toLocalFile()).fileName(); + QString path = UBPersistenceManager::audioDirectory + "/"; relativePathes << QUrl(path + completeFileName); continue; } @@ -2384,6 +2388,24 @@ QSize UBGraphicsScene::nominalSize() return mNominalSize; } +/** + * @brief Return the scene's boundary size, including any background item + * + * If no background item is present, this returns nominalSize() + */ +QSize UBGraphicsScene::sceneSize() +{ + UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast(backgroundObject()); + + if (pdfItem) { + QRectF targetRect = pdfItem->sceneBoundingRect(); + return targetRect.size().toSize(); + } + + else + return nominalSize(); +} + void UBGraphicsScene::setNominalSize(const QSize& pSize) { if (nominalSize() != pSize) diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 544aa34c..18a8c05a 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -286,6 +286,8 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem QSize nominalSize(); + QSize sceneSize(); + void setNominalSize(const QSize& pSize); void setNominalSize(int pWidth, int pHeight); diff --git a/src/domain/UBGraphicsStrokesGroup.cpp b/src/domain/UBGraphicsStrokesGroup.cpp index 5d418d01..da2c4deb 100644 --- a/src/domain/UBGraphicsStrokesGroup.cpp +++ b/src/domain/UBGraphicsStrokesGroup.cpp @@ -148,12 +148,15 @@ void UBGraphicsStrokesGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) UBItem* UBGraphicsStrokesGroup::deepCopy() const { QTransform groupTransform = transform(); + QPointF groupPos = pos(); UBGraphicsStrokesGroup* copy = new UBGraphicsStrokesGroup(); copyItemParameters(copy); copy->resetTransform(); + copy->setPos(0,0); const_cast(this)->resetTransform(); + const_cast(this)->setPos(0,0); QList chl = childItems(); @@ -175,7 +178,9 @@ UBItem* UBGraphicsStrokesGroup::deepCopy() const } } const_cast(this)->setTransform(groupTransform); + const_cast(this)->setPos(groupPos); copy->setTransform(groupTransform); + copy->setPos(groupPos); return copy; } diff --git a/src/gui/UBDocumentTreeWidget.cpp b/src/gui/UBDocumentTreeWidget.cpp index b6728e4c..2339e120 100644 --- a/src/gui/UBDocumentTreeWidget.cpp +++ b/src/gui/UBDocumentTreeWidget.cpp @@ -285,13 +285,16 @@ void UBDocumentTreeWidget::dropEvent(QDropEvent *event) QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); QString target = targetDocProxy->persistencePath() + "/" + relativeFile.toString(); + QString sourceDecoded = scene->document()->persistencePath() + "/" + relativeFile.toString(QUrl::DecodeReserved); + QString targetDecoded = targetDocProxy->persistencePath() + "/" + relativeFile.toString(QUrl::DecodeReserved); + if(QFileInfo(source).isDir()) UBFileSystemUtils::copyDir(source,target); else{ - QFileInfo fi(target); + QFileInfo fi(targetDecoded); QDir d = fi.dir(); d.mkpath(d.absolutePath()); - QFile::copy(source, target); + QFile::copy(sourceDecoded, targetDecoded); } } diff --git a/src/tools/UBGraphicsCurtainItemDelegate.cpp b/src/tools/UBGraphicsCurtainItemDelegate.cpp index 0209cd74..9e4071fb 100644 --- a/src/tools/UBGraphicsCurtainItemDelegate.cpp +++ b/src/tools/UBGraphicsCurtainItemDelegate.cpp @@ -38,7 +38,7 @@ #include "core/memcheck.h" UBGraphicsCurtainItemDelegate::UBGraphicsCurtainItemDelegate(UBGraphicsCurtainItem* pDelegated, QObject * parent) - : UBGraphicsItemDelegate(pDelegated, parent, GF_SCALABLE_ALL_AXIS | GF_MENU_SPECIFIED) + : UBGraphicsItemDelegate(pDelegated, parent, GF_MENU_SPECIFIED) { //NOOP }