diff --git a/OpenBoard.pro b/OpenBoard.pro index 64955fb9e..673e51d73 100644 --- a/OpenBoard.pro +++ b/OpenBoard.pro @@ -10,7 +10,7 @@ CONFIG += debug_and_release \ VERSION_MAJ = 1 VERSION_MIN = 3 -VERSION_PATCH = 5 +VERSION_PATCH = 6 VERSION_TYPE = r # a = alpha, b = beta, rc = release candidate, r = release, other => error VERSION_BUILD = 0 diff --git a/resources/etc/OpenBoard.config b/resources/etc/OpenBoard.config index cdef9239f..c332d35a5 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 3786d4651..a65aef29e 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 @@ -842,11 +842,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 @@ -939,11 +939,11 @@ Saving document... - + Salvataggio documento... Document has just been saved... - + Il documento è stato appena salvato... @@ -1004,7 +1004,7 @@ Show OpenBoard - + Mostra OpenBoard @@ -1123,9 +1123,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? @@ -1138,15 +1138,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 @@ -1212,8 +1212,8 @@ %1 pages copied - %1 pagine copiate - + %1 pagina copiata + %1 pagine copiate @@ -1239,23 +1239,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. @@ -1282,19 +1282,19 @@ Export to OpenBoard Format - + Esporta nel formato OpenBoard 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. @@ -1317,15 +1317,15 @@ 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. @@ -1531,19 +1531,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: @@ -1593,23 +1593,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. @@ -1628,7 +1628,7 @@ OpenBoard (*.ubz) - + OpenBoard (*.ubz) @@ -1739,27 +1739,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. @@ -1774,7 +1774,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. @@ -1860,7 +1860,7 @@ Vuoi ignorare gli errori per questo host? OpenBoard Cast - + OpenBoard Cast @@ -1919,7 +1919,7 @@ Vuoi ignorare gli errori per questo host? UBStartupHintsPalette Visible next time - + Visibile la prossima volta @@ -2319,7 +2319,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? @@ -2373,11 +2373,11 @@ p, li { white-space: pre-wrap; } Restore credentials on reboot - + Ripristina le credenziali al riavvio OpenBoard - OpenBoard + OpenBoard @@ -2442,7 +2442,7 @@ p, li { white-space: pre-wrap; } documents OpenBoard Documents - + Documenti OpenBoard @@ -2485,7 +2485,7 @@ p, li { white-space: pre-wrap; } Keyboard button size: - Dimensione pulsanti tastiera: + Dimensione pulsanti tastiera: Toolbar @@ -2585,19 +2585,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 ad9aaa5a4..65db6e639 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(); bool isCrossed = scene->isCrossedBackground(); scene->setBackground(false, false); - 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, isCrossed); } - if(!painterNeedsBegin) pdfPainter.end(); + + if(!painterNeedsBegin) + pdfPainter.end(); return true; } diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 04ea0d222..6464d01bf 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -593,9 +593,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; @@ -654,7 +651,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; @@ -1612,6 +1609,23 @@ void UBBoardController::ClearUndoStack() findUniquesItems(UBApplication::undoStack->command(i), uniqueItems); } + // Get items from clipboard in order not to delete an item that was cut + // (using source URL of graphics items as a surrogate for equality testing) + // This ensures that we can cut and paste a media item, widget, etc. from one page to the next. + QClipboard *clipboard = QApplication::clipboard(); + const QMimeData* data = clipboard->mimeData(); + QList sourceURLs; + + if (data && data->hasFormat(UBApplication::mimeTypeUniboardPageItem)) { + const UBMimeDataGraphicsItem* mimeDataGI = qobject_cast (data); + + if (mimeDataGI) { + foreach (UBItem* sourceItem, mimeDataGI->items()) { + sourceURLs << sourceItem->sourceUrl(); + } + } + } + // go through all unique items, and check, if they are on scene, or not. // if not on scene, than item can be deleted QSetIterator itUniq(uniqueItems); @@ -1623,7 +1637,12 @@ void UBBoardController::ClearUndoStack() scene = dynamic_cast(item->scene()); } - if(!scene) + bool inClipboard = false; + UBItem* ubi = dynamic_cast(item); + if (ubi && sourceURLs.contains(ubi->sourceUrl())) + inClipboard = true; + + if(!scene && !inClipboard) { if (!mActiveScene->deleteItem(item)){ delete item; diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index eff776c54..b5dc37b05 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -73,6 +73,7 @@ #include "document/UBDocumentController.h" +#include "core/UBPersistenceManager.h" #include "core/memcheck.h" UBBoardPaletteManager::UBBoardPaletteManager(QWidget* container, UBBoardController* pBoardController) @@ -846,7 +847,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 e364027d6..c1ebd4775 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(); #ifndef Q_OS_LINUX // No Podcast on Linux yet diff --git a/src/core/UBApplicationController.cpp b/src/core/UBApplicationController.cpp index 36ae40ca8..8b22b47cf 100644 --- a/src/core/UBApplicationController.cpp +++ b/src/core/UBApplicationController.cpp @@ -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()->appSoftwareUpdateURL->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() diff --git a/src/core/UBApplicationController.h b/src/core/UBApplicationController.h index 03ace3a99..c3cfb40dd 100644 --- a/src/core/UBApplicationController.h +++ b/src/core/UBApplicationController.h @@ -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_ */ diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp index 9fef16a1a..8e787e561 100644 --- a/src/core/UBPreferencesController.cpp +++ b/src/core/UBPreferencesController.cpp @@ -186,8 +186,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 cccf87b79..bea6dd66c 100644 --- a/src/core/UBSettings.cpp +++ b/src/core/UBSettings.cpp @@ -225,7 +225,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); + 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", ""); @@ -270,7 +270,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 9f024d57e..c191a4cd0 100644 --- a/src/core/UBSettings.h +++ b/src/core/UBSettings.h @@ -239,7 +239,7 @@ class UBSettings : public QObject UBSetting* appToolBarPositionedAtTop; UBSetting* appToolBarDisplayText; UBSetting* appEnableAutomaticSoftwareUpdates; - UBSetting* appEnableSoftwareUpdates; + UBSetting* appSoftwareUpdateURL; UBSetting* appToolBarOrientationVertical; UBSetting* appPreferredLanguage; diff --git a/src/document/UBDocumentController.cpp b/src/document/UBDocumentController.cpp index ebce0117e..088544f84 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 39e5f635c..62160800b 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 ee23a7bb4..aae00f2b7 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 4185fe40d..851e38f7e 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 dd5ed396f..4af649dac 100644 --- a/src/domain/UBGraphicsMediaItem.h +++ b/src/domain/UBGraphicsMediaItem.h @@ -207,11 +207,14 @@ protected slots: 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/UBGraphicsPolygonItem.h b/src/domain/UBGraphicsPolygonItem.h index eb5eb8156..8dcc26b1b 100644 --- a/src/domain/UBGraphicsPolygonItem.h +++ b/src/domain/UBGraphicsPolygonItem.h @@ -109,6 +109,8 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem qreal originalWidth() { return mOriginalWidth;} bool isNominalLine() {return mIsNominalLine;} + void setNominalLine(bool isNominalLine) { mIsNominalLine = isNominalLine; } + QColor colorOnDarkBackground() const { return mColorOnDarkBackground; diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index fe0cdcc73..a70c55282 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -893,6 +893,7 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) UBGraphicsPolygonItem* polygonItem = new UBGraphicsPolygonItem(intersectedPolygons[i][j], intersectedPolygonItem->parentItem()); intersectedPolygonItem->copyItemParameters(polygonItem); + polygonItem->setNominalLine(false); polygonItem->setStroke(intersectedPolygonItem->stroke()); polygonItem->setStrokesGroup(intersectedPolygonItem->strokesGroup()); intersectedPolygonItem->strokesGroup()->addToGroup(polygonItem); @@ -2209,15 +2210,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; } @@ -2257,6 +2262,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 29966f6d8..43a298366 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -277,6 +277,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/UBGraphicsStroke.cpp b/src/domain/UBGraphicsStroke.cpp index 7e124a116..c9b456d83 100644 --- a/src/domain/UBGraphicsStroke.cpp +++ b/src/domain/UBGraphicsStroke.cpp @@ -75,9 +75,10 @@ bool UBGraphicsStroke::hasPressure() if (!pol->isNominalLine() || pol->originalWidth() != nominalWidth) return true; } + return false; } - return false; + return true; } diff --git a/src/domain/UBGraphicsStrokesGroup.cpp b/src/domain/UBGraphicsStrokesGroup.cpp index 5d418d011..da2c4deb8 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/domain/UBGraphicsTextItemDelegate.cpp b/src/domain/UBGraphicsTextItemDelegate.cpp index 34b866e64..dfb459899 100644 --- a/src/domain/UBGraphicsTextItemDelegate.cpp +++ b/src/domain/UBGraphicsTextItemDelegate.cpp @@ -339,7 +339,10 @@ void UBGraphicsTextItemDelegate::pickFont() curCursor.mergeCharFormat(format); delegated()->setTextCursor(curCursor); - delegated()->setFont(selectedFont); + + if (curCursor.selectedText().length() == 0) + delegated()->setFont(selectedFont); + delegated()->setSelected(true); delegated()->document()->adjustSize(); delegated()->contentsChanged(); diff --git a/src/domain/UBSelectionFrame.cpp b/src/domain/UBSelectionFrame.cpp index ed3cbbd32..0ebc912d7 100644 --- a/src/domain/UBSelectionFrame.cpp +++ b/src/domain/UBSelectionFrame.cpp @@ -111,9 +111,15 @@ void UBSelectionFrame::setEnclosedItems(const QList 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 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()); diff --git a/src/domain/UBSelectionFrame.h b/src/domain/UBSelectionFrame.h index 47d482a64..cda1f5f00 100644 --- a/src/domain/UBSelectionFrame.h +++ b/src/domain/UBSelectionFrame.h @@ -103,6 +103,8 @@ private slots: QPointF mLastTranslateOffset; qreal mRotationAngle; + bool mIsLocked; + QList mButtons; DelegateButton *mDeleteButton; diff --git a/src/frameworks/UBVersion.cpp b/src/frameworks/UBVersion.cpp index a08c4fc72..b8916152b 100644 --- a/src/frameworks/UBVersion.cpp +++ b/src/frameworks/UBVersion.cpp @@ -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: diff --git a/src/gui/UBDocumentTreeWidget.cpp b/src/gui/UBDocumentTreeWidget.cpp index b6728e4cb..2339e1206 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/UBGraphicsCompass.cpp b/src/tools/UBGraphicsCompass.cpp index 20c1c28bd..d1180d5dd 100644 --- a/src/tools/UBGraphicsCompass.cpp +++ b/src/tools/UBGraphicsCompass.cpp @@ -308,6 +308,7 @@ void UBGraphicsCompass::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { updateResizeCursor(); updateDrawCursor(); + mDrewCenterCross = false; event->accept(); } else if (closeButtonRect().contains(event->pos())) diff --git a/src/tools/UBGraphicsCurtainItemDelegate.cpp b/src/tools/UBGraphicsCurtainItemDelegate.cpp index 0209cd744..9e4071fb7 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 }