Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package heimer for openSUSE:Factory checked in at 2022-08-01 21:32:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/heimer (Old) and /work/SRC/openSUSE:Factory/.heimer.new.1533 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "heimer" Mon Aug 1 21:32:58 2022 rev:4 rq:991944 version:3.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/heimer/heimer.changes 2022-06-29 16:02:37.296723603 +0200 +++ /work/SRC/openSUSE:Factory/.heimer.new.1533/heimer.changes 2022-08-01 21:34:07.098296700 +0200 @@ -1,0 +2,14 @@ +Mon Aug 1 07:22:13 UTC 2022 - Michael Vetter <mvet...@suse.com> + +- Update to 3.5.0: + * Fix GitHub Issue #112: Optimizer: Take current node locations + into account when building initial layout + + This change makes the optimizer way more stable with respect + to the original global placement + + Tries to find the best possible initial locations for the + nodes in a normalized coordinate space + + Makes only local changes within a very small search radius + (row-wise and cell-wise) + * Update German and Dutch translations + +------------------------------------------------------------------- Old: ---- 3.4.0.tar.gz New: ---- 3.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ heimer.spec ++++++ --- /var/tmp/diff_new_pack.e2BvFf/_old 2022-08-01 21:34:07.642298261 +0200 +++ /var/tmp/diff_new_pack.e2BvFf/_new 2022-08-01 21:34:07.650298284 +0200 @@ -18,7 +18,7 @@ Name: heimer -Version: 3.4.0 +Version: 3.5.0 Release: 0 Summary: Mind map, diagram, and note-taking tool License: CC-BY-SA-3.0 AND GPL-3.0-only ++++++ 3.4.0.tar.gz -> 3.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/CHANGELOG new/Heimer-3.5.0/CHANGELOG --- old/Heimer-3.4.0/CHANGELOG 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/CHANGELOG 2022-07-30 20:14:08.000000000 +0200 @@ -9,6 +9,26 @@ Other: +3.5.0 +===== + +Release date: + +Sat, 30 Jul 2022 21:12:12 +0300 + +New features: + +* Fix GitHub Issue #112: Optimizer: Take current node locations into account when building initial layout + - This change makes the optimizer way more stable with respect to the original global placement + - Tries to find the best possible initial locations for the nodes in a normalized coordinate space + - Makes only local changes within a very small search radius (row-wise and cell-wise) + +Other: + +* Update German translations + +* Update Dutch translations + 3.4.0 ===== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/CMakeLists.txt new/Heimer-3.5.0/CMakeLists.txt --- old/Heimer-3.4.0/CMakeLists.txt 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/CMakeLists.txt 2022-07-30 20:14:08.000000000 +0200 @@ -26,7 +26,7 @@ # Global version set(VERSION_MAJOR 3) -set(VERSION_MINOR 4) +set(VERSION_MINOR 5) set(VERSION_PATCH 0) set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") @@ -94,7 +94,7 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(QT_MIN_VER 5.5.1) # The version in Ubuntu 16.04 +set(QT_MIN_VER 5.9.5) # The version in Ubuntu 18.04 LTS # This is what Qt Creator 4.13.2 would generate find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Xml Widgets LinguistTools Svg Test Network REQUIRED) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/Jenkinsfile new/Heimer-3.5.0/Jenkinsfile --- old/Heimer-3.4.0/Jenkinsfile 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/Jenkinsfile 2022-07-30 20:14:08.000000000 +0200 @@ -113,6 +113,22 @@ } } } + stage('Source .tar.gz') { + agent { + docker { + image 'juzzlin/qt5-22.04:latest' + args '--privileged -t -v $WORKSPACE:/heimer' + } + } + steps { + sh "./scripts/build-archive" + } + post { + always { + archiveArtifacts artifacts: 'heimer*.tar.gz', fingerprint: true + } + } + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/scripts/build-app-image new/Heimer-3.5.0/scripts/build-app-image --- old/Heimer-3.4.0/scripts/build-app-image 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/scripts/build-app-image 2022-07-30 20:14:08.000000000 +0200 @@ -2,7 +2,7 @@ # Builds AppImage in Docker -HEIMER_VERSION=3.4.0 +HEIMER_VERSION=3.5.0 CMD="export LANG=en_US.UTF-8 && \ export LC_ALL=en_US.UTF-8 && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/scripts/build-archive new/Heimer-3.5.0/scripts/build-archive --- old/Heimer-3.4.0/scripts/build-archive 1970-01-01 01:00:00.000000000 +0100 +++ new/Heimer-3.5.0/scripts/build-archive 2022-07-30 20:14:08.000000000 +0200 @@ -0,0 +1 @@ +git archive --format=tar.gz --prefix=heimer-3.5.0/ HEAD > heimer-3.5.0.tar.gz diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/scripts/build-windows-zip new/Heimer-3.5.0/scripts/build-windows-zip --- old/Heimer-3.4.0/scripts/build-windows-zip 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/scripts/build-windows-zip 2022-07-30 20:14:08.000000000 +0200 @@ -2,7 +2,7 @@ # Builds ZIP archive for Windows in Docker -VERSION=3.4.0 +VERSION=3.5.0 CMAKE=/mxe/usr/bin/i686-w64-mingw32.static-cmake diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/scripts/update-version new/Heimer-3.5.0/scripts/update-version --- old/Heimer-3.4.0/scripts/update-version 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/scripts/update-version 2022-07-30 20:14:08.000000000 +0200 @@ -18,9 +18,9 @@ sed -i "s/^set(VERSION_MINOR.*/set(VERSION_MINOR ${VERSION_MINOR})/" ${FILE} ||??exit 1 sed -i "s/^set(VERSION_PATCH.*/set(VERSION_PATCH ${VERSION_PATCH})/" ${FILE} ||??exit 1 -for FILE in heimer.pro snapcraft.yaml scripts/build-app-image scripts/build-windows-zip; do +for FILE in heimer.pro snapcraft.yaml scripts/build-app-image scripts/build-archive scripts/build-windows-zip; do echo "Updating ${FILE} .." - sed -i -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/" ${FILE} ||??exit 1 + sed -i -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/g" ${FILE} ||??exit 1 done git diff diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/snapcraft.yaml new/Heimer-3.5.0/snapcraft.yaml --- old/Heimer-3.4.0/snapcraft.yaml 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/snapcraft.yaml 2022-07-30 20:14:08.000000000 +0200 @@ -1,5 +1,5 @@ name: heimer -version: '3.4.0' +version: '3.5.0' summary: Heimer is a simple cross-platform mind map tool. description: | Heimer is a simple cross-platform mind map creation tool. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/layout_optimizer.cpp new/Heimer-3.5.0/src/layout_optimizer.cpp --- old/Heimer-3.4.0/src/layout_optimizer.cpp 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/layout_optimizer.cpp 2022-07-30 20:14:08.000000000 +0200 @@ -58,7 +58,7 @@ { juzzlin::L().info() << "Initializing LayoutOptimizer: aspectRatio=" << aspectRatio << ", minEdgeLength=" << minEdgeLength; - if (m_mindMapData->graph().numNodes() == 0) { + if (!m_mindMapData->graph().numNodes()) { juzzlin::L().info() << "No nodes"; return false; } @@ -68,16 +68,18 @@ area += (node->size().width() + minEdgeLength) * (node->size().height() + minEdgeLength); } - const double height = std::sqrt(area / aspectRatio); - const double width = area / height; - - // Builds initial layout + // Build initial layout auto nodes = m_mindMapData->graph().getNodes(); + const auto originalLayoutDimensions = calculateLayoutDimensions(nodes); + juzzlin::L().info() << "Area: " << originalLayoutDimensions.height() * originalLayoutDimensions.width(); + const double height = std::sqrt(area / aspectRatio); + const double width = area / height; m_layout = std::make_unique<Layout>(); m_layout->cols = static_cast<size_t>(width / (Constants::Node::MIN_WIDTH + minEdgeLength)) + 1; m_layout->minEdgeLength = minEdgeLength; std::map<int, std::shared_ptr<Cell>> nodesToCells; // Used when building connections + std::vector<std::shared_ptr<Cell>> cells; const auto rows = static_cast<size_t>(height / (Constants::Node::MIN_HEIGHT + minEdgeLength)) + 1; for (size_t j = 0; j < rows; j++) { const auto row = std::make_shared<Row>(); @@ -86,21 +88,56 @@ for (size_t i = 0; i < m_layout->cols; i++) { const auto cell = std::make_shared<Cell>(); row->cells.push_back(cell); - cell->rect.x = row->rect.x + static_cast<int>(i) * Constants::Node::MIN_WIDTH; - cell->rect.y = row->rect.y; - cell->rect.h = Constants::Node::MIN_HEIGHT; - cell->rect.w = Constants::Node::MIN_WIDTH; - - if (!nodes.empty()) { - m_layout->all.push_back(cell); - cell->node = nodes.back(); - nodesToCells[cell->node.lock()->index()] = cell; - nodes.pop_back(); - } + cells.push_back(cell); + cell->rect = { row->rect.x + static_cast<int>(i) * Constants::Node::MIN_WIDTH, + row->rect.y, + Constants::Node::MIN_HEIGHT, + Constants::Node::MIN_WIDTH }; } m_layout->rows.push_back(row); } + m_rowDist = std::uniform_int_distribution<size_t> { 0, m_layout->rows.size() - 1 }; + + // Assign nodes to nearest cells + + double minX = std::numeric_limits<double>::max(); + double maxX = -minX; + double minY = std::numeric_limits<double>::max(); + double maxY = -minY; + for (auto && cell : cells) { + minX = std::min(minX, cell->x()); + maxX = std::max(maxX, cell->x()); + minY = std::min(minY, cell->y()); + maxY = std::max(maxY, cell->y()); + } + const double cellAreaW = maxX - minX; + const double cellAreaH = maxY - minY; + + for (auto && node : nodes) { + if (!cells.empty()) { + size_t nearestCellIndex = 0; + double nearestDistance = std::numeric_limits<double>::max(); + for (size_t i = 0; i < cells.size(); i++) { + const auto cell = cells.at(i); + const auto dx = (cell->x() - minX - cellAreaW / 2) / cellAreaW - (node->location().x() - originalLayoutDimensions.x() - originalLayoutDimensions.width() / 2) / originalLayoutDimensions.width(); + const auto dy = (cell->y() - minY - cellAreaH / 2) / cellAreaH - (node->location().y() - originalLayoutDimensions.y() - originalLayoutDimensions.height() / 2) / originalLayoutDimensions.height(); + if (double distance = dx * dx + dy * dy; distance < nearestDistance) { + nearestDistance = distance; + nearestCellIndex = i; + } + } + const auto cell = cells.at(nearestCellIndex); + cell->node = node; + cells.at(nearestCellIndex) = cells.back(); + cells.pop_back(); + nodesToCells[node->index()] = cell; + m_layout->all.push_back(cell); + } else { + return false; + } + } + // Setup connections for (auto && edge : m_mindMapData->graph().getEdges()) { @@ -122,73 +159,38 @@ } OptimizationInfo oi; - double cost = calculateCost(); - oi.initialCost = cost; - juzzlin::L().info() << "Initial cost: " << oi.initialCost; + oi.initialCost = calculateCost(); + oi.currentCost = oi.initialCost; + oi.sliceSize = m_layout->all.size() * 200; + oi.t0 = 33; + oi.tC = oi.t0; - std::uniform_real_distribution<double> dist { 0, 1 }; + juzzlin::L().info() << "Initial cost: " << oi.initialCost; - // TODO: Automatically decide optimal t - const double t0 = 200; - double t = t0; - while (t > 0.05 && cost > 0) { - double acceptRatio = 0; - int stuck = 0; + while (oi.tC > oi.t1 && oi.currentCost > 0) { + oi.acceptRatio = 0; + size_t stuckCounter = 0; do { - double accepts = 0; - double rejects = 0; - double sliceCost = cost; - for (size_t i = 0; i < m_layout->all.size() * 200; i++) { - const auto change = planChange(); - - LayoutOptimizer::Impl::Cell::globalMoveId++; - - double newCost = cost; - newCost -= change.sourceCell->getCost(); - newCost -= change.targetCell->getCost(); - - doChange(change); - oi.changes++; - - LayoutOptimizer::Impl::Cell::globalMoveId++; - - newCost += change.sourceCell->getCost(); - newCost += change.targetCell->getCost(); - - const double delta = newCost - cost; - if (delta <= 0) { - cost = newCost; - accepts++; - } else { - if (dist(m_engine) < std::exp(-delta / t)) { - cost = newCost; - accepts++; - } else { - undoChange(change); - rejects++; - } - } - } - - acceptRatio = accepts / (rejects + 1); - const double gain = (cost - sliceCost) / sliceCost; - juzzlin::L().debug() << "Cost: " << cost << " (" << gain * 100 << "%)" - << " acc: " << acceptRatio << " t: " << t; - - if (gain < 0.1) { - stuck++; - } else { - stuck = 0; + oi.accepts = 0; + oi.rejects = 0; + double sliceCost = oi.currentCost; + for (size_t i = 0; i < oi.sliceSize; i++) { + changeLayoutAndUpdateCost(oi); } + oi.acceptRatio = static_cast<double>(oi.accepts) / static_cast<double>(oi.rejects + 1); + const double gain = (oi.currentCost - sliceCost) / sliceCost; + juzzlin::L().debug() << "Cost: " << oi.currentCost << " (" << gain * 100 << "%)" + << " acc: " << oi.acceptRatio << " t: " << oi.tC; + stuckCounter = gain < oi.stuckTh ? stuckCounter + 1 : 0; - } while (stuck < 5); + } while (stuckCounter < oi.stuckLimit); - t *= 0.7; + oi.tC *= oi.cS; - updateProgress(std::min(1.0, 1.0 - std::log(t) / std::log(t0))); + updateProgress(std::min(1.0, 1.0 - std::log(oi.tC) / std::log(oi.t0))); } - oi.finalCost = cost; + oi.finalCost = oi.currentCost; return oi; } @@ -216,6 +218,18 @@ } private: + QRectF calculateLayoutDimensions(const Graph::NodeVector & nodes) const + { + if (nodes.empty()) { + return {}; + } + QRectF dimensions = nodes.at(0)->placementBoundingRect(); + for (auto && node : nodes) { + dimensions = dimensions.united(node->placementBoundingRect().translated(node->location())); + } + return dimensions; + } + double calculateCost() const { return std::accumulate(std::begin(m_layout->all), std::end(m_layout->all), double {}, @@ -253,6 +267,32 @@ size_t targetIndex = 0; }; + void changeLayoutAndUpdateCost(OptimizationInfo & oi) + { + const auto change = planChange(); + LayoutOptimizer::Impl::Cell::globalMoveId++; + double newCost = oi.currentCost; + newCost -= change.sourceCell->getCost(); + newCost -= change.targetCell->getCost(); + doChange(change); + oi.changes++; + LayoutOptimizer::Impl::Cell::globalMoveId++; + newCost += change.sourceCell->getCost(); + newCost += change.targetCell->getCost(); + if (const double delta = newCost - oi.currentCost; delta <= 0) { + oi.currentCost = newCost; + oi.accepts++; + } else { + if (m_saDist(m_engine) < std::exp(-delta / oi.tC)) { + oi.currentCost = newCost; + oi.accepts++; + } else { + undoChange(change); + oi.rejects++; + } + } + } + void doChange(const Change & change) { change.sourceRow->cells.at(change.sourceIndex) = change.targetCell; @@ -273,17 +313,16 @@ change.targetCell->popRect(); } + // Note: Here we plan only very local changes with a very small search radius as we assume that the nodes are already relatively well placed globally. Change planChange() { - std::uniform_int_distribution<size_t> rowDist { 0, m_layout->rows.size() - 1 }; - Change change; change.type = Change::Type::Swap; size_t sourceRowIndex = 0; size_t targetRowIndex = 0; do { - sourceRowIndex = rowDist(m_engine); + sourceRowIndex = m_rowDist(m_engine); change.sourceRow = m_layout->rows.at(sourceRowIndex); if (change.sourceRow->cells.empty()) { continue; @@ -292,13 +331,15 @@ change.sourceIndex = sourceCellDist(m_engine); change.sourceCell = change.sourceRow->cells.at(change.sourceIndex); - targetRowIndex = rowDist(m_engine); + const auto rowDelta = m_oneOrTwoDist(m_engine); + targetRowIndex = sourceRowIndex + rowDelta < m_layout->rows.size() ? sourceRowIndex + rowDelta : sourceRowIndex; change.targetRow = m_layout->rows.at(targetRowIndex); if (change.targetRow->cells.empty()) { continue; } - std::uniform_int_distribution<size_t> targetCellDist { 0, change.targetRow->cells.size() - 1 }; - change.targetIndex = targetCellDist(m_engine); + + const auto cellDelta = m_oneOrTwoDist(m_engine); + change.targetIndex = change.sourceIndex + cellDelta < change.targetRow->cells.size() ? change.sourceIndex + cellDelta : change.sourceIndex; change.targetCell = change.targetRow->cells.at(change.targetIndex); } while (change.sourceCell == change.targetCell); @@ -312,6 +353,18 @@ struct Rect { + Rect() + { + } + + Rect(int x, int y, int w, int h) + : x(x) + , y(y) + , w(w) + , h(h) + { + } + int x = 0; int y = 0; @@ -528,6 +581,13 @@ std::mt19937 m_engine; + // Will be initialized once we now the row count after building the initial layout + std::uniform_int_distribution<size_t> m_rowDist; + + std::uniform_int_distribution<size_t> m_oneOrTwoDist { 0, 1 }; + + std::uniform_real_distribution<double> m_saDist { 0, 1 }; + ProgressCallback m_progressCallback = nullptr; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/layout_optimizer.hpp new/Heimer-3.5.0/src/layout_optimizer.hpp --- old/Heimer-3.4.0/src/layout_optimizer.hpp 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/layout_optimizer.hpp 2022-07-30 20:14:08.000000000 +0200 @@ -33,11 +33,33 @@ struct OptimizationInfo { - double initialCost = 0; + double acceptRatio = 0; + + double currentCost = 0; double finalCost = 0; + double initialCost = 0; + + double tC = 0; + + double t0 = 0; + + double t1 = 0.05; + + double cS = 0.7; + + size_t accepts = 0; + size_t changes = 0; + + size_t rejects = 0; + + size_t sliceSize = 0; + + size_t stuckLimit = 5; + + double stuckTh = 0.1; }; OptimizationInfo optimize(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/translations/heimer_de.ts new/Heimer-3.5.0/src/translations/heimer_de.ts --- old/Heimer-3.4.0/src/translations/heimer_de.ts 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/translations/heimer_de.ts 2022-07-30 20:14:08.000000000 +0200 @@ -490,7 +490,7 @@ <message> <location filename="../main_window.cpp" line="221"/> <source>&Export</source> - <translation></translation> + <translation>&Exportieren</translation> </message> <message> <location filename="../main_window.cpp" line="224"/> @@ -505,7 +505,7 @@ <message> <location filename="../main_window.cpp" line="247"/> <source>&File</source> - <translation></translation> + <translation>&Datei</translation> </message> <message> <location filename="../main_window.cpp" line="250"/> @@ -560,7 +560,7 @@ <message> <location filename="../main_window.cpp" line="346"/> <source>&View</source> - <translation></translation> + <translation>&Ansicht</translation> </message> <message> <location filename="../main_window.cpp" line="349"/> @@ -765,7 +765,7 @@ <message> <location filename="../tool_bar.cpp" line="154"/> <source>Font</source> - <translation></translation> + <translation>Schrift</translation> </message> <message> <location filename="../tool_bar.cpp" line="189"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/translations/heimer_it.ts new/Heimer-3.5.0/src/translations/heimer_it.ts --- old/Heimer-3.4.0/src/translations/heimer_it.ts 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/translations/heimer_it.ts 2022-07-30 20:14:08.000000000 +0200 @@ -6,59 +6,59 @@ <message> <location filename="../dialogs/about_dialog.cpp" line="33"/> <source>About </source> - <translation type="unfinished">informazioni</translation> + <translation>informazioni </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="51"/> <source> is licenced under </source> - <translation type="unfinished"> ?? concesso in licenza sotto </translation> + <translation> ?? concesso in licenza sotto </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="53"/> <source>Package type: </source> - <translation type="unfinished">Tipo di pacchetto: </translation> + <translation>Tipo di pacchetto: </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="54"/> <source>Project website: </source> - <translation type="unfinished">Sito web del progetto: </translation> + <translation>Sito web del progetto: </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="56"/> <source>Support </source> - <translation type="unfinished">Supporto</translation> + <translation>Supporto </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="56"/> <source> via PayPal: </source> - <translation type="unfinished"></translation> + <translation>via PayPal: </translation> </message> </context> <context> <name>AboutDlg</name> <message> <source>About </source> - <translation type="vanished">informazioni</translation> + <translation>informazioni </translation> </message> <message> <source> is licenced under </source> - <translation type="vanished"> ?? concesso in licenza sotto </translation> + <translation> ?? concesso in licenza sotto </translation> </message> <message> <source>Package type: </source> - <translation type="vanished">Tipo di pacchetto: </translation> + <translation>Tipo di pacchetto: </translation> </message> <message> <source>Project website: </source> - <translation type="vanished">Sito web del progetto: </translation> + <translation>Sito web del progetto: </translation> </message> <message> <source>Support </source> - <translation type="vanished">Supporto</translation> + <translation>Supporto </translation> </message> <message> <source> on Patreon: </source> - <translation type="vanished">su Patreon: </translation> + <translation>su Patreon: </translation> </message> </context> <context> @@ -66,7 +66,7 @@ <message> <location filename="../application.cpp" line="198"/> <source>A new version %1 available at <a href='%2'>%2</a></source> - <translation type="unfinished"></translation> + <translation>Una nuova versione %1 disponibile su <a href='%2'>%2</a></translation> </message> <message> <location filename="../application.cpp" line="205"/> @@ -138,27 +138,27 @@ <name>DefaultsDlg</name> <message> <source>Defaults</source> - <translation type="vanished">Predefinito</translation> + <translation>Predefinito</translation> </message> <message> <source>Edge Arrow Style</source> - <translation type="vanished">Stile Bordo Freccia</translation> + <translation>Stile Bordo Freccia</translation> </message> <message> <source>No arrow</source> - <translation type="vanished">Nessuna freccia</translation> + <translation>Nessuna freccia</translation> </message> <message> <source>Single arrow</source> - <translation type="vanished">Singola freccia</translation> + <translation>Singola freccia</translation> </message> <message> <source>Double arrow</source> - <translation type="vanished">Doppia freccia</translation> + <translation>Doppia freccia</translation> </message> <message> <source>Reversed direction</source> - <translation type="vanished">Direzione invertita</translation> + <translation>Direzione invertita</translation> </message> </context> <context> @@ -166,32 +166,32 @@ <message> <location filename="../dialogs/defaults_tab.cpp" line="36"/> <source>Background</source> - <translation type="unfinished">Sfondo</translation> + <translation>Sfondo</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="37"/> <source>Edge color</source> - <translation type="unfinished"></translation> + <translation>Colore del bordo</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="38"/> <source>Grid color</source> - <translation type="unfinished"></translation> + <translation>Colore griglia</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="39"/> <source>Node color</source> - <translation type="unfinished"></translation> + <translation>Colore del nodo</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="40"/> <source>Node text color</source> - <translation type="unfinished"></translation> + <translation>Colore testo nodo</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="61"/> <source>These default settings will be applied each time a new mind map is created.</source> - <translation type="unfinished"></translation> + <translation>Queste impostazioni predefinite verranno applicate ogni volta che viene creata una nuova mappa mentale.</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="76"/> @@ -216,7 +216,7 @@ <message> <location filename="../dialogs/defaults_tab.cpp" line="97"/> <source>Colors</source> - <translation type="unfinished"></translation> + <translation>Colori</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="35"/> @@ -237,7 +237,7 @@ </message> <message> <source>Single arrow</source> - <translation type="vanished">Singola freccia</translation> + <translation>Singola freccia</translation> </message> <message> <location filename="../edge_context_menu.cpp" line="33"/> @@ -293,36 +293,36 @@ <message> <location filename="../dialogs/effects_tab.cpp" line="36"/> <source>Shadow color</source> - <translation type="unfinished"></translation> + <translation>Colore dell'ombra</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="37"/> <source>Selected item shadow color</source> - <translation type="unfinished"></translation> + <translation>Colore ombra oggetto selezionato</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="87"/> <source>Shadows</source> - <translation type="unfinished"></translation> + <translation>Ombre</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="90"/> <source>Shadow effect offset:</source> - <translation type="unfinished"></translation> + <translation>Compensazione dell'effetto ombra:</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="98"/> <source>Shadow blur radius:</source> - <translation type="unfinished"></translation> + <translation>Raggio sfocatura ombra:</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="108"/> <source>Selected item shadow blur radius:</source> - <translation type="unfinished"></translation> + <translation>Raggio di sfocatura dell'ombra dell'oggetto selezionato:</translation> </message> <message> <source>Autosave feature will automatically save your mind map on every modification after it has been initially saved once.</source> - <translation type="obsolete">La funzione di salvataggio automatico salver?? automaticamente la tua mappa mentale ad ogni modifica dopo che ?? stata inizialmente salvata una volta.</translation> + <translation>La funzione di salvataggio automatico salver?? automaticamente la tua mappa mentale su ogni modifica dopo che ?? stata inizialmente salvata una volta.</translation> </message> </context> <context> @@ -349,11 +349,11 @@ </message> <message> <source>Cancel</source> - <translation type="vanished">Cancella</translation> + <translation>Cancella</translation> </message> <message> <source>Optimize</source> - <translation type="vanished">Ottimizza</translation> + <translation>Ottimizza</translation> </message> </context> <context> @@ -437,7 +437,7 @@ </message> <message> <source>&Colors</source> - <translation type="vanished">&Colori</translation> + <translation>&Colori</translation> </message> </context> <context> @@ -464,7 +464,7 @@ </message> <message> <source>Copy on drag</source> - <translation type="vanished">Copia trascinando</translation> + <translation>Copia trascinando</translation> </message> <message> <source>Show grid</source> @@ -506,19 +506,19 @@ </message> <message> <source>Corner radius:</source> - <translation type="vanished">Raggio dell''angolo:</translation> + <translation>Raggio dell''angolo:</translation> </message> <message> <source>Edge width:</source> - <translation type="vanished">Larghezza del bordo:</translation> + <translation>Larghezza del bordo:</translation> </message> <message> <source>Text size:</source> - <translation type="vanished">Dimensione del testo:</translation> + <translation>Dimensione del testo:</translation> </message> <message> <source>Grid size:</source> - <translation type="vanished">Dimensione della griglia:</translation> + <translation>Dimensione della griglia:</translation> </message> <message> <location filename="../main_window.cpp" line="221"/> @@ -572,7 +572,7 @@ </message> <message> <source>&Export to PNG image</source> - <translation type="vanished">&Esporta in immagine PNG</translation> + <translation>&Esporta in immagine PNG</translation> </message> <message> <location filename="../main_window.cpp" line="305"/> @@ -707,11 +707,11 @@ </message> <message> <source>Cancel</source> - <translation type="vanished">Cancella</translation> + <translation>Cancella</translation> </message> <message> <source>Export</source> - <translation type="vanished">Esporta</translation> + <translation>Esporta</translation> </message> </context> <context> @@ -729,7 +729,7 @@ <message> <location filename="../widget_factory.cpp" line="44"/> <source>Reset to defaults</source> - <translation type="unfinished"></translation> + <translation>Ripristina i valori predefiniti</translation> </message> </context> <context> @@ -752,7 +752,7 @@ <message> <location filename="../dialogs/settings_dialog.cpp" line="56"/> <source>Effects</source> - <translation type="unfinished"></translation> + <translation>Effetti</translation> </message> </context> <context> @@ -789,11 +789,11 @@ </message> <message> <source>Cancel</source> - <translation type="vanished">Cancella</translation> + <translation>Cancella</translation> </message> <message> <source>Export</source> - <translation type="vanished">Esporta</translation> + <translation>Esporta</translation> </message> </context> <context> @@ -859,14 +859,14 @@ <message> <location filename="../dialogs/whats_new_dialog.cpp" line="29"/> <source>What's New</source> - <translation type="unfinished"></translation> + <translation>Cosa c'?? di nuovo</translation> </message> </context> <context> <name>WhatsNewDlg</name> <message> <source>What's New</source> - <translation type="vanished">Cosa c'''?? di nuovo</translation> + <translation>Cosa c'?? di nuovo</translation> </message> </context> </TS> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/translations/heimer_nl.ts new/Heimer-3.5.0/src/translations/heimer_nl.ts --- old/Heimer-3.4.0/src/translations/heimer_nl.ts 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/translations/heimer_nl.ts 2022-07-30 20:14:08.000000000 +0200 @@ -6,32 +6,32 @@ <message> <location filename="../dialogs/about_dialog.cpp" line="33"/> <source>About </source> - <translation type="unfinished">Over </translation> + <translation>Over </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="51"/> <source> is licenced under </source> - <translation type="unfinished"> is uitgebracht onder de </translation> + <translation> is uitgebracht onder de </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="53"/> <source>Package type: </source> - <translation type="unfinished">Soort pakket: </translation> + <translation>Soort pakket: </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="54"/> <source>Project website: </source> - <translation type="unfinished">Projectwebsite: </translation> + <translation>Projectwebsite: </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="56"/> <source>Support </source> - <translation type="unfinished">Ondersteunen </translation> + <translation>Ondersteunen </translation> </message> <message> <location filename="../dialogs/about_dialog.cpp" line="56"/> <source> via PayPal: </source> - <translation type="unfinished"> via PayPal: </translation> + <translation> via PayPal: </translation> </message> </context> <context> @@ -70,7 +70,7 @@ <message> <location filename="../application.cpp" line="198"/> <source>A new version %1 available at <a href='%2'>%2</a></source> - <translation type="unfinished"></translation> + <translation>Er is een nieuwe versie, %1, beschikbaar op <a href='%2'>%2</a></translation> </message> <message> <location filename="../application.cpp" line="205"/> @@ -170,32 +170,32 @@ <message> <location filename="../dialogs/defaults_tab.cpp" line="36"/> <source>Background</source> - <translation type="unfinished">Achtergrond</translation> + <translation>Achtergrond</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="37"/> <source>Edge color</source> - <translation type="unfinished"></translation> + <translation>Kaderkleur</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="38"/> <source>Grid color</source> - <translation type="unfinished"></translation> + <translation>Roosterkleur</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="39"/> <source>Node color</source> - <translation type="unfinished"></translation> + <translation>Knoopkleur</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="40"/> <source>Node text color</source> - <translation type="unfinished"></translation> + <translation>Tekstkleur van knoop</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="61"/> <source>These default settings will be applied each time a new mind map is created.</source> - <translation type="unfinished"></translation> + <translation>Deze standaardinstellingen worden toegepast bij het maken nieuwe mindmaps.</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="76"/> @@ -220,7 +220,7 @@ <message> <location filename="../dialogs/defaults_tab.cpp" line="97"/> <source>Colors</source> - <translation type="unfinished"></translation> + <translation>Kleuren</translation> </message> <message> <location filename="../dialogs/defaults_tab.cpp" line="35"/> @@ -297,32 +297,32 @@ <message> <location filename="../dialogs/effects_tab.cpp" line="36"/> <source>Shadow color</source> - <translation type="unfinished"></translation> + <translation>Schaduwkleur</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="37"/> <source>Selected item shadow color</source> - <translation type="unfinished"></translation> + <translation>Schaduwkleur van geselecteerd item</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="87"/> <source>Shadows</source> - <translation type="unfinished"></translation> + <translation>Schaduwen</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="90"/> <source>Shadow effect offset:</source> - <translation type="unfinished"></translation> + <translation>Schaduweffectverschuiving:</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="98"/> <source>Shadow blur radius:</source> - <translation type="unfinished"></translation> + <translation>Schaduwvervaging:</translation> </message> <message> <location filename="../dialogs/effects_tab.cpp" line="108"/> <source>Selected item shadow blur radius:</source> - <translation type="unfinished"></translation> + <translation>Schaduwvervaging van geselecteerd item</translation> </message> <message> <source>Autosave feature will automatically save your mind map on every modification after it has been initially saved once.</source> @@ -729,7 +729,7 @@ <message> <location filename="../widget_factory.cpp" line="44"/> <source>Reset to defaults</source> - <translation type="unfinished"></translation> + <translation>Standaardwaarden</translation> </message> </context> <context> @@ -752,7 +752,7 @@ <message> <location filename="../dialogs/settings_dialog.cpp" line="56"/> <source>Effects</source> - <translation type="unfinished"></translation> + <translation>Effecten</translation> </message> </context> <context> @@ -826,7 +826,7 @@ <message> <location filename="../tool_bar.cpp" line="132"/> <source>Arrow size:</source> - <translation type="unfinished"></translation> + <translation>Pijlgrootte</translation> </message> <message> <location filename="../tool_bar.cpp" line="149"/> @@ -859,7 +859,7 @@ <message> <location filename="../dialogs/whats_new_dialog.cpp" line="29"/> <source>What's New</source> - <translation type="unfinished">Wijzigingslog</translation> + <translation>Wijzigingslog</translation> </message> </context> <context> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Heimer-3.4.0/src/unit_tests/layout_optimizer_test/layout_optimizer_test.cpp new/Heimer-3.5.0/src/unit_tests/layout_optimizer_test/layout_optimizer_test.cpp --- old/Heimer-3.4.0/src/unit_tests/layout_optimizer_test/layout_optimizer_test.cpp 2022-06-26 20:42:56.000000000 +0200 +++ new/Heimer-3.5.0/src/unit_tests/layout_optimizer_test/layout_optimizer_test.cpp 2022-07-30 20:14:08.000000000 +0200 @@ -125,7 +125,7 @@ QVERIFY(optimizationInfo.changes > 100); const double gain = (optimizationInfo.finalCost - optimizationInfo.initialCost) / optimizationInfo.initialCost; juzzlin::L().info() << "Final cost: " << optimizationInfo.finalCost << " (" << gain * 100 << "%)"; - QVERIFY(gain < -0.3); + QVERIFY(gain < -0.25); lol.extract(); for (auto && node : nodes) {